Использование sqlite-winrt из приложения Магазина Windows C ++

Я пытаюсь использовать SQLite-WinRT из приложения Магазина Windows C ++. Я хочу специально использовать оболочку среды выполнения Windows в этом пакете, а не обычный C API из этого пакета. Я пытаюсь взглянуть на пример C #, приведенный на странице codeplex:


Код C #

  // Get the file from the install location
var file = await Package.Current.InstalledLocation.GetFileAsync("cities.db");

// Create a new SQLite instance for the file
var db = new Database(file);

// Open the database asynchronously
await db.OpenAsync(SqliteOpenMode.OpenRead);

// Prepare a SQL statement to be executed
var statement = awaitdb.PrepareStatementAsync(
"SELECT rowid, CityName FROM Cities;");

// Loop through all the results and add to the collection
while (awaitstatement.StepAsync())
items.Add(statement.GetIntAt(0) + ": "+ statement.GetTextAt(1));

Но я не могу понять точный эквивалент C ++ этого кода. Это то, что я до сих пор:


Код C ++

       auto installLoc = Windows::ApplicationModel::Package::Current->InstalledLocation;

task<Windows::Storage::StorageFile^>(installLoc->GetFileAsync("cities.db")).then([](Windows::Storage::StorageFile^ file){
auto db = ref new SQLiteWinRT::Database(file);

task<void>(db->OpenAsync(SQLiteWinRT::SqliteOpenMode::OpenRead)).then([db](){
task<SQLiteWinRT::Statement^>(db->PrepareStatementAsync("SELECT rowid, CityName FROM Cities;")).then([](SQLiteWinRT::Statement^ stmt){
// Don't know how to simulate the while loop
//task<bool>(stmt->StepAsync()).then([](bool ret){
//});
});
});
});

Я не совсем в состоянии понять, как имитировать поведение итерации, как это было сделано с помощью цикла while в C #. Есть указатели?

0

Решение

Не уверен, что это самый простой способ, но одним из способов будет преобразование цикла в рекурсивный вызов. Например что-то вроде этого:

task<void> stepInfoRecursive(std::function<void()> actionToExecute,SQLiteWinRT::Statement^ stmt)
{
return task<bool>(stmt->StepAsync()).then([actionToExecute,stmt](bool ret){
actionToExecute();

if (ret){
return stepInfoRecursive(actionToExecute,stmt);
}
return create_task([]{});

});
}

где actionToExecute будет все, что вы хотите сделать в цикле.

1

Другие решения

С последней версией Компилятор Visual C ++ ноябрь 2013 CTP, и поддержка возобновляемости и ожидания, которая приходит с этим выпуском, код C ++ теперь выглядит как гораздо более читаемый фрагмент кода ниже:

void MainPage::DoStuff() __resumable
{
auto items = ref new Vector<String^>();

auto file = __await Package::Current->InstalledLocation->GetFileAsync("cities.db");
auto db = ref new SQLiteWinRT::Database(file);
__await db->OpenAsync(SQLiteWinRT::SqliteOpenMode::OpenRead);
auto stmt = __await db->PrepareStatementAsync("SELECT rowid, CityName FROM Cities;");
while (__await stmt->StepAsync())
items->Append(stmt->GetIntAt(0) + ": " + stmt->GetTextAt(1));
}
1

Я думаю, что DatabasesCx проще http://www.almanacsoft.com/databasescx

        String^ pathName = Windows::Storage::ApplicationData::Current->LocalFolder->Path + "\\cities.db";
SQLiteCx^ mySql = ref new DatabasesCx::SQLiteCx(pathName);
auto rowsOut = ref new Vector<RowCx^>();
Concurrency::create_task(mySql->GetAsync(L"SELECT rowid, CityName FROM Cities", rowsOut))
.then([this, rowsOut]()
{
itemsViewSource->Source = rowsOut; // Data Binding to control
}, task_continuation_context::use_current());
0

Или вы можете сделать это так:

auto installLoc = Windows::ApplicationModel::Package::Current->InstalledLocation;

task<Windows::Storage::StorageFile^>(installLoc->GetFileAsync("cities.db")).then([](Windows::Storage::StorageFile^ file){
auto db = ref new SQLiteWinRT::Database(file);

task<void>(db->OpenAsync(SQLiteWinRT::SqliteOpenMode::OpenRead)).then([db](){
task<SQLiteWinRT::Statement^>(db->PrepareStatementAsync("SELECT rowid, CityName FROM Cities;")).then([](SQLiteWinRT::Statement^ stmt){

while (bool res = task<bool>(stmt->StepAsync()).get()) {
if (res == true) {

}
}});
});
});
0