QGIS API Documentation 3.99.0-Master (d270888f95f)
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
18#include "qgsproject.h"
20
21#include <QCryptographicHash>
22#include <QString>
23
24#include "moc_qgsstoredquerymanager.cpp"
25
26using namespace Qt::StringLiterals;
27
29const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryName = new QgsSettingsEntryString( u"name"_s, sTreeStoredQueries );
30const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryDefinition = new QgsSettingsEntryString( u"query"_s, sTreeStoredQueries );
32
34 : QObject( parent )
35{
36}
37
38void QgsStoredQueryManager::storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend )
39{
40 if ( query.isEmpty() || name.isEmpty() )
41 return;
42
43 bool wasAdded = false;
44 bool wasUpdated = false;
45
46 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
47 const QString hash = getQueryHash( name );
48
49 switch ( backend )
50 {
52 {
53 const bool isExisting = sTreeStoredQueries->items().contains( hash );
54 wasAdded = !isExisting;
55 wasUpdated = isExisting;
56 settingQueryName->setValue( name, hash );
57 settingQueryDefinition->setValue( query, hash );
58 break;
59 }
60
62 {
63 const bool isExisting = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s ).contains( hash );
64 wasAdded = !isExisting;
65 wasUpdated = isExisting;
66 QgsProject::instance()->writeEntry( u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash ), name );
67 QgsProject::instance()->writeEntry( u"DBManager"_s, u"savedQueries/%1/query"_s.arg( hash ), query );
68 break;
69 }
70 }
71
72 if ( wasAdded )
73 emit queryAdded( name, backend );
74 else if ( wasUpdated )
75 emit queryChanged( name, backend );
76}
77
79{
80 if ( name.isEmpty() )
81 return;
82
83 bool wasDeleted = false;
84 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
85 const QString hash = getQueryHash( name );
86
87 switch ( backend )
88 {
90 {
91 wasDeleted = sTreeStoredQueries->items().contains( hash );
92 sTreeStoredQueries->deleteItem( hash );
93 break;
94 }
95
97 {
98 wasDeleted = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s ).contains( hash );
100 "DBManager", u"savedQueries/%1"_s.arg( hash )
101 );
102 break;
103 }
104 }
105
106 if ( wasDeleted )
107 emit queryRemoved( name, backend );
108}
109
111{
112 QStringList names;
113 switch ( backend )
114 {
116 {
117 const QStringList hashes = sTreeStoredQueries->items();
118 names.reserve( hashes.size() );
119 for ( const QString &hash : hashes )
120 {
121 names.append( settingQueryName->value( hash ) );
122 }
123 break;
124 }
125
127 {
128 const QStringList hashes = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s );
129 names.reserve( hashes.size() );
130 for ( const QString &hash : hashes )
131 {
132 names.append( QgsProject::instance()->readEntry(
133 u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash )
134 ) );
135 }
136 break;
137 }
138 }
139 return names;
140}
141
142QString QgsStoredQueryManager::query( const QString &name, Qgis::QueryStorageBackend backend ) const
143{
144 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
145 const QString hash = getQueryHash( name );
146
147 switch ( backend )
148 {
150 {
151 return settingQueryDefinition->value( hash );
152 }
153
155 {
156 return QgsProject::instance()->readEntry( u"DBManager"_s, u"savedQueries/%1/query"_s.arg( hash ) );
157 }
158 }
160}
161
162QList<QgsStoredQueryManager::QueryDetails> QgsStoredQueryManager::allQueries() const
163{
164 QList<QgsStoredQueryManager::QueryDetails> res;
165
166 const QStringList localProfileHashes = sTreeStoredQueries->items();
167 const QStringList projectHashes = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s );
168 res.reserve( localProfileHashes.size() + projectHashes.size() );
169
170 for ( const QString &hash : localProfileHashes )
171 {
172 QueryDetails details;
173 details.name = settingQueryName->value( hash );
174 details.definition = settingQueryDefinition->value( hash );
176 res.append( details );
177 }
178
179 for ( const QString &hash : projectHashes )
180 {
181 QueryDetails details;
183 u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash )
184 );
186 u"DBManager"_s, u"savedQueries/%1/query"_s.arg( hash )
187 );
189 res.append( details );
190 }
191
192 std::sort( res.begin(), res.end(), []( const QueryDetails &a, const QueryDetails &b ) {
193 if ( a.name == b.name )
194 {
195 if ( a.backend == b.backend )
196 return false;
197 else
198 return a.backend == Qgis::QueryStorageBackend::CurrentProject;
199 }
200
201 return QString::localeAwareCompare( a.name, b.name ) < 0;
202 } );
203
204 return res;
205}
206
207QString QgsStoredQueryManager::getQueryHash( const QString &name )
208{
209 // for compatibility with DB manager stored queries!
210 QByteArray nameUtf8 = name.toUtf8();
211 QByteArray hash = QCryptographicHash::hash( nameUtf8, QCryptographicHash::Md5 ).toHex();
212 return u"q%1"_s.arg( QString::fromUtf8( hash ) );
213}
QueryStorageBackend
Stored query storage backends.
Definition qgis.h:3576
@ CurrentProject
Current QGIS project.
Definition qgis.h:3578
@ LocalProfile
Local user profile.
Definition qgis.h:3577
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 specified scope and key.
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:7489