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. SQLite - how to make own COLLATION?
Forum Updated to NodeBB v4.3 + New Features

SQLite - how to make own COLLATION?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 1.4k Views 2 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.
  • K Offline
    K Offline
    Kobid
    wrote on last edited by
    #1

    Hi,

    I'm searching all day how to make own collaction function. Finally I'm able to compile project using "sqlite3.h" but sqlite3_create_collation16() function is rising SIGSEGV exception and I don't know why. Here is my code:

    .pri:

    LIBS += -lsqlite3
    

    .cpp:

    #include <sqlite3.h>
    
    static int localeCompare( void* /*arg*/, int len1, const void* data1,
        int len2, const void* data2 )
    {
        qDebug() << "localeCompare";
        QString string1 = QString::fromRawData( reinterpret_cast<const QChar*>( data1 ),
            len1 / sizeof( QChar ) );
        QString string2 = QString::fromRawData( reinterpret_cast<const QChar*>( data2 ),
            len2 / sizeof( QChar ) );
    
        return QString::localeAwareCompare( string1, string2 );
    }
    
    void DataManager::initDatabase()
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    
        QString path = getConfigDir(false);
        if (!QDir(path).exists()) {
            QDir(path).mkdir(path);
        }
        db.setDatabaseName(getDBFileName());
    
        db.open();
    
        QVariant handle = db.driver()->handle();
        sqlite3* db2 = *static_cast<sqlite3**>( handle.data() );
        if (db2) {
            qDebug() << "creating locale";
            sqlite3_create_collation16(db2, "MYCOLLATION", SQLITE_UTF16, nullptr, &localeCompare );
            qDebug() << "created locale";
        }
    
        db.exec("PRAGMA foreign_keys = ON");
    }
    

    Any idea?

    Regards

    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by fcarney
      #2

      Because reasons:

          // init things
          sqlite3_initialize();
      

      Edit:
      I don't know what a collation is, but here is working code for talking to the installed version of sqlite3 to do memory copies:
      https://forum.qt.io/topic/101018/qsqldatabase-sqlite-how-to-load-into-memory-and-save-memory-to-disk/17

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      1
      • K Offline
        K Offline
        Kobid
        wrote on last edited by
        #3

        Thanks a lot! But problem was not only with missing sqlite3_initialize() . Saw this solutions in my google research but it didn't change anything. The main problem was with different sqlite version. In my linux system I have 3.22.0 but Qt 5.12.3 has sqlite version 3.26.0. I downloaded 3.26.0 version, compiled and included in my project's source:

        win32:!win32-g++: PRE_TARGETDEPS += $$PWD/libs/sqlite.lib
        else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/libs/libsqlite3.a
        

        After all, sqlite3_initialize() is necessary and also LIBS += -ldl, otherwise you get compiler error

        BTW: I'm kinda newbie in c++, why libsqlite3.a has 8MB and libsqlite3.so has 2MB? I see that my executable file is bloated. When I try to include libsqlite3.so in my project with the same way as above then sqlite3_libversion() return 3.22 and still having same issue

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          libsqlite3.a is a static library hence it contains everything it needs.
          Your application is loading the system libsqlite3 because it finds it before your own compiled version.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          K 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            libsqlite3.a is a static library hence it contains everything it needs.
            Your application is loading the system libsqlite3 because it finds it before your own compiled version.

            K Offline
            K Offline
            Kobid
            wrote on last edited by
            #5

            Can I force compiler to load my own local libsqlite3.so?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              You can use the LD_LIBRARY_PATH environment variable containing the path of the folder containing your custom libsqlite3.so. Go to the Run part of the Project panel.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • K Offline
                K Offline
                Kobid
                wrote on last edited by
                #7

                Yes, but I guess it load it only when I run my app from Qt Creator. Can I force it permanently? I want to deploy my own libsqlite3.so with my app (in local "libs" dir) to make sure that my app use correct sqlite version. How can I force compiler / linker to looks for libs first in local ./libs?

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #8

                  I think the way I did it was to load the version of sqlite that came with Qt. It is the single source file version as there is only the one c file. It might be easier to just include the source file rather than a separate lib. The license for sqlite3 is such that you don't have to do an "so" and still keep your source code under whatever license you want. At least that is how I understand it.

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Kobid
                    wrote on last edited by
                    #9

                    Ok. Solved it and can use my own libsqlite.so v3.26 in my executable local "libs" dir:

                    unix:!macx{
                      QMAKE_LFLAGS_RPATH=
                      QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/libs\'"
                    }
                    
                    1 Reply Last reply
                    1
                    • K Offline
                      K Offline
                      Kobid
                      wrote on last edited by Kobid
                      #10

                      Note also that on linux system you have to put also all symlinks points to libsqlite, the libsqlite.so alone is not enough and your app will still load system libsqlite, not your own. So in my case, in local libs I need to have:

                      libsqlite3.so
                      libsqlite3.so.0
                      libsqlite3.so.0.8.6

                      1 Reply Last reply
                      1
                      • K Offline
                        K Offline
                        Kobid
                        wrote on last edited by Kobid
                        #11

                        Mmmm, but now having free() invalid pointer in my app when closing it. In debug mode call stack is:

                        sqlite3_free
                        sqlite3HashClear
                        sqlite3LeaveMutexAndCloseZombie
                        sqlite3Close
                        QSQLiteDriver::close()
                        

                        In sqlite3_free it points on sqlite3GlobalConfig.m.xFree(p);:

                        SQLITE_API void sqlite3_free(void *p){
                          if( p==0 ) return;  /* IMP: R-49053-54554 */
                          assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
                          assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
                          if( sqlite3GlobalConfig.bMemstat ){
                            sqlite3_mutex_enter(mem0.mutex);
                            sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
                            sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
                            sqlite3GlobalConfig.m.xFree(p);
                            sqlite3_mutex_leave(mem0.mutex);
                          }else{
                            sqlite3GlobalConfig.m.xFree(p);
                          }
                        }
                        

                        I'm getting this no matter if I build app with DEFINES += SQLITE_THREADSAFE=0 or DEFINES += SQLITE_THREADSAFE=1. I think i have to ask this on sqlite forum but if someone have clue then it would be great. I think it has something related with necessary sqlite3_initialize();. Tried also call sqlite3_shutdown(); before closing my DB but it didn't help

                        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