Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How to use relative path on SQLite .db file on iOS
Forum Updated to NodeBB v4.3 + New Features

How to use relative path on SQLite .db file on iOS

Scheduled Pinned Locked Moved Solved Mobile and Embedded
19 Posts 4 Posters 1.1k 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
    Kiovtorov
    wrote on 27 Nov 2024, 12:47 last edited by
    #9

    I tried in a test app that I can not copy a file from a resource file (.qrc). I am now searching for another way

    J 1 Reply Last reply 27 Nov 2024, 13:18
    0
    • K Kiovtorov
      27 Nov 2024, 12:47

      I tried in a test app that I can not copy a file from a resource file (.qrc). I am now searching for another way

      J Offline
      J Offline
      JonB
      wrote on 27 Nov 2024, 13:18 last edited by JonB
      #10

      @Kiovtorov
      First try again on QFile::copy() but remove the qrc, keep the :, so QFile resourceFile(":/resources/Finbank.db");. https://stackoverflow.com/questions/10724899/how-to-copy-qrc-resource-file-into-filesystem
      https://forum.qt.io/topic/13131/how-to-extract-a-resource-from-qrc-solved
      Hopefully that does work? I think it's supposed to.

      If it really does not work, you would have to do the copy yourself via QFile::open(), read content, write to extracted file location.

      K 1 Reply Last reply 27 Nov 2024, 17:11
      1
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 27 Nov 2024, 13:24 last edited by
        #11

        @JonB is correct, I missed that in your code. qrc:/ is used in QML because it uses URI however, in the C++ world, it's :/ that is used to signify that you want to access a file in the resource system.

        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
        1
        • J JonB
          27 Nov 2024, 13:18

          @Kiovtorov
          First try again on QFile::copy() but remove the qrc, keep the :, so QFile resourceFile(":/resources/Finbank.db");. https://stackoverflow.com/questions/10724899/how-to-copy-qrc-resource-file-into-filesystem
          https://forum.qt.io/topic/13131/how-to-extract-a-resource-from-qrc-solved
          Hopefully that does work? I think it's supposed to.

          If it really does not work, you would have to do the copy yourself via QFile::open(), read content, write to extracted file location.

          K Offline
          K Offline
          Kiovtorov
          wrote on 27 Nov 2024, 17:11 last edited by Kiovtorov
          #12

          Hi @JonB

          Here is the corrected path but it doesn't work

          void DatabaseManager::OpenConnection() {
              // Configure the database connection parameters for SQLite
              m_db = QSqlDatabase::addDatabase("QSQLITE");
          
              // Determine the writable location for the database
              QString writablePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
              QString databasePath = writablePath + "/Finbank.db";
          
              // Ensure the writable directory exists
              QDir dir(writablePath);
              if (!dir.exists()) {
                  dir.mkpath(writablePath);
              }
          
              if (!QFile::exists(databasePath)) {
                  QFile resourceFile(":/resources/Finbank.db");
                  if (resourceFile.exists()) {
                      if (resourceFile.open(QIODevice::ReadOnly)) {
                          QFile destinationFile(databasePath);
                          if (destinationFile.open(QIODevice::WriteOnly)) {
                              destinationFile.write(resourceFile.readAll());
                              resourceFile.close();
                              destinationFile.close();
                              qDebug() << "Database successfully copied to writable location.";
                          } else {
                              qDebug() << "Failed to open destination file:" << destinationFile.errorString();
                          }
                      } else {
                          qDebug() << "Failed to open resource file:" << resourceFile.errorString();
                      }
                  } else {
                      qDebug() << "Database resource file not found.";
                  }
              }
          
              // Set the SQLite database file location
              m_db.setDatabaseName(databasePath);
          
              // Open the database connection and handle success or failure
              if (m_db.open() && m_db.isOpen()) {
                  qDebug() << "Database opened successfully at" << databasePath;
              } else {
                  // Handle connection error
                  qDebug() << "Database failed to open";
                  qDebug() << m_db.lastError().text();
              }
          }
          
          

          I get an output of

          Database opened successfully at "/Users/boyankiovtorov/Library/Application Support/appFinbank/Finbank.db"
          

          I was unable to access that directory to check the file but nevertheless I think it is generated .db file which is 0 bytes and not the db file from the resource file.
          I am currently looking at a stackoverflow case - https://stackoverflow.com/questions/50828041/how-to-open-database-sqlite-file-on-iphone-real-device

          But i am getting no success so far because I do not have Application Support folder like him

          J 1 Reply Last reply 27 Nov 2024, 17:40
          0
          • K Offline
            K Offline
            Kiovtorov
            wrote on 27 Nov 2024, 17:15 last edited by Kiovtorov
            #13

            @JonB AI thought of copying the database from the CMakeFIle.txt which worked

            cmake_minimum_required(VERSION 3.16)
            
            project(sqlite VERSION 0.1 LANGUAGES CXX)
            
            set(CMAKE_CXX_STANDARD_REQUIRED ON)
            
            find_package(Qt6 6.5 REQUIRED COMPONENTS Quick Sql)
            
            qt_standard_project_setup(REQUIRES 6.5)
            
            qt_add_executable(appsqlite
                main.cpp
            )
            
            qt_add_qml_module(appsqlite
                URI sqlite
                VERSION 1.0
                QML_FILES
                    Main.qml
                    SOURCES maketransactions.hpp maketransactions.cpp
                    RESOURCES resources.qrc
            )
            
            # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
            # If you are developing for iOS or macOS you should consider setting an
            # explicit, fixed bundle identifier manually though.
            set_target_properties(appsqlite PROPERTIES
            #    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appsqlite
                MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
                MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
                MACOSX_BUNDLE TRUE
                WIN32_EXECUTABLE TRUE
            )
            
            target_link_libraries(appsqlite
                PRIVATE Qt6::Quick Qt6::Sql
            )
            
            include(GNUInstallDirs)
            install(TARGETS appsqlite
                BUNDLE DESTINATION .
                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
                RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
            )
            
            
            # Add the database file to the bundle
            set(APP_RESOURCES Finbank.db)
            
            # Copy resources to the macOS/iOS bundle or build directory
            foreach(resource ${APP_RESOURCES})
                configure_file(${resource} ${resource} COPYONLY)
            endforeach()
            
            # Ensure it is included in the app bundle
            if(APPLE)
                set_source_files_properties(${APP_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
            endif()
            
            # Include it in the target
            target_sources(appsqlite PRIVATE ${APP_RESOURCES})
            
            

            The problem there is that for different OSs the path to this db file is different. It generates it at

            /Users/boyankiovtorov/Documents/sqlite/build/Qt_6_8_0_for_macOS-Debug/Finbank.db
            

            Do you think it is a good idea?

            1 Reply Last reply
            0
            • K Kiovtorov
              27 Nov 2024, 17:11

              Hi @JonB

              Here is the corrected path but it doesn't work

              void DatabaseManager::OpenConnection() {
                  // Configure the database connection parameters for SQLite
                  m_db = QSqlDatabase::addDatabase("QSQLITE");
              
                  // Determine the writable location for the database
                  QString writablePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
                  QString databasePath = writablePath + "/Finbank.db";
              
                  // Ensure the writable directory exists
                  QDir dir(writablePath);
                  if (!dir.exists()) {
                      dir.mkpath(writablePath);
                  }
              
                  if (!QFile::exists(databasePath)) {
                      QFile resourceFile(":/resources/Finbank.db");
                      if (resourceFile.exists()) {
                          if (resourceFile.open(QIODevice::ReadOnly)) {
                              QFile destinationFile(databasePath);
                              if (destinationFile.open(QIODevice::WriteOnly)) {
                                  destinationFile.write(resourceFile.readAll());
                                  resourceFile.close();
                                  destinationFile.close();
                                  qDebug() << "Database successfully copied to writable location.";
                              } else {
                                  qDebug() << "Failed to open destination file:" << destinationFile.errorString();
                              }
                          } else {
                              qDebug() << "Failed to open resource file:" << resourceFile.errorString();
                          }
                      } else {
                          qDebug() << "Database resource file not found.";
                      }
                  }
              
                  // Set the SQLite database file location
                  m_db.setDatabaseName(databasePath);
              
                  // Open the database connection and handle success or failure
                  if (m_db.open() && m_db.isOpen()) {
                      qDebug() << "Database opened successfully at" << databasePath;
                  } else {
                      // Handle connection error
                      qDebug() << "Database failed to open";
                      qDebug() << m_db.lastError().text();
                  }
              }
              
              

              I get an output of

              Database opened successfully at "/Users/boyankiovtorov/Library/Application Support/appFinbank/Finbank.db"
              

              I was unable to access that directory to check the file but nevertheless I think it is generated .db file which is 0 bytes and not the db file from the resource file.
              I am currently looking at a stackoverflow case - https://stackoverflow.com/questions/50828041/how-to-open-database-sqlite-file-on-iphone-real-device

              But i am getting no success so far because I do not have Application Support folder like him

              J Offline
              J Offline
              jsulm
              Lifetime Qt Champion
              wrote on 27 Nov 2024, 17:40 last edited by
              #14

              @Kiovtorov But do you see any of the errors you're printing (like "Failed to open resource file:"")?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              K 1 Reply Last reply 28 Nov 2024, 07:00
              0
              • J jsulm
                27 Nov 2024, 17:40

                @Kiovtorov But do you see any of the errors you're printing (like "Failed to open resource file:"")?

                K Offline
                K Offline
                Kiovtorov
                wrote on 28 Nov 2024, 07:00 last edited by
                #15

                @jsulm
                No, I am getting

                Database opened successfully at "/Users/boyankiovtorov/Library/Application Support/appFinbank/Finbank.db"
                

                but it is just because it automatically generates it.

                J 1 Reply Last reply 28 Nov 2024, 07:50
                0
                • K Kiovtorov
                  28 Nov 2024, 07:00

                  @jsulm
                  No, I am getting

                  Database opened successfully at "/Users/boyankiovtorov/Library/Application Support/appFinbank/Finbank.db"
                  

                  but it is just because it automatically generates it.

                  J Offline
                  J Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on 28 Nov 2024, 07:50 last edited by
                  #16

                  @Kiovtorov said in How to use relative path on SQLite .db file on iOS:

                  but it is just because it automatically generates it.

                  If it automatically generates it the copying failed.
                  Run through debugger step by step to see what happens.

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Kiovtorov
                    wrote on 28 Nov 2024, 08:09 last edited by
                    #17

                    I just tested a new method which works (kind of)

                    void DatabaseManager::OpenConnection() {
                        // Configure the database connection parameters for SQLite
                        m_db = QSqlDatabase::addDatabase("QSQLITE");
                    
                        // Use QStandardPaths to get a writable location
                        QString dbName = "identifier.sqlite";
                        QString dbLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
                        QString fullDbPath = dbLocation + "/" + dbName;
                    
                        // Set the SQLite database file location
                        m_db.setDatabaseName(fullDbPath);
                    
                        qDebug() << "Database path:" << fullDbPath;
                    
                        // Check if the database file exists
                        if (!QFile::exists(fullDbPath)) {
                            qDebug() << "Database does not exist, creating a new one.";
                        }
                    
                        // Open the database connection and handle success or failure
                        if (m_db.open()) {
                            qDebug() << "Database opened successfully";
                    
                            if (!QFile::exists(fullDbPath)) {
                                // If the database is newly created, initialize tables
                                QSqlQuery query(m_db);
                                query.prepare("SELECT * FROM users WHERE username = :username");
                                query.bindValue(":username", "test");
                    
                                if (!query.exec()) {
                                    qDebug() << "Error creating settings table:" << query.lastError().text();
                                } else {
                                    qDebug() << "Settings table created successfully.";
                                    qDebug() << "lite: " << query.value("username");
                                }
                            }
                        } else {
                            // Handle connection error
                            qDebug() << "Database failed to open";
                            qDebug() << m_db.lastError().text();
                        }
                    }
                    

                    it creates a database in my Documents folder or the ios devide documents folder. I tested if it works with creating a new table

                    QSqlQuery query(db);
                                query.prepare("CREATE TABLE settings ("
                                              "`id` INTEGER PRIMARY KEY AUTOINCREMENT, "
                                              "`username` TEXT, "
                                              "`password` TEXT, "
                                              "`remember_login` TEXT);");
                                if (!query.exec())
                                {
                                    qDebug() << "ERROR: FAILED TO CREATE TABLE -" << query.lastError().text();
                                }
                    
                                query.prepare("INSERT INTO settings (username, password, remember_login) VALUES ('aaa', 'bbb', '1')");
                                query.exec();
                    
                                query.prepare("SELECT * FROM settings");
                                query.exec();
                    
                    

                    and it works on macos and ios. Before I couldn't even find the file so I can now at least debug more. I will now try to copy the data from my original sqlite file to that one in the documents

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      Kiovtorov
                      wrote on 28 Nov 2024, 08:16 last edited by
                      #18

                      FINALLY!
                      I don't know what is the difference between a db file and sqllite file but with .sqlite file the copying from .qrc file works
                      Here is my code for everyone with the same problem

                      
                      void DatabaseManager::OpenConnection() {
                          // Configure the database connection parameters for SQLite
                          m_db = QSqlDatabase::addDatabase("QSQLITE");
                      
                          // Use QStandardPaths to get a writable location
                          QString dbName = "identifier.sqlite";
                          QString dbLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
                          QString fullDbPath = dbLocation + "/" + dbName;
                      
                          // Set the SQLite database file location
                          m_db.setDatabaseName(fullDbPath);
                      
                          qDebug() << "Database path:" << fullDbPath;
                      
                          // Check if the database file exists in the writable location
                          if (!QFile::exists(fullDbPath)) {
                              qDebug() << "Database does not exist in Documents, copying from resources.";
                      
                              // Path to the resource database file
                              QString resourceDbPath = ":/resources/identifier.sqlite"; // Adjust the path to your resource file
                      
                              // Attempt to copy the database from resources to the writable location
                              if (QFile::copy(resourceDbPath, fullDbPath)) {
                                  qDebug() << "Database copied successfully to Documents.";
                                  // Set file permissions to writable (necessary for some platforms)
                                  QFile::setPermissions(fullDbPath, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
                              } else {
                                  qDebug() << "Failed to copy database from resources.";
                              }
                          }
                      
                          // Open the database connection and handle success or failure
                          if (m_db.open()) {
                              qDebug() << "Database opened successfully.";
                      
                              // Sample query to verify the database contents
                              QSqlQuery query(m_db);
                              query.prepare("SELECT * FROM users WHERE username = :username");
                              query.bindValue(":username", "test");
                      
                              if (!query.exec()) {
                                  qDebug() << "Error executing query:" << query.lastError().text();
                              } else {
                                  while (query.next()) {
                                      qDebug() << "Username:" << query.value("username").toString();
                                  }
                              }
                          } else {
                              // Handle connection error
                              qDebug() << "Database failed to open.";
                              qDebug() << m_db.lastError().text();
                          }
                      }
                      
                      1 Reply Last reply
                      0
                      • K Kiovtorov has marked this topic as solved on 28 Nov 2024, 08:16
                      • K Offline
                        K Offline
                        Kiovtorov
                        wrote on 28 Nov 2024, 08:23 last edited by
                        #19

                        Here is the same code using appDataLocation

                        void DatabaseManager::OpenConnection() {
                            // Configure the database connection parameters for SQLite
                            m_db = QSqlDatabase::addDatabase("QSQLITE");
                        
                            // Use QStandardPaths to get the application data location
                            QString dbName = "identifier.sqlite";
                            QString dbLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
                            QString fullDbPath = dbLocation + "/" + dbName;
                        
                            QDir dbDir(dbLocation);
                            if (!dbDir.exists()) {
                                if (dbDir.mkpath(dbLocation)) {
                                    qDebug() << "Created application data directory:" << dbLocation;
                                } else {
                                    qDebug() << "Failed to create application data directory:" << dbLocation;
                                    return; // Exit if the directory cannot be created
                                }
                            }
                        
                            // Set the SQLite database file location
                            m_db.setDatabaseName(fullDbPath);
                        
                            // Check if the database file exists in the application data location
                            if (!QFile::exists(fullDbPath)) {
                                qDebug() << "Database does not exist in AppDataLocation, copying from resources.";
                        
                                // Path to the resource database file
                                QString resourceDbPath = ":/resources/identifier.sqlite"; // Adjust the path to your resource file
                        
                                // Attempt to copy the database from resources to the writable location
                                if (QFile::copy(resourceDbPath, fullDbPath)) {
                                    qDebug() << "Database copied successfully to AppDataLocation.";
                                    // Set file permissions to writable (necessary for some platforms)
                                    QFile::setPermissions(fullDbPath, QFileDevice::ReadOwner | QFileDevice::WriteOwner);
                                } else {
                                    qDebug() << "Failed to copy database from resources.";
                                    return; // Exit if the database cannot be copied
                                }
                            }
                        
                            // Open the database connection and handle success or failure
                            if (m_db.open()) {
                                qDebug() << "Database opened successfully.";
                        
                                // Sample query to verify the database contents
                            } else {
                                // Handle connection error
                                qDebug() << "Database failed to open.";
                                qDebug() << m_db.lastError().text();
                            }
                        }
                        
                        1 Reply Last reply
                        0

                        18/19

                        28 Nov 2024, 08:16

                        • Login

                        • Login or register to search.
                        18 out of 19
                        • First post
                          18/19
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved