Комментарии 34
в первой части ссылку сюда добавьте плиз.
Объясните, как так получается, что я открываю базу из множества процессов следующим образом:
sqlite3_open_v2(dbname, &dbconn, SQLITE_OPEN_READONLY, NULL);
но всё равно получаю ошибки «database locked»?
sqlite3_open_v2(dbname, &dbconn, SQLITE_OPEN_READONLY, NULL);
но всё равно получаю ошибки «database locked»?
sqlite.org/c3ref/open.html тут полное описание. База существует, если логика не подводит, то при открытии в RO база уже должна существовать, т.к. создание = запись => запрещено. Других причин не вижу.
Платформа?
Windows.
Ошибка db locked — это совсем не тоже, что и SQLITE_BUSY!
Эта ошибка означает ошибку в приложении. Которая приводит к запутыванию вызовов Sqlite.
Вот тут почитайте www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked
Эта ошибка означает ошибку в приложении. Которая приводит к запутыванию вызовов Sqlite.
Вот тут почитайте www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked
О! Это возможно. Пойду посмотрю возникает ли нечто подобное в коде.
Почитал коментарии в конце этого документа: у меня это тоже случается когда 'not set to do so'. Как 'set to do so', непонятно.
Не несколько потоков, а несколько процессов. Насколько я понимаю, это не относится к тому, что написано в документе. Или относится?
Относится, но не в том смысле) Если лезет ошибка SQLITE_LOCKED, это означает неверную логику работы с соединением. Неважно сколько процессов.
То есть если логика неверна, то неважно сколько процессов — все равно вылезет этот SQLITE_LOCKED.
То есть если логика неверна, то неважно сколько процессов — все равно вылезет этот SQLITE_LOCKED.
Реквестирую часть про работу с SQLite из Java.
Используйте тег source для оформления кода — он красивее.
Кому-то может показаться интересным, а как именно там удваивается количество записей (SQL запрос не умещается в одну строку и обрезан).
Также удобно работать с SQLite с помощью библиотеки POCO. Смотреть здесь pocoproject.org/docs/ POCO Data Library.
Приходилось ли Вам решать задачу загрузки sqlite-базы из буфера в памяти?
Знаю, что есть:
1. База :memory:
2. SQLite Backup API
Используя (2) можно загрузить базу из файла на диске в базу в оперативной памяти (1).
А вот как загрузить базу из массива char*? Пока приходится буфер писать во временный файл.
P.S. Пробовал spmemvfs. Но он от 2009 года, и пока у меня не получилось заставить его работать на последнем SQLite.
Знаю, что есть:
1. База :memory:
2. SQLite Backup API
Используя (2) можно загрузить базу из файла на диске в базу в оперативной памяти (1).
А вот как загрузить базу из массива char*? Пока приходится буфер писать во временный файл.
P.S. Пробовал spmemvfs. Но он от 2009 года, и пока у меня не получилось заставить его работать на последнем SQLite.
Мой фреймворк поддерживает репликацию таблиц, баз.
db1.CopyTo(db2)
Я затрону эти вопросы позже, если интересно.
db1.CopyTo(db2)
Я затрону эти вопросы позже, если интересно.
Мне кажется, Вы не поняли вопроса. Реплицировать базу можно через SQLite Backup API, как я написал выше. Как получить db1 из буфера в памяти?
Посмотрите вот на это: spserver.googlecode.com/files/spmemvfs.tar.gz
В данном расширении реализована работа с БД которая при открытии целиком помещается в память, думаю если разобраться как там реализована VFS, то можно написать свое расширение, которое будет работать с базой, которая изначально была в памяти.
В данном расширении реализована работа с БД которая при открытии целиком помещается в память, думаю если разобраться как там реализована VFS, то можно написать свое расширение, которое будет работать с базой, которая изначально была в памяти.
static void * load( void * arg, const char * path, int * len )
{
//printf( "load ( %p, %s, %p )\n", arg, path, len );
char * ret = NULL;
*len = 0;
FILE * fp = fopen( path, "r" );
if( NULL != fp ) {
struct stat filestat;
if( 0 == stat( path, &filestat ) ) {
*len = filestat.st_size;
ret = (char*)sqlite3_malloc( filestat.st_size + 1 ); // <---!!!!! Смотрим сюда
fread( ret, filestat.st_size, 1, fp ); // <-- потом сюда
ret[ filestat.st_size ] = '\0';
} else {
printf( "cannot stat file %s\n", path );
}
fclose( fp );
} else {
printf( "cannot open file %s\n", path );
}
return ret; // <--- и в итоге
}
А может даже и переписывать ничего не придется, только обточить напильником.
А как база оказалась внутри массива char?
Пришла по сети, например.
> А вот как загрузить базу из массива char*?
Преобразовать их в insert'ы и выполнить через sqlite3_prepare2/sqlite3_step.
Преобразовать их в insert'ы и выполнить через sqlite3_prepare2/sqlite3_step.
Это как? Под массивом подразумевается не массив значений (кортежей), а массив байт, представляющий из себя базу sqlite, как если бы мы прочитали ее из файла, например, через fopen, fread. Только в данном случае буфер приходит не из файла, а по сети например.
А, извините, я просто не понял вопрос. Я думал, что в массиве char* у вас исходные данные (значения полей в каком-то из традиционных текстовых форматов), а не бинарник файла БД. В этом случае тоже можно выкрутиться — формат известен www.sqlite.org/fileformat.html — но действительно намного проще будет просто записать массив в файл и открыть как файл штатным sqlite3_open.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
SQLite — замечательная встраиваемая БД (часть 2)