Page 1 of 2 12 LastLast
Results 1 to 20 of 25

Thread: Releasing database file with QSqlDatabase

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Releasing database file with QSqlDatabase

    Hi

    I am struggling to release a database file I use with QSqlDatabase. I need the ability to close the connection and then delete the database file before replacing it with a new database. I can't delete it because the my program is holding onto it. I create my connection using the code below and dbProject is define globally for now.

    Qt Code:
    1. bool createDBConnection() {
    2. if (QSqlDatabase::connectionNames().isEmpty()) {
    3. dbProject = QSqlDatabase::addDatabase("QSQLITE");
    4. }
    5. dbProject.setDatabaseName(active_db_file);
    6. if (!dbProject.open()) {
    7. // Error messages
    8. }
    9. return dbProject.isValid();
    10. }
    To copy to clipboard, switch view to plain text mode 

    To release the file I am trying:
    Qt Code:
    1. dbProject.close();
    To copy to clipboard, switch view to plain text mode 

    According to the QT docs it seems like this should be good enough. Does anybody know why it does not work?

    Thanks
    Jaco
    Last edited by jpn; 19th August 2008 at 12:07. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    Maybe you also need to call QSqlDatabase::removeDatabase()?

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    What is the error you are getting? Something about queries still being active?

  4. #4
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: Releasing database file with QSqlDatabase

    Thanks for the replies.

    I'll try ::removeDatabase() as well. Regarding an error message, I don't get any error message, the QFile remove() just fails since the file is opened by the program. I've verified this by trying to delete the file using an external application like windows explorer, which can't delete it because is being used by another application, my program.

    I'll give removeDatabase() a go.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    Until you have released the database using removeDatabase() a lock is held onto the file, that's correct.

  6. #6
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: Releasing database file with QSqlDatabase

    No unfortunately that did not solve the problem. I've called removeDatabase() but it still keeps a lock on the file. To verify that I'm using it correctly,

    If I add a database like this:
    QSqlDatabase dbProject = QSqlDatabase::addDatabase("QSQLITE");
    dbProject.setDatabaseName(active_db_file);

    I remove it like this:
    dbProject.close();
    QSqlDatabase::removeDatabase(active_db_file);

    Is this correct? If so there is something holding onto the database that I need to find...

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    No, this is wrong. Call removeDatabase() without parameters.

  8. #8
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: Releasing database file with QSqlDatabase

    I tried that but it does not seem to work:

    error: no matching function for call to 'QSqlDatabase::removeDatabase()'
    note: candidates are: static void QSqlDatabase::removeDatabase(const QString&)

    It needs a database name, but for this I've tried both active_db_file and "QSQLITE" without any effect. I've also tried to give a specific name to my connection but this does not seem possible.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    Blah, sorry. Should be:
    Qt Code:
    1. QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
    To copy to clipboard, switch view to plain text mode 
    or

    Qt Code:
    1. QSqlDatabase::removeDatabase(QSqlDatabase::connectionNames().first());
    To copy to clipboard, switch view to plain text mode 
    if you use Qt older than Qt 4.4.

  10. #10
    Join Date
    Aug 2008
    Posts
    132
    Thanks
    23
    Thanked 3 Times in 3 Posts

    Default Re: Releasing database file with QSqlDatabase

    Hi, thanks again for the reply.

    I've tried your suggestions and checked to see if the connectionNames() list is empty after the command which is the case. Thus it removes the database. However it still keeps lock of the database. As I said before, I verify this by using windows explorer to try and delete it. Also, the QFile remove command fails on the file.

    Any idea why the program is not losing the lock on the file?

    Thanks
    Jaco

  11. #11
    Join Date
    Jul 2010
    Posts
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    I'm bumping this thread. Has anyone found a way to resolve this problem as I am having the same issue. If not I'll have to delve into the source code.

    Basically I am doing all of the above in order to release the lock on the file. I have even dynamically created QApplication and my main window which is then deleted after use in main() and then tried to delete the database file from there without success.

    Anyone else have the same problem? It's only an issue on Windows as far as I can tell (ok under Linux).

  12. #12
    Join Date
    Jul 2010
    Posts
    53
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    actually you shouldnt replace database file. you can just drop all database's tables, and voila u have new shiny and clean database.

  13. #13
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Releasing database file with QSqlDatabase

    Be sure you don't have any active queries. Execute finish() on any existing queries.

  14. #14
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    Dear DanH,
    No Way I added the finish() function before to close database connection, but no way, the file is still lock. These are my functions:
    Qt Code:
    1. [...]
    2.  
    3. void myThread1::clearDBConn(){
    4. qry->finish();
    5. db.close();
    6. db.~QSqlDatabase();
    7. QSqlDatabase::removeDatabase(nomeDB);
    8.  
    9.  
    10. }
    11.  
    12. void myThread1::zipDB(){
    13. QString zipName,delName;
    14. zipName=nomeDB;
    15. clearDBConn();
    16. archive(zipName.replace(".s3db",".zip"),nomeDB,true);
    17. emit zipFileName(idProva, zipName);
    18. //delName=QDir().absoluteFilePath(nomeDB);
    19. QFile(nomeDB).remove();
    20. }
    To copy to clipboard, switch view to plain text mode 

    Is there something wrong?

    Thanks for your time

    Michele

  15. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    Yes. You need to destroy the db object before calling removeDatabase().
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. #16
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    Thanks wysota but... I called
    Qt Code:
    To copy to clipboard, switch view to plain text mode 
    before removeDatabase(), so I've destroy the object isn't it?

    Thanks for your time

    Michele

  17. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    If you do that, the application will crash when you quit it. Why are you storing the db object in the first place?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #18
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    Thanks wysota but, I don't understand what you say with "in frist place".
    I'd like to open only one connection per thread, so the thread can create and manage one DB, and when the test end, it should close the database, zip the file and store it into a MYSQL db archive, and delete the original db file and the zip file.

    This is the code of my thread class; the Header:
    Qt Code:
    1. #ifndef MYTHREAD1_H
    2. #define MYTHREAD1_H
    3.  
    4. #include <QThread>
    5. #include <QDataStream>
    6. #include <QTextStream>
    7. #include <QMutex>
    8. #include <QReadWriteLock>
    9. #include <QSettings>
    10. #include <QMessageBox>
    11. #include <QSqlDatabase>
    12. #include <QSqlQuery>
    13. #include <QSqlError>
    14.  
    15. #include <QDir>
    16. #include <QFile>
    17. #include "quazip/quazip.h"
    18. #include "quazip/quazipfile.h"
    19.  
    20. class myThread1 : public QThread
    21. {
    22. Q_OBJECT
    23.  
    24. public:
    25. myThread1(int nrampa, int sleep);
    26. void stop();
    27.  
    28. public slots:
    29. void generateID();
    30. void execCmd(QString cmd);
    31. void clearDBConn();
    32. void zipDB();
    33.  
    34. protected:
    35. void run();
    36.  
    37. private:
    38. volatile bool stopped;
    39. QMutex mutex;
    40. QString prefix;
    41. int sleep,nrampa,idProva;
    42. QSettings *set;
    43. QString nomeDB;
    44. QSqlQuery *qry;
    45.  
    46. void createDB();
    47. bool extract(const QString & filePath, const QString & extDirPath, const QString & singleFileName);
    48. bool archive(const QString & filePath, const QString & path, bool isFile, const QString & comment=QString(""));
    49.  
    50.  
    51. signals:
    52. void newId(int rampa, QString newId);
    53. void zipFileName(int idProva,QString zipName);
    54.  
    55.  
    56. };
    57.  
    58. #endif // MYTHREAD1_H
    To copy to clipboard, switch view to plain text mode 

    and the CODE:
    Qt Code:
    1. #include "mythread1.h"
    2.  
    3. myThread1::myThread1(int nrampa, int sleep)
    4. {
    5. stopped=true;
    6. [...]
    7. }
    8.  
    9. void myThread1::run(){
    10. // stopped=false;
    11. // while(!stopped){
    12. // //int val = qrand();
    13. // if (genID){
    14.  
    15. // }
    16. // msleep(sleep);
    17. // }
    18. }
    19.  
    20. bool myThread1::extract(const QString & filePath, const QString & extDirPath, const QString & singleFileName) {
    21.  
    22. [...]
    23.  
    24. }
    25.  
    26. bool myThread1::archive(const QString & filePath, const QString & path, bool isFile, const QString & comment) {
    27. [...]
    28. }
    29.  
    30.  
    31. void myThread1::stop(){
    32. stopped=true;
    33. }
    34.  
    35. void myThread1::generateID(){
    36. [...]
    37.  
    38. }
    39.  
    40. void myThread1::createDB(){
    41. nomeDB=QString("R%2_Prova%1.s3db").arg(idProva).arg(nrampa);
    42. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",nomeDB);
    43. db.setDatabaseName(nomeDB);
    44. if (!db.open()){
    45. msg.setText(db.lastError().text());
    46. msg.show();
    47. }else{
    48. db.exec("create table test (campo int)");
    49. }
    50. }
    51.  
    52. void myThread1::execCmd(QString cmd){
    53. qry = new QSqlQuery(db);
    54. qry->exec(cmd);
    55. }
    56.  
    57. void myThread1::clearDBConn(){
    58. qry->finish();
    59. db.close();
    60. db.~QSqlDatabase();
    61. QSqlDatabase::removeDatabase(nomeDB);
    62. }
    63.  
    64. void myThread1::zipDB(){
    65. QString zipName,delName;
    66. zipName=nomeDB;
    67. clearDBConn();
    68. archive(zipName.replace(".s3db",".zip"),nomeDB,true);
    69. emit zipFileName(idProva, zipName);
    70. QFile(nomeDB).remove();
    71. }
    To copy to clipboard, switch view to plain text mode 

    If I understood your suggest, I should use
    Qt Code:
    To copy to clipboard, switch view to plain text mode 
    isn't it? So the db is a local object and at the end of the method it free the heap, isn't it?
    But so, I should create one connection for every time I call the execCmd method, is right?

    No other way to close and re-open the db connection?

    Thanks for your time

  19. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Releasing database file with QSqlDatabase

    Quote Originally Posted by cia.michele View Post
    Thanks wysota but, I don't understand what you say with "in frist place".
    It's a figure of speech. I meant to ask why are you storing the database object (db) at all. QSqlDatabase objects are not meant to be stored as class member variables. At any point when you need the db object, you can retrieve it using QSqlDatabase::database() passing it the connection name passed to addDatabase() or cloneDatabase().
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  20. #20
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Releasing database file with QSqlDatabase

    Thanks wysota, I trying to do what you say, but I think didn't understand so much.
    I try to do it in this way, is the correct way you sayd?

    Qt Code:
    1. void myThread1::createDB(){
    2. nomeDB=QString("R%2_Prova%1.s3db").arg(idProva).arg(nrampa);
    3. QSqlDatabase::addDatabase("QSQLITE",nomeDB);
    4. QSqlDatabase(nomeDB).setDatabaseName(nomeDB);
    5. if (!QSqlDatabase(nomeDB).open()){
    6. msg.setText(QSqlDatabase(nomeDB).lastError().text());
    7. msg.show();
    8. }else{
    9. QSqlDatabase(nomeDB).exec("create table test (campo int)");
    10. }
    11. }
    12.  
    13. void myThread1::execCmd(QString cmd){
    14.  
    15. if (!QSqlDatabase(nomeDB).open()){
    16. msg.setText(QSqlDatabase(nomeDB).lastError().text());
    17. msg.show();
    18. }else{
    19. QSqlDatabase(nomeDB).exec(cmd);
    20. }
    21. QSqlDatabase(nomeDB).close();
    22.  
    23. }
    To copy to clipboard, switch view to plain text mode 
    I got this error:
    'QSqlDatabase::QSqlDatabase(const QString&)' is protected
    In which way I could address the database passing the connection name?

    Thanks for your time

    Michele

Similar Threads

  1. Multiple database connections
    By cyberboy in forum Qt Programming
    Replies: 3
    Last Post: 30th March 2008, 16:56
  2. Set up the Qt4.3.2 with Visual Studio 2005
    By lamoda in forum Installation and Deployment
    Replies: 6
    Last Post: 30th January 2008, 06:51
  3. Database: How to use an external file?
    By goes2bob in forum Newbie
    Replies: 10
    Last Post: 23rd January 2008, 14:07
  4. qt-3.3.8 fail in scratchbox
    By nass in forum Installation and Deployment
    Replies: 0
    Last Post: 25th May 2007, 15:21

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.