""" CopyCenterPlugin to provide 'TQtSQL'. Description: This python-script is a plugin for the CopyCenter.py. Author: Sebastian Sauer Copyright: GPL v2 or higher. """ class CopyCenterPlugin: """ The CopyCenterPlugin to provide 'TQtSQL' to CopyCenter.py """ name = "TQtSQL Database" """ The name this plugin has. The name should be unique and will be used for displaying a caption. """ class Plugin: def _init_(self,copycenterplugin): self.copycenterplugin = copycenterplugin self.widget = None self.database = None self.cursor = None self.isfinished = True def _init(self,copierer): self.copierer = copierer if not self.widget.connectClicked(): raise Exception("Failed to connect with database.") if self.database == None or not self.database.isOpen(): raise Exception("Database is not initialized or not opened.") self.copierer.appendProgressMessage("Connected: %s %s@%s:%i %s" % (str(self.database.driverName()),str(self.database.userName()),str(self.database.hostName()),self.database.port(),str(self.database.databaseName())) ) self.isfinished = False def isFinished(self): return self.isfinished def finish(self): self.isfinished = True self.widget.disconnectClicked() def createWidget(self,dialog,parent): return self.copycenterplugin.widget(dialog, self, parent) class Source(Plugin): plugintype = "Source" def __init__(self,copycenterplugin): self._init_(copycenterplugin) self.options = { 'driver': 'TQMYSQL3', #'TQMYSQL3','TQPSQL7','TQODBC3',... 'hostname': '127.0.0.1', 'port': 3306, 'username': 'root', #'MyUsername', 'password': '', #'MySecretPassword', 'database': '', #'MyTQtSQLDatabase', 'table': '', #'table1', 'fields': '', #'f1,f2', 'where': '', } def init(self,copierer): self._init(copierer) tablename = str(self.widget.tableedit.text()) wherestatement = str(self.widget.whereedit.text()) from TQt import tqt from TQt import tqtsql self.cursor = tqtsql.TQSqlCursor(tablename,True,self.database) self.cursor.setFilter(wherestatement) if not self.cursor.select(): raise Exception("Select on cursor failed.
%s
%s" % ( str(self.cursor.lastError().driverText()),str(self.cursor.lastError().databaseText()) )) self.fieldlist = [] for fieldname in str(self.widget.fieldedit.text()).split(","): fn = fieldname.strip() if fn != "": field = self.cursor.field(fn) if not field: raise Exception("There exists no such field \"%s\" in the table \"%s\"." % (fn,tablename)) self.fieldlist.append(str(field.name())) if len(self.fieldlist) < 1: raise Exception("No fields for table \"%s\" defined." % tablename) copierer.appendProgressMessage("SQL: %s" % str(self.cursor.executedQuery())) def read(self): if not next(self.cursor): return None record = [] for fieldname in self.fieldlist: record.append( str(self.cursor.value(fieldname).toString()).encode("latin-1") ) #print "read record: %s" % record return record class Destination(Plugin): plugintype = "Destination" def __init__(self,copycenterplugin): self._init_(copycenterplugin) self.options = { 'driver': 'TQMYSQL3', #'TQMYSQL3','TQPSQL7','TQODBC3',... 'hostname': '127.0.0.1', 'port': 3306, 'username': 'root', #'MyUsername', 'password': '', #'MySecretPassword', 'database': '', #'MyTQtSQLDatabase', 'table': '', #'table2', 'fields': '', #'field1,field2', 'operation': 'Insert', #'Insert','Update'... 'indexfield': '', } def init(self,copierer): self._init(copierer) from TQt import tqt from TQt import tqtsql self.fieldlist = [] for fieldname in str(self.widget.fieldedit.text()).split(","): fn = fieldname.strip() if fn != "": self.fieldlist.append(fn) tablename = str(self.widget.tableedit.text()) self.cursor = tqtsql.TQSqlCursor(tablename,True,self.database) { 0: self.initInsert, 1: self.initUpdate }[ self.widget.operationedit.currentItem() ]() def initInsert(self): self.write = self.writeInsert if not self.cursor.select(): raise Exception("Select on cursor failed.
%s
%s" % ( str(self.cursor.lastError().driverText()),str(self.cursor.lastError().databaseText()) )) for fieldname in self.fieldlist: # check fieldlist field = self.cursor.field(fieldname) if not field: raise Exception("There exists no such field \"%s\" in the table \"%s\"." % (fieldname, self.cursor.name())) self.copierer.appendProgressMessage("Insert SQL: %s" % str(self.cursor.executedQuery())) def writeInsert(self, record): print("insert record: %s" % record) from TQt import tqt cursorrecord = self.cursor.primeInsert() count = len(record) for i in range(len(self.fieldlist)): if i == count: break r = record[i] if r == None: v = tqt.TQVariant() else: v = tqt.TQVariant(r) cursorrecord.setValue(self.fieldlist[i], v) rowcount = self.cursor.insert() if rowcount < 1: drv = str(self.cursor.lastError().driverText()).encode("latin-1") db = str(self.cursor.lastError().databaseText()).encode("latin-1") print("failed: %s %s" % (drv,db)) self.copierer.writeFailed(record) else: self.copierer.writeSuccess(record,rowcount) #import time #time.sleep(1) return True def initUpdate(self): self.write = self.writeUpdate self.indexfieldname = str(self.widget.indexedit.text()).strip() if self.indexfieldname == "": raise Exception("No index-field defined.") pkindex = self.cursor.index(self.indexfieldname) if not pkindex: raise Exception("Invalid index-field defined.") self.cursor.setPrimaryIndex(pkindex) #self.cursor.setMode( tqtsql.TQSqlCursor.Insert | tqtsql.TQSqlCursor.Update ) self.copierer.appendProgressMessage("Update SQL: %s" % str(self.cursor.executedQuery())) def writeUpdate(self, record): from TQt import tqt # determinate the primary-index try: idx = self.fieldlist.index(self.indexfieldname) indexvalue = record[idx] except: import traceback print("".join( traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) )) raise Exception("Failed to determinate the value for the primary key.") # select cursor and go to matching record. wherestatement = "%s = \"%s\"" % (self.indexfieldname, indexvalue) if not self.cursor.select(wherestatement): raise Exception("Select on cursor failed.
%s
%s" % ( str(self.cursor.lastError().driverText()),str(self.cursor.lastError().databaseText()) )) if not next(self.cursor): #print "No such record to update !" return False # Prepare updating the record. cursorrecord = self.cursor.primeUpdate() # Update the fields in the record. count = len(record) for i in range(len(self.fieldlist)): if i == count: break fieldname = self.fieldlist[i] if self.indexfieldname != fieldname: # don't update the indexfield! r = record[i] if r == None: v = tqt.TQVariant() else: v = tqt.TQVariant(r) cursorrecord.setValue(fieldname, v) # Write updated record. rowcount = self.cursor.update() if rowcount < 1: self.copierer.writeFailed(record) else: self.copierer.writeSuccess(record,rowcount) print("updated record (rowcount %s): %s" % (rowcount,record)) return True def __init__(self, copycenter): """ Constructor. """ pass def widget(self,dialog,plugin,parent): """ Each plugin may provide a tqt.TQWidget back to the CopyCenter.py. The widget will be used to configure our plugin settings. """ from TQt import tqt import os self.dialog = dialog ListViewDialog = self.dialog.ListViewDialog class TableDialog(ListViewDialog): def __init__(self, mainwidget): ListViewDialog.__init__(self,mainwidget,"Tables") self.mainwidget = mainwidget self.listview.addColumn("Name") text = str(self.mainwidget.tableedit.text()) item = None for table in self.mainwidget.plugin.database.tables(): if item == None: item = tqt.TQListViewItem(self.listview,table) else: item = tqt.TQListViewItem(self.listview,item,table) if table == text: self.listview.setSelected(item,True) self.listview.ensureItemVisible(item) tqt.TQObject.connect(self.listview, tqt.TQ_SIGNAL("doubleClicked(TQListViewItem*, const TQPoint&, int)"), self.okClicked) tqt.TQObject.connect(self.okbtn, tqt.TQ_SIGNAL("clicked()"), self.okClicked) def okClicked(self): item = self.listview.selectedItem() if item == None: self.mainwidget.tableedit.setText("") else: self.mainwidget.tableedit.setText(item.text(0)) self.close() class FieldsDialog(ListViewDialog): def __init__(self, mainwidget): ListViewDialog.__init__(self,parent,"Fields") self.mainwidget = mainwidget self.listview.setSelectionMode(tqt.TQListView.Multi) self.listview.setSorting(-1) self.listview.header().setClickEnabled(False) self.listview.addColumn("Name") self.listview.addColumn("Type") self.listview.addColumn("Options") tablename = str(self.mainwidget.tableedit.text()) recinfo = self.mainwidget.plugin.database.recordInfo(tablename) if recinfo != None: fieldslist = str(self.mainwidget.fieldedit.text()).split(",") allfields = ("*" in fieldslist) item = None for fieldinfo in recinfo: opts = "" for s in ('Required','Calculated'): #,'Generated'): if getattr(fieldinfo,"is%s" % s)(): opts += "%s " % s item = self.addItem((fieldinfo.name(), tqt.TQVariant.typeToName(fieldinfo.type()), opts),item) if allfields or fieldinfo.name() in fieldslist: self.listview.setSelected(item,True) tqt.TQObject.connect(self.okbtn, tqt.TQ_SIGNAL("clicked()"), self.okClicked) def okClicked(self): selitems = [] item = self.listview.firstChild() while item: if item.isSelected(): selitems.append(str(item.text(0))) item = item.nextSibling() self.mainwidget.fieldedit.setText(",".join(selitems)) self.close() class MainWidget(tqt.TQHBox): def __init__(self,plugin,dialog,parent): from TQt import tqt from TQt import tqtsql tqt.TQHBox.__init__(self,parent) self.dialog = dialog self.plugin = plugin self.connectionbox = tqt.TQVBox(parent) self.connectionbox.setSpacing(2) driverbox = tqt.TQHBox(self.connectionbox) driverlabel = tqt.TQLabel("Driver:",driverbox) self.driveredit = tqt.TQComboBox(driverbox) for driver in tqtsql.TQSqlDatabase.drivers(): self.driveredit.insertItem(driver) if self.plugin.options['driver'] == driver: self.driveredit.setCurrentItem(self.driveredit.count() - 1) driverlabel.setBuddy(self.driveredit) driverbox.setStretchFactor(self.driveredit,1) hostbox = tqt.TQHBox(self.connectionbox) hostlabel = tqt.TQLabel("Hostname:",hostbox) self.hostedit = tqt.TQLineEdit(self.plugin.options['hostname'],hostbox) hostlabel.setBuddy(self.hostedit) hostbox.setStretchFactor(self.hostedit,1) portbox = tqt.TQHBox(self.connectionbox) portlabel = tqt.TQLabel("Port:",portbox) self.portedit = tqt.TQLineEdit(str(self.plugin.options['port']),portbox) portlabel.setBuddy(self.portedit) portbox.setStretchFactor(self.portedit,1) userbox = tqt.TQHBox(self.connectionbox) userlabel = tqt.TQLabel("Username:",userbox) self.useredit = tqt.TQLineEdit(self.plugin.options['username'],userbox) userlabel.setBuddy(self.useredit) userbox.setStretchFactor(self.useredit,1) passbox = tqt.TQHBox(self.connectionbox) passlabel = tqt.TQLabel("Password:",passbox) self.passedit = tqt.TQLineEdit(self.plugin.options['password'],passbox) self.passedit.setEchoMode(tqt.TQLineEdit.Password) passlabel.setBuddy(self.passedit) passbox.setStretchFactor(self.passedit,1) dbbox = tqt.TQHBox(self.connectionbox) dblabel = tqt.TQLabel("Database:",dbbox) self.dbedit = tqt.TQLineEdit(self.plugin.options['database'],dbbox) dblabel.setBuddy(self.dbedit) dbbox.setStretchFactor(self.dbedit,1) statusbar = tqt.TQHBox(parent) statusbar.setSpacing(2) statusbar.setStretchFactor(tqt.TQWidget(statusbar),1) self.connectbtn = tqt.TQPushButton("Connect",statusbar) tqt.TQObject.connect(self.connectbtn, tqt.TQ_SIGNAL("clicked()"),self.connectClicked) self.disconnectbtn = tqt.TQPushButton("Disconnect",statusbar) self.disconnectbtn.setEnabled(False) tqt.TQObject.connect(self.disconnectbtn, tqt.TQ_SIGNAL("clicked()"),self.disconnectClicked) tablebox = tqt.TQHBox(parent) tablelabel = tqt.TQLabel("Table:",tablebox) self.tableedit = tqt.TQLineEdit(self.plugin.options['table'],tablebox) tqt.TQObject.connect(self.tableedit, tqt.TQ_SIGNAL("textChanged(const TQString&)"), self.tableEditChanged) self.tablebtn = tqt.TQPushButton("...",tablebox) self.tablebtn.setEnabled(False) tqt.TQObject.connect(self.tablebtn, tqt.TQ_SIGNAL("clicked()"), self.tableBtnClicked) tablelabel.setBuddy(self.tableedit) tablebox.setStretchFactor(self.tableedit,1) fieldbox = tqt.TQHBox(parent) fieldlabel = tqt.TQLabel("Fields:",fieldbox) self.fieldedit = tqt.TQLineEdit(self.plugin.options['fields'],fieldbox) self.fieldbtn = tqt.TQPushButton("...",fieldbox) self.fieldbtn.setEnabled(False) tqt.TQObject.connect(self.fieldbtn, tqt.TQ_SIGNAL("clicked()"), self.fieldBtnClicked) fieldlabel.setBuddy(self.fieldedit) fieldbox.setStretchFactor(self.fieldedit,1) if self.plugin.plugintype == "Source": box = tqt.TQHBox(parent) wherelabel = tqt.TQLabel("Where:",box) self.whereedit = tqt.TQLineEdit(self.plugin.options['where'],box) wherelabel.setBuddy(self.whereedit) box.setStretchFactor(self.whereedit,1) elif self.plugin.plugintype == "Destination": class OperationBox(tqt.TQVBox): def __init__(self, mainwidget, parent): self.mainwidget = mainwidget tqt.TQVBox.__init__(self, parent) opbox = tqt.TQHBox(self) operationlabel = tqt.TQLabel("Operation:",opbox) self.mainwidget.operationedit = tqt.TQComboBox(opbox) for op in ('Insert','Update'): self.mainwidget.operationedit.insertItem(op) if self.mainwidget.plugin.options['operation'] == op: self.mainwidget.operationedit.setCurrentItem(self.mainwidget.operationedit.count() - 1) operationlabel.setBuddy(self.mainwidget.operationedit) opbox.setStretchFactor(self.mainwidget.operationedit,1) self.box = None tqt.TQObject.connect(self.mainwidget.operationedit, tqt.TQ_SIGNAL("activated(int)"), self.operationActivated) self.operationActivated() def operationActivated(self, **args): if self.box: self.box.hide() self.box.destroy() self.box = None def showInsert(self): pass def showUpdate(self): self.box = tqt.TQHBox(self) indexlabel = tqt.TQLabel("Indexfield:", self.box) self.mainwidget.indexedit = tqt.TQLineEdit(self.mainwidget.plugin.options['indexfield'], self.box) indexlabel.setBuddy(self.mainwidget.indexedit) self.box.setStretchFactor(self.mainwidget.indexedit,1) { 0: showInsert, 1: showUpdate, }[ self.mainwidget.operationedit.currentItem() ](self) if self.box != None: self.box.show() OperationBox(self,parent) def tableEditChanged(self,text): if self.plugin.database != None and self.plugin.database.isOpen(): if str(text) in self.plugin.database.tables(): self.fieldbtn.setEnabled(True) return self.fieldbtn.setEnabled(False) def tableBtnClicked(self): dialog = TableDialog(self) dialog.show() def fieldBtnClicked(self): dialog = FieldsDialog(self) dialog.show() def updateConnectState(self): connected = self.plugin.database != None and self.plugin.database.isOpen() self.connectionbox.setEnabled(not connected) self.connectbtn.setEnabled(not connected) self.disconnectbtn.setEnabled(connected) self.tablebtn.setEnabled(connected) self.tableEditChanged(self.tableedit.text()) def getOptionValue(self,optionname): try: if optionname == 'driver': return str(self.driveredit.currentText()) if optionname == 'hostname': return str(self.hostedit.text()) if optionname == 'port': return str(self.portedit.text()) if optionname == 'username': return str(self.useredit.text()) if optionname == 'password': return str(self.passedit.text()) if optionname == 'database': return str(self.dbedit.text()) if optionname == 'table': return str(self.tableedit.text()) if optionname == 'fields': return str(self.fieldedit.text()) if optionname == 'where': return str(self.whereedit.text()) if optionname == 'operation': return str(self.operationedit.currentText()) if optionname == 'indexfield': return str(self.indexedit.text()) except: import traceback print("".join( traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) )) return "" def connectClicked(self): if self.plugin.database != None and self.plugin.database.isOpen(): print("already connected. not needed to reconnect...") self.updateConnectState() return True print("trying to connect...") from TQt import tqtsql drivername = str(self.driveredit.currentText()) print("drivername: %s" % drivername) connectionname = "CopyCenter%s" % self.plugin.plugintype print("connectionname: %s" % connectionname) self.plugin.database = tqtsql.TQSqlDatabase.addDatabase(drivername,connectionname) if not self.plugin.database: tqt.TQMessageBox.critical(self,"Failed to connect","Failed to create database for driver \"%s\"" % drivername) return False hostname = str(self.hostedit.text()) self.plugin.database.setHostName(hostname) portnumber = int(str(self.portedit.text())) self.plugin.database.setPort(portnumber) username = str(self.useredit.text()) self.plugin.database.setUserName(username) password = str(self.passedit.text()) self.plugin.database.setPassword(password) databasename = str(self.dbedit.text()) self.plugin.database.setDatabaseName(databasename) if not self.plugin.database.open(): tqt.TQMessageBox.critical(self,"Failed to connect","%s

%s
" % (self.plugin.database.lastError().driverText(),self.plugin.database.lastError().databaseText())) return False print("database is opened now!") self.updateConnectState() return True def disconnectClicked(self): print("trying to disconnect...") if self.plugin.database: self.plugin.database.close() self.plugin.database = None print("database is closed now!") self.updateConnectState() plugin.widget = MainWidget(plugin,self.dialog,parent) return plugin.widget