Russian Qt Forum
Март 29, 2024, 17:58 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Отключиться от embedded MySQL  (Прочитано 6498 раз)
antoshib
Гость
« : Декабрь 06, 2016, 14:50 »

Экспериментирую тут с Embedded MySQL под Qt, в итоге "оно" через пень колоду заработало.

На данном этапе приложение ломается при завершении и при попытке закрыть соединение.

Лепил по вот этому примеру http://dev.mysql.com/doc/refman/5.7/en/libmysqld-example.html,
с адаптацией под использование Qt классов для работы с БД, т.е.:

Код:
MYSQL       *mysql;

// ... тут соединение с БД

    QMYSQLDriver *drv = new QMYSQLDriver(mysql);
    QSqlDatabase mydb = QSqlDatabase::addDatabase( drv, "connection1" );

//... тут простой запрос, отрабатывает как надо

// и приложение ломается

    if (!mysql) return;

    QSqlDatabase::removeDatabase( "connection1" );

    mysql_close(mysql);
    mysql_library_end();


Если не использовать кутишные классы и делать, как в примере по ссылке,
то приложение не ломается, закрытие соединения отрабатывает как надо.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #1 : Декабрь 06, 2016, 15:39 »

ну а документацию хотя-бы почитать?
Записан
antoshib
Гость
« Ответ #2 : Декабрь 06, 2016, 15:55 »

ну а документацию хотя-бы почитать?

хотя бы почитал, выход у меня реализован при закрытии виджета, т.е. в отдельной секции.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #3 : Декабрь 06, 2016, 16:09 »

А все здесь должны об этом догадываться по приведенным обрывкам кода?
Записан
antoshib
Гость
« Ответ #4 : Декабрь 06, 2016, 16:51 »

Ок, это выяснили, давайте по существу, пожалуйста, какие еще нужно сведения?
Qt 4.5.2 собраны из исходников static под виндой на MS VC++ Express 2010, MySQL 5.5.30 тоже из исходников собрано.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #5 : Декабрь 07, 2016, 08:07 »

Не нужны ни какие сведения - нужен рабочий код или тестовый код, воспроизводящий проблему.
QMYSQLDriver - это просто ошибка или действительно свой самопальный драйвер?
Что за класс MYSQL?
Для начала код надо проверить на соединение с не-embedded сервером.
P.S. Телепаты все в отпуске...
Записан
antoshib
Гость
« Ответ #6 : Декабрь 07, 2016, 11:38 »

QMYSQLDriver подключается из qsql_mysql_p.h из исходников плагина драйвера mysql (%QTDIR%\src\sql\drivers\mysql\qsql_mysql_p.h) в соответствии с рекомендациями в доках по QSqlDatabase::addDatabase, только там для PostgreSQL, но есть и инструкция для мускуля. И вот тут один из примеров реализации http://stackoverflow.com/questions/8364157/use-mysql-embedded-with-qt.

Вот то, что у меня:
Код:
#include "mainwindow.h"

#include <QtDebug>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlDriver>
#include <QtSql/QtSql>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>


#include <my_config.h>
#include <my_global.h>
#include <mysql.h>
#include "../src/sql/drivers/mysql/qsql_mysql.cpp"

MYSQL       *mysql;
MYSQL_RES   *results;
MYSQL_ROW   record;



static char *server_options[]= { "mysql_test", "--defaults-file=my.ini", NULL };
int             num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
static char *server_groups[] = { "client", "mysqld" "mysql", NULL };


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    qDebug() << "Loading embedded, num_elements"<< num_elements << "..";

    int mli = mysql_library_init(num_elements, server_options, server_groups);

    qDebug() << "init code " << mli;

    mysql = mysql_init(NULL);

    mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP,  "client");
    mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);


    if (mysql != mysql_real_connect( mysql, NULL,NULL,NULL, "mysql", 0, NULL, 0 )){
        qDebug() << "Warning! mysql_real_connect faulted!";
        return;
    }

