Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Another Database Question | MySQL
Forum Updated to NodeBB v4.3 + New Features

Another Database Question | MySQL

Scheduled Pinned Locked Moved General and Desktop
5 Posts 3 Posters 3.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    subin
    wrote on last edited by
    #1

    Hi All,

    I've setup a database handler class as follows.

    dbhandler.h

    @#ifndef DBHANDLER_H
    #define DBHANDLER_H
    #include <QList>
    #include <QtSql>

    class DbHandler
    {
    private:
    QSqlDatabase db;
    QList<QString> _currencyData;
    QList<QString> _lengthData;
    QList<float> _currencyRate;
    QList<float> _lengthRate;
    public:
    DbHandler();
    void readAllData();
    QList<QString> getCurrencyData();
    QList<float> getCurrencyRate();
    QList<QString> getLengthData();
    QList<float> getLengthRate();
    };

    #endif // DBHANDLER_H@

    dbhandler.cpp

    @#include "dbhandler.h"

    DbHandler::DbHandler() {
    db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("convertr");
    db.setUserName("root");
    db.setPassword("toor");
    readAllData(); // If it is called like this, it works fine
    }

    void DbHandler::readAllData() {
    if(db.open()) {
    qDebug() << "Opened database!";
    QSqlQuery qry;
    if(qry.exec("select * from currency;")) {
    while(qry.next()) {
    _currencyData.append(qry.value(0).toString());
    _currencyRate.append(qry.value(1).toFloat());
    }
    qDebug() << "Currency done!";
    }
    else {
    qDebug() << "Fetching currency data from db failed : " << db.lastError().text();
    }
    qry.finish();
    if(qry.exec("select * from length;")) {
    while(qry.next()) {
    _lengthData.append(qry.value(0).toString());
    _lengthRate.append(qry.value(1).toFloat());
    }
    qDebug() << "Length done!";
    }
    else {
    qDebug() << "Fetching length data from db failed";
    }
    qry.finish();
    db.close();
    } else {
    qDebug() << "Something went Wrong : " << db.lastError().text();
    }
    }

    QList<QString> DbHandler::getCurrencyData() {
    return _currencyData;
    }

    QList<float> DbHandler::getCurrencyRate() {
    return _currencyRate;
    }

    QList<QString> DbHandler::getLengthData() {
    return _lengthData;
    }

    QList<float> DbHandler::getLengthRate() {
    return _lengthRate;
    }
    @

    I've an object of this db handler class named _dbH. If I make a call to readAllData() with that object, the applicaion doesn't work. I get the following error.

    @Starting /home/napster/Programs/Learning-Qt/Convertr-build-desktop/Convertr...
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    Something went Wrong : "Driver not loaded Driver not loaded"
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    /home/napster/Programs/Learning-Qt/Convertr-build-desktop/Convertr exited with code 0@

    But, if readAllData() is called from inside the constructor, it works fine.
    Can someone help me out? It may be some stupid misktake of mine, but remember I'm just another n00b! :)

    Thanks & Regards

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bu7ch3r
      wrote on last edited by
      #2

      This is normal behaviour, reported in the documentation. You should read QSqlDatabase Class Reference from the online help.

      Returning to the problem:
      -QSqlQuery qry; when you instance a qyerry like this the default database is used.
      -db = QSqlDatabase::addDatabase("QMYSQL"); If you don't provide as second argument a name for the database this becomes your default database.
      If you have one object as DbHandler everytime you call ReadAllData() Methor db.open will be called. In your case, when you have only a default database, db.open should be called only once. The second call of db.open will close previous connection an open a new one pointing to the same default database. In addition DBHandler should be singletone, or instanced only once. The second instance of DBHandler will throw you the same errors.

      In my opinion in constructor you should call db.open. and remove "if(db.open()) {" from ReadAllData.

      If you want to be sure that the database is open test that in constructor or make an automated variable in your readall method e.g.

      QSqlDatabase localTempDb = QSqlDatabase::database(); // This should return the default database object but in your code you don't need to have a QSqlDatabase object in that method so it's pointless. Open database only once in DBHandler constructor.

      I must repeat again this:D If you have a QSqlQuery object instanced without a name to a database the default database is used when you .exec() the querry.

      In case you must use more than one database you shuld take into consideration naming your databases connections. Again you musthave only one call of .open() for each database object.

      for(int i = 200; i > 0;)
      try
      {
      //do something
      }
      catch(...)
      {
      i--;//try again
      }

      1 Reply Last reply
      0
      • S Offline
        S Offline
        subin
        wrote on last edited by
        #3

        Thank you bu7ch3r

        1 Reply Last reply
        0
        • B Offline
          B Offline
          bu7ch3r
          wrote on last edited by
          #4

          Hope my last post made you thank me. Also I am very sorry about bad(very bad) spelling mistakes but sometimes when I am writing answers I am also debuging or writing code at work :D

          for(int i = 200; i > 0;)
          try
          {
          //do something
          }
          catch(...)
          {
          i--;//try again
          }

          1 Reply Last reply
          0
          • G Offline
            G Offline
            goetz
            wrote on last edited by
            #5

            A better place to open the database connection (and close it) would be at application startup. This way you make sure that nothing reopens an already open database handle and thus avoid invalidating open queries. The main() method or the constructor of your main window are good places for this.

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved