Results 1 to 8 of 8

Thread: Attempting to use Sqlite backup api from driver handle fails

  1. #1
    Join Date
    Nov 2010
    Posts
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Attempting to use Sqlite backup api from driver handle fails

    I want to be able to either load or save db between memory and file. I have attempted to use the handle to sqlite3 api from the Qsqldatabase object.

    I follow the example code to obtain the driver. The function is passed Qsqldatabase pointer for the two databases.

    Showing snippet for one db to obtain handle:

    v = db1->driver()->handle();
    if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*")==0)
    // v.data() returns a pointer to the handle
    pInMemory = *static_cast<sqlite3 **>(v.data());

    After checking that both handles are not null, I decide which is the src and dest db and load the to/from sqlite3 pointers ( same as the backup example on Sqlite website)

    sqlite3_backup_init(pTo, "main", pFrom, "main");

    I receive the following error:

    First-chance exception at 0x00000000 in xxx.exe: 0xC0000005: Access violation reading location 0x00000000.

    Note: I am using the qt sqlite library. To get to the sqlite api I have also included the sqlite3 library in the build (Found couple of online references to doing this).

    Can anyone shed light on this error when using the driver ahndle to sqlite api?

    Thanks

  2. #2
    Join Date
    Nov 2010
    Posts
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    To make SQLite in-memory load/save I use this steps:

    1. Add two rows to .pro file:
    Qt Code:
    1. INCLUDEPATH = $$[QT_INSTALL_PREFIX]/src/3rdparty/sqlite
    2. SOURCES += $$[QT_INSTALL_PREFIX]/src/3rdparty/sqlite/sqlite3.c
    To copy to clipboard, switch view to plain text mode 

    2. Add include to file where I plan to use SQLite API:
    Qt Code:
    1. #include <sqlite3.h>
    To copy to clipboard, switch view to plain text mode 

    3. Use function similar to this:
    Qt Code:
    1. /*
    2. ** This function is used to load the contents of a database file on disk
    3. ** into the "main" database of open database connection pInMemory, or
    4. ** to save the current contents of the database opened by pInMemory into
    5. ** a database file on disk. pInMemory is probably an in-memory database,
    6. ** but this function will also work fine if it is not.
    7. **
    8. ** Parameter zFilename points to a nul-terminated string containing the
    9. ** name of the database file on disk to load from or save to. If parameter
    10. ** isSave is non-zero, then the contents of the file zFilename are
    11. ** overwritten with the contents of the database opened by pInMemory. If
    12. ** parameter isSave is zero, then the contents of the database opened by
    13. ** pInMemory are replaced by data loaded from the file zFilename.
    14. **
    15. ** If the operation is successful, SQLITE_OK is returned. Otherwise, if
    16. ** an error occurs, an SQLite error code is returned.
    17. */
    18. bool sqliteDBMemFile( QSqlDatabase memdb, QString filename, bool save )
    19. {
    20. bool state = false;
    21. QVariant v = memdb.driver()->handle();
    22. if( v.isValid() && qstrcmp(v.typeName(),"sqlite3*") == 0 )
    23. {
    24. // v.data() returns a pointer to the handle
    25. sqlite3 * handle = *static_cast<sqlite3 **>(v.data());
    26. if( handle != 0 ) // check that it is not NULL
    27. {
    28. sqlite3 * pInMemory = handle;
    29. const char * zFilename = filename.toLocal8Bit().data();
    30. int rc; /* Function return code */
    31. sqlite3 *pFile; /* Database connection opened on zFilename */
    32. sqlite3_backup *pBackup; /* Backup object used to copy data */
    33. sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */
    34. sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */
    35.  
    36. /* Open the database file identified by zFilename. Exit early if this fails
    37.   ** for any reason. */
    38. rc = sqlite3_open( zFilename, &pFile );
    39. if( rc==SQLITE_OK ){
    40.  
    41. /* If this is a 'load' operation (isSave==0), then data is copied
    42.   ** from the database file just opened to database pInMemory.
    43.   ** Otherwise, if this is a 'save' operation (isSave==1), then data
    44.   ** is copied from pInMemory to pFile. Set the variables pFrom and
    45.   ** pTo accordingly. */
    46. pFrom = ( save ? pInMemory : pFile);
    47. pTo = ( save ? pFile : pInMemory);
    48.  
    49. /* Set up the backup procedure to copy from the "main" database of
    50.   ** connection pFile to the main database of connection pInMemory.
    51.   ** If something goes wrong, pBackup will be set to NULL and an error
    52.   ** code and message left in connection pTo.
    53.   **
    54.   ** If the backup object is successfully created, call backup_step()
    55.   ** to copy data from pFile to pInMemory. Then call backup_finish()
    56.   ** to release resources associated with the pBackup object. If an
    57.   ** error occurred, then an error code and message will be left in
    58.   ** connection pTo. If no error occurred, then the error code belonging
    59.   ** to pTo is set to SQLITE_OK.
    60.   */
    61. pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main");
    62. if( pBackup ){
    63. (void)sqlite3_backup_step(pBackup, -1);
    64. (void)sqlite3_backup_finish(pBackup);
    65. }
    66. rc = sqlite3_errcode(pTo);
    67. }
    68.  
    69. /* Close the database connection opened on database file zFilename
    70.   ** and return the result of this function. */
    71. (void)sqlite3_close(pFile);
    72.  
    73. if( rc == SQLITE_OK ) state = true;
    74. }
    75. }
    76. return state;
    77. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Apr 2011
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    This also crashes on me at sqlite3_backup_init. To isolate the problem I have created a small test program. sqlite3.h & .c are taken from the Qt 4.7.1. archive (the version I am developing with), somehow those files were missing in the OpenSUSE 11.4 Qt Source package.

    This code tries to do an online backup of an opened database, so it's not from memory.

    ==12265== Thread 2:
    ==12265== Invalid write of size 8
    ==12265== at 0x438492: pthreadMutexEnter (sqlite3.c:15266)
    ==12265== by 0x4382F0: sqlite3_mutex_enter (sqlite3.c:14537)
    ==12265== by 0x454E0A: sqlite3_backup_init (sqlite3.c:45601)

    Qt Code:
    1. #include <QtSql/QSqlDatabase>
    2. #include <QtSql/QSqlDriver>
    3. #include <QString>
    4. #include <QVariant>
    5. #include "sqlite3/sqlite3.h"
    6.  
    7. void backup(QString src, QString dst) {
    8. QSqlDatabase sqlDb = QSqlDatabase::addDatabase("QSQLITE");
    9. sqlDb.setDatabaseName(src);
    10. sqlDb.open();
    11.  
    12. QVariant v = sqlDb.driver()->handle();
    13. sqlite3* pSource = *static_cast<sqlite3 **>(v.data());
    14.  
    15. int rc;
    16. sqlite3 *pDest;
    17. sqlite3_backup *pBackup;
    18. rc = sqlite3_open(dst.toLocal8Bit().data(), &pDest);
    19. if(rc == SQLITE_OK) {
    20. pBackup = sqlite3_backup_init(pDest, "main", pSource, "main");
    21. if (pBackup) {
    22. do {
    23. rc = sqlite3_backup_step(pBackup, 5);
    24. if (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
    25. sqlite3_sleep(250);
    26. }
    27. } while(rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED );
    28.  
    29. /* Release resources allocated by backup_init(). */
    30. sqlite3_backup_finish(pBackup);
    31. }
    32. sqlite3_close(pDest);
    33. }
    34.  
    35. sqlDb.close();
    36. }
    37.  
    38.  
    39. int main(int argc, char *argv[]) {
    40. backup("/home/arkay/Projects/QtWebApp/database/Current/architektur.db",
    41. "/home/arkay/Projects/QtWebApp/database/Backup/architektur.db");
    42. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Apr 2011
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    Problem solved

    SUSE links the Qt sqlite plugin against a current sqlite release so I only had to use the source they supplied instead of the ancient one which comes with the Qt source distribution.

  5. #5
    Join Date
    Nov 2010
    Posts
    2
    Qt products
    Qt4
    Platforms
    Windows

    Post Re: Attempting to use Sqlite backup api from driver handle fails

    There is some corrected code from my previous post:
    Qt Code:
    1. /*
    2. ** This function is used to load the contents of a database file on disk
    3. ** into the "main" database of open database connection pInMemory, or
    4. ** to save the current contents of the database opened by pInMemory into
    5. ** a database file on disk. pInMemory is probably an in-memory database,
    6. ** but this function will also work fine if it is not.
    7. **
    8. ** Parameter zFilename points to a nul-terminated string containing the
    9. ** name of the database file on disk to load from or save to. If parameter
    10. ** isSave is non-zero, then the contents of the file zFilename are
    11. ** overwritten with the contents of the database opened by pInMemory. If
    12. ** parameter isSave is zero, then the contents of the database opened by
    13. ** pInMemory are replaced by data loaded from the file zFilename.
    14. **
    15. ** If the operation is successful, SQLITE_OK is returned. Otherwise, if
    16. ** an error occurs, an SQLite error code is returned.
    17. */
    18. bool sqliteDBMemFile( QSqlDatabase memdb, QString filename, bool save )
    19. {
    20. bool state = false;
    21. QVariant v = memdb.driver()->handle();
    22. if( v.isValid() && qstrcmp(v.typeName(),"sqlite3*") == 0 )
    23. {
    24. // v.data() returns a pointer to the handle
    25. sqlite3 * handle = *static_cast<sqlite3 **>(v.data());
    26. if( handle != 0 ) // check that it is not NULL
    27. {
    28. sqlite3 * pInMemory = handle;
    29. QByteArray array = filename.toLocal8Bit();
    30. const char * zFilename = array.data();
    31. int rc; /* Function return code */
    32. sqlite3 *pFile; /* Database connection opened on zFilename */
    33. sqlite3_backup *pBackup; /* Backup object used to copy data */
    34. sqlite3 *pTo; /* Database to copy to (pFile or pInMemory) */
    35. sqlite3 *pFrom; /* Database to copy from (pFile or pInMemory) */
    36.  
    37. /* Open the database file identified by zFilename. Exit early if this fails
    38.   ** for any reason. */
    39. rc = sqlite3_open( zFilename, &pFile );
    40. if( rc==SQLITE_OK ){
    41.  
    42. /* If this is a 'load' operation (isSave==0), then data is copied
    43.   ** from the database file just opened to database pInMemory.
    44.   ** Otherwise, if this is a 'save' operation (isSave==1), then data
    45.   ** is copied from pInMemory to pFile. Set the variables pFrom and
    46.   ** pTo accordingly. */
    47. pFrom = ( save ? pInMemory : pFile);
    48. pTo = ( save ? pFile : pInMemory);
    49.  
    50. /* Set up the backup procedure to copy from the "main" database of
    51.   ** connection pFile to the main database of connection pInMemory.
    52.   ** If something goes wrong, pBackup will be set to NULL and an error
    53.   ** code and message left in connection pTo.
    54.   **
    55.   ** If the backup object is successfully created, call backup_step()
    56.   ** to copy data from pFile to pInMemory. Then call backup_finish()
    57.   ** to release resources associated with the pBackup object. If an
    58.   ** error occurred, then an error code and message will be left in
    59.   ** connection pTo. If no error occurred, then the error code belonging
    60.   ** to pTo is set to SQLITE_OK.
    61.   */
    62. pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main");
    63. if( pBackup ){
    64. (void)sqlite3_backup_step(pBackup, -1);
    65. (void)sqlite3_backup_finish(pBackup);
    66. }
    67. rc = sqlite3_errcode(pTo);
    68. }
    69.  
    70. /* Close the database connection opened on database file zFilename
    71.   ** and return the result of this function. */
    72. (void)sqlite3_close(pFile);
    73.  
    74. if( rc == SQLITE_OK ) state = true;
    75. }
    76. }
    77. return state;
    78. }
    To copy to clipboard, switch view to plain text mode 
    The bug was located in this old line:
    Qt Code:
    1. const char * zFilename = filename.toLocal8Bit().data();
    To copy to clipboard, switch view to plain text mode 
    It is example of wrong using of QByteArray temporary object generated by toLocal8Bit() method. The data() method returns point to temporary object, that can be destroyed at any next moment. So in corrected code of this post I use copy of temporary QByteArray object to solve some potential problems.

    Both code examples (in this post and in my previous post in this forum's thread) are published under public domain license. Main part of code was used from SQLite documentation (http://www.sqlite.org/backup.html).

  6. #6
    Join Date
    Sep 2011
    Posts
    5
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Windows

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    This is a fairly old thread, but hoping someone's still reading this.
    I've followed the code by chemmalion (10th November 2011), which works well. However, if I try to use sqlite3_exec(), I get an exception: "Unhandled exception at 0x778f15de in app.exe: 0xC0000005: Access violation." Oddly, if I call the sqliteDBMemFile() before hand, I do not get the exception. Here's the code:

    Qt Code:
    1. db = QSqlDatabase::addDatabase("QSQLITE", "testsqliteptr");
    2. db.setDatabaseName("blabla.sqlite");
    3. if (!db.open()) {
    4. return -1;
    5. }
    6. //Uncommenting line below prevents error at <tag_error>. What's this function doing that prevents the error?
    7. //sqliteDBMemFile(db, "newfile.sqlite", true);
    8. v = db.driver()->handle();
    9. sqlite3* sql3_db = *static_cast<sqlite3 **>(v.data());
    10. //<tag_error>
    11. sqlite3_exec(sql3_db, "CREATE TABLE if not exists ABC(foo,bar)", 0, 0, 0);
    To copy to clipboard, switch view to plain text mode 
    Any idea as to what's going on? How stable is it to use both handles at the same time? I prefer to use QSql but require sqlite3* handle for a library I'm using.

  7. #7
    Join Date
    Apr 2015
    Posts
    1
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    The answer is already here, but not written explicitly. THE call that makes the difference between crash and no crash is sqlite3_open. Apparently having the sqlite3.dll plugin on one side and the sqlite3.c compiled in on the other (to be able to call any of the sqlite3 API directly messes up or misses some init. So basically what is needed is:
    1. Include sqlite code (.c and .h files) in your project
    2. Use this snippet after m_Database.open()::
    Qt Code:
    1. QVariant v = m_Database.driver()->handle();
    2. if (v.isValid() && strcmp(v.typeName(), "sqlite3*") == 0) {
    3. // v.data() returns a pointer to the handle
    4. sqlite3 *handle = *static_cast<sqlite3 **>(v.data());
    5. if (handle != 0) { // check that it is not NULL
    6. sqlite3 *p; //without this there is a crash.
    7. int result = sqlite3_open( ":memory:", &p );
    8. if (result == SQLITE_OK) {
    9. sqlite3_close(p);
    10. //call any API you need on handle.
    11. } else
    12. qDebug() << "Could not sqlite3_open p" << result;
    13. } else {
    14. qDebug() << "Could not get sqlite handle";
    15. }
    16. } else {
    17. qDebug() << "handle variant returned typename " << v.typeName();
    18. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jimmytaker; 12th June 2016 at 05:48.

  8. #8

    Default Re: Attempting to use Sqlite backup api from driver handle fails

    hello
    I still having this problem
    with throw exception at this section:

    SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
    sqlite3WalEndWriteTransaction(pWal);
    if( pWal->readLock>=0 ){
    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
    pWal->readLock = -1;
    }
    }


    and I attempts all your answers

    here my code

    QSqlDatabase m_db = QSqlDatabase::addDatabase("QSQLITE");

    m_db.setDatabaseName(":memory:");
    m_db.open();
    qDebug() << "create: " << m_db.driverName();

    // create a table in the memory DB
    QSqlQuery q_create = m_db.exec("CREATE TABLE qdn (id int, name varchar(50))");
    qDebug() << "create: " << q_create.lastError();

    // populate with some data
    QSqlQuery q_insert(m_db);
    q_insert.prepare("INSERT INTO qdn (id, name) VALUES (:id, :name)");
    q_insert.bindValue(":id", QVariant::fromValue(1));
    q_insert.bindValue(":name", "Volker");
    qDebug() << "insert volker: " << q_insert.exec();

    q_insert.bindValue(":id", QVariant::fromValue(2));
    q_insert.bindValue(":name", "Root");
    qDebug() << "insert root: " << q_insert.exec();

    // get the inner sqlite3 handle(as QVariant)
    QVariant v = m_db.driver()->handle();
    //// check its validity
    if (v.isValid() && strcmp(v.typeName(), "sqlite3*") == 0)
    {

    // v.data() returns a pointer to the handle
    // it is valid, so cast to sqlite3 handle
    sqlite3 *handle = *static_cast<sqlite3 **>(v.data());
    if (handle != 0)
    {

    loadOrSaveDb(handle, "d:/backupfrommemory.sqlite", 1);
    }
    else
    {
    qDebug() << "Could not get sqlite handle";
    }
    }

    else
    {
    qDebug() << "handle variant returned typename " << v.typeName();
    }
    }

    also I tried with sqliteDBMemFile as answer but also same error ... so please if I can find help
    with thanks

Similar Threads

  1. QT & SQLite - driver not loaded
    By Tomasz in forum Newbie
    Replies: 5
    Last Post: 15th June 2014, 12:59
  2. Sqlite driver not loading
    By waynew in forum Installation and Deployment
    Replies: 4
    Last Post: 23rd May 2010, 14:15
  3. Embed SQLite driver
    By NoRulez in forum Qt Programming
    Replies: 2
    Last Post: 7th October 2009, 10:41
  4. SQLite driver unavailable
    By kandalf in forum Installation and Deployment
    Replies: 5
    Last Post: 11th February 2009, 17:36
  5. SQlite driver not loaded error
    By ibergmark in forum Installation and Deployment
    Replies: 2
    Last Post: 17th March 2008, 02:09

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.