3
Vote

Support ":memory:" and blocking Step() API

description

Hi,

Thanks for the work on this WinRT wrapper. There's just 2 quick additions that we'd appreciate if you could fuse them into the main release of sqlite-winrt.

1) Support in-memory databases by allowing a CTOR that provides a vanilla path, and thus permits to specify RAM-based databases via ":memory:".

2) Opening up the "blocking" sqlite3_step() interface -- essentially by "publicizing" the existing Statement::Step() function, and transferring into it the handling of SqliteReturnCode.

Ad 1) yes, such RAM-based SQLite can get wiped out during some cases of app suspension
-- and I can deal with it. I don't have -that- much penalty for repopulating the SQLite contents
after app re-activation, whereas I need SQLite to compute its query results as fast as it can.

Ad 2), although that horrible overhead of "await stmt.StepAsync()" can be mitigated by
".ConfigureAwait(false)", this still doesn't bring it up-to-speed with non-WinRT implementations.
The usage pattern that makes sense for me - but also for a lot of use cases that aren't ":memory:" -
is to have the first execution step done as "await stmt.StepAsync()", and all the subsequent
"next record" steps to be done via a [blocking] "stmt.Step()".
That first call is sufficient to let our caller off the hook -- after which we can run to completion
as fast as possible, without needing to spawn 1000 tasks for pulling out 1000 records,
.ConfigureAwait(false) nonwithstanding...

The related code changes are small - I paste them below.

Thank you
Boris


1)
Database::Database(String^ path) : 
  m_path(path)
{
}
2)
IAsyncOperation<bool>^ Statement::StepAsync()
{
    return create_async([this]()
    {
        return Step();
    });
}
[now public and bool-returning]
bool Statement::Step(void)
{
    CheckForMoreRows();
    SimulateSlowOperation();
    auto result = (SqliteReturnCode) sqlite3_step(m_statement);

    switch (result)
    {
    case SqliteReturnCode::Done:
        m_noMoreRows = true;
        break;

    case SqliteReturnCode::MoreRows:
        break;

    default:
        ThrowIfStepFailed(result);
        break;
    }
    if (!m_noMoreRows && m_columnsEnabled)
    {
        if (m_columns == nullptr)
            m_columns = ref new Platform::Collections::Map<String^, String^>();
        else
            m_columns->Clear();

        for (auto i = 0; i < GetColumnCount(); i++)
        {
            m_columns->Insert(GetColumnName(i), GetTextAt(i));
        }
    }
    return !m_noMoreRows;
}

comments