Russian Qt Forum

Qt => Базы данных => Тема начата: kandrey от Январь 25, 2014, 10:48



Название: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 10:48
Есть необходимость использовать некоторые функции sqlite клиента из sqlite3.h
Можно ли унаследовать QSQLiteDriver или надо полностью реализовывать интерфейсы QSqlDriver и QSqlResult ?
Подскажите, плз, у кого есть опыт.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 10:57
Есть необходимость использовать некоторые функции sqlite клиента из sqlite3.h
Можно ли унаследовать QSQLiteDriver или надо полностью реализовывать интерфейсы QSqlDriver и QSqlResult ?
Подскажите, плз, у кого есть опыт.
Может хватит возможности получить хендл базы и дергать нужные функции sqlite?
Посмотрите на
QVariant QSqlDriver::handle () const [virtual]

В описании есть пример получения.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 11:03
может быть,..
дескриптор sqlite3* удалось получить, а как через него вызвать функцию sqlite ?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 11:04
может быть,..
дескриптор sqlite3* удалось получить, а как через него вызвать функцию sqlite ?
Подключаете нужные хедеры (точней там один хедер) и вызываете.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 11:08
sqlite3.h я подключил
а можно пример, вот мне нужен вызов
const char *sqlite3_column_table_name(sqlite3_stmt*,int)
и как получить указатель на sqlite3_stmt ?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 11:18
sqlite3.h я подключил
а можно пример, вот мне нужен вызов
const char *sqlite3_column_table_name(sqlite3_stmt*,int)
и как получить указатель на sqlite3_stmt ?
int sqlite3_prepare(      sqlite3* db, const char* sql, int sql_len,
                              sqlite3_stmt** stmt_ref, const char** tail );
int sqlite3_prepare16(    sqlite3* db, const void* sql, int sql_len,
                              sqlite3_stmt** stmt_ref, const char** tail );
int sqlite3_prepare_v2(   sqlite3* db, const char* sql, int sql_len,
                              sqlite3_stmt** stmt_ref, const char** tail );
int sqlite3_prepare16_v2( sqlite3* db, const void* sql, int sql_len,
                              sqlite3_stmt** stmt_ref, const char** tail );


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 11:29
undefined reference to `sqlite3_prepare'

у меня бинарная сборка qt 5.2.0, sqlite подключается видимо как плагин


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 11:40
undefined reference to `sqlite3_prepare'

у меня бинарная сборка qt 5.2.0, sqlite подключается видимо как плагин
Можно руками подключить sqlite в свой проект.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 11:51
я вот так добавил

SOURCES += main.cpp\
        widget.cpp \
        C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/src/3rdparty/sqlite/sqlite3.c

HEADERS  += widget.h \
        C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/src/3rdparty/sqlite/sqlite3.h

это правильно?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 11:58
это правильно?
Да.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 11:59
Большое спасибо.


Название: Re: [Решено] Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 12:37
Что то не ладится. Делаю так

            sqlite3_stmt *stmt;
            const char *tail;
            sqlite3_prepare_v2(handle, "select 1", -1, &stmt, &tail);

и sqlite3_prepare_v2 валится на вызове sqlite3_mutex_enter



Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Serr500 от Январь 25, 2014, 14:37
я вот так добавил

SOURCES += main.cpp\
        widget.cpp \
        C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/src/3rdparty/sqlite/sqlite3.c

HEADERS  += widget.h \
        C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/src/3rdparty/sqlite/sqlite3.h

это правильно?
Нет.

Что то не ладится. Делаю так

            sqlite3_stmt *stmt;
            const char *tail;
            sqlite3_prepare_v2(handle, "select 1", -1, &stmt, &tail);

и sqlite3_prepare_v2 валится на вызове sqlite3_mutex_enter
Так и должно быть. Именно потому, что предыдущее неправильно. Почему это не работает - сложно сказать. Какие-то побочные эффекты от дублирования кода в проекте и плагине. Возможно, разные распределители памяти, возможно, разные значения внутренних переменных.

