from twisted.internet.defer import Deferred

from twisted.internet import abstract
from pyPgSQL import libpq

class PgAsyncConn(abstract.FileDescriptor):
    def __init__(self):
        abstract.FileDescriptor.__init__(self)

        # PostgreSQL stuff
        self.conn = libpq.PQconnectdb("dbname=isi")
        self.conn.setnonblocking(1)
        self.fileno = lambda: self.conn.socket
        self.startReading()

    def write(self, data):
        print "writing", data

    def query(self, *args, **kwargs):
        print "sending query ..."
        self.deferred = Deferred()
        self.conn.sendQuery(*args)
        print "query sent."
        return self.deferred
        
    def doRead(self):
        self.conn.consumeInput()
        print "consumed!"
        if not self.conn.isBusy:
            print "data available"
            res = self.conn.getResult()
            print "got result.", res
            assert res is not None

            bla = self.conn.getResult()
            assert bla is None
            print "query sucessfully processed."

            # call callback here
            width = range(res.nfields)
            height = range(res.ntuples)
            results = [ [None for x in width] for y in height ]
            for y in height:
                row = results[y]
                for x in width:
                    row[x] = res.getvalue(y, x)
            print "results!", results
            self.deferred.callback(results)

    def connectionLost(self, reason):
        """The connection was lost.
        """
        self.conn.finish()
        self.deferred.errback(reason)

import sys
from twisted.python import log

def doit():
	c = PgAsyncConn()
	return c.query('select * from isi_users').addCallbacks(sys.stdout.write, log.err)