~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/database/databasecorebackend.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-12-21 23:19:11 UTC
  • mfrom: (1.2.33 upstream) (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20101221231911-z9jip7s5aht1jqn9
Tags: 2:1.7.0-1ubuntu1
* Merge from Debian Experimental. Remaining Ubuntu changes:
  - Export .pot name and copy to plugins in debian/rules
  - Version build-depends on kipi-plugins-dev to ensure build is against the
    same version on all archs
* Drop debian/patches/kubuntu_01_linker.diff, incoporated upstream
* Remove patches directory and unused patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
{
62
62
 
63
63
DatabaseLocking::DatabaseLocking()
64
 
               : mutex(QMutex::Recursive), lockCount(0) // create a recursive mutex
 
64
    : mutex(QMutex::Recursive), lockCount(0) // create a recursive mutex
65
65
{
66
66
}
67
67
 
85
85
};
86
86
 
87
87
DatabaseCoreBackendPrivate::DatabaseCoreBackendPrivate(DatabaseCoreBackend* backend)
88
 
                          : q(backend)
 
88
    : q(backend)
89
89
{
90
90
 
91
91
    status          = DatabaseCoreBackend::Unavailable;
117
117
    QThread* thread = QThread::currentThread();
118
118
    QSqlDatabase db = threadDatabases[thread];
119
119
    int isValid = databasesValid[thread];
 
120
 
120
121
    if (!isValid || !db.isOpen())
121
122
    {
122
123
        // need to open a db for thread
123
124
        bool success = open(db);
 
125
 
124
126
        if (!success)
125
 
           kDebug() << "Error while opening the database. Details: [" << db.lastError() << "]";
 
127
        {
 
128
            kDebug() << "Error while opening the database. Details: [" << db.lastError() << "]";
 
129
        }
126
130
 
127
131
        QObject::connect(thread, SIGNAL(finished()),
128
132
                         q, SLOT(slotThreadFinished()));
129
133
    }
 
134
 
130
135
#ifdef DATABASCOREBACKEND_DEBUG
131
136
    else
132
137
    {
133
138
        kDebug() << "Database ["<< connectionName(thread) <<"] already open for thread ["<< thread <<"].";
134
139
    }
 
140
 
135
141
#endif
136
142
 
137
143
    return db;
139
145
 
140
146
void DatabaseCoreBackendPrivate::closeDatabaseForThread()
141
147
{
142
 
    QThread *thread = QThread::currentThread();
 
148
    QThread* thread = QThread::currentThread();
143
149
    // scope, so that db is destructed when calling removeDatabase
144
150
    {
145
151
        QSqlDatabase db = threadDatabases[thread];
 
152
 
146
153
        if (db.isValid())
 
154
        {
147
155
            db.close();
 
156
        }
148
157
    }
149
158
    threadDatabases.remove(thread);
150
159
    databasesValid[thread] = 0;
160
169
bool DatabaseCoreBackendPrivate::open(QSqlDatabase& db)
161
170
{
162
171
    if (db.isValid())
 
172
    {
163
173
        db.close();
 
174
    }
164
175
 
165
 
    QThread *thread = QThread::currentThread();
 
176
    QThread* thread = QThread::currentThread();
166
177
 
167
178
    db = QSqlDatabase::addDatabase(parameters.databaseType, connectionName(thread));
168
179
 
203
214
{
204
215
    QThread* thread = QThread::currentThread();
205
216
    QHash<QThread*, int>::const_iterator it;
 
217
 
206
218
    for (it=transactionCount.constBegin(); it != transactionCount.constEnd(); ++it)
207
219
        if (it.key() != thread && it.value())
 
220
        {
208
221
            return true;
 
222
        }
 
223
 
209
224
    return false;
210
225
}
211
226
 
216
231
 
217
232
bool DatabaseCoreBackendPrivate::isInUIThread() const
218
233
{
219
 
    QApplication* app = qobject_cast<QApplication *>(QCoreApplication::instance());
 
234
    QApplication* app = qobject_cast<QApplication*>(QCoreApplication::instance());
 
235
 
220
236
    if (!app)
 
237
    {
221
238
        return false;
 
239
    }
 
240
 
222
241
    return QThread::currentThread() == app->thread();
223
242
}
224
243
 
236
255
{
237
256
    // the backend returns connection error e.g. for Constraint Failed errors.
238
257
    if (parameters.isSQLite())
 
258
    {
239
259
        return false;
 
260
    }
 
261
 
240
262
    return query.lastError().type() == QSqlError::ConnectionError || query.lastError().number()==2006;
241
263
}
242
264
 
256
278
    if (!isInUIThread())
257
279
    {
258
280
        if (retries == 1)
 
281
        {
259
282
            kDebug() << "Detected locked database file. Waiting at most 10s trying again.";
 
283
        }
260
284
 
261
285
        sotoSleep::sleep(1);
262
286
        return true;
271
295
    kDebug() << "Failure executing query:\n"
272
296
             << query.executedQuery()
273
297
             << "\nError messages:" << query.lastError().text() << query.lastError().number()
274
 
                  << query.lastError().type() << query.lastError().databaseText()
275
 
                  << query.lastError().driverText() << query.driver()->lastError()
 
298
             << query.lastError().type() << query.lastError().databaseText()
 
299
             << query.lastError().driverText() << query.driver()->lastError()
276
300
             << "\nBound values: " << query.boundValues().values();
277
301
}
278
302
 
279
303
 
280
304
DatabaseCoreBackendPrivate::ErrorLocker::ErrorLocker(DatabaseCoreBackendPrivate* d)
281
 
                          : count(0), d(d)
 
305
    : count(0), d(d)
282
306
{
283
307
    // Why two mutexes? The main mutex is recursive and won't work with a condvar.
284
308
 
288
312
    count = d->lock->lockCount;
289
313
    // set lock count to 0
290
314
    d->lock->lockCount = 0;
 
315
 
291
316
    // unlock
292
317
    for (int i=0; i<count; ++i)
 
318
    {
293
319
        d->lock->mutex.unlock();
 
320
    }
294
321
 
295
322
    // lock condvar mutex (lock only if main mutex is locked)
296
323
    d->errorLockMutex.lock();
300
327
    d->lock->mutex.unlock();
301
328
}
302
329
 
303
 
    /** This suspends the current thread if the query status as
304
 
     *  set by setFlag() is Wait and until the thread is woken with wakeAll().
305
 
     *  The DatabaseAccess mutex will be unlocked while waiting.
306
 
     */
 
330
/** This suspends the current thread if the query status as
 
331
 *  set by setFlag() is Wait and until the thread is woken with wakeAll().
 
332
 *  The DatabaseAccess mutex will be unlocked while waiting.
 
333
 */
307
334
void DatabaseCoreBackendPrivate::ErrorLocker::wait()
308
335
{
309
336
    // we use a copy of the flag under lock of the errorLockMutex to be able to check it here
310
337
    while (d->errorLockOperationStatus == DatabaseCoreBackend::Wait)
 
338
    {
311
339
        d->errorLockCondVar.wait(&d->errorLockMutex);
 
340
    }
312
341
}
313
342
 
314
343
DatabaseCoreBackendPrivate::ErrorLocker::~ErrorLocker()
318
347
 
319
348
    // lock main mutex as often as it was locked before
320
349
    for (int i=0; i<count; ++i)
 
350
    {
321
351
        d->lock->mutex.lock();
 
352
    }
 
353
 
322
354
    // update lock count
323
355
    d->lock->lockCount = count;
324
356
}
325
357
 
326
 
    /** Set the wait flag to queryStatus. Typically, call this with Wait. */
 
358
/** Set the wait flag to queryStatus. Typically, call this with Wait. */
327
359
void DatabaseCoreBackendPrivate::setQueryOperationFlag(DatabaseCoreBackend::QueryOperationStatus status)
328
360
{
329
361
    // Enforce lock order (first main mutex, second error lock mutex)
333
365
    operationStatus = status;
334
366
}
335
367
 
336
 
    /** Set the wait flag to queryStatus and wake all waiting threads.
337
 
     *  Typically, call wakeAll with status ExecuteNormal or AbortQueries. */
 
368
/** Set the wait flag to queryStatus and wake all waiting threads.
 
369
 *  Typically, call wakeAll with status ExecuteNormal or AbortQueries. */
338
370
void DatabaseCoreBackendPrivate::queryOperationWakeAll(DatabaseCoreBackend::QueryOperationStatus status)
339
371
{
340
372
    QMutexLocker l(&errorLockMutex);
352
384
    }
353
385
 
354
386
    if (operationStatus == DatabaseCoreBackend::ExecuteNormal)
 
387
    {
355
388
        return true;
 
389
    }
356
390
    else if (operationStatus == DatabaseCoreBackend::AbortQueries)
 
391
    {
357
392
        return false;
 
393
    }
358
394
 
359
395
    return false;
360
396
}
418
454
        closeDatabaseForThread();
419
455
 
420
456
    }
 
457
 
421
458
    return false;
422
459
}
423
460
 
