Changeset 796

Show
Ignore:
Timestamp:
03/06/07 22:28:16 (1 year ago)
Author:
mfenniak
Message:

throw away some work on db-api compliant code, and begin working on a more natural interface given the pg fe protocol.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pg8000/trunk/pg8000.py

    r795 r796  
    44import md5 
    55 
    6 apilevel = '2.0' 
    7 threadsafety = 1 
    8 paramstyle = 'named' # check this later 
    9  
    106class Warning(StandardError): 
    117    pass 
     
    3834    pass 
    3935 
    40 class Cursor(object): 
    41     def __init__(self, c): 
    42         self.c = c 
    43         self.arraysize = 1 
    44  
    45     def getDescription(self): 
    46         return None 
    47     description = property(getDescription, None, None) 
    48  
    49     def getRowCount(self): 
    50         return -1 
    51     rowcount = property(getRowCount, None, None) 
    52  
    53     def callproc(self, procname, *params): 
    54         pass 
    55  
    56     def close(self): 
    57         pass 
    58  
    59     def execute(self, operation, *params): 
    60         self.row_desc = self.c.query(operation) 
    61         #for f in row_desc.fields: 
    62         #    print repr(f) 
    63  
    64     def executemany(self, operation, seq): 
    65         pass 
    66  
    67     def fetchone(self): 
    68         row = self.c.getrow() 
    69         if row == None: 
    70             return None 
    71         return [Types.convert(row.fields[i], self.row_desc.fields[i]) for i in range(len(row.fields))] 
    72  
    73     def fetchmany(self, size=None): 
    74         if size == None: 
    75             size = self.arraysize 
    76         pass 
    77  
    78     def fetchall(self): 
    79         retval = [] 
    80         while 1: 
    81             row = self.fetchone() 
    82             if row == None: 
    83                 break 
    84             retval.append(row) 
     36 
     37class DataIterator(object): 
     38    def __init__(self, connection): 
     39        self.connection = connection 
     40        if self.connection.iterate_dicts: 
     41            self.method = Connection.read_dict 
     42        else: 
     43            self.method = Connection.read_tuple 
     44 
     45    def __iter__(self): 
     46        return self 
     47 
     48    def next(self): 
     49        retval = self.method(self.connection) 
     50        if retval == None: 
     51            raise StopIteration() 
    8552        return retval 
    8653 
    87     def setinputsizes(self, sizes): 
    88         pass 
    89  
    90     def setoutputsize(self, size, *columns): 
    91         pass 
    92  
    9354 
    9455class Connection(object): 
     56 
     57    iterate_dicts = False 
     58 
    9559    def __init__(self, host, user, port=5432, database=None, password=None): 
     60        self._row_desc = None 
    9661        try: 
    9762            self.c = Protocol.Connection(host, port) 
     
    10065        except socket.error, e: 
    10166            raise InterfaceError("communication error", e) 
    102         self._cursor = Cursor(self.c) 
    103  
    104     def close(self): 
     67 
     68    def execute(self, command, *args, **kwargs): 
     69        pass 
     70 
     71    def query(self, query, *args, **kwargs): 
     72        self._row_desc = self.c.query(query) 
     73 
     74    def _fetch(self): 
     75        row = self.c.getrow() 
     76        if row == None: 
     77            return None 
     78        return tuple([Types.convert(row.fields[i], self._row_desc.fields[i]) for i in range(len(row.fields))]) 
     79 
     80    def read_dict(self): 
     81        row = self._fetch() 
     82        if row == None: 
     83            return row 
     84        retval = {} 
     85        for i in range(len(self._row_desc.fields)): 
     86            col_name = self._row_desc.fields[i]['name'] 
     87            if retval.has_key(col_name): 
     88                raise InterfaceError("cannot return dict of row when two columns have the same name (%r)" % (col_name,)) 
     89            retval[col_name] = row[i] 
     90        return retval 
     91 
     92    def read_tuple(self): 
     93        row = self._fetch() 
     94        if row == None: 
     95            return row 
     96        return row 
     97 
     98    def __iter__(self): 
     99        return DataIterator(self) 
     100 
     101    def begin(self): 
    105102        pass 
    106103 
     
    110107    def rollback(self): 
    111108        pass 
    112  
    113     def cursor(self): 
    114         return self._cursor 
    115  
    116 connect = Connection 
    117109 
    118110 
     
    240232            return "<ErrorResponse %s %s %r>" % (self.severity, self.code, self.msg) 
    241233 
     234        def createException(self): 
     235            return ProgrammingError(self.severity, self.code, self.msg) 
     236 
    242237        def createFromData(data): 
    243238            args = {} 
     
    267262                data = data[null+1:] 
    268263                field["table_oid"], field["column_attrnum"], field["type_oid"], field["type_size"], field["type_modifier"], field["format"] = struct.unpack("!ihihih", data[:18]) 
    269                 data = data[19:] 
     264                data = data[18:] 
    270265                fields.append(field) 
    271266            return Protocol.RowDescription(fields) 
     
    345340                    self.state = "ready" 
    346341                    break 
     342                elif isinstance(msg, Protocol.ErrorResponse): 
     343                    raise msg.createException() 
    347344 
    348345        def query(self, qs): 
     
    354351                return msg 
    355352            elif isinstance(msg, Protocol.ErrorResponse): 
    356                 raise ProgrammingError(msg.severity, msg.code, msg.msg
     353                raise msg.createException(
    357354            else: 
    358355                raise InternalError("RowDescription expected, other message recv'd") 
  • pg8000/trunk/pg8000-test.py

    r794 r796  
    33import pg8000 
    44 
    5 db = pg8000.connect(host='localhost', user='mfenniak') 
    6 cur = db.cursor() 
     5db = pg8000.Connection(host='joy.fenniak.net', user='Mathieu Fenniak', password='hello', database='software') 
     6db.iterate_dicts = True 
    77 
    8 cur.execute("SELECT 5000+1, true, false, '2001-01-01 01:01:01'::timestamp") 
    9 res = cur.fetchall() 
    10 print repr(res) 
     8print "begin query..." 
     9db.query("SELECT 5000 + 1, True as pg_stuff, False, '2000-01-02 03:04:05'::timestamp") 
     10for row in db: 
     11    print repr(row) 
     12print "end query..." 
    1113