Skip to content
Permalink
Browse files

Add a cancel button for Postgis and Spatialite

  • Loading branch information
pblottiere committed Mar 2, 2018
1 parent 0081f78 commit bf7df6d2e38babc9699f794832a8366a2d147edb
@@ -42,6 +42,9 @@ def __del__(self):
def uri(self):
return QgsDataSourceUri(self._uri.uri(False))

def cancel(self):
pass

def publicUri(self):
publicUri = QgsDataSourceUri.removePassword(self._uri.uri(False))
return QgsDataSourceUri(publicUri)
@@ -22,11 +22,18 @@
from builtins import str
from builtins import range

from qgis.PyQt.QtCore import Qt, QTime, QRegExp, QAbstractTableModel
from qgis.PyQt.QtGui import QFont, QStandardItemModel, QStandardItem
from qgis.PyQt.QtCore import (Qt,
QTime,
QRegExp,
QAbstractTableModel,
pyqtSignal,
QObject)
from qgis.PyQt.QtGui import (QFont,
QStandardItemModel,
QStandardItem)
from qgis.PyQt.QtWidgets import QApplication

from .plugin import DbError
from .plugin import DbError, BaseError


class BaseTableModel(QAbstractTableModel):
@@ -139,6 +146,33 @@ def rowCount(self, index=None):
return self.table.rowCount if self.table.rowCount is not None and self.columnCount(index) > 0 else 0


class SqlResultModelAsync(QObject):

done = pyqtSignal()

def __init__(self, db, sql, parent=None):
QObject.__init__(self)
self.db = db
self.sql = sql
self.parent = parent
self.error = BaseError('')
self.status = None
self.model = None
self.task = None

def cancel(self):
if self.task:
self.task.cancelQuery()

def modelDone(self):
if self.task:
self.status = self.task.status
self.model = self.task.model
self.error = self.task.error

self.done.emit()


class SqlResultModel(BaseTableModel):

def __init__(self, db, sql, parent=None):
@@ -256,6 +256,11 @@ def sqlResultModel(self, sql, parent):

return SqlResultModel(self, sql, parent)

def sqlResultModelAsync(self, sql, parent):
from .data_model import SqlResultModelAsync

return SqlResultModelAsync(self, sql, parent)

def columnUniqueValuesModel(self, col, table, limit=10):
l = ""
if limit is not None:
@@ -186,6 +186,10 @@ def _checkRasterColumnsTable(self):
self.has_raster_columns_access = self.getTablePrivileges('raster_columns')[0]
return self.has_raster_columns

def cancel(self):
if self.connection:
self.connection.cancel()

def getInfo(self):
c = self._execute(None, u"SELECT version()")
res = self._fetchone(c)
@@ -20,8 +20,9 @@
***************************************************************************/
"""


from ..data_model import TableDataModel, SqlResultModel
from qgis.core import QgsTask
from ..plugin import BaseError
from ..data_model import TableDataModel, SqlResultModel, SqlResultModelAsync


class PGTableDataModel(TableDataModel):
@@ -79,5 +80,41 @@ def fetchMoreData(self, row_start):
self.fetchedFrom = row_start


class PGSqlResultModelTask(QgsTask):

def __init__(self, db, sql, parent):
QgsTask.__init__(self)
self.db = db
self.sql = sql
self.parent = parent
self.error = BaseError('')
self.model = None

def run(self):

try:
self.model = PGSqlResultModel(self.db, self.sql, self.parent)
except BaseError as e:
self.error = e
QgsMessageLog.logMessage(e.msg)
return False

return True

def cancelQuery(self):
self.db.connector.cancel()
self.cancel()


class PGSqlResultModelAsync(SqlResultModelAsync):

def __init__(self, db, sql, parent):
SqlResultModelAsync.__init__(self, db, sql, parent)

self.task = PGSqlResultModelTask(db, sql, parent)
self.task.taskCompleted.connect(self.modelDone)
self.task.taskTerminated.connect(self.modelDone)


class PGSqlResultModel(SqlResultModel):
pass
@@ -134,6 +134,11 @@ def sqlResultModel(self, sql, parent):

return PGSqlResultModel(self, sql, parent)

def sqlResultModelAsync(self, sql, parent):
from .data_model import PGSqlResultModelAsync

return PGSqlResultModelAsync(self, sql, parent)

def registerDatabaseActions(self, mainWindow):
Database.registerDatabaseActions(self, mainWindow)

@@ -59,6 +59,12 @@ def __init__(self, uri):
def _connectionInfo(self):
return str(self.dbname)

def cancel(self):
# https://www.sqlite.org/c3ref/interrupt.html
# This function causes any pending database operation to abort and return at its earliest opportunity.
if self.connection:
self.connection.interrupt()

@classmethod
def isValidDatabase(self, path):
if not QFile.exists(path):
@@ -20,7 +20,10 @@
***************************************************************************/
"""

