SQLite на встроенной системе - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь настроить SQLite для работы во встроенной системе (ARM® Cortex®-M7). Я загрузил объединение с веб-сайта SQLite, импортировал его в проект и добавил следующие символы: SQLITE_THREADSAFE = 0, SQLITE_OS_OTHER = 1, SQLITE_OMIT_WAL = 1, чтобы разрешить его компиляцию.

Затем я скачал test_onefile.c (доступно здесь: http://www.sqlite.org/vfs.html), который должен позволять SQLite работать непосредственно на встроенном носителе без использования промежуточной файловой системы, и импортировал его в проект (я также был уверен, что предоставлю sqlite3_os_init () функция для регистрации VFS).

SQLITE_API int sqlite3_os_init(void)
{
    extern int fs_register(void);
    return fs_register();
}

В отдельном файле fs_register () выглядит так:

/*
** This procedure registers the fs vfs with SQLite. If the argument is
** true, the fs vfs becomes the new default vfs. It is the only publicly
** available function in this file.
*/
int fs_register(void)
{
    if (fs_vfs.pParent) return SQLITE_OK;

    fs_vfs.pParent = sqlite3_vfs_find(0);
    fs_vfs.base.mxPathname = fs_vfs.pParent->mxPathname;
    fs_vfs.base.szOsFile = MAX(sizeof(tmp_file), sizeof(fs_file));
    return sqlite3_vfs_register(&fs_vfs.base, 0);
}

Я могу успешно зарегистрировать файловую систему, открыть базу данных и подготовить операторы SQL, используя sqlite3_register_vfs (), sqlite3_open () и sqlite3_prepare (). При открытии базы данных я обязательно использую строку «: memory:» для создания базы данных в памяти, а не в виде файла.

static void TestSQLiteOpenDB(void)
{
    /******** setup ********************************/
    sqlite3 *db;
    int rc;

    /******** run element/component under test *****/
    rc = sqlite3_open(":memory:", &db);
    sqlite3_close(db);

    /******** assertion test ***********************/
    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);
}

Моя проблема возникает при попытке запустить sqlite3_exec (). Программа аварийно завершает работу, когда вызывается следующий фрагмент кода из test_onefile.c:

/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
static int fsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut)
{
   sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
   return pParent->xRandomness(pParent, nByte, zBufOut);
}

Если я изменю эту функцию, чтобы просто вернуть 0, она, кажется, работает. Затем я могу создавать таблицы, вставлять данные в таблицы и т.д. ...

У меня такой вопрос: существует ли необходимость в SQLite для заполнения этого буфера случайными данными или этот обходной путь подходит? Я не хочу создавать дополнительные головные боли для себя, но это было кошмаром, чтобы отследить это как точку отказа, и я не могу полностью обернуть голову вокруг того, что происходит.

1 Ответ

0 голосов
/ 08 мая 2018

SQLite использует эту случайность для временных файлов, для принудительного внесения изменений в файлы журнала / WAL, для генерации уникальных имен столбцов и при переполнении автоинкрементных идентификаторов.

Если возвращаемое значение является постоянным, некоторые из них могут войти в бесконечный цикл, поэтому вы должны попытаться получить фактическую случайность. (Он не должен быть криптографически безопасным.)

...