34 sqlite3_close_v2( database );
39 sqlite3_finalize( statement );
44 return sqlite3_step( get() );
49 return QString::fromUtf8(
static_cast<const char *
>( sqlite3_column_name( get(), column ) ) );
54 return sqlite3_column_double( get(), column );
59 return sqlite3_column_count( get() );
64 return QString::fromUtf8(
reinterpret_cast<const char *
>( sqlite3_column_text( get(), column ) ) );
69 const void *blob = sqlite3_column_blob( get(), column );
70 const int size = sqlite3_column_bytes( get(), column );
71 return QByteArray(
reinterpret_cast<const char *
>( blob ), size );
76 return sqlite3_column_int64( get(), column );
82 const int result = sqlite3_open( path.toUtf8(), &database );
90 const int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
97 return QString( sqlite3_errmsg( get() ) );
102 sqlite3_stmt *preparedStatement =
nullptr;
103 const char *tail =
nullptr;
104 resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
106 s.reset( preparedStatement );
114 const int ret = sqlite3_exec( get(), sql.toUtf8(),
nullptr,
nullptr, &errMsg );
119 sqlite3_free( errMsg );
127 QSet<QString> uniqueFieldsResults;
129 std::vector<std::string> rows;
130 const QByteArray tableNameUtf8 = tableName.toUtf8();
132 "where type='table' and name='%q'", tableNameUtf8.constData() );
139 static_cast<std::vector<std::string>*
>( data )->push_back( argv[0] );
143 int rc = sqlite3_exec( connection, sql.toUtf8(), cb, (
void * )&rows, &zErrMsg );
144 if ( rc != SQLITE_OK )
146 errorMessage = zErrMsg;
147 sqlite3_free( zErrMsg );
148 return uniqueFieldsResults;
152 std::smatch uniqueFieldMatch;
153 static const std::regex sFieldIdentifierRe { R
"raw(\s*(["`]([^"`]+)["`])|(([^\s]+)\s).*)raw" };
154 for (
auto tableDefinition : rows )
156 tableDefinition = tableDefinition.substr( tableDefinition.find(
'(' ), tableDefinition.rfind(
')' ) );
157 std::stringstream tableDefinitionStream { tableDefinition };
158 while ( tableDefinitionStream.good() )
160 std::string fieldStr;
161 std::getline( tableDefinitionStream, fieldStr,
',' );
162 std::string upperCaseFieldStr { fieldStr };
163 std::transform( upperCaseFieldStr.begin(), upperCaseFieldStr.end(), upperCaseFieldStr.begin(), ::toupper );
164 if ( upperCaseFieldStr.find(
"UNIQUE" ) != std::string::npos )
166 if ( std::regex_search( fieldStr, uniqueFieldMatch, sFieldIdentifierRe ) )
168 const std::string quoted { uniqueFieldMatch.str( 2 ) };
169 uniqueFieldsResults.insert( QString::fromStdString( quoted.length() ? quoted : uniqueFieldMatch.str( 4 ) ) );
178 " tbl_name='%q' AND sql LIKE 'CREATE UNIQUE INDEX%%'", tableNameUtf8.constData() );
179 rc = sqlite3_exec( connection, sql.toUtf8(), cb, (
void * )&rows, &zErrMsg );
180 if ( rc != SQLITE_OK )
182 errorMessage = zErrMsg;
183 sqlite3_free( zErrMsg );
184 return uniqueFieldsResults;
187 if ( rows.size() > 0 )
189 static const std::regex sFieldIndexIdentifierRe { R
"raw(\(\s*[`"]?([^",`\)]+)["`]?\s*\))raw" };
190 for (
auto indexDefinition : rows )
192 std::string upperCaseIndexDefinition { indexDefinition };
193 std::transform( upperCaseIndexDefinition.begin(), upperCaseIndexDefinition.end(), upperCaseIndexDefinition.begin(), ::toupper );
194 if ( upperCaseIndexDefinition.find(
"UNIQUE" ) != std::string::npos )
196 indexDefinition = indexDefinition.substr( indexDefinition.find(
'(' ), indexDefinition.rfind(
')' ) );
197 if ( std::regex_search( indexDefinition, uniqueFieldMatch, sFieldIndexIdentifierRe ) )
199 uniqueFieldsResults.insert( QString::fromStdString( uniqueFieldMatch.str( 1 ) ) );
204 return uniqueFieldsResults;
209 long long result { -1 };
211 dsPtr.reset( connection );
216 .arg( quotedTableName ), resultCode )};
217 if ( resultCode == SQLITE_OK )
220 result = sqlite3_column_int64( stmt.get(), 0 );
222 if ( sqlite3_column_count( stmt.get() ) == 0 )
224 dsPtr.
exec( QStringLiteral(
"INSERT INTO sqlite_sequence (name, seq) VALUES (%1, 1)" ).arg( quotedTableName ), errorMessage );
225 if ( errorMessage.isEmpty() )
231 errorMessage = QObject::tr(
"Error retrieving default value for %1" ).arg( tableName );
236 if ( dsPtr.
exec( QStringLiteral(
"UPDATE sqlite_sequence SET seq = %1 WHERE name = %2" )
237 .arg( QString::number( ++result ), quotedTableName ),
238 errorMessage ) != SQLITE_OK )
240 errorMessage = QObject::tr(
"Error retrieving default value for %1" ).arg( tableName );
252 if ( value.isNull() )
253 return QStringLiteral(
"NULL" );
256 v.replace(
'\'', QLatin1String(
"''" ) );
257 return v.prepend(
'\'' ).append(
'\'' );
262 QString id( identifier );
263 id.replace(
'\"', QLatin1String(
"\"\"" ) );
264 return id.prepend(
'\"' ).append(
'\"' );
270 return QStringLiteral(
"NULL" );
272 switch ( value.type() )
275 case QVariant::LongLong:
276 case QVariant::Double:
277 return value.toString();
281 return value.toBool() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" );
284 case QVariant::String:
285 QString v = value.toString();
290 return v.replace(
'\'', QLatin1String(
"''" ) ).prepend(
'\'' ).append(
'\'' );
296 return QStringList() << QStringLiteral(
"SpatialIndex" ) << QStringLiteral(
"geom_cols_ref_sys" ) << QStringLiteral(
"geometry_columns" )
297 << QStringLiteral(
"geometry_columns_auth" ) << QStringLiteral(
"views_geometry_columns" ) << QStringLiteral(
"virts_geometry_columns" )
298 << QStringLiteral(
"spatial_ref_sys" ) << QStringLiteral(
"spatial_ref_sys_all" ) << QStringLiteral(
"spatial_ref_sys_aux" )
299 << QStringLiteral(
"sqlite_sequence" ) << QStringLiteral(
"tableprefix_metadata" ) << QStringLiteral(
"tableprefix_rasters" )
300 << QStringLiteral(
"layer_params" ) << QStringLiteral(
"layer_statistics" ) << QStringLiteral(
"layer_sub_classes" )
301 << QStringLiteral(
"layer_table_layout" ) << QStringLiteral(
"pattern_bitmaps" ) << QStringLiteral(
"symbol_bitmaps" )
302 << QStringLiteral(
"project_defs" ) << QStringLiteral(
"raster_pyramids" ) << QStringLiteral(
"sqlite_stat1" ) << QStringLiteral(
"sqlite_stat2" )
303 << QStringLiteral(
"spatialite_history" ) << QStringLiteral(
"geometry_columns_field_infos" ) << QStringLiteral(
"geometry_columns_statistics" )
304 << QStringLiteral(
"geometry_columns_time" ) << QStringLiteral(
"sql_statements_log" ) << QStringLiteral(
"vector_layers" )
305 << QStringLiteral(
"vector_layers_auth" ) << QStringLiteral(
"vector_layers_field_infos" ) << QStringLiteral(
"vector_layers_statistics" )
306 << QStringLiteral(
"views_geometry_columns_auth" ) << QStringLiteral(
"views_geometry_columns_field_infos" )
307 << QStringLiteral(
"views_geometry_columns_statistics" ) << QStringLiteral(
"virts_geometry_columns_auth" )
308 << QStringLiteral(
"virts_geometry_columns_field_infos" ) << QStringLiteral(
"virts_geometry_columns_statistics" )
309 << QStringLiteral(
"virts_layer_statistics" ) << QStringLiteral(
"views_layer_statistics" )
310 << QStringLiteral(
"ElementaryGeometries" );
316 va_start( ap, format );
317 char *c_str = sqlite3_vmprintf( format, ap );
319 QString res( QString::fromUtf8( c_str ) );
320 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.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
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.
QString CORE_EXPORT qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
void operator()(sqlite3 *database) const
Closes an sqlite database.
void operator()(sqlite3_stmt *statement) const
Finalizes an sqlite3 statement.