from ..data_model import TableDataModel, SqlResultModel
from qgis.core import QgsTask
from ..plugin import BaseError
from ..data_model import TableDataModel, SqlResultModel, SqlResultModelAsync
from .plugin import SLDatabase


class SLTableDataModel(TableDataModel):
@@ -60,5 +63,47 @@ def rowCount(self, index=None):
return self.fetchedCount


class SLSqlResultModelTask(QgsTask):

def __init__(self, db, sql, parent):
QgsTask.__init__(self)
self.db = db
self.sql = sql
self.parent = parent
self.error = BaseError('')
self.model = None
self.clone = None

def run(self):
try:
self.clone = SLDatabase(None, self.db.connector.uri())

# import time
# self.clone.connector.connection.create_function("sleep", 1, time.sleep)

self.model = SLSqlResultModel(self.clone, self.sql, None)
except BaseError as e:
self.error = e
QgsMessageLog.logMessage(e.msg)
return False

return True

def cancelQuery(self):
if self.clone:
self.clone.connector.cancel()
self.cancel()


class SLSqlResultModelAsync(SqlResultModelAsync):

def __init__(self, db, sql, parent):
SqlResultModelAsync.__init__(self, db, sql, parent)

self.task = SLSqlResultModelTask(db, sql, parent)
self.task.taskCompleted.connect(self.modelDone)
self.task.taskTerminated.connect(self.modelDone)


class SLSqlResultModel(SqlResultModel):
pass
@@ -130,6 +130,11 @@ def sqlResultModel(self, sql, parent):

return SLSqlResultModel(self, sql, parent)

def sqlResultModelAsync(self, sql, parent):
from .data_model import SLSqlResultModelAsync

return SLSqlResultModelAsync(self, sql, parent)

def registerDatabaseActions(self, mainWindow):
action = QAction(self.tr("Run &Vacuum"), self)
mainWindow.registerAction(action, self.tr("&Database"), self.runVacuumActionSlot)
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-

"""
/***************************************************************************
Name : DB Manager
Description : Database manager plugin for QGIS
Date : January 15, 2018
copyright : (C) 2018 by Paul Blottiere
email : paul.blottiere@oslandia.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. *
* *
***************************************************************************/
"""

from qgis.PyQt.QtWidgets import QDialog, QLabel, QHBoxLayout
from qgis.PyQt.QtGui import QMovie
from qgis.PyQt.QtCore import QSize, Qt, pyqtSignal

from qgis.core import QgsApplication

from .ui.ui_DlgCancelTaskQuery import Ui_DlgCancelTaskQuery as Ui_Dialog


class DlgCancelTaskQuery(QDialog, Ui_Dialog):

canceled = pyqtSignal()

def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setupUi(self)

gif = QgsApplication.iconPath("/mIconLoading.gif")
self.mGif = QMovie(gif)
self.mGif.setScaledSize(QSize(16, 16))

self.mMovie.setMovie(self.mGif)
self.setWindowModality(Qt.ApplicationModal)

self.mCancelButton.clicked.connect(self.cancel)

self.cancelStatus = False

def cancel(self):
self.mLabel.setText("Stopping SQL...")
self.cancelStatus = True
self.mCancelButton.setEnabled(False)
self.canceled.emit()

def show(self):
self.cancelStatus = False
self.mGif.start()
self.mCancelButton.setEnabled(True)
self.mLabel.setText("Executing SQL...")
super(QDialog, self).show()

def hide(self):
self.cancelStatus = False
self.mGif.stop()
super(QDialog, self).hide()

0 comments on commit bf7df6d

Please sign in to comment.
You can’t perform that action at this time.