Skip to content

Commit 9d12b0a

Browse files
authored
Merge pull request #6749 from slarosa/db_quey_history_1
[FEATURE][needs-docs] DB Manager: adds SQL query history
2 parents 0cc0fed + 84d8693 commit 9d12b0a

2 files changed

Lines changed: 278 additions & 166 deletions

File tree

‎python/plugins/db_manager/dlg_sql_window.py‎

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
from builtins import str
2727

2828
from qgis.PyQt.QtCore import Qt, pyqtSignal
29-
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QInputDialog, QStyledItemDelegate
29+
from qgis.PyQt.QtWidgets import QDialog, QWidget, QAction, QApplication, QInputDialog, QStyledItemDelegate, QTableWidgetItem
3030
from qgis.PyQt.QtGui import QKeySequence, QCursor, QClipboard, QIcon, QStandardItemModel, QStandardItem
3131
from qgis.PyQt.Qsci import QsciAPIs
3232

33-
from qgis.core import QgsProject, QgsApplication, QgsTask
33+
from qgis.core import QgsProject, QgsApplication, QgsTask, QgsSettings
3434
from qgis.utils import OverrideCursor
3535

3636
from .db_plugins.plugin import BaseError
@@ -53,19 +53,22 @@
5353

5454
class DlgSqlWindow(QWidget, Ui_Dialog):
5555
nameChanged = pyqtSignal(str)
56+
QUERY_HISTORY_LIMIT = 20
5657

5758
def __init__(self, iface, db, parent=None):
5859
QWidget.__init__(self, parent)
5960
self.mainWindow = parent
6061
self.iface = iface
6162
self.db = db
63+
self.dbType = db.connection().typeNameString()
64+
self.connectionName = db.connection().connectionName()
6265
self.filter = ""
6366
self.modelAsync = None
6467
self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, SpatiaLite doesn't
6568
self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases
6669
self.setupUi(self)
6770
self.setWindowTitle(
68-
self.tr(u"{0} - {1} [{2}]").format(self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()))
71+
self.tr(u"{0} - {1} [{2}]").format(self.windowTitle(), self.connectionName, self.dbType))
6972

7073
self.defaultLayerName = 'QueryLayer'
7174

@@ -79,6 +82,17 @@ def __init__(self, iface, db, parent=None):
7982
self.editSql.setMarginVisible(True)
8083
self.initCompleter()
8184

85+
settings = QgsSettings()
86+
self.history = settings.value('DB_Manager/queryHistory/' + self.dbType, {self.connectionName: []})
87+
if self.connectionName not in self.history:
88+
self.history[self.connectionName] = []
89+
90+
self.queryHistoryWidget.setVisible(False)
91+
self.queryHistoryTableWidget.verticalHeader().hide()
92+
self.queryHistoryTableWidget.doubleClicked.connect(self.insertQueryInEditor)
93+
self.populateQueryHistory()
94+
self.btnQueryHistory.toggled.connect(self.showHideQueryHistory)
95+
8296
self.btnCancel.setText(self.tr("Cancel (ESC)"))
8397
self.btnCancel.setEnabled(False)
8498
self.btnCancel.clicked.connect(self.executeSqlCanceled)
@@ -140,6 +154,45 @@ def __init__(self, iface, db, parent=None):
140154

141155
self.presetName.textChanged.connect(self.nameChanged)
142156

157+
def insertQueryInEditor(self, item):
158+
sql = item.data(Qt.DisplayRole)
159+
self.editSql.insertText(sql)
160+
161+
def showHideQueryHistory(self, visible):
162+
self.queryHistoryWidget.setVisible(visible)
163+
164+
def populateQueryHistory(self):
165+
self.queryHistoryTableWidget.clearContents()
166+
self.queryHistoryTableWidget.setRowCount(0)
167+
dictlist = self.history[self.connectionName]
168+
169+
if not dictlist:
170+
return
171+
172+
for i in range(len(dictlist)):
173+
self.queryHistoryTableWidget.insertRow(0)
174+
queryItem = QTableWidgetItem(dictlist[i]['query'])
175+
rowsItem = QTableWidgetItem(str(dictlist[i]['rows']))
176+
durationItem = QTableWidgetItem(str(dictlist[i]['secs']))
177+
self.queryHistoryTableWidget.setItem(0, 0, queryItem)
178+
self.queryHistoryTableWidget.setItem(0, 1, rowsItem)
179+
self.queryHistoryTableWidget.setItem(0, 2, durationItem)
180+
181+
self.queryHistoryTableWidget.resizeColumnsToContents()
182+
self.queryHistoryTableWidget.resizeRowsToContents()
183+
184+
def writeQueryHistory(self, sql, affectedRows, secs):
185+
if len(self.history[self.connectionName]) >= self.QUERY_HISTORY_LIMIT:
186+
self.history[self.connectionName].pop(0)
187+
188+
settings = QgsSettings()
189+
self.history[self.connectionName].append({'query': sql,
190+
'rows': affectedRows,
191+
'secs': secs})
192+
settings.setValue('DB_Manager/queryHistory/' + self.dbType, self.history)
193+
194+
self.populateQueryHistory()
195+
143196
def updatePresetsCombobox(self):
144197
self.presetCombo.clear()
145198

@@ -236,12 +289,14 @@ def executeSqlCompleted(self):
236289
quotedCols = []
237290

238291
self.viewResult.setModel(model)
239-
self.lblResult.setText(self.tr("{0} rows, {1:.1f} seconds").format(model.affectedRows(), model.secs()))
292+
self.lblResult.setText(self.tr("{0} rows, {1:.3f} seconds").format(model.affectedRows(), model.secs()))
240293
cols = self.viewResult.model().columnNames()
241294
for col in cols:
242295
quotedCols.append(self.db.connector.quoteId(col))
243296

244297
self.setColumnCombos(cols, quotedCols)
298+
299+
self.writeQueryHistory(self.modelAsync.task.sql, model.affectedRows(), model.secs())
245300
self.update()
246301
elif not self.modelAsync.canceled:
247302
DlgDbError.showError(self.modelAsync.error, self)

0 commit comments

Comments
 (0)