437
474
 
438
475
// ---------------------------
439
476
 
440
 
DatabaseCoreBackend::DatabaseCoreBackend(const QString &backendName, DatabaseLocking *locking)
441
 
                   : d_ptr(new DatabaseCoreBackendPrivate(this))
 
477
DatabaseCoreBackend::DatabaseCoreBackend(const QString& backendName, DatabaseLocking* locking)
 
478
    : d_ptr(new DatabaseCoreBackendPrivate(this))
442
479
{
443
480
    d_ptr->init(backendName, locking);
444
481
}
445
482
 
446
 
DatabaseCoreBackend::DatabaseCoreBackend(const QString &backendName, DatabaseLocking *locking, DatabaseCoreBackendPrivate &dd)
447
 
                   : d_ptr(&dd)
 
483
DatabaseCoreBackend::DatabaseCoreBackend(const QString& backendName, DatabaseLocking* locking, DatabaseCoreBackendPrivate& dd)
 
484
    : d_ptr(&dd)
448
485
{
449
486
    d_ptr->init(backendName, locking);
450
487
}
464
501
DatabaseAction DatabaseCoreBackend::getDBAction(const QString& actionName) const
465
502
{
466
503
    DatabaseAction action = configElement().sqlStatements.value(actionName);
 
504
 
467
505
    if (action.name.isNull())
 
506
    {
468
507
        kError() << "No DB action defined for" << actionName << "! Implementation missing for this database type.";
 
508
    }
 
509
 
469
510
    return action;
470
511
}
471
512
 
472
513
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execDBAction(const DatabaseAction& action, QList<QVariant>* values,
473
 
                                                                  QVariant* lastInsertId)
 
514
        QVariant* lastInsertId)
474
515
{
475
516
    return execDBAction(action, QMap<QString, QVariant>(), values, lastInsertId);
476
517
}
477
518
 
478
519
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execDBAction(const DatabaseAction& action, const QMap<QString, QVariant>& bindingMap,
479
 
                                                                  QList<QVariant>* values, QVariant* lastInsertId)
 
520
        QList<QVariant>* values, QVariant* lastInsertId)
480
521
{
481
522
    Q_D(DatabaseCoreBackend);
482
523
 
484
525
    QSqlDatabase db                              = d->databaseForThread();
485
526
 
486
527
    if (action.name.isNull())
 
528
    {
487
529
        kError() << "Attempt to execute null action";
 
530
    }
488
531
 
489
 
    #ifdef DATABASCOREBACKEND_DEBUG
 
532
#ifdef DATABASCOREBACKEND_DEBUG
490
533
    kDebug() << "Executing DBAction ["<<  action.name  <<"]";
491
 
    #endif
 
534
#endif
492
535
 
493
536
    bool wrapInTransaction = (action.mode == QString("transaction"));
 
537
 
494
538
    if (wrapInTransaction)
495
539
    {
496
540
        beginTransaction();
499
543
    foreach (DatabaseActionElement actionElement, action.dbActionElements)
500
544
    {
501
545
        DatabaseCoreBackend::QueryState result;
 
546
 
502
547
        if (actionElement.mode == QString("query"))
503
548
        {
504
549
            result = execSql(actionElement.statement, bindingMap, values, lastInsertId);
507
552
        {
508
553
            result = execDirectSql(actionElement.statement);
509
554
        }
 
555
 
510
556
        if (result != DatabaseCoreBackend::NoErrors)
511
557
        {
512
558
            kDebug() << "Error while executing DBAction ["<<  action.name  <<"] Statement ["<<actionElement.statement<<"]";
544
590
 
545
591
    QSqlDatabase db = d->databaseForThread();
546
592
 
547
 
    #ifdef DATABASCOREBACKEND_DEBUG
 
593
#ifdef DATABASCOREBACKEND_DEBUG
548
594
    kDebug() << "Executing DBAction ["<<  action.name  <<"]";
549
 
    #endif
 
595
#endif
550
596
 
551
597
    QSqlQuery result;
552
598
    foreach (DatabaseActionElement actionElement, action.dbActionElements)
563
609
        if (result.lastError().isValid() && result.lastError().number())
564
610
        {
565
611
            kDebug() << "Error while executing DBAction ["<<  action.name
566
 
                          <<"] Statement ["<<actionElement.statement<<"] Errornr. [" << result.lastError() << "]";
 
612
                     <<"] Statement ["<<actionElement.statement<<"] Errornr. [" << result.lastError() << "]";
567
613
            break;
568
614
        }
569
615
    }
575
621
    Q_D(DatabaseCoreBackend);
576
622
 
577
623
    if (d->errorHandler)
 
624
    {
578
625
        delete d->errorHandler;
 
626
    }
579
627
 
580
628
    d->errorHandler = handler;
581
629
}
611
659
    forever
612
660
    {
613
661
        QSqlDatabase database = d->databaseForThread();
 
662
 
614
663
        if (!database.isOpen())
615
664
        {
616
665
            kDebug() << "Error while opening the database. Trying again.";
 
666
 
617
667
            if (connectionErrorHandling(retries++))
 
668
            {
618
669
                continue;
 
670
            }
619
671
            else
 
672
            {
620
673
                return false;
 
674
            }
621
675
        }
622
676
        else
623
 
            break;
 
677
            { break; }
624
678
    }
625
679
    d->status = Open;
626
680
    return true;
629
683
bool DatabaseCoreBackend::initSchema(ThumbnailSchemaUpdater* updater)
630
684
{
631
685
    Q_D(DatabaseCoreBackend);
 
686
 
632
687
    if (d->status == OpenSchemaChecked)
 
688
    {
633
689
        return true;
 
690
    }
 
691
 
634
692
    if (d->status == Unavailable)
 
693
    {
635
694
        return false;
 
695
    }
 
696
 
636
697
    if (updater->update())
637
698
    {
638
699
        d->status = OpenSchemaChecked;
639
700
        return true;
640
701
    }
 
702
 
641
703
    return false;
642
704
}
643
705
 
682
744
    while (query.next())
683
745
    {
684
746
        for (int i=0; i<count; ++i)
685
 
      list << query.value(i);
 
747
        {
 
748
            list << query.value(i);
 
749
        }
686
750
    }
 
751
 
687
752
#ifdef DATABASCOREBACKEND_DEBUG
688
753
    kDebug() << "Setting result value list ["<< list <<"]";
689
754
#endif
699
764
            return DatabaseCoreBackend::ConnectionError;
700
765
        }
701
766
    }
 
767
 
702
768
    if (lastInsertId)
 
769
    {
703
770
        (*lastInsertId) = query.lastInsertId();
 
771
    }
 
772
 
704
773
    if (values)
 
774
    {
705
775
        (*values) = readToList(query);
 
776
    }
 
777
 
706
778
    return DatabaseCoreBackend::NoErrors;
707
779
}
708
780
 