Один хороший программист (мой знакомый) использует следующее решение. Перекомпилировал плагин sqlite так, чтобы он работал с библиотекой sqlite3.dll. Затем ресолвит из этой dll нужные ему функции и использует где необходимо. Всё работает.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 14:53
Нет.
Хотелось бы узнать причину неправильности?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Serr500 от Январь 25, 2014, 14:57
Компиляция sqlite3.dll из amalgamation (GCC/MinGW):
Код:
gcc -O2 -s -fno-keep-inline-dllexport -static-libgcc -mthreads -fexceptions -shared -Wl,--out-implib,libsqlite3.a -o sqlite3.dll sqlite3.c

Компиляция плагина с динамической библиотекой sqlite3.dll (Windows, MinGW):
Код:
cd %QTDIR%\src\plugins\sqldrivers\sqlite
qmake "INCLUDEPATH=%SQLITE_DIR%" "LIBS+=-L%SQLITE_DIR% -lsqlite3"
mingw32-make
Затем кидаем плагины в папку %QTDIR%\plugins\sqldrivers, а sqlite3.dll - в %QTDIR%\bin.

Ресолвим имена:
Код:
typedef int (*pf_sqlite3_open16)(const char*, sqlite3**);
pf_sqlite3_open16 f_sqlite3_open16 = NULL;

QLibrary sqlite3_dll("sqlite3");
if (sqlite3_dll.load()) {
    f_sqlite3_open16 = reinterpret_cast<pf_sqlite3_open16>(sqlite3_dll.resolve("sqlite3_open16"));
}
Далее используем как обычную функцию.

Хотелось бы узнать причину неправильности?
Почему это не работает - сложно сказать. Какие-то побочные эффекты от дублирования кода в проекте и плагине. Возможно, разные распределители памяти, возможно, разные значения внутренних переменных.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 15:00
А как будет выглядеть решение для линукс и андроид ?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 15:03
Почему это не работает - сложно сказать. Какие-то побочные эффекты от дублирования кода в проекте и плагине. Возможно, разные распределители памяти, возможно, разные значения внутренних переменных.
Ребята, какие распределители памяти, какие разные значения переменных? :)
Нужно подключать sqlite с теми же флагами, с которыми это делает Qt, а они перечислены в qtbase/src/3rdparty/sqlite.pri
Кстати, так ее подключать даже удобней. :)

А использовать разделяемую библиотеку лучше, что бы избежать дублирование кода.



Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 15:21
т.е. в .pro файл приложения добавить

DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_RTREE
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
winrt: DEFINES += SQLITE_OS_WINRT

?


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 15:32
т.е. в .pro файл приложения добавить

DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_RTREE
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
winrt: DEFINES += SQLITE_OS_WINRT

?

Попробуйте просто инклюдить sqlite.pri, вместо подключения sqlite.cpp|h
А если не получиться, то да - добавьте эту строку.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 15:47
Попробовал оба варианта. Все так же валится.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 15:50
Попробовал оба варианта. Все так же валится.
Выложите компилируемый проект.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 25, 2014, 15:54
Архив проекта


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: Old от Январь 25, 2014, 16:58
Архив проекта
Да, беру свои слова назад, у меня тоже не получилось с наскоку запустить. С проблемой разбираться сейчас нет времени (думаю это из-за статической конфигурации), поэтому остается вариант с разделяемой библиотекой.


Название: Re: Расширение функциональности драйвера QSQLiteDriver
Отправлено: kandrey от Январь 26, 2014, 14:23
мне кажется если подключать sqlite в проект то решение должно быть примерно таким

    QString dbName = "./test.db";
    sqlite3 *conn = 0;
    int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    sqlite3_open_v2(dbName.toUtf8().constData(), &conn, openMode, NULL);
    QSQLiteDriver *sqliteDrv = new QSQLiteDriver(conn);
    QSqlDatabase db = QSqlDatabase::addDatabase(sqliteDrv);

только у меня ошибка undefined reference QSQLiteDriver, видимо из-за того что драйвер плагином подключен,..как решить пока не знаю