LINUX.ORG.RU

Как после ошибки в sqlite3_step прибить sqlite3_stmt?

 


0

1

Судя по документации sqlite3_finalize тут не поможет:

If the most recent evaluation of statement S failed, then sqlite3_finalize(S) returns the appropriate error code or extended error code.

А если я, испугавшись ошибки, перехотел выполнять запрос, что делать?

Ответ на: комментарий от wota

Действительно, помогает. Проверил с помощью valgrind.

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sqlite3.h>

int main(int argc, char *argv[])
{
	sqlite3 *p_db;
	if (sqlite3_open_v2("db.sqlite3", &p_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK)
	{
		puts("Can't open database.");
		return EXIT_FAILURE;
	}

	sqlite3_stmt *p_stmt;
	if
	(
		sqlite3_prepare_v2
		(p_db, "SELECT * FROM sqlite_master;", -1, &p_stmt, NULL) != SQLITE_OK
	)
	{
		puts("Can't prepare statement.");
		return EXIT_FAILURE;
	}

	setvbuf(stdout, NULL, _IONBF, 0);
	unsigned i;
	for (i=5; i>0; i--)
	{
		printf("\x0dYou have %i seconds to lock database.", i);
		sleep(1);
	}
	puts("\x0dYou have 0 seconds to lock database.");

	printf("sqlite3_step return %i\n", sqlite3_step(p_stmt));
	if (argc==2)
		printf("sqlite3_finalize return %i\n", sqlite3_finalize(p_stmt));

	if (sqlite3_close(p_db) != SQLITE_OK)
	{
		puts("Can't close database.");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}

Компилируем

gcc main.c -Wall -lsqlite3 -o main
Запускаем valgrind
valgrind ./main do not finalize
За 5 секунд нужно успеть выполнить
sqlite3 db.sqlite3
и там
BEGIN EXCLUSIVE;
valgrind сообщает, что
possibly lost: 56 bytes in 1 blocks

Теперь в запущенном sqlite3 делаем

COMMIT;
Запускаем valgrind
valgrind ./main finalize
За 5 секунд успеваем выполнить
BEGIN EXCLUSIVE;
И valgrind сообщает, что
no leaks are possible

Теперь можно спать спокойно.

LinuxUser ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.