713
785
}
714
786
 
715
787
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql, const QVariant& boundValue1,
716
 
                                                             QList<QVariant>* values, QVariant* lastInsertId)
 
788
        QList<QVariant>* values, QVariant* lastInsertId)
717
789
{
718
790
    SqlQuery query = execQuery(sql, boundValue1);
719
791
    return handleQueryResult(query, values, lastInsertId);
720
792
}
721
793
 
722
794
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql,
723
 
                                                             const QVariant& boundValue1, const QVariant& boundValue2,
724
 
                                                             QList<QVariant>* values, QVariant* lastInsertId)
 
795
        const QVariant& boundValue1, const QVariant& boundValue2,
 
796
        QList<QVariant>* values, QVariant* lastInsertId)
725
797
{
726
798
    SqlQuery query = execQuery(sql, boundValue1, boundValue2);
727
799
    return handleQueryResult(query, values, lastInsertId);
728
800
}
729
801
 
730
802
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql,
731
 
                              const QVariant& boundValue1, const QVariant& boundValue2,
732
 
                              const QVariant& boundValue3, QList<QVariant>* values,
733
 
                              QVariant* lastInsertId)
 
803
        const QVariant& boundValue1, const QVariant& boundValue2,
 
804
        const QVariant& boundValue3, QList<QVariant>* values,
 
805
        QVariant* lastInsertId)
