1 /***************************************************************************
2   qgsspatialitetransaction.cpp - QgsSpatialiteTransaction
3 
4  ---------------------
5  begin                : 30.3.2020
6  copyright            : (C) 2020 by Alessandro Pasotti
7  email                : elpaso at itopen dot it
8  ***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 
17 #include "qgsspatialitetransaction.h"
18 #include "qgslogger.h"
19 #include <QDebug>
20 
21 ///@cond PRIVATE
22 
23 QAtomicInt QgsSpatiaLiteTransaction::sSavepointId = 0;
24 
QgsSpatiaLiteTransaction(const QString & connString,QgsSqliteHandle * sharedHandle)25 QgsSpatiaLiteTransaction::QgsSpatiaLiteTransaction( const QString &connString, QgsSqliteHandle *sharedHandle )
26   : QgsTransaction( connString )
27   , mSharedHandle( sharedHandle )
28 {
29   if ( mSharedHandle )
30     mSqliteHandle = mSharedHandle->handle();
31   mSavepointId = ++sSavepointId;
32 }
33 
beginTransaction(QString & error,int)34 bool QgsSpatiaLiteTransaction::beginTransaction( QString &error, int /* statementTimeout */ )
35 {
36   return executeSql( QStringLiteral( "BEGIN" ), error );
37 }
38 
commitTransaction(QString & error)39 bool QgsSpatiaLiteTransaction::commitTransaction( QString &error )
40 {
41   return executeSql( QStringLiteral( "COMMIT" ), error );
42 }
43 
rollbackTransaction(QString & error)44 bool QgsSpatiaLiteTransaction::rollbackTransaction( QString &error )
45 {
46   return executeSql( QStringLiteral( "ROLLBACK" ), error );
47 }
48 
executeSql(const QString & sql,QString & errorMsg,bool isDirty,const QString & name)49 bool QgsSpatiaLiteTransaction::executeSql( const QString &sql, QString &errorMsg, bool isDirty, const QString &name )
50 {
51 
52   if ( ! mSqliteHandle )
53   {
54     QgsDebugMsg( QStringLiteral( "Spatialite handle is not set" ) );
55     return false;
56   }
57 
58   if ( isDirty )
59   {
60     createSavepoint( errorMsg );
61     if ( ! errorMsg.isEmpty() )
62     {
63       QgsDebugMsg( errorMsg );
64       return false;
65     }
66   }
67 
68   char *errMsg = nullptr;
69   if ( sqlite3_exec( mSqliteHandle, sql.toUtf8().constData(), nullptr, nullptr, &errMsg ) != SQLITE_OK )
70   {
71     if ( isDirty )
72     {
73       rollbackToSavepoint( savePoints().last(), errorMsg );
74     }
75     errorMsg = QStringLiteral( "%1\n%2" ).arg( errMsg, errorMsg );
76     QgsDebugMsg( errMsg );
77     sqlite3_free( errMsg );
78     return false;
79   }
80 
81   if ( isDirty )
82   {
83     dirtyLastSavePoint();
84     emit dirtied( sql, name );
85   }
86 
87   QgsDebugMsg( QStringLiteral( "... ok" ) );
88   return true;
89 }
90 
sqliteHandle() const91 sqlite3 *QgsSpatiaLiteTransaction::sqliteHandle() const
92 {
93   return mSqliteHandle;
94 }
95 ///@endcond
96