//
//   Этот код отрабатывает без проблем, но без привязок к классам Qt
//
//    mysql_query(mysql, "SELECT * FROM `user`");
//    results = mysql_store_result(mysql);
//
//    while((record = mysql_fetch_row(results))) {
//       qDebug("%s - %s \n", record[0], record[1]);
//    }
//
//    mysql_free_result(results);
//    mysql_close(mysql);
//    mysql_library_end();



    connect(this, SIGNAL(destroyed()), this, SLOT(releaseMysql()));



    QMYSQLDriver *drv = new QMYSQLDriver(mysql);
    QSqlDatabase mydb = QSqlDatabase::addDatabase( drv, "connection1" );

    qDebug() << "Embedded driver added";

    mydb.setDatabaseName("mysql");

    if ( !mydb.isValid() ){
        qDebug() << "\n\tERR!!! Database driver use fails";
        return;
    }

    qDebug() << "\n\tOK... Database driver accepted";

    if ( mydb.isOpen() ){ //Try to opens the database
        qDebug() << "The database is already opened";
    }else{
        qDebug() << "Try to opens the database";
        mydb.open();
    }


    if (mydb.isOpen()){

        QSqlQuery   query;
        QString     queryText = "SELECT * FROM `user`";
        QSqlRecord  r;

        query = mydb.exec( queryText );

        while( query.next() ){
            r = query.record();
            qDebug("%s - %s \n", r.value(0).toString(), r.value(1).toString());
        }

        qDebug() << "The database is accessable";
    }else
        qDebug() << "Error while opening the database";

}

void MainWindow::releaseMysql(){

    if (!mysql) return;

   // После следующей инструкции возникает эксепшн
   //
    QSqlDatabase::removeDatabase( "connection1" );



    mysql_close(mysql);
    mysql_library_end();

    mysql = 0;
}


MainWindow::~MainWindow()
{

}




Файл проекта:
Код:
QT += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = untitled
TEMPLATE = app

INCLUDEPATH+="C:/mysql/include/"
INCLUDEPATH+=$$[QT_INSTALL_PREFIX]/src/sql/kernel/
INCLUDEPATH+=$$[QT_INSTALL_PREFIX]/include/QtSql/5.4.2/
INCLUDEPATH+=$$[QT_INSTALL_PREFIX]/include/QtCore/5.4.2/QtCore

SOURCES += \
        $$[QT_INSTALL_PREFIX]/src/sql/drivers/mysql/qsql_mysql.cpp\
        main.cpp\
        mainwindow.cpp\


HEADERS  += mainwindow.h

win32:LIBS+="-L C:/mysql/libmysqld/Debug"

Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #7 : Декабрь 07, 2016, 13:35 »

Там по ссылке есть ответ с куском из исходника Qt.
Рекомендация: сделать как указано в исходнике, т.е. закомментировать дефайн, пересобрать плагин с указанием в командной строке при сборке директивы линковки статической библиотеки (типа LIBS+="-L C:/mysql/libmysqld/Debug -l libmysqld"), выбросить всю мускульную шнягу из проекта и подключаться как
Код
C++ (Qt)
QSqlDatabase mydb = QSqlDatabase::addDatabase( "MYSQL", "connection1" );
Пусть QSqlDatabase сам обращается куда надо.
Записан
antoshib
Гость
« Ответ #8 : Декабрь 07, 2016, 14:32 »

А как при подключении libmysqld узнает о существовании папки с данными или хотя бы my.ini? При сборке модуля это нигде не указывается. Дефайн комментировал, либы подключал.
Попробую, вдруг пойдет по дефолтным настройкам.

upd: не, так не прокатывает - не может открыть бд
« Последнее редактирование: Декабрь 07, 2016, 15:11 от antoshib » Записан
antoshib
Гость
« Ответ #9 : Декабрь 07, 2016, 16:01 »

Вынес все таки в отдельный блок addDatabase и стало работать без эксепшена, только ругается при отключении.

QSqlDatabasePrivate::removeDatabase: connection 'connection1' is still in use, all queries will cease to work.


Код:
//...
    QSqlDatabase mydb;
{
    QMYSQLDriver *drv = new QMYSQLDriver(mysql);
    //QSqlDatabase
            mydb = QSqlDatabase::addDatabase( drv, "connection1" );

    qDebug() << "Embedded driver added";

    mydb.setDatabaseName("mysql");

    if ( !mydb.isValid() ){
        qDebug() << "\n\tERR!!! Database driver use fails";
        return;
    }

    qDebug() << "\n\tOK... Database driver accepted";

    if ( mydb.isOpen() ){ //Try to opens the database
        qDebug() << "The database is already opened";
    }else{
        qDebug() << "Try to opens the database";
        mydb.open();
    }
}


    if (mydb.isOpen()){

//...
        query.clear();
        releaseMysql();
        mydb.close();

        qDebug() << "The database is accessable";
    }else
        qDebug() << "Error while opening the database";

Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #10 : Декабрь 07, 2016, 16:54 »

Не надо отключение базы держать вместе с запросом. Лучше переопределить closeEvent у формы и в нем добавить
Код
C++ (Qt)
QSqlDatabase::removeDatabase("connection1");
Но если используются вьюхи с доступом к этой базе, то все-равно будет ругаться.
Записан
antoshib
Гость
« Ответ #11 : Декабрь 07, 2016, 17:17 »

Понял, спасибо!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.111 секунд. Запросов: 22.