734
806
{
735
807
    SqlQuery query = execQuery(sql, boundValue1, boundValue2, boundValue3);
736
808
    return handleQueryResult(query, values, lastInsertId);
737
809
}
738
810
 
739
811
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql,
740
 
                const QVariant& boundValue1, const QVariant& boundValue2,
741
 
                const QVariant& boundValue3, const QVariant& boundValue4,
742
 
                QList<QVariant>* values, QVariant* lastInsertId)
 
812
        const QVariant& boundValue1, const QVariant& boundValue2,
 
813
        const QVariant& boundValue3, const QVariant& boundValue4,
 
814
        QList<QVariant>* values, QVariant* lastInsertId)
743
815
{
744
816
    SqlQuery query = execQuery(sql, boundValue1, boundValue2, boundValue3, boundValue4);
745
817
    return handleQueryResult(query, values, lastInsertId);
746
818
}
747
819
 
748
820
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql, const QList<QVariant>& boundValues,
749
 
                              QList<QVariant>* values, QVariant* lastInsertId)
 
821
        QList<QVariant>* values, QVariant* lastInsertId)
750
822
{
751
823
    SqlQuery query = execQuery(sql, boundValues);
752
824
    return handleQueryResult(query, values, lastInsertId);
753
825
}
754
826
 
755
827
DatabaseCoreBackend::QueryState DatabaseCoreBackend::execSql(const QString& sql, const QMap<QString, QVariant>& bindingMap,
756
 
                                                             QList<QVariant>* values, QVariant* lastInsertId)
 
828
        QList<QVariant>* values, QVariant* lastInsertId)
