33   sqlite3_close_v2( database );
 
   38   sqlite3_finalize( statement );
 
   43   return sqlite3_step( get() );
 
   48   return QString::fromUtf8( 
static_cast<const char *
>( sqlite3_column_name( get(), column ) ) );
 
   53   return sqlite3_column_double( get(), column );
 
   58   return sqlite3_column_count( get() );
 
   63   return QString::fromUtf8( 
reinterpret_cast<const char *
>( sqlite3_column_text( get(), column ) ) );
 
   68   const void *blob = sqlite3_column_blob( get(), column );
 
   69   const int size = sqlite3_column_bytes( get(), column );
 
   70   return QByteArray( 
reinterpret_cast<const char *
>( blob ), size );
 
   75   return sqlite3_column_int64( get(), column );
 
   81   const int result = sqlite3_open( path.toUtf8(), &database );
 
   89   const int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
 
   96   return QString( sqlite3_errmsg( get() ) );
 
  101   sqlite3_stmt *preparedStatement = 
nullptr;
 
  102   const char *tail = 
nullptr;
 
  103   resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
 
  105   s.reset( preparedStatement );
 
  113   const int ret = sqlite3_exec( get(), sql.toUtf8(), 
nullptr, 
nullptr, &errMsg );
 
  118     sqlite3_free( errMsg );
 
  126   QSet<QString> uniqueFieldsResults;
 
  128   std::vector<std::string> rows;
 
  129   const QByteArray tableNameUtf8 = tableName.toUtf8();
 
  131                                      "where type='table' and name='%q'", tableNameUtf8.constData() );
 
  138     static_cast<std::vector<std::string>*
