[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice/kexi/kexidb
From:       Jarosław Staniek <staniek () kde ! org>
Date:       2010-04-25 22:24:32
Message-ID: 20100425222432.72B3DAC8A4 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1118804 by staniek:

KexiDB
*fix crash or freeze for testing database connection on error or timeout
BUG:124959
CCBUG:234536



 M  +55 -54    utils.cpp  
 M  +1 -1      utils.h  
 M  +24 -5     utils_p.h  


--- trunk/koffice/kexi/kexidb/utils.cpp #1118803:1118804
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2004-2009 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2004-2010 Jarosław Staniek <staniek@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -31,14 +31,16 @@
 #include <qpixmap.h>
 #include <QMutex>
 #include <QSet>
+#include <QProgressBar>
 
 #include <kdebug.h>
 #include <klocale.h>
 #include <kmessagebox.h>
 #include <klocale.h>
 #include <kiconloader.h>
-#include <qprogressbar.h>
 
+#include <memory>
+
 #include "utils_p.h"
 
 using namespace KexiDB;
@@ -334,54 +336,55 @@
 
 //------------------------------------------
 
-class ConnectionTestThread : public QThread
-{
-public:
-    ConnectionTestThread(ConnectionTestDialog *dlg, const KexiDB::ConnectionData& \
                connData);
-    virtual void run();
-protected:
-    ConnectionTestDialog* m_dlg;
-    KexiDB::ConnectionData m_connData;
-};
-
 ConnectionTestThread::ConnectionTestThread(ConnectionTestDialog* dlg, const \
KexiDB::ConnectionData& connData)  : m_dlg(dlg), m_connData(connData)
 {
+    connect(this, SIGNAL(error(const QString&,const QString&)),
+            dlg, SLOT(error(const QString&,const QString&)), Qt::QueuedConnection);
+
+    // try to load driver now because it's not supported in different thread
+    KexiDB::DriverManager manager;
+    m_driver = manager.driver(m_connData.driverName);
+    if (manager.error()) {
+        emitError(&manager);
+        m_driver = 0;
 }
+}
 
+void ConnectionTestThread::emitError(KexiDB::Object* object)
+{
+    QString msg;
+    QString details;
+    KexiDB::getHTMLErrorMesage(object, msg, details);
+    emit error(msg, details);
+}
+
 void ConnectionTestThread::run()
 {
-    KexiDB::DriverManager manager;
-    KexiDB::Driver* drv = manager.driver(m_connData.driverName);
-// KexiGUIMessageHandler msghdr;
-    if (!drv || manager.error()) {
-//move  msghdr.showErrorMessage(&Kexi::driverManager());
-        m_dlg->error(&manager);
+    if (!m_driver) {
         return;
     }
-    KexiDB::Connection * conn = drv->createConnection(m_connData);
-    if (!conn || drv->error()) {
-//move  msghdr.showErrorMessage(drv);
-        delete conn;
-        m_dlg->error(drv);
+    std::auto_ptr<KexiDB::Connection> conn(m_driver->createConnection(m_connData));
+    if (!conn.get() || m_driver->error()) {
+        //kDebug() << "err 1";
+        emitError(m_driver);
         return;
     }
-    if (!conn->connect() || conn->error()) {
-//move  msghdr.showErrorMessage(conn);
-        m_dlg->error(conn);
-        delete conn;
+    if (!conn.get()->connect() || conn.get()->error()) {
+        //kDebug() << "err 2";
+        emitError(conn.get());
         return;
     }
     // SQL database backends like PostgreSQL require executing "USE database"
     // if we really want to know connection to the server succeeded.
     QString tmpDbName;
     if (!conn->useTemporaryDatabaseIfNeeded(tmpDbName)) {
-        m_dlg->error(conn);
-        delete conn;
+        //kDebug() << "err 3";
+        emitError(conn.get());
         return;
     }
-    delete conn;
-    m_dlg->error(0);
+    //kDebug() << "emitError(0)";
+    emitError(0);
 }
 
 ConnectionTestDialog::ConnectionTestDialog(QWidget* parent,
@@ -396,7 +399,7 @@
         , m_connData(data)
         , m_msgHandler(&msgHandler)
         , m_elapsedTime(0)
-        , m_errorObj(0)
+        , m_error(false)
         , m_stopWaiting(false)
 {
     setModal(true);
@@ -417,6 +420,7 @@
 
 int ConnectionTestDialog::exec()
 {
+    //kDebug() << "tid:" << QThread::currentThread() << "this_thread:" << thread();
     m_timer.start(20);
     m_thread->start();
     const int res = KProgressDialog::exec();
@@ -427,20 +431,26 @@
 
 void ConnectionTestDialog::slotTimeout()
 {
-// KexiDBDbg << "ConnectionTestDialog::slotTimeout() " << m_errorObj;
+    //kDebug() << "tid:" << QThread::currentThread() << "this_thread:" << thread();
+    KexiDBDbg << m_error;
     bool notResponding = false;
     if (m_elapsedTime >= 1000*5) {//5 seconds
         m_stopWaiting = true;
         notResponding = true;
     }
+    KexiDBDbg << m_elapsedTime << m_stopWaiting << notResponding;
     if (m_stopWaiting) {
         m_timer.disconnect(this);
         m_timer.stop();
         reject();
+        KexiDBDbg << "after reject";
 //  close();
-        if (m_errorObj) {
-            m_msgHandler->showErrorMessage(m_errorObj);
-            m_errorObj = 0;
+        if (m_error) {
+            KexiDBDbg << "show?";
+            m_msgHandler->showErrorMessage(m_msg, m_details);
+            //m_msgHandler->showErrorMessage(m_errorObj);
+            KexiDBDbg << "shown";
+            m_error = false;
         } else if (notResponding) {
             KMessageBox::sorry(0,
                                i18n("<qt>Test connection to <b>%1</b> database \
server failed. The server is not responding.</qt>", \
m_connData.serverInfoString(true)), @@ -460,27 +470,18 @@
     progressBar()->setValue(m_elapsedTime);
 }
 
-void ConnectionTestDialog::error(KexiDB::Object *obj)
+void ConnectionTestDialog::error(const QString& msg, const QString& details)
 {
-    KexiDBDbg << "ConnectionTestDialog::error()";
+    //kDebug() << "tid:" << QThread::currentThread() << "this_thread:" << thread();
+    kDebug() << msg << details;
     m_stopWaiting = true;
-    m_errorObj = obj;
-    /*  reject();
-        m_msgHandler->showErrorMessage(obj);
-      if (obj) {
+    if (!msg.isEmpty() || !details.isEmpty()) {
+        m_error = true;
+        m_msg = msg;
+        m_details = details;
+        kDebug() << "ERR!";
+//        m_msgHandler->showErrorMessage(msg, details);
       }
-      else {
-        accept();
-      }*/
-    QMutex mutex;
-    mutex.lock();
-#ifdef __GNUC__
-#warning QWaitCondition::wait() OK?
-#else
-#pragma WARNING( QWaitCondition::wait() OK? )
-#endif
-    m_wait.wait(&mutex);
-    mutex.unlock();
 }
 
 void ConnectionTestDialog::reject()
--- trunk/koffice/kexi/kexidb/utils.h #1118803:1118804
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2004-2009 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2004-2010 Jarosław Staniek <staniek@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
--- trunk/koffice/kexi/kexidb/utils_p.h #1118803:1118804
@@ -1,5 +1,5 @@
 /* This file is part of the KDE project
-   Copyright (C) 2006 Jarosław Staniek <staniek@kde.org>
+   Copyright (C) 2006-2010 Jarosław Staniek <staniek@kde.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -27,8 +27,24 @@
 
 #include "msghandler.h"
 
-class ConnectionTestThread;
+class ConnectionTestDialog;
 
+class ConnectionTestThread : public QThread
+{
+    Q_OBJECT
+public:
+    ConnectionTestThread(ConnectionTestDialog *dlg, const KexiDB::ConnectionData& \
connData); +    virtual void run();
+signals:
+    void error(const QString& msg, const QString& details);
+protected:
+    void emitError(KexiDB::Object* object);
+
+    ConnectionTestDialog* m_dlg;
+    KexiDB::ConnectionData m_connData;
+    KexiDB::Driver *m_driver;
+};
+
 class ConnectionTestDialog : protected KProgressDialog
 {
     Q_OBJECT
@@ -39,7 +55,8 @@
 
     int exec();
 
-    void error(KexiDB::Object *obj);
+public slots:
+    void error(const QString& msg, const QString& details);
 
 protected slots:
     void slotTimeout();
@@ -51,9 +68,11 @@
     QTimer m_timer;
     KexiDB::MessageHandler* m_msgHandler;
     uint m_elapsedTime;
-    KexiDB::Object *m_errorObj;
+    bool m_error;
+    QString m_msg;
+    QString m_details;
     QWaitCondition m_wait;
-    bool m_stopWaiting : 1;
+    bool m_stopWaiting;
 };
 
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic