bool statement::exec() { if ( !is_prepared() ) { prepare(); } try { int const r = ::sqlite3_step(impl_); switch ( r ) { case SQLITE_ROW: // statement has result (select for ex.) - update into holders std::for_each(q_.intos().begin(), q_.intos().end(), update(*this)); return s_.last_exec_ = true; case SQLITE_DONE: // reset statement to be ready for the next exec s_.check_error( ::sqlite3_reset(impl_) ); return s_.last_exec_ = false; default: s_.check_error(r); // should never return this return false; } } catch (std::exception const&) { finalize(false); throw; } }
void statement::finalize(bool check_error) // throw { if ( is_prepared() ) { int const r = ::sqlite3_finalize(impl_); impl_ = 0; if ( check_error ) s_.check_error(r); } }
void statement::reset(bool rebind) { if ( is_prepared() ) { s_.check_error( ::sqlite3_reset(impl_) ); if ( rebind ) { std::accumulate(q_.uses().begin(), q_.uses().end(), 1, bind(*this)); } } }
void replica::on_prepare(message_ptr& request) { check_hashed_access(); replica_configuration rconfig; unmarshall(request, rconfig); mutation_ptr mu = mutation::read_from(request); decree decree = mu->data.header.decree; ddebug( "%s: mutation %s on_prepare", name(), mu->name()); dassert (mu->data.header.ballot == rconfig.ballot, ""); if (mu->data.header.ballot < get_ballot()) { ddebug( "%s: mutation %s on_prepare skipped due to old view", name(), mu->name()); return; } // update configuration when necessary else if (rconfig.ballot > get_ballot()) { update_local_configuration(rconfig); } if (PS_INACTIVE == status() || PS_ERROR == status()) { ddebug( "%s: mutation %s on_prepare to %s skipped", name(), mu->name(), enum_to_string(status()) ); ack_prepare_message(ERR_INVALID_STATE, mu); return; } else if (PS_POTENTIAL_SECONDARY == status()) { if (_potential_secondary_states.learning_status != LearningWithPrepare && _potential_secondary_states.learning_status != LearningSucceeded) { ddebug( "%s: mutation %s on_prepare to %s skipped, learnings state = %s", name(), mu->name(), enum_to_string(status()), enum_to_string(_potential_secondary_states.learning_status) ); // do not retry as there may retries later return; } } dassert (rconfig.status == status(), ""); if (decree <= last_committed_decree()) { ack_prepare_message(ERR_SUCCESS, mu); return; } // real prepare start auto mu2 = _prepare_list->get_mutation_by_decree(decree); if (mu2 != nullptr && mu2->data.header.ballot == mu->data.header.ballot) { ddebug( "%s: mutation %s redundant prepare skipped", name(), mu->name()); if (mu2->is_prepared()) { ack_prepare_message(ERR_SUCCESS, mu); } return; } int err = _prepare_list->prepare(mu, status()); dassert (err == ERR_SUCCESS, ""); if (PS_POTENTIAL_SECONDARY == status()) { dassert (mu->data.header.decree <= last_committed_decree() + _options.staleness_for_start_prepare_for_potential_secondary, ""); } else { dassert (PS_SECONDARY == status(), ""); dassert (mu->data.header.decree <= last_committed_decree() + _options.staleness_for_commit, ""); } // write log dassert (mu->log_task() == nullptr, ""); mu->log_task() = _stub->_log->append(mu, LPC_WRITE_REPLICATION_LOG, this, std::bind(&replica::on_append_log_completed, this, mu, std::placeholders::_1, std::placeholders::_2), gpid_to_hash(get_gpid()) ); if (nullptr == mu->log_task()) { err = ERR_FILE_OPERATION_FAILED; ack_prepare_message(err, mu); handle_local_failure(err); } }