mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE][needs-docs] DB Manager: adds SQL query history
This commit is contained in:
parent
b18aaae014
commit
1242402a56
@ -26,11 +26,11 @@ from builtins import next
|
||||
from builtins import str
|
||||
|
||||
from qgis.PyQt.QtCore import Qt, pyqtSignal
|
||||
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QInputDialog, QStyledItemDelegate
|
||||
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QInputDialog, QStyledItemDelegate, QTableWidgetItem
|
||||
from qgis.PyQt.QtGui import QKeySequence, QCursor, QClipboard, QIcon, QStandardItemModel, QStandardItem
|
||||
from qgis.PyQt.Qsci import QsciAPIs
|
||||
|
||||
from qgis.core import QgsProject, QgsApplication, QgsTask
|
||||
from qgis.core import QgsProject, QgsApplication, QgsTask, QgsSettings
|
||||
from qgis.utils import OverrideCursor
|
||||
|
||||
from .db_plugins.plugin import BaseError
|
||||
@ -59,13 +59,15 @@ class DlgSqlWindow(QWidget, Ui_Dialog):
|
||||
self.mainWindow = parent
|
||||
self.iface = iface
|
||||
self.db = db
|
||||
self.dbType = db.connection().typeNameString()
|
||||
self.connectionName = db.connection().connectionName()
|
||||
self.filter = ""
|
||||
self.modelAsync = None
|
||||
self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, SpatiaLite doesn't
|
||||
self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases
|
||||
self.setupUi(self)
|
||||
self.setWindowTitle(
|
||||
self.tr(u"{0} - {1} [{2}]").format(self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()))
|
||||
self.tr(u"{0} - {1} [{2}]").format(self.windowTitle(), self.connectionName, self.dbType))
|
||||
|
||||
self.defaultLayerName = 'QueryLayer'
|
||||
|
||||
@ -79,6 +81,17 @@ class DlgSqlWindow(QWidget, Ui_Dialog):
|
||||
self.editSql.setMarginVisible(True)
|
||||
self.initCompleter()
|
||||
|
||||
settings = QgsSettings()
|
||||
self.history = settings.value('DB_Manager/queryHistory/' + self.dbType, {self.connectionName: []})
|
||||
if self.connectionName not in self.history:
|
||||
self.history[self.connectionName] = []
|
||||
|
||||
self.queryHistoryWidget.setVisible(False)
|
||||
self.queryHistoryTableWidget.verticalHeader().hide()
|
||||
self.queryHistoryTableWidget.doubleClicked.connect(self.insertQueryInEditor)
|
||||
self.populateQueryHistory()
|
||||
self.btnQueryHistory.toggled.connect(self.showHideQueryHistory)
|
||||
|
||||
self.btnCancel.setText(self.tr("Cancel (ESC)"))
|
||||
self.btnCancel.setEnabled(False)
|
||||
self.btnCancel.clicked.connect(self.executeSqlCanceled)
|
||||
@ -140,6 +153,42 @@ class DlgSqlWindow(QWidget, Ui_Dialog):
|
||||
|
||||
self.presetName.textChanged.connect(self.nameChanged)
|
||||
|
||||
def insertQueryInEditor(self, item):
|
||||
sql = item.data(Qt.DisplayRole)
|
||||
self.editSql.insertText(sql)
|
||||
|
||||
def showHideQueryHistory(self, visible):
|
||||
self.queryHistoryWidget.setVisible(visible)
|
||||
|
||||
def populateQueryHistory(self):
|
||||
self.queryHistoryTableWidget.clearContents()
|
||||
self.queryHistoryTableWidget.setRowCount(0)
|
||||
dictlist = self.history[self.connectionName]
|
||||
|
||||
if not dictlist:
|
||||
return
|
||||
|
||||
for i in range(len(dictlist)):
|
||||
self.queryHistoryTableWidget.insertRow(0)
|
||||
queryItem = QTableWidgetItem(dictlist[i]['query'])
|
||||
rowsItem = QTableWidgetItem(str(dictlist[i]['rows']))
|
||||
durationItem = QTableWidgetItem(str(dictlist[i]['secs']))
|
||||
self.queryHistoryTableWidget.setItem(0, 0, queryItem)
|
||||
self.queryHistoryTableWidget.setItem(0, 1, rowsItem)
|
||||
self.queryHistoryTableWidget.setItem(0, 2, durationItem)
|
||||
|
||||
self.queryHistoryTableWidget.resizeColumnsToContents()
|
||||
self.queryHistoryTableWidget.resizeRowsToContents()
|
||||
|
||||
def writeQueryHistory(self, sql, affectedRows, secs):
|
||||
settings = QgsSettings()
|
||||
self.history[self.connectionName].append({'query': sql,
|
||||
'rows': affectedRows,
|
||||
'secs': secs})
|
||||
settings.setValue('DB_Manager/queryHistory/' + self.dbType, self.history)
|
||||
|
||||
self.populateQueryHistory()
|
||||
|
||||
def updatePresetsCombobox(self):
|
||||
self.presetCombo.clear()
|
||||
|
||||
@ -236,12 +285,14 @@ class DlgSqlWindow(QWidget, Ui_Dialog):
|
||||
quotedCols = []
|
||||
|
||||
self.viewResult.setModel(model)
|
||||
self.lblResult.setText(self.tr("{0} rows, {1:.1f} seconds").format(model.affectedRows(), model.secs()))
|
||||
self.lblResult.setText(self.tr("{0} rows, {1:.3f} seconds").format(model.affectedRows(), model.secs()))
|
||||
cols = self.viewResult.model().columnNames()
|
||||
for col in cols:
|
||||
quotedCols.append(self.db.connector.quoteId(col))
|
||||
|
||||
self.setColumnCombos(cols, quotedCols)
|
||||
|
||||
self.writeQueryHistory(self.modelAsync.task.sql, model.affectedRows(), model.secs())
|
||||
self.update()
|
||||
elif not self.modelAsync.canceled:
|
||||
DlgDbError.showError(self.modelAsync.error, self)
|
||||
|
@ -19,8 +19,225 @@
|
||||
<property name="windowTitle">
|
||||
<string>SQL Window</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="queryBuilderBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Saved query</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="presetCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="presetName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="presetStore">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="presetDelete">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QSplitter" name="splitterHistory">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="handleWidth">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QgsCodeEditorSQL" name="editSql"/>
|
||||
<widget class="QWidget" name="queryHistoryWidget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableWidget" name="queryHistoryTableWidget">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Query</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Rows affected</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Duration (secs)</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnExecute">
|
||||
<property name="toolTip">
|
||||
<string>Execute query (Ctrl+R)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Execute</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+R</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblResult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnCreateView">
|
||||
<property name="text">
|
||||
<string>Create a view</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnQueryHistory">
|
||||
<property name="text">
|
||||
<string>Query History</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="viewResult">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QGroupBox" name="loadAsLayerGroup">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@ -233,167 +450,7 @@ unique values</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="queryBuilderBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Saved query</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="presetCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="presetName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="presetStore">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="presetDelete">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCodeEditorSQL" name="editSql"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnExecute">
|
||||
<property name="toolTip">
|
||||
<string>Execute query (Ctrl+R)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Execute</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+R</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblResult">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnCreateView">
|
||||
<property name="text">
|
||||
<string>Create a view</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="viewResult">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
|
Loading…
x
Reference in New Issue
Block a user