Results 1 to 4 of 4

Thread: How to correctly close a database connection

  1. #1
    Join Date
    Nov 2010
    Location
    Cienfuegos, Cuba
    Posts
    16
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default How to correctly close a database connection

    Hi, in my app I use the same database for several objects. Each one creates a new connection to the database on the constructor and in the other functions the databse is opened, a query is executed and the database is closed. On the destructor of the class I use the function QSqlDatabase::removeDatabase("connectionName");. In other words:

    Qt Code:
    1. // I don't have this specified but this class is like abstract, I never instantiates it.
    2. class DAO
    3. {
    4. protected:
    5. private:
    6. QString connName;
    7. public:
    8. DAO(QString dbName, QString connName)
    9. {
    10. this->connName = connName;
    11. this->db = QSqlDatabase::addDatabase("QSQLITE", this->connName);
    12. this->db.setDatabaseName(dbName);
    13. }
    14.  
    15. ~DAO ( )
    16. {
    17. /* when this is executed I receive the warning "QSqlDatabasePrivate::removeDatabase: connection 'this->connName' is still in use, all queries will cease to work" the this->connName is replaced by its value */
    18. QSqlDatabase::removeDatabase(this->connName);
    19. }
    20.  
    21. };
    22.  
    23. // this is the class that I use
    24. class SomethingDAO : public DAO
    25. {
    26. SomethingDAO(QString dbName):DAO(dbName, "something"){};
    27.  
    28. QString getSomethingWithId(int id)
    29. {
    30. this->db.open();
    31. QSqlQuery q(db);
    32. q.exec("...") //the query
    33. this->db.close();
    34.  
    35. // ... stuff with the query
    36. }
    37.  
    38. };
    To copy to clipboard, switch view to plain text mode 

    When I use one of my DAO objetcs I do it like:

    Qt Code:
    1. SomethingDAO*sDAO = new SomethingDAO("data.db3");
    2. QString a = sDAO->getSomethingWithId(1);
    3. delete sDAO;
    To copy to clipboard, switch view to plain text mode 

    I have some other classes like SomethingDAO (Something1DAO, Something2DAO ...), each one especialized on the queries related to a specific class. The problem arises because Something1DAO uses Something2DAO and this uses Something3DAO. In a moment a get by db.lastError().text() the message "Driver not loaded" when trying to open the database. If I comment one of the "create dao object - query - delete dao object" sections this problem is solved but obviously I don't load all the data that I need. Is there a maximum number of connections allowed?

    Initially all my connections had the same name, and in some moment I received the warning of duplicate connection, the database dosn't open, the "driver not loaded" error appears and the program crash, so, for each especialized class the connection name is now "something1" or "something2". With this, the problem is solved but I expect that in some moment the problem appears again if I try to make more connections.

    So, how can I delete all the references to the db connection because it seems that using only QSqlDatabase::removeDatabase(this->connName) is not enought? (in the documentation says that all the objects using the database must be out of scope and I think this is not the problem except by this->db but this is closed).

    Thanks for tips and ideas...
    Last edited by anoraxis; 5th April 2011 at 14:18. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Thanks
    5
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to correctly close a database connection

    Using a QSqlDatabase member object isn't so correct.

    Use QSqlDatabase::database each time you need it using connName

    Qt Code:
    1. // I don't have this specified but this class is like abstract, I never instantiates it.
    2. class DAO
    3. {
    4. protected:
    5. QString connName;
    6. public:
    7. DAO(QString dbName, QString connName)
    8. {
    9. this->connName = connName;
    10. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", this->connName);
    11. db.setDatabaseName(dbName);
    12. }
    13.  
    14. ~DAO ( )
    15. {
    16. /* when this is executed I receive the warning "QSqlDatabasePrivate::removeDatabase: connection 'this->connName' is still in use, all queries will cease to work" the this->connName is replaced by its value */
    17. {
    18. QSqlDatabase db = QSqlDatabase::database(this->connName, false);
    19. if (db.isOpen())
    20. db.close();
    21. }
    22. QSqlDatabase::removeDatabase(this->connName);
    23. }
    24.  
    25. };
    26.  
    27. // this is the class that I use
    28. class SomethingDAO : public DAO
    29. {
    30. SomethingDAO(QString dbName):DAO(dbName, "something"){};
    31.  
    32. QString getSomethingWithId(int id)
    33. {
    34. QSqlDatabase db = QSqlDatabase::database (this->connName); // Open Connection
    35. QSqlQuery q(db);
    36. q.exec("...") //the query
    37. this->db.close();
    38.  
    39. // ... stuff with the query
    40. }
    41.  
    42. };
    To copy to clipboard, switch view to plain text mode 
    Last edited by mcosta; 6th April 2011 at 10:55. Reason: updated contents
    A camel can go 14 days without drink,
    I can't!!!

  3. #3
    Join Date
    Nov 2010
    Location
    Cienfuegos, Cuba
    Posts
    16
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to correctly close a database connection

    Hi and thank you. Your solution works well but I don't want to create a QSqlDatabase every time I need to make a query so I solved the problem using another solution.

    Instead of removing the QSqlDatabase instance from my class I modified the destructor of the class. Now it looks like

    Qt Code:
    1. DAO::~DAO()
    2. {
    3. this->db = QSqlDatabase();
    4. QSqlDatabase::removeDatabase(this->connName);
    5. }
    To copy to clipboard, switch view to plain text mode 

    On the firts instruction of the destructor, the reference to my database is destroyed so now I can remove the database with the removeDatabase function. Tested and working perfect: all the warnings gone!

  4. #4
    Join Date
    Jan 2006
    Location
    Napoli, Italy
    Posts
    621
    Thanks
    5
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to correctly close a database connection

    QSqlDatabase uses Implicit data sharing in order to minimize copying.

    Using my version (suggested by Qt) you copy very small amount of data
    A camel can go 14 days without drink,
    I can't!!!

Similar Threads

  1. QSqlDatabase Connection Close on Destruction
    By Sanuden in forum Qt Programming
    Replies: 1
    Last Post: 1st September 2011, 15:32
  2. Connection With database
    By sudheer168 in forum Qt Programming
    Replies: 4
    Last Post: 22nd December 2010, 09:18
  3. how to reconnect CORRECTLY qmysql database?
    By yaseminyilmaz in forum Newbie
    Replies: 7
    Last Post: 12th January 2010, 13:09
  4. how to reconnect CORRECTLY qmysql database?
    By yaseminyilmaz in forum Qt Programming
    Replies: 0
    Last Post: 31st December 2009, 12:20
  5. Closing correctly sqlite connection?
    By 0xl33t in forum Newbie
    Replies: 1
    Last Post: 9th August 2009, 13:22

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.