>( data )->push_back( argv[0] );
 
  142   int rc = sqlite3_exec( connection, sql.toUtf8(), cb, ( 
void * )&rows, &zErrMsg );
 
  143   if ( rc != SQLITE_OK )
 
  145     errorMessage = zErrMsg;
 
  146     sqlite3_free( zErrMsg );
 
  147     return uniqueFieldsResults;
 
  151   std::smatch uniqueFieldMatch;
 
  152   static const std::regex sFieldIdentifierRe { R
"raw(\s*(["`]([^"`]+)["`])|(([^\s]+)\s).*)raw" }; 
  153   for ( 
auto tableDefinition : rows )
 
  155     tableDefinition = tableDefinition.substr( tableDefinition.find( 
'(' ), tableDefinition.rfind( 
')' ) );
 
  156     std::stringstream tableDefinitionStream { tableDefinition };
 
  157     while ( tableDefinitionStream.good() )
 
  159       std::string fieldStr;
 
  160       std::getline( tableDefinitionStream, fieldStr, 
',' );
 
  161       std::string upperCaseFieldStr { fieldStr };
 
  162       std::transform( upperCaseFieldStr.begin(), upperCaseFieldStr.end(), upperCaseFieldStr.begin(), ::toupper );
 
  163       if ( upperCaseFieldStr.find( 
"UNIQUE" ) != std::string::npos )
 
  165         if ( std::regex_search( fieldStr, uniqueFieldMatch, sFieldIdentifierRe ) )
 
  167           const std::string quoted { uniqueFieldMatch.str( 2 ) };
 
  168           uniqueFieldsResults.insert( QString::fromStdString( quoted.length() ? quoted :  uniqueFieldMatch.str( 4 ) ) );
 
  177                              " tbl_name='%q' AND sql LIKE 'CREATE UNIQUE INDEX%%'", tableNameUtf8.constData() );
 
  178   rc = sqlite3_exec( connection, sql.toUtf8(), cb, ( 
void * )&rows, &zErrMsg );
 
  179   if ( rc != SQLITE_OK )
 
  181     errorMessage = zErrMsg;
 
  182     sqlite3_free( zErrMsg );
 
  183     return uniqueFieldsResults;
 
  186   if ( rows.size() > 0 )
 
  188     static const std::regex sFieldIndexIdentifierRe { R
"raw(\(\s*[`"]?([^",`\)]+)["`]?\s*\))raw" }; 
  189     for ( 
auto indexDefinition : rows )
 
  191       std::string upperCaseIndexDefinition { indexDefinition };
 
  192       std::transform( upperCaseIndexDefinition.begin(), upperCaseIndexDefinition.end(), upperCaseIndexDefinition.begin(), ::toupper );
 
  193       if ( upperCaseIndexDefinition.find( 
"UNIQUE" ) != std::string::npos )
 
  195         indexDefinition = indexDefinition.substr( indexDefinition.find( 
'(' ), indexDefinition.rfind( 
')' ) );
 
  196         if ( std::regex_search( indexDefinition, uniqueFieldMatch, sFieldIndexIdentifierRe ) )
 
  198           uniqueFieldsResults.insert( QString::fromStdString( uniqueFieldMatch.str( 1 ) ) );
 
  203   return uniqueFieldsResults;
 
  208   long long result { -1 };
 
  210   dsPtr.reset( connection );
 
  215                                       .arg( quotedTableName ), resultCode )};
 
  216   if ( resultCode == SQLITE_OK )
 
  219     result = sqlite3_column_int64( stmt.get(), 0 );
 
  221     if ( sqlite3_column_count( stmt.get() ) == 0 )
 
  223       dsPtr.
exec( QStringLiteral( 
"INSERT INTO sqlite_sequence (name, seq) VALUES (%1, 1)" ).arg( quotedTableName ), errorMessage );
 
  224       if ( errorMessage.isEmpty() )
 
  230         errorMessage = QObject::tr( 
"Error retrieving default value for %1" ).arg( tableName );
 
  235       if ( dsPtr.
exec( QStringLiteral( 
"UPDATE sqlite_sequence SET seq = %1 WHERE name = %2" )
 
  236                        .arg( QString::number( ++result ), quotedTableName ),
 
  237                        errorMessage ) != SQLITE_OK )
 
  239         errorMessage = QObject::tr( 
"Error retrieving default value for %1" ).arg( tableName );
 
  251   if ( value.isNull() )
 
  252     return QStringLiteral( 
"NULL" );
 
  255   v.replace( 
'\'', QLatin1String( 
"''" ) );
 
  256   return v.prepend( 
'\'' ).append( 
'\'' );
 
  261   QString id( identifier );
 
  262   id.replace( 
'\"', QLatin1String( 
"\"\"" ) );
 
  263   return id.prepend( 
'\"' ).append( 
'\"' );
 
  268   if ( value.isNull() )
 
  269     return QStringLiteral( 
"NULL" );
 
  271   switch ( value.type() )
 
  274     case QVariant::LongLong:
 
  275     case QVariant::Double:
 
  276       return value.toString();
 
  280       return value.toBool() ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" );
 
  283     case QVariant::String:
 
  284       QString v = value.toString();
 
  289       return v.replace( 
'\'', QLatin1String( 
"''" ) ).prepend( 
'\'' ).append( 
'\'' );
 
  295   return QStringList() << QStringLiteral( 
"SpatialIndex" ) << QStringLiteral( 
"geom_cols_ref_sys" ) << QStringLiteral( 
"geometry_columns" )
 
  296          << QStringLiteral( 
"geometry_columns_auth" ) << QStringLiteral( 
"views_geometry_columns" ) << QStringLiteral( 
"virts_geometry_columns" )
 
  297          << QStringLiteral( 
"spatial_ref_sys" ) << QStringLiteral( 
"spatial_ref_sys_all" ) << QStringLiteral( 
"spatial_ref_sys_aux" )
 
  298          << QStringLiteral( 
"sqlite_sequence" ) << QStringLiteral( 
"tableprefix_metadata" ) << QStringLiteral( 
"tableprefix_rasters" )
 
  299          << QStringLiteral( 
"layer_params" ) << QStringLiteral( 
"layer_statistics" ) << QStringLiteral( 
"layer_sub_classes" )
 
  300          << QStringLiteral( 
"layer_table_layout" ) << QStringLiteral( 
"pattern_bitmaps" ) << QStringLiteral( 
"symbol_bitmaps" )
 
  301          << QStringLiteral( 
"project_defs" ) << QStringLiteral( 
"raster_pyramids" ) << QStringLiteral( 
"sqlite_stat1" ) << QStringLiteral( 
"sqlite_stat2" )
 
  302          << QStringLiteral( 
"spatialite_history" ) << QStringLiteral( 
"geometry_columns_field_infos" ) << QStringLiteral( 
"geometry_columns_statistics" )
 
  303          << QStringLiteral( 
"geometry_columns_time" ) << QStringLiteral( 
"sql_statements_log" ) << QStringLiteral( 
"vector_layers" )
 
  304          << QStringLiteral( 
"vector_layers_auth" ) << QStringLiteral( 
"vector_layers_field_infos" ) << QStringLiteral( 
"vector_layers_statistics" )
 
  305          << QStringLiteral( 
"views_geometry_columns_auth" ) << QStringLiteral( 
"views_geometry_columns_field_infos" )
 
  306          << QStringLiteral( 
"views_geometry_columns_statistics" ) << QStringLiteral( 
"virts_geometry_columns_auth" )
 
  307          << QStringLiteral( 
"virts_geometry_columns_field_infos" ) << QStringLiteral( 
"virts_geometry_columns_statistics" )
 
  308          << QStringLiteral( 
"virts_layer_statistics" ) << QStringLiteral( 
"views_layer_statistics" )
 
  309          << QStringLiteral( 
"ElementaryGeometries" );
 
  315   va_start( ap, format );
 
  316   char *c_str = sqlite3_vmprintf( format, ap );
 
  318   QString res( QString::fromUtf8( c_str ) );
 
  319   sqlite3_free( c_str );
 
static QString quotedString(const QString &value)
Returns a quoted string value, surround by ' characters and with special characters correctly escaped...
 
static QStringList systemTables()
Returns a string list of SQLite (and spatialite) system tables.
 
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
 
static QSet< QString > uniqueFields(sqlite3 *connection, const QString &tableName, QString &errorMessage)
Returns a list of field names for connection and tableName having a UNIQUE constraint,...
 
static long long nextSequenceValue(sqlite3 *connection, const QString &tableName, QString errorMessage)
Increments and returns an SQLITE sequence of the table "sqlite_sequence" for tableName and returns it...
 
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
 
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
 
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
 
int open(const QString &path)
Opens the database at the specified file path.
 
QString errorMessage() const
Returns the most recent error message encountered by the database.
 
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
 
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
 
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
 
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
 
QString columnName(int column) const
Returns the name of column.
 
double columnAsDouble(int column) const
Gets column value from the current statement row as a double.
 
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
 
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
 
int columnCount() const
Gets the number of columns that this statement returns.
 
QByteArray columnAsBlob(int column) const
Returns the column value from the current statement row as raw byte array.
 
QString qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
 
void operator()(sqlite3 *database)
Closes an sqlite database.
 
void operator()(sqlite3_stmt *statement)
Finalizes an sqlite3 statement.