Как стать автором
Обновить

Комментарии 34

в первой части ссылку сюда добавьте плиз.
Ок, пока не получается. Хабр ошибку выдает припопытке отредактировать.
Объясните, как так получается, что я открываю базу из множества процессов следующим образом:
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
О! Это возможно. Пойду посмотрю возникает ли нечто подобное в коде.
Почитал коментарии в конце этого документа: у меня это тоже случается когда 'not set to do so'. Как 'set to do so', непонятно.
Если у вас несколько потоков используют одно и тоже соединение к SQLite — это нехорошо, но допустимо, если SQLite работает в режиме сериализации вызовов (по умолчанию — не работает).

Почитайте — тут.
Не несколько потоков, а несколько процессов. Насколько я понимаю, это не относится к тому, что написано в документе. Или относится?
Относится, но не в том смысле) Если лезет ошибка SQLITE_LOCKED, это означает неверную логику работы с соединением. Неважно сколько процессов.

То есть если логика неверна, то неважно сколько процессов — все равно вылезет этот SQLITE_LOCKED.
Я подозреваю, что это возникает в результате того, что я открываю два стейтмента и использую их одновременно. Может такое быть?
Может.
Реквестирую часть про работу с SQLite из Java.
Это я сам нагуглил за первые 5 секунд. Хотелось бы про личный опыт и на каком варианте остановились.
Используйте тег source для оформления кода — он красивее.
Кому-то может показаться интересным, а как именно там удваивается количество записей (SQL запрос не умещается в одну строку и обрезан).
INSERT INTO FOO SELECT * FROM FOO;
Также удобно работать с SQLite с помощью библиотеки POCO. Смотреть здесь pocoproject.org/docs/ POCO Data Library.
Приходилось ли Вам решать задачу загрузки sqlite-базы из буфера в памяти?

Знаю, что есть:
1. База :memory:
2. SQLite Backup API
Используя (2) можно загрузить базу из файла на диске в базу в оперативной памяти (1).

А вот как загрузить базу из массива char*? Пока приходится буфер писать во временный файл.

P.S. Пробовал spmemvfs. Но он от 2009 года, и пока у меня не получилось заставить его работать на последнем SQLite.
Мой фреймворк поддерживает репликацию таблиц, баз.

db1.CopyTo(db2)

Я затрону эти вопросы позже, если интересно.
Мне кажется, Вы не поняли вопроса. Реплицировать базу можно через SQLite Backup API, как я написал выше. Как получить db1 из буфера в памяти?
Посмотрите вот на это: spserver.googlecode.com/files/spmemvfs.tar.gz
В данном расширении реализована работа с БД которая при открытии целиком помещается в память, думаю если разобраться как там реализована VFS, то можно написать свое расширение, которое будет работать с базой, которая изначально была в памяти.
про spmemvfs я писал в своем сообщении
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; // <--- и в итоге 
}


А может даже и переписывать ничего не придется, только обточить напильником.
одной функцией load там дело не ограничивается
А как база оказалась внутри массива char?
Пришла по сети, например.
Мне кажется странной идея передавать базу по сети в формате файла. Если это действительно необходимо, то, пожалуй, через сохранение временный файл. Особенно, если база большая.

Если же базы небольшие, то может гнать через сеть, т.н. SQL дамп базы? И применять его к базе в памяти?..

> А вот как загрузить базу из массива char*?

Преобразовать их в insert'ы и выполнить через sqlite3_prepare2/sqlite3_step.
Это как? Под массивом подразумевается не массив значений (кортежей), а массив байт, представляющий из себя базу sqlite, как если бы мы прочитали ее из файла, например, через fopen, fread. Только в данном случае буфер приходит не из файла, а по сети например.
А, извините, я просто не понял вопрос. Я думал, что в массиве char* у вас исходные данные (значения полей в каком-то из традиционных текстовых форматов), а не бинарник файла БД. В этом случае тоже можно выкрутиться — формат известен www.sqlite.org/fileformat.html — но действительно намного проще будет просто записать массив в файл и открыть как файл штатным sqlite3_open.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории