Merge pull request #7152 from rouault/fix_memleaks_qgsstyle

Fix various memleaks in QgsStyle
This commit is contained in:
Even Rouault 2018-06-05 17:03:55 +02:00 committed by GitHub
commit 370bac9935
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 147 additions and 169 deletions

View File

@ -134,6 +134,7 @@ returns 0 if not found
Returns default application-wide style
%End
bool tagSymbol( StyleEntity type, const QString &symbol, const QStringList &tags );
%Docstring
Tags the symbol with the tags in the list
@ -453,56 +454,10 @@ Is emitted every time a new symbol has been added to the database
void groupsModified();
%Docstring
Is emitted every time a tag or smartgroup has been added, removed, or renamed
%End
protected:
bool openDatabase( const QString &filename );
%Docstring
Convenience function to open the DB and return a sqlite3 object
%End
bool runEmptyQuery( char *query, bool freeQuery = true );
%Docstring
Convenience function that would run queries which don't generate return values
:param query: query to run
:param freeQuery: release query memory
:return: success true on success
%End
int getId( const QString &table, const QString &name );
%Docstring
Gets the id from the table for the given name from the database, 0 if not found
%End
QString getName( const QString &table, int id ) const;
%Docstring
Gets the name from the table for the given id from the database, empty if not found
%End
bool updateSymbol( StyleEntity type, const QString &name );
%Docstring
Updates the properties of an existing symbol/colorramp
.. note::
This should not be called separately, only called through addSymbol or addColorRamp
:param type: is either SymbolEntity or ColorrampEntity
:param name: is the name of an existing symbol or a color ramp
:return: Success state of the update operation
%End
};
/************************************************************************
* This file has been generated automatically from *
* *

View File

@ -47,6 +47,7 @@
#include "qgs3drendererregistry.h"
#include "qgslayoutrendercontext.h"
#include "qgssqliteutils.h"
#include "qgsstyle.h"
#include "gps/qgsgpsconnectionregistry.h"
#include "processing/qgsprocessingregistry.h"
@ -1089,6 +1090,8 @@ void QgsApplication::exitQgis()
// is destroyed before the static variables of the cache, we might use freed memory.
QgsCoordinateTransform::invalidateCache();
QgsStyle::cleanDefaultStyle();
// tear-down GDAL/OGR
OGRCleanupAll();
GDALDestroyDriverManager();

View File

@ -18,6 +18,7 @@
#include "qgssqliteutils.h"
#include <sqlite3.h>
#include <stdarg.h>
void QgsSqlite3Closer::operator()( sqlite3 *database )
{
@ -89,3 +90,14 @@ sqlite3_statement_unique_ptr sqlite3_database_unique_ptr::prepare( const QString
s.reset( preparedStatement );
return s;
}
QString QgsSqlite3Mprintf( const char *format, ... )
{
va_list ap;
va_start( ap, format );
char *c_str = sqlite3_vmprintf( format, ap );
va_end( ap );
QString res( QString::fromUtf8( c_str ) );
sqlite3_free( c_str );
return res;
}

View File

@ -135,7 +135,15 @@ class CORE_EXPORT sqlite3_database_unique_ptr : public std::unique_ptr< sqlite3,
* argument will be filled with the sqlite3 result code.
*/
sqlite3_statement_unique_ptr prepare( const QString &sql, int &resultCode ) const;
};
/**
* Wraps sqlite3_mprintf() by automatically freeing the memory.
* \note not available in Python bindings.
* \since QGIS 3.2
*/
QString CORE_EXPORT QgsSqlite3Mprintf( const char *format, ... );
#endif // QGSSQLITEUTILS_H

View File

