Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsspatialiteutils.cpp 3 : : ------------------- 4 : : begin : Nov, 2017 5 : : copyright : (C) 2017 by Matthias Kuhn 6 : : email : matthias@opengis.ch 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : 19 : : #include "qgsspatialiteutils.h" 20 : : #include "qgslogger.h" 21 : : 22 : : #include <sqlite3.h> 23 : : #include <spatialite.h> 24 : : 25 : : // Define this variable to print all spatialite SQL statements 26 : : #ifdef SPATIALITE_PRINT_ALL_SQL 27 : : // Debugging code 28 : : #include <QDebug> 29 : : #include <QThread> 30 : : static int trace_callback( unsigned, void *ctx, void *p, void * ) 31 : : { 32 : : sqlite3_stmt *stmt = ( sqlite3_stmt * )p; 33 : : char *sql = sqlite3_expanded_sql( stmt ); 34 : : qDebug() << "SPATIALITE" << QThread::currentThreadId() << ( sqlite3 * ) ctx << sql; 35 : : sqlite3_free( sql ); 36 : : return 0; 37 : : } 38 : : #endif 39 : : 40 : : 41 : 0 : int spatialite_database_unique_ptr::open( const QString &path ) 42 : : { 43 : 0 : auto &deleter = get_deleter(); 44 : 0 : deleter.mSpatialiteContext = spatialite_alloc_connection(); 45 : : 46 : 0 : sqlite3 *database = nullptr; 47 : 0 : int result = sqlite3_open( path.toUtf8(), &database ); 48 : 0 : std::unique_ptr< sqlite3, QgsSpatialiteCloser>::reset( database ); 49 : : 50 : 0 : if ( result == SQLITE_OK ) 51 : 0 : spatialite_init_ex( database, deleter.mSpatialiteContext, 0 ); 52 : : 53 : 0 : return result; 54 : 0 : } 55 : : 56 : 0 : void spatialite_database_unique_ptr::reset() 57 : : { 58 : 0 : std::unique_ptr< sqlite3, QgsSpatialiteCloser>::reset(); 59 : 0 : } 60 : : 61 : 13 : int spatialite_database_unique_ptr::open_v2( const QString &path, int flags, const char *zVfs ) 62 : : { 63 : 13 : auto &deleter = get_deleter(); 64 : 13 : deleter.mSpatialiteContext = spatialite_alloc_connection(); 65 : : 66 : 13 : sqlite3 *database = nullptr; 67 : 13 : int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs ); 68 : 13 : std::unique_ptr< sqlite3, QgsSpatialiteCloser>::reset( database ); 69 : : 70 : 13 : if ( result == SQLITE_OK ) 71 : 13 : spatialite_init_ex( database, deleter.mSpatialiteContext, 0 ); 72 : : 73 : : #ifdef SPATIALITE_PRINT_ALL_SQL 74 : : // Log all queries 75 : : sqlite3_trace_v2( 76 : : database, 77 : : SQLITE_TRACE_STMT, 78 : : trace_callback, 79 : : database 80 : : ); 81 : : #endif 82 : : 83 : 13 : return result; 84 : 0 : } 85 : : 86 : 0 : QString spatialite_database_unique_ptr::errorMessage() const 87 : : { 88 : 0 : return QString( sqlite3_errmsg( get() ) ); 89 : : } 90 : : 91 : 0 : sqlite3_statement_unique_ptr spatialite_database_unique_ptr::prepare( const QString &sql, int &resultCode ) 92 : : { 93 : 0 : sqlite3_stmt *preparedStatement = nullptr; 94 : 0 : const char *tail = nullptr; 95 : 0 : const QByteArray sqlUtf8 = sql.toUtf8(); 96 : 0 : resultCode = sqlite3_prepare( get(), sqlUtf8, sqlUtf8.length(), &preparedStatement, &tail ); 97 : 0 : sqlite3_statement_unique_ptr s; 98 : 0 : s.reset( preparedStatement ); 99 : 0 : return s; 100 : 0 : } 101 : : 102 : 13 : void QgsSpatialiteCloser::operator()( sqlite3 *handle ) 103 : : { 104 : 13 : int res = sqlite3_close_v2( handle ); 105 : 13 : if ( res != SQLITE_OK ) 106 : : { 107 : 0 : QgsDebugMsg( QStringLiteral( "sqlite3_close_v2() failed: %1" ).arg( res ) ); 108 : 0 : } 109 : : 110 : 13 : spatialite_cleanup_ex( mSpatialiteContext ); 111 : 13 : mSpatialiteContext = nullptr; 112 : 13 : }