#!/usr/bin/env python

import sys
from qt import *
from qtsql import *

from sqlex import SqlEx
from connect import ConnectDialog

from dbpar import *

TRUE = 1
FALSE = 0

def showError(err, parent):
    errStr = QString("The database reported an error:\n\n")
    if not err.databaseText().isEmpty():
        errStr.append(err.databaseText())
        errStr.append("\n")
    if not err.driverText().isEmpty():
        errStr.append(err.driverText())
        errStr.append("\n")
    QMessageBox.warning(parent, "Error", errStr)

class CustomSqlCursor(QSqlCursor):
    def __init__(self, query = None, autopopulate = TRUE, db = None):
        QSqlCursor.__init__(self, None, autopopulate, db)
        self.execQuery(query)
        if self.isSelect() and autopopulate:
            fields = self.driver().recordInfo(self)
            for f in fields:
                self.append(f)
        self.setMode(QSqlCursor.ReadOnly)

    def select(self, filter, sort = QSqlIndex()):
        return self.execQuery(self.lastQuery())

    def primaryIndex(self, prime = TRUE):
        return QSqlIndex()

    def insert(self, invalidate = TRUE):
        return FALSE

    def update(self, invalidate = TRUE):
        return FALSE

    def delRecords(self, invalidate = TRUE):
        return FALSE

    def setName(self, name, autopopulate = TRUE):
        return


class MainWindow(SqlEx):
    def __init__(self,parent = None,name = None,fl = 0):
        SqlEx.__init__(self,parent,name,fl)
        self.conDiag = ConnectDialog(self, "Connection Dialog", TRUE)
        self.firstconn = TRUE

    def dbConnect(self):
        if self.firstconn:
            self.firstconn = FALSE
            self.conDiag.editUsername.setText(DB_USERNAME)
            self.conDiag.editPassword.setText(DB_PASSWORD)
            self.conDiag.editHostname.setText(DB_HOSTNAMES[0])
            self.conDiag.editDatabase.setText(DB_DATABASES[0])
            for i in range(self.conDiag.comboDriver.count()):
                if str(self.conDiag.comboDriver.text(i)) == DB_DRIVER:
                    self.conDiag.comboDriver.setCurrentItem(i)
                    break
        if self.conDiag.exec_loop() != QDialog.Accepted:
            return
        if self.dt.sqlCursor():
            self.dt.setSqlCursor()

        # close old connection (if any)
        if QSqlDatabase.contains("SqlEx"):
            oldDb = QSqlDatabase.database("SqlEx")
            oldDb.close()
            QSqlDatabase.removeDatabase("SqlEx")

        # open the new connection
        db = QSqlDatabase.addDatabase(self.conDiag.comboDriver.currentText(), "SqlEx")
        if not db:
            QMessageBox.warning(self, "Error", "Could not open database")
            return

        db.setHostName(self.conDiag.editHostname.text())
        db.setDatabaseName(self.conDiag.editDatabase.text())
        db.setPort(self.conDiag.portSpinBox.value())
        if not db.open(self.conDiag.editUsername.text(),
                       self.conDiag.editPassword.text()):
            showError(db.lastError(), self)
            return

        self.lbl.setText("Double-Click on a table-name to view the contents")
        self.lv.clear()
        
        tables = db.tables()
        for t in tables:
            lvi = QListViewItem(self.lv, t)
            fields = db.recordInfo(t)
            for f in fields:
                req = "?"
                if f.isRequired() > 0:
                    req = "Yes"
                elif f.isRequired() == 0:
                    req = "No"
                fi = QListViewItem(lvi, f.name(), QVariant.typeToName(f.type()), req)
                lvi.insertItem(fi)
            self.lv.insertItem(lvi)

        self.submitBtn.setEnabled(TRUE)

    def execQuery(self):
        cursor = CustomSqlCursor(self.te.text(), TRUE,
                                 QSqlDatabase.database("SqlEx", TRUE))
        if cursor.isSelect():
            self.dt.setSqlCursor(cursor, TRUE, TRUE)
            self.dt.refresh()
            txt = QString("Query OK")
            if cursor.size() >= 0:
                txt.append(", returned rows: %s" % cursor.size())
            self.lbl.setText(txt)
        else:
            if not cursor.isActive():
                # an error occured
                showError(cursor.lastError(), self)
            else:
                self.lbl.setText("Query OK, affected rows: %s" %
                                 cursor.numRowsAffected())

    def showTable(self, item):
        i = item.parent()
        if not i:
            i = item
        cursor = QSqlCursor(i.text(0), TRUE, QSqlDatabase.database("SqlEx", TRUE))
        self.dt.setSqlCursor(cursor, TRUE, TRUE)
        self.dt.setSort(cursor.primaryIndex())
        self.dt.refresh(QDataTable.RefreshAll)
        self.lbl.setText("Displaying table %s" % i.text(0))


if __name__ == "__main__":
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = MainWindow()
    a.setMainWidget(w)
    w.show()
    a.exec_loop()