@ -68,6 +68,11 @@ QgsStyle *QgsStyle::defaultStyle() // static
return sDefaultStyle;
}
void QgsStyle::cleanDefaultStyle() // static
{
delete sDefaultStyle;
sDefaultStyle = nullptr;
}
void QgsStyle::clear()
{
@ -117,8 +122,8 @@ bool QgsStyle::saveSymbol( const QString &name, QgsSymbol *symbol, bool favorite
QTextStream stream( &xmlArray );
stream.setCodec( "UTF-8" );
symEl.save( stream, 4 );
char *query = sqlite3_mprintf( "INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
auto query = QgsSqlite3Mprintf( "INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
if ( !runEmptyQuery( query ) )
{
@ -223,8 +228,8 @@ bool QgsStyle::saveColorRamp( const QString &name, QgsColorRamp *ramp, bool favo
QTextStream stream( &xmlArray );
stream.setCodec( "UTF-8" );
rampEl.save( stream, 4 );
char *query = sqlite3_mprintf( "INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
auto query = QgsSqlite3Mprintf( "INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
if ( !runEmptyQuery( query ) )
{
QgsDebugMsg( "Couldn't insert colorramp into the database!" );
@ -242,7 +247,7 @@ bool QgsStyle::removeColorRamp( const QString &name )
if ( !ramp )
return false;
char *query = sqlite3_mprintf( "DELETE FROM colorramp WHERE name='%q'", name.toUtf8().constData() );
auto query = QgsSqlite3Mprintf( "DELETE FROM colorramp WHERE name='%q'", name.toUtf8().constData() );
if ( !runEmptyQuery( query ) )
{
QgsDebugMsg( "Couldn't remove color ramp from the database." );
@ -319,29 +324,29 @@ bool QgsStyle::createMemoryDatabase()
void QgsStyle::createTables()
{
char *query = sqlite3_mprintf( "CREATE TABLE symbol("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE colorramp("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE tag("\
"id INTEGER PRIMARY KEY,"\
"name TEXT);"\
"CREATE TABLE tagmap("\
"tag_id INTEGER NOT NULL,"\
"symbol_id INTEGER);"\
"CREATE TABLE ctagmap("\
"tag_id INTEGER NOT NULL,"\
"colorramp_id INTEGER);"\
"CREATE TABLE smartgroup("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"xml TEXT);" );
auto query = QgsSqlite3Mprintf( "CREATE TABLE symbol("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE colorramp("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE tag("\
"id INTEGER PRIMARY KEY,"\
"name TEXT);"\
"CREATE TABLE tagmap("\
"tag_id INTEGER NOT NULL,"\
"symbol_id INTEGER);"\
"CREATE TABLE ctagmap("\
"tag_id INTEGER NOT NULL,"\
"colorramp_id INTEGER);"\
"CREATE TABLE smartgroup("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"xml TEXT);" );
runEmptyQuery( query );
}
@ -358,13 +363,13 @@ bool QgsStyle::load( const QString &filename )
}
// Make sure there are no Null fields in parenting symbols and groups
char *query = sqlite3_mprintf( "UPDATE symbol SET favorite=0 WHERE favorite IS NULL;"
"UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
);
auto query = QgsSqlite3Mprintf( "UPDATE symbol SET favorite=0 WHERE favorite IS NULL;"
"UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
);
runEmptyQuery( query );
// First create all the main symbols
query = sqlite3_mprintf( "SELECT * FROM symbol" );
query = QgsSqlite3Mprintf( "SELECT * FROM symbol" );
sqlite3_statement_unique_ptr statement;
int rc;
@ -387,7 +392,7 @@ bool QgsStyle::load( const QString &filename )
mSymbols.insert( symbol_name, symbol );
}
query = sqlite3_mprintf( "SELECT * FROM colorramp" );
query = QgsSqlite3Mprintf( "SELECT * FROM colorramp" );
statement = mCurrentDB.prepare( query, rc );
while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
{
@ -505,7 +510,7 @@ bool QgsStyle::renameColorRamp( const QString &oldName, const QString &newName )
int rampid = 0;
sqlite3_statement_unique_ptr statement;
char *query = sqlite3_mprintf( "SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
auto query = QgsSqlite3Mprintf( "SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
int nErr;
statement = mCurrentDB.prepare( query, nErr );
if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
@ -525,14 +530,14 @@ QStringList QgsStyle::symbolsOfFavorite( StyleEntity type ) const
return QStringList();
}
char *query = nullptr;
QString query;
if ( type == SymbolEntity )
{
query = sqlite3_mprintf( "SELECT name FROM symbol WHERE favorite=1" );
query = QgsSqlite3Mprintf( "SELECT name FROM symbol WHERE favorite=1" );
}
else if ( type == ColorrampEntity )
{
query = sqlite3_mprintf( "SELECT name FROM colorramp WHERE favorite=1" );
query = QgsSqlite3Mprintf( "SELECT name FROM colorramp WHERE favorite=1" );
}
else
{
@ -561,14 +566,14 @@ QStringList QgsStyle::symbolsWithTag( StyleEntity type, int tagid ) const
return QStringList();
}
char *subquery = nullptr;
QString subquery;;
if ( type == SymbolEntity )
{
subquery = sqlite3_mprintf( "SELECT symbol_id FROM tagmap WHERE tag_id=%d", tagid );
subquery = QgsSqlite3Mprintf( "SELECT symbol_id FROM tagmap WHERE tag_id=%d", tagid );
}
else if ( type == ColorrampEntity )
{
subquery = sqlite3_mprintf( "SELECT colorramp_id FROM ctagmap WHERE tag_id=%d", tagid );
subquery = QgsSqlite3Mprintf( "SELECT colorramp_id FROM ctagmap WHERE tag_id=%d", tagid );
}
else
{
@ -586,9 +591,9 @@ QStringList QgsStyle::symbolsWithTag( StyleEntity type, int tagid ) const
{
int id = sqlite3_column_int( statement.get(), 0 );
char *query = type == SymbolEntity
? sqlite3_mprintf( "SELECT name FROM symbol WHERE id=%d", id )
: sqlite3_mprintf( "SELECT name FROM colorramp WHERE id=%d", id );
auto query = type == SymbolEntity
? QgsSqlite3Mprintf( "SELECT name FROM symbol WHERE id=%d", id )
: QgsSqlite3Mprintf( "SELECT name FROM colorramp WHERE id=%d", id );
int rc;
sqlite3_statement_unique_ptr statement2;
@ -608,7 +613,7 @@ int QgsStyle::addTag( const QString &tagname )
return 0;
sqlite3_statement_unique_ptr statement;
char *query = sqlite3_mprintf( "INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
auto query = QgsSqlite3Mprintf( "INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
int nErr;
statement = mCurrentDB.prepare( query, nErr );
if ( nErr == SQLITE_OK )
@ -629,7 +634,7 @@ QStringList QgsStyle::tags() const
sqlite3_statement_unique_ptr statement;
char *query = sqlite3_mprintf( "SELECT name FROM tag" );
auto query = QgsSqlite3Mprintf( "SELECT name FROM tag" );
int nError;
statement = mCurrentDB.prepare( query, nError );
@ -645,21 +650,21 @@ QStringList QgsStyle::tags() const
void QgsStyle::rename( StyleEntity type, int id, const QString &newName )
{
bool groupRenamed = false;
char *query = nullptr;
QString query;
switch ( type )
{
case SymbolEntity:
query = sqlite3_mprintf( "UPDATE symbol SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
query = QgsSqlite3Mprintf( "UPDATE symbol SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
break;
case ColorrampEntity:
query = sqlite3_mprintf( "UPDATE colorramp SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
query = QgsSqlite3Mprintf( "UPDATE colorramp SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
break;
case TagEntity:
query = sqlite3_mprintf( "UPDATE tag SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
query = QgsSqlite3Mprintf( "UPDATE tag SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
groupRenamed = true;
break;
case SmartgroupEntity:
query = sqlite3_mprintf( "UPDATE smartgroup SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
query = QgsSqlite3Mprintf( "UPDATE smartgroup SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
groupRenamed = true;
break;
default:
@ -682,21 +687,21 @@ void QgsStyle::rename( StyleEntity type, int id, const QString &newName )
void QgsStyle::remove( StyleEntity type, int id )
{
bool groupRemoved = false;
char *query = nullptr;
QString query;
switch ( type )
{
case SymbolEntity:
query = sqlite3_mprintf( "DELETE FROM symbol WHERE id=%d; DELETE FROM tagmap WHERE symbol_id=%d", id, id );
query = QgsSqlite3Mprintf( "DELETE FROM symbol WHERE id=%d; DELETE FROM tagmap WHERE symbol_id=%d", id, id );
break;
case ColorrampEntity:
query = sqlite3_mprintf( "DELETE FROM colorramp WHERE id=%d", id );
query = QgsSqlite3Mprintf( "DELETE FROM colorramp WHERE id=%d", id );
break;
case TagEntity:
query = sqlite3_mprintf( "DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d", id, id );
query = QgsSqlite3Mprintf( "DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d", id, id );
groupRemoved = true;
break;
case SmartgroupEntity:
query = sqlite3_mprintf( "DELETE FROM smartgroup WHERE id=%d", id );
query = QgsSqlite3Mprintf( "DELETE FROM smartgroup WHERE id=%d", id );
groupRemoved = true;
break;
default:
@ -720,18 +725,13 @@ void QgsStyle::remove( StyleEntity type, int id )
}
}
bool QgsStyle::runEmptyQuery( char *query, bool freeQuery )
bool QgsStyle::runEmptyQuery( const QString &query )
{
if ( !mCurrentDB )
return false;
char *zErr = nullptr;
int nErr = sqlite3_exec( mCurrentDB.get(), query, nullptr, nullptr, &zErr );
if ( freeQuery )
{
sqlite3_free( query );
}
int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(), nullptr, nullptr, &zErr );
if ( nErr != SQLITE_OK )
{
@ -744,15 +744,15 @@ bool QgsStyle::runEmptyQuery( char *query, bool freeQuery )
bool QgsStyle::addFavorite( StyleEntity type, const QString &name )
{
char *query = nullptr;
QString query;
switch ( type )
{
case SymbolEntity:
query = sqlite3_mprintf( "UPDATE symbol SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE symbol SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
break;
case ColorrampEntity:
query = sqlite3_mprintf( "UPDATE colorramp SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE colorramp SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
break;
default:
@ -765,15 +765,15 @@ bool QgsStyle::addFavorite( StyleEntity type, const QString &name )
bool QgsStyle::removeFavorite( StyleEntity type, const QString &name )
{
char *query = nullptr;
QString query;
switch ( type )
{
case SymbolEntity:
query = sqlite3_mprintf( "UPDATE symbol SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE symbol SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
break;
case ColorrampEntity:
query = sqlite3_mprintf( "UPDATE colorramp SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE colorramp SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
break;
default:
@ -794,8 +794,8 @@ QStringList QgsStyle::findSymbols( StyleEntity type, const QString &qword )
// first find symbols with matching name
QString item = ( type == SymbolEntity ) ? QStringLiteral( "symbol" ) : QStringLiteral( "colorramp" );
char *query = sqlite3_mprintf( "SELECT name FROM %q WHERE name LIKE '%%%q%%'",
item.toUtf8().constData(), qword.toUtf8().constData() );
auto query = QgsSqlite3Mprintf( "SELECT name FROM %q WHERE name LIKE '%%%q%%'",
item.toUtf8().constData(), qword.toUtf8().constData() );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -807,7 +807,7 @@ QStringList QgsStyle::findSymbols( StyleEntity type, const QString &qword )
}
// next add symbols with matching tags
query = sqlite3_mprintf( "SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
query = QgsSqlite3Mprintf( "SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
statement = mCurrentDB.prepare( query, nErr );
QStringList tagids;
@ -820,13 +820,13 @@ QStringList QgsStyle::findSymbols( StyleEntity type, const QString &qword )
if ( type == SymbolEntity )
{
query = sqlite3_mprintf( "SELECT symbol_id FROM tagmap WHERE tag_id IN (%q)",
dummy.toUtf8().constData() );
query = QgsSqlite3Mprintf( "SELECT symbol_id FROM tagmap WHERE tag_id IN (%q)",
dummy.toUtf8().constData() );
}
else
{
query = sqlite3_mprintf( "SELECT colorramp_id FROM ctagmap WHERE tag_id IN (%q)",
dummy.toUtf8().constData() );
query = QgsSqlite3Mprintf( "SELECT colorramp_id FROM ctagmap WHERE tag_id IN (%q)",
dummy.toUtf8().constData() );
}
statement = mCurrentDB.prepare( query, nErr );
@ -837,8 +837,8 @@ QStringList QgsStyle::findSymbols( StyleEntity type, const QString &qword )
}
dummy = symbolids.join( QStringLiteral( ", " ) );
query = sqlite3_mprintf( "SELECT name FROM %q WHERE id IN (%q)",
item.toUtf8().constData(), dummy.toUtf8().constData() );
query = QgsSqlite3Mprintf( "SELECT name FROM %q WHERE id IN (%q)",
item.toUtf8().constData(), dummy.toUtf8().constData() );
statement = mCurrentDB.prepare( query, nErr );
while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
{
@ -870,7 +870,7 @@ bool QgsStyle::tagSymbol( StyleEntity type, const QString &symbol, const QString
if ( !tag.isEmpty() )
{
// sql: gets the id of the tag if present or insert the tag and get the id of the tag
char *query = sqlite3_mprintf( "SELECT id FROM tag WHERE LOWER(name)='%q'", tag.toUtf8().toLower().constData() );
auto query = QgsSqlite3Mprintf( "SELECT id FROM tag WHERE LOWER(name)='%q'", tag.toUtf8().toLower().constData() );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -889,14 +889,15 @@ bool QgsStyle::tagSymbol( StyleEntity type, const QString &symbol, const QString
if ( !symbolHasTag( type, symbol, tag ) )
{
query = type == SymbolEntity
? sqlite3_mprintf( "INSERT INTO tagmap VALUES (%d,%d)", tagid, symbolid )
: sqlite3_mprintf( "INSERT INTO ctagmap VALUES (%d,%d)", tagid, symbolid );
? QgsSqlite3Mprintf( "INSERT INTO tagmap VALUES (%d,%d)", tagid, symbolid )
: QgsSqlite3Mprintf( "INSERT INTO ctagmap VALUES (%d,%d)", tagid, symbolid );
char *zErr = nullptr;
nErr = sqlite3_exec( mCurrentDB.get(), query, nullptr, nullptr, &zErr );
nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(), nullptr, nullptr, &zErr );
if ( nErr )
{
QgsDebugMsg( zErr );
sqlite3_free( zErr );
}
}
}
@ -913,9 +914,9 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol, const QStri
return false;
}
char *query = type == SymbolEntity
? sqlite3_mprintf( "SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
: sqlite3_mprintf( "SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
auto query = type == SymbolEntity
? QgsSqlite3Mprintf( "SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
: QgsSqlite3Mprintf( "SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -931,7 +932,7 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol, const QStri
Q_FOREACH ( const QString &tag, tags )
{
query = sqlite3_mprintf( "SELECT id FROM tag WHERE name='%q'", tag.toUtf8().constData() );
query = QgsSqlite3Mprintf( "SELECT id FROM tag WHERE name='%q'", tag.toUtf8().constData() );
sqlite3_statement_unique_ptr statement2;
statement2 = mCurrentDB.prepare( query, nErr );
@ -946,8 +947,8 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol, const QStri
{
// remove from the tagmap
query = type == SymbolEntity
? sqlite3_mprintf( "DELETE FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
: sqlite3_mprintf( "DELETE FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
? QgsSqlite3Mprintf( "DELETE FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
: QgsSqlite3Mprintf( "DELETE FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
runEmptyQuery( query );
}
}
@ -966,9 +967,9 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol )
return false;
}
char *query = type == SymbolEntity
? sqlite3_mprintf( "SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
: sqlite3_mprintf( "SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
auto query = type == SymbolEntity
? QgsSqlite3Mprintf( "SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
: QgsSqlite3Mprintf( "SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
sqlite3_statement_unique_ptr statement;
int nErr;
statement = mCurrentDB.prepare( query, nErr );
@ -985,8 +986,8 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol )
// remove all tags
query = type == SymbolEntity
? sqlite3_mprintf( "DELETE FROM tagmap WHERE symbol_id=%d", symbolid )
: sqlite3_mprintf( "DELETE FROM ctagmap WHERE colorramp_id=%d", symbolid );
? QgsSqlite3Mprintf( "DELETE FROM tagmap WHERE symbol_id=%d", symbolid )
: QgsSqlite3Mprintf( "DELETE FROM ctagmap WHERE colorramp_id=%d", symbolid );
runEmptyQuery( query );
// TODO Perform tag cleanup
@ -1008,9 +1009,9 @@ QStringList QgsStyle::tagsOfSymbol( StyleEntity type, const QString &symbol )
return QStringList();
// get the ids of tags for the symbol
char *query = type == SymbolEntity
? sqlite3_mprintf( "SELECT tag_id FROM tagmap WHERE symbol_id=%d", symbolid )
: sqlite3_mprintf( "SELECT tag_id FROM ctagmap WHERE colorramp_id=%d", symbolid );
auto query = type == SymbolEntity
? QgsSqlite3Mprintf( "SELECT tag_id FROM tagmap WHERE symbol_id=%d", symbolid )
: QgsSqlite3Mprintf( "SELECT tag_id FROM ctagmap WHERE colorramp_id=%d", symbolid );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -1018,7 +1019,7 @@ QStringList QgsStyle::tagsOfSymbol( StyleEntity type, const QString &symbol )
QStringList tagList;
while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
{
char *subquery = sqlite3_mprintf( "SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
auto subquery = QgsSqlite3Mprintf( "SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
sqlite3_statement_unique_ptr statement2;
int pErr;
@ -1052,9 +1053,9 @@ bool QgsStyle::symbolHasTag( StyleEntity type, const QString &symbol, const QStr
}
// get the ids of tags for the symbol
char *query = type == SymbolEntity
? sqlite3_mprintf( "SELECT tag_id FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
: sqlite3_mprintf( "SELECT tag_id FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
auto query = type == SymbolEntity
? QgsSqlite3Mprintf( "SELECT tag_id FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
: QgsSqlite3Mprintf( "SELECT tag_id FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -1069,7 +1070,7 @@ QString QgsStyle::tag( int id ) const
sqlite3_statement_unique_ptr statement;
char *query = sqlite3_mprintf( "SELECT name FROM tag WHERE id=%d", id );
auto query = QgsSqlite3Mprintf( "SELECT name FROM tag WHERE id=%d", id );
int nError;
statement = mCurrentDB.prepare( query, nError );
@ -1084,7 +1085,7 @@ QString QgsStyle::tag( int id ) const
int QgsStyle::getId( const QString &table, const QString &name )
{
char *query = sqlite3_mprintf( "SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), name.toUtf8().toLower().constData() );
auto query = QgsSqlite3Mprintf( "SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), name.toUtf8().toLower().constData() );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -1100,7 +1101,7 @@ int QgsStyle::getId( const QString &table, const QString &name )
QString QgsStyle::getName( const QString &table, int id ) const
{
char *query = sqlite3_mprintf( "SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number( id ).toUtf8().constData() );
auto query = QgsSqlite3Mprintf( "SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number( id ).toUtf8().constData() );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -1160,8 +1161,8 @@ int QgsStyle::addSmartgroup( const QString &name, const QString &op, const QgsSm
QTextStream stream( &xmlArray );
stream.setCodec( "UTF-8" );
smartEl.save( stream, 4 );
char *query = sqlite3_mprintf( "INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
name.toUtf8().constData(), xmlArray.constData() );
auto query = QgsSqlite3Mprintf( "INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
name.toUtf8().constData(), xmlArray.constData() );
if ( runEmptyQuery( query ) )
{
@ -1186,7 +1187,7 @@ QgsSymbolGroupMap QgsStyle::smartgroupsListMap()
return QgsSymbolGroupMap();
}
char *query = sqlite3_mprintf( "SELECT * FROM smartgroup" );
auto query = QgsSqlite3Mprintf( "SELECT * FROM smartgroup" );
// Now run the query and retrieve the group names
sqlite3_statement_unique_ptr statement;
@ -1211,7 +1212,7 @@ QStringList QgsStyle::smartgroupNames()
return QStringList();
}
char *query = sqlite3_mprintf( "SELECT name FROM smartgroup" );
auto query = QgsSqlite3Mprintf( "SELECT name FROM smartgroup" );
// Now run the query and retrieve the group names
sqlite3_statement_unique_ptr statement;
@ -1231,7 +1232,7 @@ QStringList QgsStyle::symbolsOfSmartgroup( StyleEntity type, int id )
{
QStringList symbols;
char *query = sqlite3_mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
auto query = QgsSqlite3Mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
sqlite3_statement_unique_ptr statement;
int nErr; statement = mCurrentDB.prepare( query, nErr );
@ -1333,7 +1334,7 @@ QgsSmartConditionMap QgsStyle::smartgroup( int id )
QgsSmartConditionMap condition;
char *query = sqlite3_mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
auto query = QgsSqlite3Mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
sqlite3_statement_unique_ptr statement;
int nError;
@ -1373,7 +1374,7 @@ QString QgsStyle::smartgroupOperator( int id )
QString op;
char *query = sqlite3_mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
auto query = QgsSqlite3Mprintf( "SELECT xml FROM smartgroup WHERE id=%d", id );
int nError;
sqlite3_statement_unique_ptr statement;
@ -1506,8 +1507,7 @@ bool QgsStyle::importXml( const QString &filename )
QDomElement e = symbolsElement.firstChildElement();
// gain speed by re-grouping the INSERT statements in a transaction
char *query = nullptr;
query = sqlite3_mprintf( "BEGIN TRANSACTION;" );
auto query = QgsSqlite3Mprintf( "BEGIN TRANSACTION;" );
runEmptyQuery( query );
if ( version == STYLE_CURRENT_VERSION )
@ -1594,7 +1594,7 @@ bool QgsStyle::importXml( const QString &filename )
e = e.nextSiblingElement();
}
query = sqlite3_mprintf( "COMMIT TRANSACTION;" );
query = QgsSqlite3Mprintf( "COMMIT TRANSACTION;" );
runEmptyQuery( query );
mFileName = filename;
@ -1609,7 +1609,7 @@ bool QgsStyle::updateSymbol( StyleEntity type, const QString &name )
QTextStream stream( &xmlArray );
stream.setCodec( "UTF-8" );
char *query = nullptr;
QString query;
if ( type == SymbolEntity )
{
@ -1627,8 +1627,8 @@ bool QgsStyle::updateSymbol( StyleEntity type, const QString &name )
return false;
}
symEl.save( stream, 4 );
query = sqlite3_mprintf( "UPDATE symbol SET xml='%q' WHERE name='%q';",
xmlArray.constData(), name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE symbol SET xml='%q' WHERE name='%q';",
xmlArray.constData(), name.toUtf8().constData() );
}
else if ( type == ColorrampEntity )
{
@ -1646,8 +1646,8 @@ bool QgsStyle::updateSymbol( StyleEntity type, const QString &name )
return false;
}
symEl.save( stream, 4 );
query = sqlite3_mprintf( "UPDATE colorramp SET xml='%q' WHERE name='%q';",
xmlArray.constData(), name.toUtf8().constData() );
query = QgsSqlite3Mprintf( "UPDATE colorramp SET xml='%q' WHERE name='%q';",
xmlArray.constData(), name.toUtf8().constData() );
}
else
{

View File

@ -167,6 +167,9 @@ class CORE_EXPORT QgsStyle : public QObject
//! Returns default application-wide style
static QgsStyle *defaultStyle();
//! Deletes the default style. Only to be used by QgsApplication::exitQgis()
static void cleanDefaultStyle() SIP_SKIP;
/**
* Tags the symbol with the tags in the list
*
@ -417,7 +420,7 @@ class CORE_EXPORT QgsStyle : public QObject
//! Is emitted every time a tag or smartgroup has been added, removed, or renamed
void groupsModified();
protected:
private:
QgsSymbolMap mSymbols;
QgsVectorColorRampMap mColorRamps;
@ -436,10 +439,9 @@ class CORE_EXPORT QgsStyle : public QObject
* Convenience function that would run queries which don't generate return values
*
* \param query query to run
* \param freeQuery release query memory
* \returns success true on success
*/
bool runEmptyQuery( char *query, bool freeQuery = true );
bool runEmptyQuery( const QString &query );
//! Gets the id from the table for the given name from the database, 0 if not found
int getId( const QString &table, const QString &name );
@ -457,9 +459,7 @@ class CORE_EXPORT QgsStyle : public QObject
*/
bool updateSymbol( StyleEntity type, const QString &name );
private:
Q_DISABLE_COPY( QgsStyle )
};
#endif