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. sql query thread termination
Forum Updated to NodeBB v4.3 + New Features

sql query thread termination

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 361 Views 1 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.
  • Seb TurS Offline
    Seb TurS Offline
    Seb Tur
    wrote on last edited by Seb Tur
    #1

    Hi,
    I have a lengthy queries that I execute in a separate thread to keep the UI responsive.

    I read forum posts and opinions that feeding QsqlQueryModel/QSqlQuery from thread to mainapp is not recommended solution.
    So instead I execute the query in the thread and create a QVariantMap that is sent as signal argument when read and can be picked up by mainWindow slot that will convert the QVariantMap into QStandardItemModel and then to QTableView.

    I also have a button that allows the user to terminate the thread if user is impatient.

    So in the thread's run() I do

    QSqlQuery query(threadDB);
    query.prepare(queryString);
    setQueryBinds(query, queryBinds);
    result = query.exec();
    QVariantMap results; // Create a map to store extracted data
           QStringList headers;
           for (int i = 0; i < query.record().count(); ++i) {
               headers.append(query.record().fieldName(i));
           }
           results.insert("headers", headers);
           int rowCount = 0;
           while (query.next()) {
               QVariantMap row;
               for (int i = 0; i < query.record().count(); ++i) {
                   QString columnName = query.record().fieldName(i);
                   QVariant columnValue = query.value(i);
                   row.insert(columnName, columnValue);
               }
               results.insert(QString::number(rowCount), row);
               ++rowCount;
           }
    
           if (!isInterruptionRequested())
               emit queryExecutionFinished(results); // Emit the signal with the results
    
    

    and in my mainWindow uses

    void iSqlManager::abortQuery() {
        qDebug()<<Q_FUNC_INFO;
        if (execThread && execThread->isRunning()) {
            execThread->requestInterruption(); // Safer way to signal the thread to stop
            // execThread->terminate();
            execThread->wait();
            queryAbortButton->setText("Anulowano zapytanie");
            emit queryAborted();
            emit errorOccurred("Anulowano zapytanie.");
            // execThread->deleteLater();
        }
    }
    

    The problem is that if i call abortQuery() no matter if I call requestInterruption() or terminate() the query keeps running and running .

    to avoid race conditions I want the app to be able to have only one sql thread running so in the preparation for execution of query i check there's no other thread already

    if (execThread && execThread->isRunning()) {
            QString error = "Another query is already running.";
            emit errorOccurred(error);
            qDebug()<<error;
            return;
        }
    

    If the abortQuery does not terminate the thread effectively the user has to wait until query is fetched even if he decided to cancel the execution with the abort button.

    What is the proper way to terminate the query execution and generation of results ?

    Christian EhrlicherC 1 Reply Last reply
    0
    • Seb TurS Seb Tur

      Hi,
      I have a lengthy queries that I execute in a separate thread to keep the UI responsive.

      I read forum posts and opinions that feeding QsqlQueryModel/QSqlQuery from thread to mainapp is not recommended solution.
      So instead I execute the query in the thread and create a QVariantMap that is sent as signal argument when read and can be picked up by mainWindow slot that will convert the QVariantMap into QStandardItemModel and then to QTableView.

      I also have a button that allows the user to terminate the thread if user is impatient.

      So in the thread's run() I do

      QSqlQuery query(threadDB);
      query.prepare(queryString);
      setQueryBinds(query, queryBinds);
      result = query.exec();
      QVariantMap results; // Create a map to store extracted data
             QStringList headers;
             for (int i = 0; i < query.record().count(); ++i) {
                 headers.append(query.record().fieldName(i));
             }
             results.insert("headers", headers);
             int rowCount = 0;
             while (query.next()) {
                 QVariantMap row;
                 for (int i = 0; i < query.record().count(); ++i) {
                     QString columnName = query.record().fieldName(i);
                     QVariant columnValue = query.value(i);
                     row.insert(columnName, columnValue);
                 }
                 results.insert(QString::number(rowCount), row);
                 ++rowCount;
             }
      
             if (!isInterruptionRequested())
                 emit queryExecutionFinished(results); // Emit the signal with the results
      
      

      and in my mainWindow uses

      void iSqlManager::abortQuery() {
          qDebug()<<Q_FUNC_INFO;
          if (execThread && execThread->isRunning()) {
              execThread->requestInterruption(); // Safer way to signal the thread to stop
              // execThread->terminate();
              execThread->wait();
              queryAbortButton->setText("Anulowano zapytanie");
              emit queryAborted();
              emit errorOccurred("Anulowano zapytanie.");
              // execThread->deleteLater();
          }
      }
      

      The problem is that if i call abortQuery() no matter if I call requestInterruption() or terminate() the query keeps running and running .

      to avoid race conditions I want the app to be able to have only one sql thread running so in the preparation for execution of query i check there's no other thread already

      if (execThread && execThread->isRunning()) {
              QString error = "Another query is already running.";
              emit errorOccurred(error);
              qDebug()<<error;
              return;
          }
      

      If the abortQuery does not terminate the thread effectively the user has to wait until query is fetched even if he decided to cancel the execution with the abort button.

      What is the proper way to terminate the query execution and generation of results ?

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Seb-Tur said in sql query thread termination:

      requestInterruption()

      But you don't check for it in your thread.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      Seb TurS 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        @Seb-Tur said in sql query thread termination:

        requestInterruption()

        But you don't check for it in your thread.

        Seb TurS Offline
        Seb TurS Offline
        Seb Tur
        wrote on last edited by
        #3

        @Christian-Ehrlicher

        I do below

        if (!isInterruptionRequested())
                   emit queryExecutionFinished(results); // Emit the signal with the results
        

        but my question is how do I kill the thread stuck at the query.exec() ?

        Christian EhrlicherC 1 Reply Last reply
        0
        • Seb TurS Seb Tur

          @Christian-Ehrlicher

          I do below

          if (!isInterruptionRequested())
                     emit queryExecutionFinished(results); // Emit the signal with the results
          

          but my question is how do I kill the thread stuck at the query.exec() ?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Seb-Tur said in sql query thread termination:

          I do below
          if (!isInterruptionRequested())
          emit queryExecutionFinished(results); // Emit the signal with the results

          You should do inside the query.next() when there are a lot of rows.

          but my question is how do I kill the thread stuck at the query.exec() ?

          simply exit the run() function.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          2

          • Login

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