QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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
37void QgsStoredQueryManager::storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend )
38{
39 if ( query.isEmpty() || name.isEmpty() )
40 return;
41
42 bool wasAdded = false;
43 bool wasUpdated = false;
44
45 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
46 const QString hash = getQueryHash( name );
47
48 switch ( backend )
49 {
51 {
52 const bool isExisting = sTreeStoredQueries->items().contains( hash );
53 wasAdded = !isExisting;
54 wasUpdated = isExisting;
55 settingQueryName->setValue( name, hash );
56 settingQueryDefinition->setValue( query, hash );
57 break;
58 }
59
61 {
62 const bool isExisting = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s ).contains( hash );
63 wasAdded = !isExisting;
64 wasUpdated = isExisting;
65 QgsProject::instance()->writeEntry( u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash ), name );
66 QgsProject::instance()->writeEntry( u"DBManager"_s, u"savedQueries/%1/query"_s.arg( hash ), query );
67 break;
68 }
69 }
70
71 if ( wasAdded )
72 emit queryAdded( name, backend );
73 else if ( wasUpdated )
74 emit queryChanged( name, backend );
75}
76
78{
79 if ( name.isEmpty() )
80 return;
81
82 bool wasDeleted = false;
83 // Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
84 const QString hash = getQueryHash( name );
85
86 switch ( backend )
87 {
89 {
90 wasDeleted = sTreeStoredQueries->items().contains( hash );
91 sTreeStoredQueries->deleteItem( hash );
92 break;
93 }
94
96 {
97 wasDeleted = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s ).contains( hash );
98 QgsProject::instance()->removeEntry( "DBManager", u"savedQueries/%1"_s.arg( hash ) );
99 break;
100 }
101 }
102
103 if ( wasDeleted )
104 emit queryRemoved( name, backend );
105}
106
108{
109 QStringList names;
110 switch ( backend )
111 {
113 {
114 const QStringList hashes = sTreeStoredQueries->items();
115 names.reserve( hashes.size() );
116 for ( const QString &hash : hashes )
117 {
118 names.append( settingQueryName->value( hash ) );
119 }
120 break;
121 }
122
124 {
125 const QStringList hashes = QgsProject::instance()->subkeyList( u"DBManager"_s, u"savedQueries"_s );
126 names.reserve( hashes.size() );
127 for ( const QString &hash : hashes )
128 {
129 names.append( QgsProject::instance()->readEntry( u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash ) ) );
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( u"DBManager"_s, u"savedQueries/%1/query"_s.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( u"DBManager"_s, u"savedQueries"_s );
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;
177 details.name = QgsProject::instance()->readEntry( u"DBManager"_s, u"savedQueries/%1/name"_s.arg( hash ) );
178 details.definition = QgsProject::instance()->readEntry( u"DBManager"_s, u"savedQueries/%1/query"_s.arg( hash ) );
180 res.append( details );
181 }
182
183 std::sort( res.begin(), res.end(), []( const QueryDetails &a, const QueryDetails &b ) {
184 if ( a.name == b.name )
185 {
186 if ( a.backend == b.backend )
187 return false;
188 else
189 return a.backend == Qgis::QueryStorageBackend::CurrentProject;
190 }
191
192 return QString::localeAwareCompare( a.name, b.name ) < 0;
193 } );
194
195 return res;
196}
197
198QString QgsStoredQueryManager::getQueryHash( const QString &name )
199{
200 // for compatibility with DB manager stored queries!
201 QByteArray nameUtf8 = name.toUtf8();
202 QByteArray hash = QCryptographicHash::hash( nameUtf8, QCryptographicHash::Md5 ).toHex();
203 return u"q%1"_s.arg( QString::fromUtf8( hash ) );
204}
QueryStorageBackend
Stored query storage backends.
Definition qgis.h:3631
@ CurrentProject
Current QGIS project.
Definition qgis.h:3633
@ LocalProfile
Local user profile.
Definition qgis.h:3632
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:7540