Esempio n. 1
0
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;
	}
}
Esempio n. 2
0
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);
	}
}
Esempio n. 3
0
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));
		}
	}
}
Esempio n. 4
0
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);
    }
}