mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-05 00:09:32 -04:00
Create a class for managing stored database queries
This class is designed to be compatible with DB Manager's storage of queries in projects, but extended to allow storage within the local profile too.
This commit is contained in:
parent
c8fe793e53
commit
bb4827e9f9
@ -6187,6 +6187,19 @@ Qgis.HistoryProviderBackend.baseClass = Qgis
|
||||
Qgis.HistoryProviderBackends = lambda flags=0: Qgis.HistoryProviderBackend(flags)
|
||||
Qgis.HistoryProviderBackends.baseClass = Qgis
|
||||
HistoryProviderBackends = Qgis # dirty hack since SIP seems to introduce the flags in module
|
||||
# monkey patching scoped based enum
|
||||
Qgis.QueryStorageBackend.LocalProfile.__doc__ = "Local user profile"
|
||||
Qgis.QueryStorageBackend.CurrentProject.__doc__ = "Current QGIS project"
|
||||
Qgis.QueryStorageBackend.__doc__ = """Stored query storage backends.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
|
||||
* ``LocalProfile``: Local user profile
|
||||
* ``CurrentProject``: Current QGIS project
|
||||
|
||||
"""
|
||||
# --
|
||||
Qgis.QueryStorageBackend.baseClass = Qgis
|
||||
QgsProcessing.SourceType = Qgis.ProcessingSourceType
|
||||
# monkey patching scoped based enum
|
||||
QgsProcessing.TypeMapLayer = Qgis.ProcessingSourceType.MapLayer
|
||||
|
@ -1932,6 +1932,12 @@ The development version
|
||||
typedef QFlags<Qgis::HistoryProviderBackend> HistoryProviderBackends;
|
||||
|
||||
|
||||
enum class QueryStorageBackend /BaseType=IntEnum/
|
||||
{
|
||||
LocalProfile,
|
||||
CurrentProject,
|
||||
};
|
||||
|
||||
enum class ProcessingSourceType /BaseType=IntEnum/
|
||||
{
|
||||
MapLayer,
|
||||
|
@ -45,6 +45,7 @@ try:
|
||||
QgsGui.windowManager = staticmethod(QgsGui.windowManager)
|
||||
QgsGui.setWindowManager = staticmethod(QgsGui.setWindowManager)
|
||||
QgsGui.inputControllerManager = staticmethod(QgsGui.inputControllerManager)
|
||||
QgsGui.storedQueryManager = staticmethod(QgsGui.storedQueryManager)
|
||||
QgsGui.higFlags = staticmethod(QgsGui.higFlags)
|
||||
QgsGui.sampleColor = staticmethod(QgsGui.sampleColor)
|
||||
QgsGui.findScreenAt = staticmethod(QgsGui.findScreenAt)
|
||||
|
10
python/PyQt6/gui/auto_additions/qgsstoredquerymanager.py
Normal file
10
python/PyQt6/gui/auto_additions/qgsstoredquerymanager.py
Normal file
@ -0,0 +1,10 @@
|
||||
# The following has been generated automatically from src/gui/qgsstoredquerymanager.h
|
||||
try:
|
||||
QgsStoredQueryManager.QueryDetails.__attribute_docs__ = {'name': 'Name of the query.', 'definition': 'Query definition.', 'backend': 'Storage backend.'}
|
||||
except (NameError, AttributeError):
|
||||
pass
|
||||
try:
|
||||
QgsStoredQueryManager.__attribute_docs__ = {'queryAdded': 'Emitted when a query is added to the manager.\n', 'queryChanged': 'Emitted when an existing query is changed in the manager.\n', 'queryRemoved': 'Emitted when a query is removed from the manager.\n'}
|
||||
QgsStoredQueryManager.__signal_arguments__ = {'queryAdded': ['name: str', 'backend: Qgis.QueryStorageBackend'], 'queryChanged': ['name: str', 'backend: Qgis.QueryStorageBackend'], 'queryRemoved': ['name: str', 'backend: Qgis.QueryStorageBackend']}
|
||||
except (NameError, AttributeError):
|
||||
pass
|
@ -215,6 +215,13 @@ Sets the global window ``manager``. Ownership is transferred to the QgsGui insta
|
||||
Returns the global input controller manager.
|
||||
|
||||
.. versionadded:: 3.32
|
||||
%End
|
||||
|
||||
static QgsStoredQueryManager *storedQueryManager() /KeepReference/;
|
||||
%Docstring
|
||||
Returns the global stored SQL query manager.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
enum HigFlag /BaseType=IntEnum/
|
||||
|
121
python/PyQt6/gui/auto_generated/qgsstoredquerymanager.sip.in
Normal file
121
python/PyQt6/gui/auto_generated/qgsstoredquerymanager.sip.in
Normal file
@ -0,0 +1,121 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsstoredquerymanager.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.py again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsStoredQueryManager : QObject
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
A manager for stored SQL queries.
|
||||
|
||||
:py:class:`QgsStoredQueryManager` is not usually directly created, instead
|
||||
use the instance accessible through :py:func:`QgsGui.storedQueryManager()`.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsstoredquerymanager.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsStoredQueryManager( QObject *parent = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsStoredQueryManager, with the specified
|
||||
``parent`` object.
|
||||
%End
|
||||
|
||||
void storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
%Docstring
|
||||
Saves a query to the manager.
|
||||
|
||||
If a query with the same ``name`` already exists it will be overwritten with the new definition.
|
||||
|
||||
:param name: user-set, unique name for the query.
|
||||
:param query: query definition to store
|
||||
:param backend: storage backend for query
|
||||
|
||||
.. seealso:: :py:func:`queryAdded`
|
||||
|
||||
.. seealso:: :py:func:`queryChanged`
|
||||
%End
|
||||
|
||||
void removeQuery( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
%Docstring
|
||||
Removes the stored query with matching ``name``.
|
||||
|
||||
:param name: name of query to remove
|
||||
:param backend: storage backend for query
|
||||
|
||||
.. seealso:: :py:func:`queryRemoved`
|
||||
%End
|
||||
|
||||
QStringList allQueryNames( Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
%Docstring
|
||||
Returns a list of the names of all stored queries for the specified ``backend``.
|
||||
%End
|
||||
|
||||
QString query( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
%Docstring
|
||||
Returns the query definition with matching ``name``, from the specified ``backend``.
|
||||
%End
|
||||
|
||||
class QueryDetails
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Contains details about a stored query.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsstoredquerymanager.h"
|
||||
%End
|
||||
public:
|
||||
QString name;
|
||||
|
||||
QString definition;
|
||||
|
||||
Qgis::QueryStorageBackend backend;
|
||||
};
|
||||
|
||||
QList< QgsStoredQueryManager::QueryDetails > allQueries() const;
|
||||
%Docstring
|
||||
Returns details of all queries stored in the manager.
|
||||
|
||||
Queries will be sorted by name.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void queryAdded( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when a query is added to the manager.
|
||||
%End
|
||||
|
||||
void queryChanged( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when an existing query is changed in the manager.
|
||||
%End
|
||||
|
||||
void queryRemoved( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when a query is removed from the manager.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsstoredquerymanager.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.py again *
|
||||
************************************************************************/
|
@ -208,6 +208,7 @@
|
||||
%Include auto_generated/qgssourceselectprovider.sip
|
||||
%Include auto_generated/qgssourceselectproviderregistry.sip
|
||||
%Include auto_generated/qgsstatusbar.sip
|
||||
%Include auto_generated/qgsstoredquerymanager.sip
|
||||
%Include auto_generated/qgsstyleitemslistwidget.sip
|
||||
%Include auto_generated/qgssublayersdialog.sip
|
||||
%Include auto_generated/qgssubstitutionlistwidget.sip
|
||||
|
@ -6128,6 +6128,19 @@ Qgis.HistoryProviderBackend.__doc__ = """History provider backends.
|
||||
Qgis.HistoryProviderBackend.baseClass = Qgis
|
||||
Qgis.HistoryProviderBackends.baseClass = Qgis
|
||||
HistoryProviderBackends = Qgis # dirty hack since SIP seems to introduce the flags in module
|
||||
# monkey patching scoped based enum
|
||||
Qgis.QueryStorageBackend.LocalProfile.__doc__ = "Local user profile"
|
||||
Qgis.QueryStorageBackend.CurrentProject.__doc__ = "Current QGIS project"
|
||||
Qgis.QueryStorageBackend.__doc__ = """Stored query storage backends.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
|
||||
* ``LocalProfile``: Local user profile
|
||||
* ``CurrentProject``: Current QGIS project
|
||||
|
||||
"""
|
||||
# --
|
||||
Qgis.QueryStorageBackend.baseClass = Qgis
|
||||
QgsProcessing.SourceType = Qgis.ProcessingSourceType
|
||||
# monkey patching scoped based enum
|
||||
QgsProcessing.TypeMapLayer = Qgis.ProcessingSourceType.MapLayer
|
||||
|
@ -1932,6 +1932,12 @@ The development version
|
||||
typedef QFlags<Qgis::HistoryProviderBackend> HistoryProviderBackends;
|
||||
|
||||
|
||||
enum class QueryStorageBackend
|
||||
{
|
||||
LocalProfile,
|
||||
CurrentProject,
|
||||
};
|
||||
|
||||
enum class ProcessingSourceType
|
||||
{
|
||||
MapLayer,
|
||||
|
@ -30,6 +30,7 @@ try:
|
||||
QgsGui.windowManager = staticmethod(QgsGui.windowManager)
|
||||
QgsGui.setWindowManager = staticmethod(QgsGui.setWindowManager)
|
||||
QgsGui.inputControllerManager = staticmethod(QgsGui.inputControllerManager)
|
||||
QgsGui.storedQueryManager = staticmethod(QgsGui.storedQueryManager)
|
||||
QgsGui.higFlags = staticmethod(QgsGui.higFlags)
|
||||
QgsGui.sampleColor = staticmethod(QgsGui.sampleColor)
|
||||
QgsGui.findScreenAt = staticmethod(QgsGui.findScreenAt)
|
||||
|
10
python/gui/auto_additions/qgsstoredquerymanager.py
Normal file
10
python/gui/auto_additions/qgsstoredquerymanager.py
Normal file
@ -0,0 +1,10 @@
|
||||
# The following has been generated automatically from src/gui/qgsstoredquerymanager.h
|
||||
try:
|
||||
QgsStoredQueryManager.QueryDetails.__attribute_docs__ = {'name': 'Name of the query.', 'definition': 'Query definition.', 'backend': 'Storage backend.'}
|
||||
except (NameError, AttributeError):
|
||||
pass
|
||||
try:
|
||||
QgsStoredQueryManager.__attribute_docs__ = {'queryAdded': 'Emitted when a query is added to the manager.\n', 'queryChanged': 'Emitted when an existing query is changed in the manager.\n', 'queryRemoved': 'Emitted when a query is removed from the manager.\n'}
|
||||
QgsStoredQueryManager.__signal_arguments__ = {'queryAdded': ['name: str', 'backend: Qgis.QueryStorageBackend'], 'queryChanged': ['name: str', 'backend: Qgis.QueryStorageBackend'], 'queryRemoved': ['name: str', 'backend: Qgis.QueryStorageBackend']}
|
||||
except (NameError, AttributeError):
|
||||
pass
|
@ -215,6 +215,13 @@ Sets the global window ``manager``. Ownership is transferred to the QgsGui insta
|
||||
Returns the global input controller manager.
|
||||
|
||||
.. versionadded:: 3.32
|
||||
%End
|
||||
|
||||
static QgsStoredQueryManager *storedQueryManager() /KeepReference/;
|
||||
%Docstring
|
||||
Returns the global stored SQL query manager.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
enum HigFlag
|
||||
|
121
python/gui/auto_generated/qgsstoredquerymanager.sip.in
Normal file
121
python/gui/auto_generated/qgsstoredquerymanager.sip.in
Normal file
@ -0,0 +1,121 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsstoredquerymanager.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.py again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsStoredQueryManager : QObject
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
A manager for stored SQL queries.
|
||||
|
||||
:py:class:`QgsStoredQueryManager` is not usually directly created, instead
|
||||
use the instance accessible through :py:func:`QgsGui.storedQueryManager()`.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsstoredquerymanager.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsStoredQueryManager( QObject *parent = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsStoredQueryManager, with the specified
|
||||
``parent`` object.
|
||||
%End
|
||||
|
||||
void storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
%Docstring
|
||||
Saves a query to the manager.
|
||||
|
||||
If a query with the same ``name`` already exists it will be overwritten with the new definition.
|
||||
|
||||
:param name: user-set, unique name for the query.
|
||||
:param query: query definition to store
|
||||
:param backend: storage backend for query
|
||||
|
||||
.. seealso:: :py:func:`queryAdded`
|
||||
|
||||
.. seealso:: :py:func:`queryChanged`
|
||||
%End
|
||||
|
||||
void removeQuery( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
%Docstring
|
||||
Removes the stored query with matching ``name``.
|
||||
|
||||
:param name: name of query to remove
|
||||
:param backend: storage backend for query
|
||||
|
||||
.. seealso:: :py:func:`queryRemoved`
|
||||
%End
|
||||
|
||||
QStringList allQueryNames( Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
%Docstring
|
||||
Returns a list of the names of all stored queries for the specified ``backend``.
|
||||
%End
|
||||
|
||||
QString query( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
%Docstring
|
||||
Returns the query definition with matching ``name``, from the specified ``backend``.
|
||||
%End
|
||||
|
||||
class QueryDetails
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Contains details about a stored query.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsstoredquerymanager.h"
|
||||
%End
|
||||
public:
|
||||
QString name;
|
||||
|
||||
QString definition;
|
||||
|
||||
Qgis::QueryStorageBackend backend;
|
||||
};
|
||||
|
||||
QList< QgsStoredQueryManager::QueryDetails > allQueries() const;
|
||||
%Docstring
|
||||
Returns details of all queries stored in the manager.
|
||||
|
||||
Queries will be sorted by name.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void queryAdded( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when a query is added to the manager.
|
||||
%End
|
||||
|
||||
void queryChanged( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when an existing query is changed in the manager.
|
||||
%End
|
||||
|
||||
void queryRemoved( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
%Docstring
|
||||
Emitted when a query is removed from the manager.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsstoredquerymanager.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.py again *
|
||||
************************************************************************/
|
@ -208,6 +208,7 @@
|
||||
%Include auto_generated/qgssourceselectprovider.sip
|
||||
%Include auto_generated/qgssourceselectproviderregistry.sip
|
||||
%Include auto_generated/qgsstatusbar.sip
|
||||
%Include auto_generated/qgsstoredquerymanager.sip
|
||||
%Include auto_generated/qgsstyleitemslistwidget.sip
|
||||
%Include auto_generated/qgssublayersdialog.sip
|
||||
%Include auto_generated/qgssubstitutionlistwidget.sip
|
||||
|
@ -3342,6 +3342,18 @@ class CORE_EXPORT Qgis
|
||||
Q_DECLARE_FLAGS( HistoryProviderBackends, HistoryProviderBackend )
|
||||
Q_FLAG( HistoryProviderBackends )
|
||||
|
||||
/**
|
||||
* Stored query storage backends.
|
||||
*
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
enum class QueryStorageBackend : int
|
||||
{
|
||||
LocalProfile, //!< Local user profile
|
||||
CurrentProject, //!< Current QGIS project
|
||||
};
|
||||
Q_ENUM( QueryStorageBackend )
|
||||
|
||||
/**
|
||||
* Processing data source types.
|
||||
*
|
||||
|
@ -67,6 +67,7 @@ class CORE_EXPORT QgsSettingsTree
|
||||
static inline QgsSettingsTreeNode *sTreeAttributeTable = treeRoot()->createChildNode( QStringLiteral( "attribute-table" ) );
|
||||
static inline QgsSettingsTreeNode *sTreeWindowState = sTreeGui->createChildNode( QStringLiteral( "window-state" ) );
|
||||
static inline QgsSettingsTreeNode *sTreeAuthentication = treeRoot()->createChildNode( QStringLiteral( "authentication" ) );
|
||||
static inline QgsSettingsTreeNode *sTreeDatabase = treeRoot()->createChildNode( QStringLiteral( "database" ) );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -772,6 +772,7 @@ set(QGIS_GUI_SRCS
|
||||
qgssqlcomposerdialog.cpp
|
||||
qgsstackedwidget.cpp
|
||||
qgsstatusbar.cpp
|
||||
qgsstoredquerymanager.cpp
|
||||
qgssymbolbutton.cpp
|
||||
qgssymbollayerselectionwidget.cpp
|
||||
qgstabbarproxystyle.cpp
|
||||
@ -1040,6 +1041,7 @@ set(QGIS_GUI_HDRS
|
||||
qgssqlcomposerdialog.h
|
||||
qgsstackedwidget.h
|
||||
qgsstatusbar.h
|
||||
qgsstoredquerymanager.h
|
||||
qgsstyleitemslistwidget.h
|
||||
qgssublayersdialog.h
|
||||
qgssubstitutionlistwidget.h
|
||||
|
@ -69,7 +69,7 @@
|
||||
#include "qgssensorguiregistry.h"
|
||||
#include "qgshistoryentry.h"
|
||||
#include "qgsstacsourceselectprovider.h"
|
||||
|
||||
#include "qgsstoredquerymanager.h"
|
||||
#include "qgssettingseditorwidgetregistry.h"
|
||||
|
||||
|
||||
@ -226,6 +226,11 @@ QgsInputControllerManager *QgsGui::inputControllerManager()
|
||||
return instance()->mInputControllerManager;
|
||||
}
|
||||
|
||||
QgsStoredQueryManager *QgsGui::storedQueryManager()
|
||||
{
|
||||
return instance()->mStoredQueryManager;
|
||||
}
|
||||
|
||||
void QgsGui::setWindowManager( QgsWindowManagerInterface *manager )
|
||||
{
|
||||
instance()->mWindowManager.reset( manager );
|
||||
@ -271,6 +276,7 @@ QgsGui::~QgsGui()
|
||||
delete mInputControllerManager;
|
||||
delete mSettingsRegistryGui;
|
||||
delete mSensorGuiRegistry;
|
||||
delete mStoredQueryManager;
|
||||
delete mSettingsEditorRegistry;
|
||||
}
|
||||
|
||||
@ -324,6 +330,7 @@ QgsGui::QgsGui()
|
||||
|
||||
mSettingsEditorRegistry = new QgsSettingsEditorWidgetRegistry();
|
||||
|
||||
mStoredQueryManager = new QgsStoredQueryManager();
|
||||
mCodeEditorColorSchemeRegistry = new QgsCodeEditorColorSchemeRegistry();
|
||||
|
||||
// provider gui registry initialize QgsProviderRegistry too
|
||||
|
@ -54,6 +54,7 @@ class QgsHistoryProviderRegistry;
|
||||
class QgsSensorGuiRegistry;
|
||||
class QgsSettingsEditorWidgetRegistry;
|
||||
class QgsInputControllerManager;
|
||||
class QgsStoredQueryManager;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
@ -261,6 +262,12 @@ class GUI_EXPORT QgsGui : public QObject
|
||||
*/
|
||||
static QgsInputControllerManager *inputControllerManager() SIP_KEEPREFERENCE;
|
||||
|
||||
/**
|
||||
* Returns the global stored SQL query manager.
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
static QgsStoredQueryManager *storedQueryManager() SIP_KEEPREFERENCE;
|
||||
|
||||
/**
|
||||
* HIG flags, which indicate the Human Interface Guidelines for the current platform.
|
||||
* \since QGIS 3.4
|
||||
@ -373,6 +380,7 @@ class GUI_EXPORT QgsGui : public QObject
|
||||
QgsSensorGuiRegistry *mSensorGuiRegistry = nullptr;
|
||||
QgsSettingsEditorWidgetRegistry *mSettingsEditorRegistry = nullptr;
|
||||
QgsInputControllerManager *mInputControllerManager = nullptr;
|
||||
QgsStoredQueryManager *mStoredQueryManager = nullptr;
|
||||
std::unique_ptr<QgsWindowManagerInterface> mWindowManager;
|
||||
|
||||
#ifdef SIP_RUN
|
||||
|
203
src/gui/qgsstoredquerymanager.cpp
Normal file
203
src/gui/qgsstoredquerymanager.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
/***************************************************************************
|
||||
qgsstoredquerymanager.cpp
|
||||
------------------------------------
|
||||
Date : February 2025
|
||||
Copyright : (C) 2025 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsstoredquerymanager.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgssettingsentryimpl.h"
|
||||
#include "moc_qgsstoredquerymanager.cpp"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
||||
///@cond PRIVATE
|
||||
const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryName = new QgsSettingsEntryString( QStringLiteral( "name" ), sTreeStoredQueries );
|
||||
const QgsSettingsEntryString *QgsStoredQueryManager::settingQueryDefinition = new QgsSettingsEntryString( QStringLiteral( "query" ), sTreeStoredQueries );
|
||||
///@endcond PRIVATE
|
||||
|
||||
QgsStoredQueryManager::QgsStoredQueryManager( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsStoredQueryManager::storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend )
|
||||
{
|
||||
if ( query.isEmpty() || name.isEmpty() )
|
||||
return;
|
||||
|
||||
bool wasAdded = false;
|
||||
bool wasUpdated = false;
|
||||
|
||||
// Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
|
||||
const QString hash = getQueryHash( name );
|
||||
|
||||
switch ( backend )
|
||||
{
|
||||
case Qgis::QueryStorageBackend::LocalProfile:
|
||||
{
|
||||
const bool isExisting = sTreeStoredQueries->items().contains( hash );
|
||||
wasAdded = !isExisting;
|
||||
wasUpdated = isExisting;
|
||||
settingQueryName->setValue( name, hash );
|
||||
settingQueryDefinition->setValue( query, hash );
|
||||
break;
|
||||
}
|
||||
|
||||
case Qgis::QueryStorageBackend::CurrentProject:
|
||||
{
|
||||
const bool isExisting = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) ).contains( hash );
|
||||
wasAdded = !isExisting;
|
||||
wasUpdated = isExisting;
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash ), name );
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash ), query );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( wasAdded )
|
||||
emit queryAdded( name, backend );
|
||||
else if ( wasUpdated )
|
||||
emit queryChanged( name, backend );
|
||||
}
|
||||
|
||||
void QgsStoredQueryManager::removeQuery( const QString &name, Qgis::QueryStorageBackend backend )
|
||||
{
|
||||
if ( name.isEmpty() )
|
||||
return;
|
||||
|
||||
bool wasDeleted = false;
|
||||
// Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
|
||||
const QString hash = getQueryHash( name );
|
||||
|
||||
switch ( backend )
|
||||
{
|
||||
case Qgis::QueryStorageBackend::LocalProfile:
|
||||
{
|
||||
wasDeleted = sTreeStoredQueries->items().contains( hash );
|
||||
sTreeStoredQueries->deleteItem( hash );
|
||||
break;
|
||||
}
|
||||
|
||||
case Qgis::QueryStorageBackend::CurrentProject:
|
||||
{
|
||||
wasDeleted = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) ).contains( hash );
|
||||
QgsProject::instance()->removeEntry(
|
||||
"DBManager", QStringLiteral( "savedQueries/%1" ).arg( hash )
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( wasDeleted )
|
||||
emit queryRemoved( name, backend );
|
||||
}
|
||||
|
||||
QStringList QgsStoredQueryManager::allQueryNames( Qgis::QueryStorageBackend backend ) const
|
||||
{
|
||||
QStringList names;
|
||||
switch ( backend )
|
||||
{
|
||||
case Qgis::QueryStorageBackend::LocalProfile:
|
||||
{
|
||||
const QStringList hashes = sTreeStoredQueries->items();
|
||||
names.reserve( hashes.size() );
|
||||
for ( const QString &hash : hashes )
|
||||
{
|
||||
names.append( settingQueryName->value( hash ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qgis::QueryStorageBackend::CurrentProject:
|
||||
{
|
||||
const QStringList hashes = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) );
|
||||
names.reserve( hashes.size() );
|
||||
for ( const QString &hash : hashes )
|
||||
{
|
||||
names.append( QgsProject::instance()->readEntry(
|
||||
QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash )
|
||||
) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
QString QgsStoredQueryManager::query( const QString &name, Qgis::QueryStorageBackend backend ) const
|
||||
{
|
||||
// Yes, this looks odd! It's this way for compatibility with DB Manager stored queries...
|
||||
const QString hash = getQueryHash( name );
|
||||
|
||||
switch ( backend )
|
||||
{
|
||||
case Qgis::QueryStorageBackend::LocalProfile:
|
||||
{
|
||||
return settingQueryDefinition->value( hash );
|
||||
}
|
||||
|
||||
case Qgis::QueryStorageBackend::CurrentProject:
|
||||
{
|
||||
return QgsProject::instance()->readEntry( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash ) );
|
||||
}
|
||||
}
|
||||
BUILTIN_UNREACHABLE;
|
||||
}
|
||||
|
||||
QList<QgsStoredQueryManager::QueryDetails> QgsStoredQueryManager::allQueries() const
|
||||
{
|
||||
QList<QgsStoredQueryManager::QueryDetails> res;
|
||||
|
||||
const QStringList localProfileHashes = sTreeStoredQueries->items();
|
||||
const QStringList projectHashes = QgsProject::instance()->subkeyList( QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries" ) );
|
||||
res.reserve( localProfileHashes.size() + projectHashes.size() );
|
||||
|
||||
for ( const QString &hash : localProfileHashes )
|
||||
{
|
||||
QueryDetails details;
|
||||
details.name = settingQueryName->value( hash );
|
||||
details.definition = settingQueryDefinition->value( hash );
|
||||
details.backend = Qgis::QueryStorageBackend::LocalProfile;
|
||||
res.append( details );
|
||||
}
|
||||
|
||||
for ( const QString &hash : projectHashes )
|
||||
{
|
||||
QueryDetails details;
|
||||
details.name = QgsProject::instance()->readEntry(
|
||||
QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/name" ).arg( hash )
|
||||
);
|
||||
details.definition = QgsProject::instance()->readEntry(
|
||||
QStringLiteral( "DBManager" ), QStringLiteral( "savedQueries/%1/query" ).arg( hash )
|
||||
);
|
||||
details.backend = Qgis::QueryStorageBackend::CurrentProject;
|
||||
res.append( details );
|
||||
}
|
||||
|
||||
std::sort( res.begin(), res.end(), [=]( const QueryDetails &a, const QueryDetails &b ) {
|
||||
if ( a.name == b.name )
|
||||
return a.backend == Qgis::QueryStorageBackend::CurrentProject;
|
||||
|
||||
return QString::localeAwareCompare( a.name, b.name ) < 0;
|
||||
} );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
QString QgsStoredQueryManager::getQueryHash( const QString &name )
|
||||
{
|
||||
// for compatibility with DB manager stored queries!
|
||||
QByteArray nameUtf8 = name.toUtf8();
|
||||
QByteArray hash = QCryptographicHash::hash( nameUtf8, QCryptographicHash::Md5 ).toHex();
|
||||
return QStringLiteral( "q%1" ).arg( QString::fromUtf8( hash ) );
|
||||
}
|
142
src/gui/qgsstoredquerymanager.h
Normal file
142
src/gui/qgsstoredquerymanager.h
Normal file
@ -0,0 +1,142 @@
|
||||
/***************************************************************************
|
||||
qgsstoredquerymanager.h
|
||||
----------------------------------
|
||||
Date : February 2025
|
||||
Copyright : (C) 2025 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSTOREDQUERYMANAGER_H
|
||||
#define QGSSTOREDQUERYMANAGER_H
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgssettingstree.h"
|
||||
|
||||
///@cond NOT_STABLE
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \brief A manager for stored SQL queries.
|
||||
*
|
||||
* QgsStoredQueryManager is not usually directly created, instead
|
||||
* use the instance accessible through QgsGui::storedQueryManager().
|
||||
*
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
class GUI_EXPORT QgsStoredQueryManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
#ifndef SIP_RUN
|
||||
///@cond PRIVATE
|
||||
static inline QgsSettingsTreeNamedListNode *sTreeStoredQueries = QgsSettingsTree::sTreeDatabase->createNamedListNode( QStringLiteral( "stored-queries" ) );
|
||||
static const QgsSettingsEntryString *settingQueryName;
|
||||
static const QgsSettingsEntryString *settingQueryDefinition;
|
||||
///@endcond
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Constructor for QgsStoredQueryManager, with the specified
|
||||
* \a parent object.
|
||||
*/
|
||||
QgsStoredQueryManager( QObject *parent = nullptr );
|
||||
|
||||
/**
|
||||
* Saves a query to the manager.
|
||||
*
|
||||
* If a query with the same \a name already exists it will be overwritten with the new definition.
|
||||
*
|
||||
* \param name user-set, unique name for the query.
|
||||
* \param query query definition to store
|
||||
* \param backend storage backend for query
|
||||
*
|
||||
* \see queryAdded()
|
||||
* \see queryChanged()
|
||||
*/
|
||||
void storeQuery( const QString &name, const QString &query, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
|
||||
/**
|
||||
* Removes the stored query with matching \a name.
|
||||
*
|
||||
* \param name name of query to remove
|
||||
* \param backend storage backend for query
|
||||
*
|
||||
* \see queryRemoved()
|
||||
*/
|
||||
void removeQuery( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile );
|
||||
|
||||
/**
|
||||
* Returns a list of the names of all stored queries for the specified \a backend.
|
||||
*/
|
||||
QStringList allQueryNames( Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
|
||||
/**
|
||||
* Returns the query definition with matching \a name, from the specified \a backend.
|
||||
*/
|
||||
QString query( const QString &name, Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile ) const;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \brief Contains details about a stored query.
|
||||
*
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
class QueryDetails
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Name of the query.
|
||||
*/
|
||||
QString name;
|
||||
|
||||
/**
|
||||
* Query definition.
|
||||
*/
|
||||
QString definition;
|
||||
|
||||
/**
|
||||
* Storage backend.
|
||||
*/
|
||||
Qgis::QueryStorageBackend backend = Qgis::QueryStorageBackend::LocalProfile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns details of all queries stored in the manager.
|
||||
*
|
||||
* Queries will be sorted by name.
|
||||
*/
|
||||
QList< QgsStoredQueryManager::QueryDetails > allQueries() const;
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when a query is added to the manager.
|
||||
*/
|
||||
void queryAdded( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
|
||||
/**
|
||||
* Emitted when an existing query is changed in the manager.
|
||||
*/
|
||||
void queryChanged( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
|
||||
/**
|
||||
* Emitted when a query is removed from the manager.
|
||||
*/
|
||||
void queryRemoved( const QString &name, Qgis::QueryStorageBackend backend );
|
||||
|
||||
private:
|
||||
static QString getQueryHash( const QString &name );
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
#endif // QGSSTOREDQUERYMANAGER_H
|
@ -334,6 +334,7 @@ ADD_PYTHON_TEST(PyQgsExternalStorageSimpleCopy test_qgsexternalstorage_simplecop
|
||||
ADD_PYTHON_TEST(PyQgsSpatialIndex test_qgsspatialindex.py)
|
||||
ADD_PYTHON_TEST(PyQgsSpatialiteProvider test_provider_spatialite.py)
|
||||
ADD_PYTHON_TEST(PyQgsSQLStatement test_qgssqlstatement.py)
|
||||
ADD_PYTHON_TEST(PyQgsStoredQueryManager test_qgsstoredquerymanager.py)
|
||||
ADD_PYTHON_TEST(PyQgsStringStatisticalSummary test_qgsstringstatisticalsummary.py)
|
||||
ADD_PYTHON_TEST(PyQgsSymbolLayer test_qgssymbollayer.py)
|
||||
ADD_PYTHON_TEST(PyQgsSymbolBufferSettingsWidget test_qgssymbolbuffersettingswidget.py)
|
||||
|
312
tests/src/python/test_qgsstoredquerymanager.py
Normal file
312
tests/src/python/test_qgsstoredquerymanager.py
Normal file
@ -0,0 +1,312 @@
|
||||
"""QGIS Unit tests for QgsStoredQueryManager.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from qgis.PyQt.QtCore import QCoreApplication, QLocale
|
||||
from qgis.PyQt.QtTest import QSignalSpy
|
||||
from qgis.core import (
|
||||
Qgis,
|
||||
QgsProject,
|
||||
QgsSettings,
|
||||
)
|
||||
from qgis.gui import QgsGui
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
from utilities import unitTestDataPath
|
||||
|
||||
start_app()
|
||||
TEST_DATA_DIR = unitTestDataPath()
|
||||
|
||||
|
||||
class TestQgsStoredQueryManager(QgisTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""Run before all tests"""
|
||||
super().setUpClass()
|
||||
QCoreApplication.setOrganizationName("QGIS_Test")
|
||||
QCoreApplication.setOrganizationDomain("QGIS_TestQgsStoredQueryManager.com")
|
||||
QCoreApplication.setApplicationName("QGIS_TestQgsStoredQueryManager")
|
||||
QgsSettings().clear()
|
||||
QLocale.setDefault(QLocale(QLocale.Language.English))
|
||||
start_app()
|
||||
|
||||
def test_project_storage(self):
|
||||
"""
|
||||
Test storage of queries in a project
|
||||
"""
|
||||
p = QgsProject.instance()
|
||||
manager = QgsGui.storedQueryManager()
|
||||
QgsSettings().clear()
|
||||
QgsProject.instance().clear()
|
||||
|
||||
self.assertFalse(manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject))
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
signal_added = QSignalSpy(manager.queryAdded)
|
||||
signal_changed = QSignalSpy(manager.queryChanged)
|
||||
signal_removed = QSignalSpy(manager.queryRemoved)
|
||||
manager.storeQuery(
|
||||
"first query",
|
||||
"select * from something",
|
||||
Qgis.QueryStorageBackend.CurrentProject,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 1)
|
||||
self.assertEqual(signal_added[-1][0], "first query")
|
||||
self.assertEqual(len(signal_changed), 0)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject),
|
||||
["first query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
manager.storeQuery(
|
||||
"ANOTHER query",
|
||||
"""INSERT INTO Students (name) VALUES ('Robert');
|
||||
DROP TABLE Students;--');""",
|
||||
Qgis.QueryStorageBackend.CurrentProject,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(signal_added[-1][0], "ANOTHER query")
|
||||
self.assertEqual(len(signal_changed), 0)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"""INSERT INTO Students (name) VALUES ('Robert');
|
||||
DROP TABLE Students;--');""",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
# update an existing query
|
||||
manager.storeQuery(
|
||||
"ANOTHER query",
|
||||
"DROP TABLE Students",
|
||||
Qgis.QueryStorageBackend.CurrentProject,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(signal_changed[-1][0], "ANOTHER query")
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"DROP TABLE Students",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
# remove a query which doesn't exist
|
||||
manager.removeQuery("xxx", Qgis.QueryStorageBackend.CurrentProject)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
|
||||
# remove a query
|
||||
manager.removeQuery("first query", Qgis.QueryStorageBackend.CurrentProject)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(len(signal_removed), 1)
|
||||
self.assertEqual(signal_removed[-1][0], "first query")
|
||||
self.assertEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject),
|
||||
["ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.CurrentProject),
|
||||
"DROP TABLE Students",
|
||||
)
|
||||
p.clear()
|
||||
self.assertFalse(manager.allQueryNames(Qgis.QueryStorageBackend.CurrentProject))
|
||||
|
||||
def test_local_profile_storage(self):
|
||||
"""
|
||||
Test storage of queries in the local profile
|
||||
"""
|
||||
QgsSettings().clear()
|
||||
QgsProject.instance().clear()
|
||||
manager = QgsGui.storedQueryManager()
|
||||
|
||||
self.assertFalse(manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile))
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
signal_added = QSignalSpy(manager.queryAdded)
|
||||
signal_changed = QSignalSpy(manager.queryChanged)
|
||||
signal_removed = QSignalSpy(manager.queryRemoved)
|
||||
manager.storeQuery(
|
||||
"first query",
|
||||
"select * from something",
|
||||
Qgis.QueryStorageBackend.LocalProfile,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 1)
|
||||
self.assertEqual(signal_added[-1][0], "first query")
|
||||
self.assertEqual(len(signal_changed), 0)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile),
|
||||
["first query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
manager.storeQuery(
|
||||
"ANOTHER query",
|
||||
"""INSERT INTO Students (name) VALUES ('Robert');
|
||||
DROP TABLE Students;--');""",
|
||||
Qgis.QueryStorageBackend.LocalProfile,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(signal_added[-1][0], "ANOTHER query")
|
||||
self.assertEqual(len(signal_changed), 0)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"""INSERT INTO Students (name) VALUES ('Robert');
|
||||
DROP TABLE Students;--');""",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
# update an existing query
|
||||
manager.storeQuery(
|
||||
"ANOTHER query",
|
||||
"DROP TABLE Students",
|
||||
Qgis.QueryStorageBackend.LocalProfile,
|
||||
)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(signal_changed[-1][0], "ANOTHER query")
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("first query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"select * from something",
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"DROP TABLE Students",
|
||||
)
|
||||
self.assertFalse(manager.query("test"))
|
||||
|
||||
# remove a query which doesn't exist
|
||||
manager.removeQuery("xxx", Qgis.QueryStorageBackend.LocalProfile)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(len(signal_removed), 0)
|
||||
self.assertCountEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile),
|
||||
["first query", "ANOTHER query"],
|
||||
)
|
||||
|
||||
# remove a query
|
||||
manager.removeQuery("first query", Qgis.QueryStorageBackend.LocalProfile)
|
||||
self.assertEqual(len(signal_added), 2)
|
||||
self.assertEqual(len(signal_changed), 1)
|
||||
self.assertEqual(len(signal_removed), 1)
|
||||
self.assertEqual(signal_removed[-1][0], "first query")
|
||||
self.assertEqual(
|
||||
manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile),
|
||||
["ANOTHER query"],
|
||||
)
|
||||
self.assertEqual(
|
||||
manager.query("ANOTHER query", Qgis.QueryStorageBackend.LocalProfile),
|
||||
"DROP TABLE Students",
|
||||
)
|
||||
QgsSettings().clear()
|
||||
self.assertFalse(manager.allQueryNames(Qgis.QueryStorageBackend.LocalProfile))
|
||||
|
||||
def test_all_queries(self):
|
||||
"""
|
||||
Test retrieving all queries.
|
||||
"""
|
||||
QgsSettings().clear()
|
||||
QgsProject.instance().clear()
|
||||
manager = QgsGui.storedQueryManager()
|
||||
|
||||
manager.storeQuery(
|
||||
"first project query",
|
||||
"select * from something",
|
||||
Qgis.QueryStorageBackend.CurrentProject,
|
||||
)
|
||||
manager.storeQuery(
|
||||
"SECOND project query",
|
||||
"select * from something_else",
|
||||
Qgis.QueryStorageBackend.CurrentProject,
|
||||
)
|
||||
|
||||
manager.storeQuery(
|
||||
"first PROFILE query",
|
||||
"select * from something3",
|
||||
Qgis.QueryStorageBackend.LocalProfile,
|
||||
)
|
||||
manager.storeQuery(
|
||||
"2 PROFILE query",
|
||||
"select * from something4",
|
||||
Qgis.QueryStorageBackend.LocalProfile,
|
||||
)
|
||||
|
||||
res = manager.allQueries()
|
||||
self.assertEqual(len(res), 4)
|
||||
self.assertEqual(res[0].name, "2 PROFILE query")
|
||||
self.assertEqual(res[0].definition, "select * from something4")
|
||||
self.assertEqual(res[0].backend, Qgis.QueryStorageBackend.LocalProfile)
|
||||
self.assertEqual(res[1].name, "first PROFILE query")
|
||||
self.assertEqual(res[1].definition, "select * from something3")
|
||||
self.assertEqual(res[1].backend, Qgis.QueryStorageBackend.LocalProfile)
|
||||
self.assertEqual(res[2].name, "first project query")
|
||||
self.assertEqual(res[2].definition, "select * from something")
|
||||
self.assertEqual(res[2].backend, Qgis.QueryStorageBackend.CurrentProject)
|
||||
self.assertEqual(res[3].name, "SECOND project query")
|
||||
self.assertEqual(res[3].definition, "select * from something_else")
|
||||
self.assertEqual(res[3].backend, Qgis.QueryStorageBackend.CurrentProject)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user