QGIS API Documentation 3.43.0-Master (ebb4087afc0)
Loading...
Searching...
No Matches
qgsstoredquerymanager.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsstoredquerymanager.cpp
3 ------------------------------------
4 Date : February 2025
5 Copyright : (C) 2025 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgsproject.h"
19#include "moc_qgsstoredquerymanager.cpp"
20
21#include <QCryptographicHash>
22
24const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryName = new QgsSettingsEntryString( QStringLiteral( "name" ), sTreeStoredQueries );
25const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryDefinition = new QgsSettingsEntryString( QStringLiteral( "query" ), sTreeStoredQueries );
27
29 : QObject( parent )
30{
31}
32
33void QgsStoredQueryManager::storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend )
34{
35 if ( query.isEmpty() || name.isEmpty() )
36 return;
37
38 bool wasAdded = false;
39 bool wasUpdated = false;
40
41 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
42 const QString hash = getQueryHash( name );
43
44 switch ( backend )
45 {
47 {
48 const bool isExisting = sTreeStoredQueries->items().contains( hash );
49 wasAdded = !isExisting;
50 wasUpdated = isExisting;
51 settingQueryName->setValue( name, hash );
52 settingQueryDefinition->setValue( query, hash );
53 break;
54 }
55
57 {
58 const bool isExisting = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) ).contains( hash );
59 wasAdded = !isExisting;
60 wasUpdated = isExisting;
61 QgsProject::instance()->writeEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash ), name );
62 QgsProject::instance()->writeEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash ), query );
63 break;
64 }
65 }
66
67 if ( wasAdded )
68 emit queryAdded( name, backend );
69 else if ( wasUpdated )
70 emit queryChanged( name, backend );
71}
72
74{
75 if ( name.isEmpty() )
76 return;
77
78 bool wasDeleted = false;
79 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
80 const QString hash = getQueryHash( name );
81
82 switch ( backend )
83 {
85 {
86 wasDeleted = sTreeStoredQueries->items().contains( hash );
87 sTreeStoredQueries->deleteItem( hash );
88 break;
89 }
90
92 {
93 wasDeleted = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) ).contains( hash );
95 "DBManager", QStringLiteral( "savedQueries/%1" ).arg( hash )
96 );
97 break;
98 }
99 }
100
101 if ( wasDeleted )
102 emit queryRemoved( name, backend );
103}
104
106{
107 QStringList names;
108 switch ( backend )
109 {
111 {
112 const QStringList hashes = sTreeStoredQueries->items();
113 names.reserve( hashes.size() );
114 for ( const QString &hash : hashes )
115 {
116 names.append( settingQueryName->value( hash ) );
117 }
118 break;
119 }
120
122 {
123 const QStringList hashes = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) );
124 names.reserve( hashes.size() );
125 for ( const QString &hash : hashes )
126 {
127 names.append( QgsProject::instance()->readEntry(
128 QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash )
129 ) );
130 }
131 break;
132 }
133 }
134 return names;
135}
136
137QString QgsStoredQueryManager::query( const QString &name, Qgis::QueryStorageBackend backend ) const
138{
139 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
140 const QString hash = getQueryHash( name );
141
142 switch ( backend )
143 {
145 {
146 return settingQueryDefinition->value( hash );
147 }
148
150 {
151 return QgsProject::instance()->readEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash ) );
152 }
153 }
155}
156
157QList<QgsStoredQueryManager::QueryDetails> QgsStoredQueryManager::allQueries() const
158{
159 QList<QgsStoredQueryManager::QueryDetails> res;
160
161 const QStringList localProfileHashes = sTreeStoredQueries->items();
162 const QStringList projectHashes = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) );
163 res.reserve( localProfileHashes.size() + projectHashes.size() );
164
165 for ( const QString &hash : localProfileHashes )
166 {
167 QueryDetails details;
168 details.name = settingQueryName->value( hash );
169 details.definition = settingQueryDefinition->value( hash );
171 res.append( details );
172 }
173
174 for ( const QString &hash : projectHashes )
175 {
176 QueryDetails details;
178 QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash )
179 );
181 QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash )
182 );
184 res.append( details );
185 }
186
187 std::sort( res.begin(), res.end(), [=]( const QueryDetails &a, const QueryDetails &b ) {
188 if ( a.name == b.name )
189 return a.backend == Qgis::QueryStorageBackend::CurrentProject;
190
191 return QString::localeAwareCompare( a.name, b.name ) < 0;
192 } );
193
194 return res;
195}
196
197QString QgsStoredQueryManager::getQueryHash( const QString &name )
198{
199 // for compatibility with DB manager stored queries!
200 QByteArray nameUtf8 = name.toUtf8();
201 QByteArray hash = QCryptographicHash::hash( nameUtf8, QCryptographicHash::Md5 ).toHex();
202 return QStringLiteral( "q%1" ).arg( QString::fromUtf8( hash ) );
203}
QueryStorageBackend
Stored query storage backends.
Definition qgis.h:3381
@ CurrentProject
Current QGIS project.
@ LocalProfile
Local user profile.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
QStringList subkeyList(const QString &scope, const QString &key) const
Returns a list of child keys which contain other keys that exist within the the specified scope and k...
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
A string settings entry.
Contains details about a stored query.
Qgis::QueryStorageBackend backend
Storage backend.
QList< QgsStoredQueryManager::QueryDetails > allQueries() const
Returns details of all queries stored in the manager.
QStringList allQueryNames(Qgis::QueryStorageBackend backend=Qgis::QueryStorageBackend::LocalProfile) const
Returns a list of the names of all stored queries for the specified backend.
void queryRemoved(const QString &name, Qgis::QueryStorageBackend backend)
Emitted when a query is removed from the manager.
void queryChanged(const QString &name, Qgis::QueryStorageBackend backend)
Emitted when an existing query is changed in the manager.
void queryAdded(const QString &name, Qgis::QueryStorageBackend backend)
Emitted when a query is added to the manager.
QgsStoredQueryManager(QObject *parent=nullptr)
Constructor for QgsStoredQueryManager, with the specified parent object.
QString query(const QString &name, Qgis::QueryStorageBackend backend=Qgis::QueryStorageBackend::LocalProfile) const
Returns the query definition with matching name, from the specified backend.
void removeQuery(const QString &name, Qgis::QueryStorageBackend backend=Qgis::QueryStorageBackend::LocalProfile)
Removes the stored query with matching name.
void storeQuery(const QString &name, const QString &query, Qgis::QueryStorageBackend backend=Qgis::QueryStorageBackend::LocalProfile)
Saves a query to the manager.
#define BUILTIN_UNREACHABLE
Definition qgis.h:6840