SqlBrowser/SqlBrowserWidget.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the SQL Browser widget.
8 """
9
10 from PyQt4.QtCore import *
11 from PyQt4.QtGui import *
12 from PyQt4.QtSql import QSqlDatabase, QSqlError, QSqlTableModel, QSqlQueryModel, QSqlQuery
13
14 from SqlConnectionDialog import SqlConnectionDialog
15
16 from Ui_SqlBrowserWidget import Ui_SqlBrowserWidget
17
18 class SqlBrowserWidget(QWidget, Ui_SqlBrowserWidget):
19 """
20 Class implementing the SQL Browser widget.
21
22 @signal statusMessage(string) emitted to show a status message
23 """
24 cCount = 0
25
26 def __init__(self, parent = None):
27 """
28 Constructor
29
30 @param parent reference to the parent widget (QWidget)
31 """
32 QWidget.__init__(self, parent)
33 self.setupUi(self)
34
35 self.table.addAction(self.insertRowAction)
36 self.table.addAction(self.deleteRowAction)
37
38 if len(QSqlDatabase.drivers()) == 0:
39 QMessageBox.information(None,
40 self.trUtf8("No database drivers found"),
41 self.trUtf8("""This tool requires at least one Qt database driver. """
42 """Please check the Qt documentation how to build the """
43 """Qt SQL plugins."""))
44
45 self.connect(self.connections, SIGNAL("tableActivated(QString)"),
46 self.on_connections_tableActivated)
47 self.connect(self.connections, SIGNAL("schemaRequested(QString)"),
48 self.on_connections_schemaRequested)
49 self.connect(self.connections, SIGNAL("cleared()"),
50 self.on_connections_cleared)
51
52 self.emit(SIGNAL("statusMessage(QString)"), self.trUtf8("Ready"))
53
54 @pyqtSlot()
55 def on_clearButton_clicked(self):
56 """
57 Private slot to clear the SQL entry widget.
58 """
59 self.sqlEdit.clear()
60 self.sqlEdit.setFocus()
61
62 @pyqtSlot()
63 def on_executeButton_clicked(self):
64 """
65 Private slot to execute the entered SQL query.
66 """
67 self.executeQuery()
68 self.sqlEdit.setFocus()
69
70 @pyqtSlot()
71 def on_insertRowAction_triggered(self):
72 """
73 Private slot handling the action to insert a new row.
74 """
75 self.__insertRow()
76
77 @pyqtSlot()
78 def on_deleteRowAction_triggered(self):
79 """
80 Private slot handling the action to delete a row.
81 """
82 self.__deleteRow()
83
84 @pyqtSlot(str)
85 def on_connections_tableActivated(self, table):
86 """
87 Private slot to show the contents of a table.
88
89 @param table name of the table for which to show the contents (string)
90 """
91 self.showTable(table)
92
93 @pyqtSlot(str)
94 def on_connections_schemaRequested(self, table):
95 """
96 Private slot to show the schema of a table.
97
98 @param table name of the table for which to show the schema (string)
99 """
100 self.showSchema(table)
101
102 @pyqtSlot()
103 def on_connections_cleared(self):
104 """
105 Private slot to clear the table.
106 """
107 model = QStandardItemModel(self.table)
108 self.table.setModel(model)
109 self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
110
111 self.updateActions()
112
113 def addConnection(self, driver, dbName, user, password, host, port):
114 """
115 Public method to add a database connection.
116
117 @param driver name of the Qt database driver (string)
118 @param dbName name of the database (string)
119 @param user user name (string)
120 @param password password (string)
121 @param host host name (string)
122 @param port port number (integer)
123 """
124 err = QSqlError()
125
126 self.__class__.cCount += 1
127 db = QSqlDatabase.addDatabase(driver.upper(),
128 "Browser%d" % self.__class__.cCount)
129 db.setDatabaseName(dbName)
130 db.setHostName(host)
131 db.setPort(port)
132 if not db.open(user, password):
133 err = db.lastError()
134 db = QSqlDatabase()
135 QSqlDatabase.removeDatabase("Browser%d" % self.__class__.cCount)
136
137 self.connections.refresh()
138
139 return err
140
141 def addConnectionByDialog(self):
142 """
143 Public slot to add a database connection via an input dialog.
144 """
145 dlg = SqlConnectionDialog(self)
146 if dlg.exec_() == QDialog.Accepted:
147 driver, dbName, user, password, host, port = dlg.getData()
148 err = self.addConnection(driver, dbName, user, password, host, port)
149
150 if err.type() != QSqlError.NoError:
151 QMessageBox.warning(self,
152 self.trUtf8("Unable to open database"),
153 self.trUtf8("""An error occurred while opening the connection."""))
154
155 def showTable(self, table):
156 """
157 Public slot to show the contents of a table.
158
159 @param table name of the table to be shown (string)
160 """
161 model = QSqlTableModel(self.table, self.connections.currentDatabase())
162 model.setEditStrategy(QSqlTableModel.OnRowChange)
163 model.setTable(table)
164 model.select()
165 if model.lastError().type() != QSqlError.NoError:
166 self.emit(SIGNAL("statusMessage(QString)"), model.lastError().text())
167 self.table.setModel(model)
168 self.table.setEditTriggers(
169 QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed)
170
171 self.table.resizeColumnsToContents()
172
173 self.connect(self.table.selectionModel(),
174 SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"),
175 self.updateActions)
176
177 self.updateActions()
178
179 def showSchema(self, table):
180 """
181 Public slot to show the schema of a table.
182
183 @param table name of the table to be shown (string)
184 """
185 rec = self.connections.currentDatabase().record(table)
186 model = QStandardItemModel(self.table)
187
188 model.insertRows(0, rec.count())
189 model.insertColumns(0, 7)
190
191 model.setHeaderData(0, Qt.Horizontal, QVariant("Fieldname"))
192 model.setHeaderData(1, Qt.Horizontal, QVariant("Type"))
193 model.setHeaderData(2, Qt.Horizontal, QVariant("Length"))
194 model.setHeaderData(3, Qt.Horizontal, QVariant("Precision"))
195 model.setHeaderData(4, Qt.Horizontal, QVariant("Required"))
196 model.setHeaderData(5, Qt.Horizontal, QVariant("Auto Value"))
197 model.setHeaderData(6, Qt.Horizontal, QVariant("Default Value"))
198
199 for i in range(rec.count()):
200 fld = rec.field(i)
201 model.setData(model.index(i, 0), QVariant(fld.name()))
202 if fld.typeID() == -1:
203 model.setData(model.index(i, 1),
204 QVariant(QVariant.typeToName(fld.type())))
205 else:
206 model.setData(model.index(i, 1), QVariant("%s1 (%s)" % (\
207 QVariant.typeToName(fld.type()),
208 fld.typeID())))
209 if fld.length() < 0:
210 model.setData(model.index(i, 2), QVariant("?"))
211 else:
212 model.setData(model.index(i, 2), QVariant(fld.length()))
213 if fld.precision() < 0:
214 model.setData(model.index(i, 3), QVariant("?"))
215 else:
216 model.setData(model.index(i, 3), QVariant(fld.precision()))
217 if fld.requiredStatus() == -1:
218 model.setData(model.index(i, 4), QVariant("?"))
219 else:
220 model.setData(model.index(i, 4), QVariant(bool(fld.requiredStatus())))
221 model.setData(model.index(i, 5), QVariant(fld.isAutoValue()))
222 model.setData(model.index(i, 6), QVariant(fld.defaultValue()))
223
224 self.table.setModel(model)
225 self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
226
227 self.table.resizeColumnsToContents()
228
229 self.updateActions()
230
231 def updateActions(self):
232 """
233 Public slot to update the actions.
234 """
235 enableIns = isinstance(self.table.model(), QSqlTableModel)
236 enableDel = enableIns & self.table.currentIndex().isValid()
237
238 self.insertRowAction.setEnabled(enableIns)
239 self.deleteRowAction.setEnabled(enableDel)
240
241 def __insertRow(self):
242 """
243 Privat slot to insert a row into the database table.
244 """
245 model = self.table.model()
246 if not isinstance(model, QSqlTableModel):
247 return
248
249 insertIndex = self.table.currentIndex()
250 if insertIndex.row() == -1:
251 row = 0
252 else:
253 row = insertIndex.row()
254 model.insertRow(row)
255 insertIndex = model.index(row, 0)
256 self.table.setCurrentIndex(insertIndex)
257 self.table.edit(insertIndex)
258
259 def __deleteRow(self):
260 """
261 Privat slot to delete a row from the database table.
262 """
263 model = self.table.model()
264 if not isinstance(model, QSqlTableModel):
265 return
266
267 model.setEditStrategy(QSqlTableModel.OnManualSubmit)
268
269 currentSelection = self.table.selectionModel().selectedIndexes()
270 for selectedIndex in currentSelection:
271 if selectedIndex.column() != 0:
272 continue
273 model.removeRow(selectedIndex.row())
274
275 model.submitAll()
276 model.setEditStrategy(QSqlTableModel.OnRowChange)
277
278 self.updateActions()
279
280 def executeQuery(self):
281 """
282 Public slot to execute the entered query.
283 """
284 model = QSqlQueryModel(self.table)
285 model.setQuery(
286 QSqlQuery(self.sqlEdit.toPlainText(), self.connections.currentDatabase()))
287 self.table.setModel(model)
288
289 if model.lastError().type() != QSqlError.NoError:
290 self.emit(SIGNAL("statusMessage(QString)"), model.lastError().text())
291 elif model.query().isSelect():
292 self.emit(SIGNAL("statusMessage(QString)"), self.trUtf8("Query OK."))
293 else:
294 self.emit(SIGNAL("statusMessage(QString)"),
295 self.trUtf8("Query OK, number of affected rows: {0}")\
296 .format(model.query().numRowsAffected()))
297
298 self.table.resizeColumnsToContents()
299
300 self.updateActions()

eric ide

mercurial