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 int size = sqlite3_column_bytes( get(), column );
70 return QByteArray(
reinterpret_cast<const char *
>( blob ), size );
75 return sqlite3_column_int64( get(), column );
81 int result = sqlite3_open( path.toUtf8(), &database );
89 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 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 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.