On Tue, 2011-02-22 at 08:46 -0800, Roger Binns wrote:
> On 02/22/2011 05:29 AM, Robert Hairgrove wrote:
> > I'm trying to understand how the VFS implementation works. 
> 
> What you think you are seeing is not happening.  The documentation is correct.

OK ... but what about that which the GDB debugger is seeing?

> > However, if I open a database and inspect the VFS contained in the sqlite3*,
> 
> That should just point to the VFS used.  There is no copying or modification.

Or so says the documentation... 

Maybe some more details will help here:

The OS is Linux Ubuntu 10.04 LTS, AKA "Lucid Lynx" running on a Dell
Inspiron 1420N notebook (and Dell supplies the drivers etc. for this
distro of Linux). GCC version is 4.4.3.

SQLite version is 3.6.19 (I know it's not the latest and greatest, but
this is what is supplied together with the Qt sources... these are
version 4.7.1 -- which is pretty much up-to-date, but not cutting edge).

I compiled the Qt libraries from source myself and built SQLite
statically into Qt, as opposed to a plug-in.  The SQLite sources are all
in the amalgamation file "sqlite.c".

I created a little console project in QtCreator to test the SQLite VFS
functionality. I had to add "sqlite3.c" to the project because I was
getting linker errors when trying to call some of the SQLite API
functions, such as "sqlite3_vfs_find" ... (hmmm...seems that these
symbols aren't exported from the Qt shared libraries).

Obviously, SOMETHING is resetting these pointers. Here is a snippet from
the test code I wrote. It should compile and run OK if you have a newer
version of Qt installed on your system. Here is my Qt .pro file:

//==== my Qt project file: =======================================
QT += core sql
INCLUDEPATH += \
  {wherever the Qt sources are...}/src/3rdparty/sqlite
SOURCES += main.cpp \
  {wherever the Qt sources are...}/src/3rdparty/sqlite/sqlite3.c
HEADERS += \
  {wherever the Qt sources are...}/src/3rdparty/sqlite/sqlite3.h
//==== end of Qt project file =======================================

And here is the source code of my test app in "main.cpp":

//==== BEGIN CODE: ============================================
#include <QtCore>
#include <QtSql>
#include <iostream>
#include <sqlite3.h>

void showVFS(const sqlite3_vfs * const &);

int main(int argc, char *argv[])
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","default_db");
    sqlite3 * pSqliteDb = 0;
    //----------------------------------------------------------------
    // Using an on-disk database seems to give the exact same results:
    // db.setDatabaseName("/home/bob/code/SQLite_Test_VFS/test.db");
    //----------------------------------------------------------------
    db.setDatabaseName(":memory:");
    if (db.open()) {
        //-------------------------------------------------------
        // Some of the following lines of code are copied and
        // pasted from the Qt docs:
        //-------------------------------------------------------
        QVariant v = db.driver()->handle();
        if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*")==0) {
            // v.data() returns a pointer to the handle...
            //????????????????????????????????????????????????????
            // Actually, it seems to return either int
            // or void* ... (see below):
            //????????????????????????????????????????????????????
            sqlite3 *pSqliteDb = *static_cast<sqlite3 **>(v.data());
            if (pSqliteDb) {
                //????????????????????????????????????????????????????
                // Interesting that using static_cast<> does not work below;
                // probably because QSqlDriver::handle() returns void* (???)
                // although the Qt docs AND the sources say differently:
                //????????????????????????????????????????????????????
                sqlite3_vfs * pvfs = *reinterpret_cast<sqlite3_vfs 
**>(pSqliteDb);
                
//----------------------------------------------------------------
                // The line below gives a VFS with non-NULL values
                // for the struct members under discussion:
                
//----------------------------------------------------------------
                // sqlite3_vfs * pvfs = sqlite3_vfs_find(0);
                
//----------------------------------------------------------------
                if (pvfs) {
                    showVFS(pvfs);
                }
            } else {
                std::cout << "No VFS handle!" << std::endl;
            }
        }
    }
    return 0;
}
////////////////////////////////////////////////////////
void showVFS(const sqlite3_vfs * const &pVfs)
{
    if (pVfs->zName) {
        std::cout << "=====================================================\n";
        std::cout << "Name of VFS:\t" << pVfs->zName << std::endl;
#ifdef SQLITE_OMIT_LOAD_EXTENSION
        std::cout << "SQLITE_OMIT_LOAD_EXTENSION = true" << std::endl;
#endif
        std::cout << "=====================================================\n";
        std::cout << "iVersion        = " << pVfs->iVersion   << std::endl;     
       /* Structure version number */
        std::cout << "szOsFile        = " << pVfs->szOsFile   << std::endl;     
       /* Size of subclassed sqlite3_file */
        std::cout << "mxPathname      = " << pVfs->mxPathname << std::endl;     
     /* Maximum file pathname length */
        std::cout << "pNext           = " << pVfs->pNext      << std::endl;     
  /* Next registered VFS */
        std::cout << "zName           = " << pVfs->zName      << std::endl;     
  /* Name of this virtual file system */
        std::cout << "pAppData        = " << pVfs->pAppData   << std::endl;     
     /* Pointer to application-specific data */

        std::cout << "xOpen           = " << (void*)pVfs->xOpen         << 
std::endl;
        std::cout << "xDelete         = " << (void*)pVfs->xDelete       << 
std::endl;
        std::cout << "xAccess         = " << (void*)pVfs->xAccess       << 
std::endl;
        std::cout << "xFullPathname   = " << (void*)pVfs->xFullPathname << 
std::endl;
        
/////////////////////////////////////////////////////////////////////////////
        // Up to here, nothing is changed in the VFS whether I use 
sqlite3_vfs_find()
        // or get it from the sqlite3* database pointer. But the following four
        // members are always NULL if I use the VFS in the database which is 
open!...
        
//---------------------------------------------------------------------------
        std::cout << "xDlOpen         = " << (void*)(pVfs->xDlOpen)     << 
std::endl;
        std::cout << "xDlError        = " << (void*)(pVfs->xDlError)    << 
std::endl;
        std::cout << "xDlSym          = " << (void*)(pVfs->xDlSym)      << 
std::endl;
        std::cout << "xDlClose        = " << (void*)(pVfs->xDlClose)    << 
std::endl;
        
/////////////////////////////////////////////////////////////////////////////
        std::cout << "xRandomness     = " << (void*)pVfs->xRandomness   << 
std::endl;
        std::cout << "xSleep          = " << (void*)pVfs->xSleep        << 
std::endl;
        std::cout << "xCurrentTime    = " << (void*)pVfs->xCurrentTime  << 
std::endl;
        std::cout << "xGetLastError   = " << (void*)pVfs->xGetLastError << 
std::endl;
    }
}
//==== END CODE ============================================


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to