757
829
{
758
830
    SqlQuery query = execQuery(sql, bindingMap);
759
831
    return handleQueryResult(query, values, lastInsertId);
807
879
SqlQuery DatabaseCoreBackend::execQuery(const QString& sql, const QList<QVariant>& boundValues)
808
880
{
809
881
    SqlQuery query = prepareQuery(sql);
 
882
 
810
883
    for (int i=0; i<boundValues.size(); ++i)
 
884
    {
811
885
        query.bindValue(i, boundValues[i]);
 
886
    }
 
887
 
812
888
    exec(query);
813
889
    return query;
814
890
}
830
906
 
831
907
    if (!bindingMap.isEmpty())
832
908
    {
833
 
        #ifdef DATABASCOREBACKEND_DEBUG
 
909
#ifdef DATABASCOREBACKEND_DEBUG
834
910
        kDebug()<<"Prepare statement ["<< preparedString <<"] with binding map ["<< bindingMap <<"]";
835
 
        #endif
 
911
#endif
836
912
 
837
913
        QRegExp identifierRegExp(":[A-Za-z0-9]+");
838
914
        int pos=0;
840
916
        while ((pos=identifierRegExp.indexIn(preparedString, pos))!=-1)
841
917
        {
842
918
            QString namedPlaceholder = identifierRegExp.cap(0);
 
919
 
843
920
            if (!bindingMap.contains(namedPlaceholder))
844
921
            {
845
922
                kError()<<"Missing place holder ["<< namedPlaceholder <<"] in binding map. Following values are defined for this action ["<< bindingMap.keys() <<"]. This is a setup error!";
846
923
                //TODO What should we do here? How can we cancel that action?
847
924
            }
 
925
 
848
926
            QVariant placeHolderValue = bindingMap[namedPlaceholder];
849
927
            // Check if this is a map - then we assume, that there is a custom field/value list
850
928
            QString replaceStr;
851
 
            if (placeHolderValue.userType() == qMetaTypeId<DBActionType>()){
 
929
 
 
930
            if (placeHolderValue.userType() == qMetaTypeId<DBActionType>())
 
931
            {
852
932
                DBActionType actionType = placeHolderValue.value<DBActionType>();
853
933
                bool isValue            = actionType.isValue();
854
934
                QVariant value          = actionType.getActionValue();
 
935
 
855
936
                if ( value.type()==QVariant::Map )
856
937
                {
857
938
                    QMap<QString, QVariant> placeHolderMap = value.toMap();
858
939
                    QMap<QString, QVariant>::const_iterator iterator;
 
940
 
859
941
                    for (iterator = placeHolderMap.constBegin(); iterator != placeHolderMap.constEnd(); ++iterator)
860
942
                    {
861
943
                        QString  key   = iterator.key();
875
957
                {
876
958
                    QList<QVariant> placeHolderList = value.toList();
877
959
                    QList<QVariant>::const_iterator iterator;
878
 
                    for (iterator = placeHolderList.constBegin(); iterator != placeHolderList.constEnd(); ++iterator){
 
960
 
 
961
                    for (iterator = placeHolderList.constBegin(); iterator != placeHolderList.constEnd(); ++iterator)
 
962
                    {
879
963
                        QVariant  entry = *iterator;
 
964
 
880
965
                        if (isValue)
881
966
                        {
882
967
                            replaceStr.append("?");
898
983
                {
899
984
                    QStringList placeHolderList = value.toStringList();
900
985
                    QStringList::const_iterator iterator;
901
 
                    for (iterator = placeHolderList.constBegin(); iterator != placeHolderList.constEnd(); ++iterator){
 
986
 
 
987
                    for (iterator = placeHolderList.constBegin(); iterator != placeHolderList.constEnd(); ++iterator)
 
988
                    {
902
989
                        QString  entry = *iterator;
 
990
 
903
991
                        if (isValue)
904
992
                        {
905
993
                            replaceStr.append("?");
920
1008
            }
921
1009
            else
922
1010
            {
923
 
                #ifdef DATABASCOREBACKEND_DEBUG
 
1011
#ifdef DATABASCOREBACKEND_DEBUG
924
1012
                kDebug()<<"Bind key ["<< namedPlaceholder <<"] to value ["<< bindingMap[namedPlaceholder] <<"]";
925
 
                #endif
 
1013
#endif
926
1014
 
927
1015
                namedPlaceholderValues.append(bindingMap[namedPlaceholder]);
928
1016
                replaceStr="?";
932
1020
            pos=0; // reset pos
933
1021
        }
934
1022
    }
935
 
    #ifdef DATABASCOREBACKEND_DEBUG
 
1023
 
 
1024
#ifdef DATABASCOREBACKEND_DEBUG
936
1025
    kDebug()<<"Prepared statement ["<< preparedString <<"] values ["<< namedPlaceholderValues <<"]";
937
 
    #endif
 
1026
#endif
938
1027
 
939
1028
    SqlQuery query = prepareQuery(preparedString);
940
1029
 
941
 
    for(int i=0; i<namedPlaceholderValues.size(); i++)
 
1030
    for (int i=0; i<namedPlaceholderValues.size(); i++)
942
1031
    {
943
1032
        query.bindValue(i, namedPlaceholderValues[i]);
944
1033
    }
978
1067
    if (d->isSQLiteLockError(query))
979
1068
    {
980
1069
        if (d->checkRetrySQLiteLockError(retries))
 
1070
        {
981
1071
            return true;
 
1072
        }
982
1073
    }
983
1074
    else if (d->needToHandleWithErrorHandler(query))
984
1075
    {
985
1076
        if (d->handleWithErrorHandler(&query))
 
1077
        {
986
1078
            return true;
 
1079
        }
987
1080
        else
 
1081
        {
988
1082
            return false;
 
1083
        }
989
1084
    }
 
1085
 
990
1086
    return false;
991
1087
}
992
1088
 
995
1091
    Q_D(DatabaseCoreBackend);
996
1092
 
997
1093
    if (!d->checkOperationStatus())
 
1094
    {
998
1095
        return DatabaseCoreBackend::SQLError;
 
1096
    }
999
1097
 
1000
1098
    SqlQuery query = getQuery();
1001
1099
 
1003
1101
    forever
1004
1102
    {
1005
1103
        if (query.exec(sql))
 
1104
        {
1006
1105
            break;
 
1106
        }
1007
1107
        else
1008
1108
        {
1009
1109
            if (queryErrorHandling(query, retries++))
 
1110
            {
1010
1111
                continue;
 
1112
            }
1011
1113
            else
1012
 
                return DatabaseCoreBackend::SQLError;
 
1114
                { return DatabaseCoreBackend::SQLError; }
1013
1115
        }
1014
1116
    }
1015
1117
    return DatabaseCoreBackend::NoErrors;
1020
1122
    Q_D(DatabaseCoreBackend);
1021
1123
 
1022
1124
    if (!d->checkOperationStatus())
 
1125
    {
1023
1126
        return false;
 
1127
    }
1024
1128
 
1025
1129
    int retries = 0;
1026
1130
    forever
1027
1131
    {
1028
 
        #ifdef DATABASCOREBACKEND_DEBUG
 
1132
#ifdef DATABASCOREBACKEND_DEBUG
1029
1133
        kDebug() << "Trying to query ["<<query.lastQuery()<<"] values ["<< query.boundValues() <<"]";
1030
 
        #endif
 
1134
#endif
1031
1135
 
1032
1136
        if (query.exec())
 
1137
        {
1033
1138
            break;
 
1139
        }
1034
1140
        else
1035
1141
        {
1036
1142
            if (queryErrorHandling(query, retries++))
 
1143
            {
1037
1144
                continue;
 
1145
            }
1038
1146
            else
1039
 
                return false;
 
1147
                { return false; }
1040
1148
        }
1041
1149
    }
1042
1150
    return true;
1047
1155
    Q_D(DatabaseCoreBackend);
1048
1156
 
1049
1157
    if (!d->checkOperationStatus())
 
1158
    {
1050
1159
        return false;
 
1160
    }
1051
1161
 
1052
1162
    int retries = 0;
1053
1163
    forever
1054
1164
    {
1055
1165
        if (query.execBatch())
 
1166
        {
1056
1167
            break;
 
1168
        }
1057
1169
        else
1058
1170
        {
1059
1171
            if (queryErrorHandling(query, retries++))
 
1172
            {
1060
1173
                continue;
 
1174
            }
1061
1175
            else
1062
 
                return false;
 
1176
                { return false; }
1063
1177
        }
1064
1178
    }
1065
1179
    return true;
1072
1186
    forever
1073
1187
    {
1074
1188
        SqlQuery query = getQuery();
 
1189
 
1075
1190
        if (query.prepare(sql))
 
1191
        {
1076
1192
            return query;
 
1193
        }
1077
1194
        else
1078
1195
        {
1079
1196
            kDebug() << "Prepare failed!";
 
1197
 
1080
1198
            if (queryErrorHandling(query, retries++))
 
1199
            {
1081
1200
                continue;
 
1201
            }
1082
1202
            else
1083
 
                return query;
 
1203
                { return query; }
1084
1204
        }
1085
1205
    }
1086
1206
}
1093
1213
    query.setForwardOnly(old.isForwardOnly());
1094
1214
    // only for positional binding
1095
1215
    QList<QVariant> boundValues = old.boundValues().values();
1096
 
    foreach (const QVariant &value, boundValues)
 
1216
    foreach (const QVariant& value, boundValues)
1097
1217
    {
1098
1218
        kDebug() << "Bind value to query ["<<value<<"]";
1099
1219
        query.addBindValue(value);
1116
1236
    Q_D(DatabaseCoreBackend);
1117
1237
    // Call databaseForThread before touching transaction count - open() will reset the count
1118
1238
    QSqlDatabase db = d->databaseForThread();
 
1239
 
1119
1240
    if (d->incrementTransactionCount())
1120
1241
    {
1121
1242
        if (!db.transaction())
1122
1243
        {
1123
1244
            d->decrementTransactionCount();
 
1245
 
1124
1246
            if (db.lastError().type() == QSqlError::ConnectionError)
1125
1247
            {
1126
1248
                return DatabaseCoreBackend::ConnectionError;
1127
1249
            }
1128
1250
        }
 
1251
 
1129
1252
        d->isInTransaction = true;
1130
1253
    }
 
1254
 
1131
1255
    return DatabaseCoreBackend::NoErrors;
1132
1256
}
1133
1257
 
1134
1258
DatabaseCoreBackend::QueryState DatabaseCoreBackend::commitTransaction()
1135
1259
{
1136
1260
    Q_D(DatabaseCoreBackend);
 
1261
 
1137
1262
    if (d->decrementTransactionCount())
1138
1263
    {
1139
1264
        QSqlDatabase db = d->databaseForThread();
 
1265
 
1140
1266
        if (!db.commit())
1141
1267
        {
1142
1268
            d->incrementTransactionCount();
 
1269
 
1143
1270
            if (db.lastError().type() == QSqlError::ConnectionError)
1144
1271
            {
1145
1272
                return DatabaseCoreBackend::ConnectionError;
1146
1273
            }
1147
1274
        }
 
1275
 
1148
1276
        d->isInTransaction = false;
1149
1277
        d->transactionFinished();
1150
1278
    }
 
1279
 
1151
1280
    return DatabaseCoreBackend::NoErrors;
1152
1281
}
1153
1282