QGIS API Documentation  3.12.1-București (121cc00ff0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgssqliteutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssqliteutils.cpp
3  -------------------
4  begin : Nov, 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 #include "qgssqliteutils.h"
19 
20 #include <sqlite3.h>
21 #include <cstdarg>
22 #include <QVariant>
23 
25 {
26  sqlite3_close_v2( database );
27 }
28 
29 void QgsSqlite3StatementFinalizer::operator()( sqlite3_stmt *statement )
30 {
31  sqlite3_finalize( statement );
32 }
33 
35 {
36  return sqlite3_step( get() );
37 }
38 
39 QString sqlite3_statement_unique_ptr::columnName( int column ) const
40 {
41  return QString::fromUtf8( static_cast<const char *>( sqlite3_column_name( get(), column ) ) );
42 }
43 
45 {
46  return sqlite3_column_double( get(), column );
47 }
48 
50 {
51  return sqlite3_column_count( get() );
52 }
53 
54 QString sqlite3_statement_unique_ptr::columnAsText( int column ) const
55 {
56  return QString::fromUtf8( reinterpret_cast<const char *>( sqlite3_column_text( get(), column ) ) );
57 }
58 
59 QByteArray sqlite3_statement_unique_ptr::columnAsBlob( int column ) const
60 {
61  const void *blob = sqlite3_column_blob( get(), column );
62  int size = sqlite3_column_bytes( get(), column );
63  return QByteArray( reinterpret_cast<const char *>( blob ), size );
64 }
65 
66 qlonglong sqlite3_statement_unique_ptr::columnAsInt64( int column ) const
67 {
68  return sqlite3_column_int64( get(), column );
69 }
70 
71 int sqlite3_database_unique_ptr::open( const QString &path )
72 {
73  sqlite3 *database = nullptr;
74  int result = sqlite3_open( path.toUtf8(), &database );
75  reset( database );
76  return result;
77 }
78 
79 int sqlite3_database_unique_ptr::open_v2( const QString &path, int flags, const char *zVfs )
80 {
81  sqlite3 *database = nullptr;
82  int result = sqlite3_open_v2( path.toUtf8(), &database, flags, zVfs );
83  reset( database );
84  return result;
85 }
86 
88 {
89  return QString( sqlite3_errmsg( get() ) );
90 }
91 
92 sqlite3_statement_unique_ptr sqlite3_database_unique_ptr::prepare( const QString &sql, int &resultCode ) const
93 {
94  sqlite3_stmt *preparedStatement = nullptr;
95  const char *tail = nullptr;
96  resultCode = sqlite3_prepare( get(), sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
98  s.reset( preparedStatement );
99  return s;
100 }
101 
102 int sqlite3_database_unique_ptr::exec( const QString &sql, QString &errorMessage ) const
103 {
104  char *errMsg;
105 
106  int ret = sqlite3_exec( get(), sql.toUtf8(), nullptr, nullptr, &errMsg );
107 
108  if ( errMsg )
109  {
110  errorMessage = QString::fromUtf8( errMsg );
111  sqlite3_free( errMsg );
112  }
113 
114  return ret;
115 }
116 
117 QString QgsSqliteUtils::quotedString( const QString &value )
118 {
119  if ( value.isNull() )
120  return QStringLiteral( "NULL" );
121 
122  QString v = value;
123  v.replace( '\'', QLatin1String( "''" ) );
124  return v.prepend( '\'' ).append( '\'' );
125 }
126 
127 QString QgsSqliteUtils::quotedIdentifier( const QString &identifier )
128 {
129  QString id( identifier );
130  id.replace( '\"', QLatin1String( "\"\"" ) );
131  return id.prepend( '\"' ).append( '\"' );
132 }
133 
134 QString QgsSqliteUtils::quotedValue( const QVariant &value )
135 {
136  if ( value.isNull() )
137  return QStringLiteral( "NULL" );
138 
139  switch ( value.type() )
140  {
141  case QVariant::Int:
142  case QVariant::LongLong:
143  case QVariant::Double:
144  return value.toString();
145 
146  case QVariant::Bool:
147  //SQLite has no boolean literals
148  return value.toBool() ? QStringLiteral( "1" ) : QStringLiteral( "0" );
149 
150  default:
151  case QVariant::String:
152  QString v = value.toString();
153  // https://www.sqlite.org/lang_expr.html :
154  // """A string constant is formed by enclosing the string in single quotes (').
155  // A single quote within the string can be encoded by putting two single quotes
156  // in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL. """
157  return v.replace( '\'', QLatin1String( "''" ) ).prepend( '\'' ).append( '\'' );
158  }
159 }
160 
162 {
163  return QStringList() << QStringLiteral( "SpatialIndex" ) << QStringLiteral( "geom_cols_ref_sys" ) << QStringLiteral( "geometry_columns" )
164  << QStringLiteral( "geometry_columns_auth" ) << QStringLiteral( "views_geometry_columns" ) << QStringLiteral( "virts_geometry_columns" )
165  << QStringLiteral( "spatial_ref_sys" ) << QStringLiteral( "spatial_ref_sys_all" ) << QStringLiteral( "spatial_ref_sys_aux" )
166  << QStringLiteral( "sqlite_sequence" ) << QStringLiteral( "tableprefix_metadata" ) << QStringLiteral( "tableprefix_rasters" )
167  << QStringLiteral( "layer_params" ) << QStringLiteral( "layer_statistics" ) << QStringLiteral( "layer_sub_classes" )
168  << QStringLiteral( "layer_table_layout" ) << QStringLiteral( "pattern_bitmaps" ) << QStringLiteral( "symbol_bitmaps" )
169  << QStringLiteral( "project_defs" ) << QStringLiteral( "raster_pyramids" ) << QStringLiteral( "sqlite_stat1" ) << QStringLiteral( "sqlite_stat2" )
170  << QStringLiteral( "spatialite_history" ) << QStringLiteral( "geometry_columns_field_infos" ) << QStringLiteral( "geometry_columns_statistics" )
171  << QStringLiteral( "geometry_columns_time" ) << QStringLiteral( "sql_statements_log" ) << QStringLiteral( "vector_layers" )
172  << QStringLiteral( "vector_layers_auth" ) << QStringLiteral( "vector_layers_field_infos" ) << QStringLiteral( "vector_layers_statistics" )
173  << QStringLiteral( "views_geometry_columns_auth" ) << QStringLiteral( "views_geometry_columns_field_infos" )
174  << QStringLiteral( "views_geometry_columns_statistics" ) << QStringLiteral( "virts_geometry_columns_auth" )
175  << QStringLiteral( "virts_geometry_columns_field_infos" ) << QStringLiteral( "virts_geometry_columns_statistics" )
176  << QStringLiteral( "virts_layer_statistics" ) << QStringLiteral( "views_layer_statistics" )
177  << QStringLiteral( "ElementaryGeometries" );
178 }
179 
180 QString QgsSqlite3Mprintf( const char *format, ... )
181 {
182  va_list ap;
183  va_start( ap, format );
184  char *c_str = sqlite3_vmprintf( format, ap );
185  va_end( ap );
186  QString res( QString::fromUtf8( c_str ) );
187  sqlite3_free( c_str );
188  return res;
189 }
void operator()(sqlite3_stmt *statement)
Finalizes an sqlite3 statement.
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
static QStringList systemTables()
Returns a string list of SQLite (and spatialite) system tables.
QByteArray columnAsBlob(int column) const
Returns the column value from the current statement row as raw byte array.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
int columnCount() const
Gets the number of columns that this statement returns.
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
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.
struct sqlite3 sqlite3
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
void operator()(sqlite3 *database)
Closes an sqlite database.
QString QgsSqlite3Mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
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.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
static QString quotedString(const QString &value)
Returns a quoted string value, surround by &#39; characters and with special characters correctly escaped...