python-adodb-2.10/0000755000175000017500000000000011044140676012447 5ustar dgildgilpython-adodb-2.10/adodb.gif0000644000175000017500000000210307647041436014213 0ustar dgildgilGIF89aX3dd k++fAAvRRRも99ӠffZohJqqKK f((~XX11p::Bkk!!zzzfRRr<!.,XADrl:Ш4Z0%,O&!xL.Te]8awL~~ !B V,,!! % (!% &! ' $" !$& `X&Yt H `̃x a U˷߯Z @@`a` 8h,!3hmdLffN&gy@k9B'pr盀ڧf"I':'} zli:ZV褖IzZ(⩨/1j|)ꥉI蟈 &멭Z餄Z&RizT{*鮆ztЁ@v`*Ъ'목ތ0Ⱦ,ko,H 7G,T -?e! ,$lX|0,;python-adodb-2.10/LICENSE.txt0000644000175000017500000000301610220525130014255 0ustar dgildgil BSD Style-License ================= Copyright (c) 2004-2005 John Lim All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the John Lim nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOHN LIM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.python-adodb-2.10/adodb2.gif0000644000175000017500000000266207647041436014307 0ustar dgildgilGIF89af/ٶӰЧǠƒozzqqkkddXXRRKKNNNAA::9911++((~!!zvrophf k ffZRJB<3!1,f/@pH,Ȥrl2ШT`HWUF `/*RWtJf{k:H4Bc$}yP|RvwP_| sP{wb\sr y QPikuRsu|RZw‰~eWW|P~QW_*kVf@)s)R7=j#JH3jȱǏ3\aR<˗0cʜI!DH! 2@ТH*]ʴӧPz9O,`a*`Cx KٳhӪ]˖%RX!D9G(}^aC྄p_8c7.QρQP :(qDh"08B"$7 B0丢wEf!JE) ¡7p;7˗4bCJX (}w(߅Qiy$D P(@|@AfDv x]p Q5B -ajNXPzpGEh2JA$0dĊ-J P8CxV*jޘ6.%b pZB#m`RP~b02Q[CHD>"_). N}bw䜝`)x5xDr 訧KjJ8G tr矶0kO2!v_* * s*,ڡ nkJ|y!F  QP4Vzj!k麢*-Fd!%@"Y*u?~HԽ׍^팯x٢gNy/;뀗^8f_޶ܣW>D;8g;޽gS_ߝs9KzʗN|3 * @OBK\0:'H ZV;" GH-8aiXafH8̡wCE UHL"PlZ;python-adodb-2.10/adodb/0000755000175000017500000000000011044140676013520 5ustar dgildgilpython-adodb-2.10/adodb/adodb.py0000644000175000017500000004516711037372232015155 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## __author__ = "John Lim (jlim#natsoft.com)" __credits__ = "(c) 2004-2008 John Lim" import exceptions,sys,re from datetime import datetime try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 MapTypes = { 'VARCHAR' : 'C', 'VARCHAR2' : 'C', 'CHAR' : 'C', 'C' : 'C', 'STRING' : 'C', 'NCHAR' : 'C', 'NVARCHAR' : 'C', 'VARYING' : 'C', 'BPCHAR' : 'C', 'CHARACTER' : 'C', 'INTERVAL' : 'C', # Postgres ## 'LONGCHAR' : 'X', 'TEXT' : 'X', 'NTEXT' : 'X', 'M' : 'X', 'X' : 'X', 'CLOB' : 'X', 'NCLOB' : 'X', 'LVARCHAR' : 'X', ## 'BLOB' : 'B', 'IMAGE' : 'B', 'BINARY' : 'B', 'VARBINARY' : 'B', 'LONGBINARY' : 'B', 'B' : 'B', ## 'YEAR' : 'D', # mysql 'DATE' : 'D', 'D' : 'D', ## 'TIME' : 'T', 'TIMESTAMP' : 'T', 'DATETIME' : 'T', 'TIMESTAMPTZ' : 'T', 'T' : 'T', ## 'BOOL' : 'L', 'BOOLEAN' : 'L', 'BIT' : 'L', 'L' : 'L', ## 'COUNTER' : 'R', 'R' : 'R', 'SERIAL' : 'R', # ifx 'INT IDENTITY' : 'R', ## 'INT' : 'I', 'INTEGER' : 'I', 'INTEGER UNSIGNED' : 'I', 'SHORT' : 'I', 'TINYINT' : 'I', 'SMALLINT' : 'I', 'I' : 'I', ## 'LONG' : 'N', # interbase is numeric, oci8 is blob 'BIGINT' : 'N', # this is bigger than PHP 32-bit integers 'DECIMAL' : 'N', 'DEC' : 'N', 'REAL' : 'N', 'DOUBLE' : 'N', 'DOUBLE PRECISION' : 'N', 'SMALLFLOAT' : 'N', 'FLOAT' : 'N', 'NUMBER' : 'N', 'NUM' : 'N', 'NUMERIC' : 'N', 'MONEY' : 'N', ## informix 9.2 'SQLINT' : 'I', 'SQLSERIAL' : 'I', 'SQLSMINT' : 'I', 'SQLSMFLOAT' : 'N', 'SQLFLOAT' : 'N', 'SQLMONEY' : 'N', 'SQLDECIMAL' : 'N', 'SQLDATE' : 'D', 'SQLVCHAR' : 'C', 'SQLCHAR' : 'C', 'SQLDTIME' : 'T', 'SQLINTERVAL' : 'N', 'SQLBYTES' : 'B', 'SQLTEXT' : 'X'} class adodb_iter: cursor = None def __iter__(self): return self def next(self): if self.cursor.EOF: raise StopIteration ret = self.cursor.fields self.cursor.MoveNext() return ret def NewADOConnection(modulename): if modulename.find(':') >= 0: # handle connection string of the form driver://user:pwd@server/database # where user, pwd, database are all optional match=re.match('([^:]*)://(.*)/([^\?]*)\?*(.*)', modulename) if match: gps = match.groups() server = '' user = '' pwd = '' db = '' if len(gps) >= 1: modulename = gps[0] if len(gps) >= 2: mid = gps[1] if mid.find('@') >= 0: upwd,server = mid.split('@') if mid.find(':') >= 0: user,pwd = upwd.split(':') else: if mid.find(':') >= 0: user,pwd = mid.split(':') else: server = mid if len(gps) >= 3: db = gps[2] #print server, user, pwd, db conn = NewADOConnection(modulename) conn.Connect(server,user,pwd,db) return conn if modulename == 'oracle': modulename = 'oci8' try: modulename = 'adodb_'+modulename module = __import__(modulename,globals(), None, [modulename]) except ImportError: return None klass = vars(module)[modulename] return klass() def ADONewConnection(modulename): return NewADOConnection(modulename) class ADOConnection: databaseType = None dataProvider = 'native' host = None user = None password = None database = None replaceQuote = "\\'" useExceptions = True debug = None getLOBs = True hasRowCount = True metaColSQL = 'Invalid' fmtDate = '%Y-%m-%d' fmtTimeStamp = '%Y-%m-%d %H:%M:%S' _errormsg = '' _errno = 0 _conn = None _autocommit = True _connected = True def __init__(self): pass def Connect(self,host=None,user=None,password=None,database=None): self.database = database self.host = host self.user = user self.password = password self._connect(host,user,password,database) return bool(self._conn) def IsConnected(self): return bool(self._conn) def DriverInfo(self): try: m = self.Module() print "Driver =",self.databaseType print "API Level =",m.apilevel print "Param Style =",m.paramstyle print "Thread Safety =",m.threadsafety," (0=none, 1=module, 2=connections, 3=cursors)" print "--------------" except: print "???????" def ErrorMsg(self): return self._errormsg def ErrorNo(self): return self._errno def qstr(self,s): if (self.replaceQuote == "\\'"): s = str(s).replace('\\','\\\\') return "'"+str(s).replace("'", self.replaceQuote)+"'" def quote(self,s): return "'"+str(s).replace("'", self.replaceQuote)+"'" def addq(self,s): if (self.replaceQuote == "\\'"): s = str(s).replace('\\','\\\\') return str(s).replace("'", self.replaceQuote) def Conn(self): return self._conn def _query(self,sql,params=None,_cursor=None): try: if _cursor == None: _cursor = self._conn.cursor() if self.debug: s = "(%s): %s" % (self.databaseType, sql) if type(self.debug) is str: try: f = file(self.debug,'w') f.write(s+"\n") f.close() except: pass elif long(self.debug) == 2: print "
"+s.replace('&','&').replace('<','<')+"
" else: print s; #if debug if params == None: _cursor.execute(sql) else: _cursor.execute(sql,params) self._errormsg = '' self._errno = 0 except StandardError, err: self._errormsg = str(err) self._errno = -1 if self.useExceptions: # use default python error handling raise sys.exc_info()[0] ,str(err)+': '+sql _cursor = None return _cursor def SelectLimit(self,sql,limit,offset=-1,params=None): pass def Execute(self,sql,params=None): c = self._query(sql,params) if c == None: return None rs = self._newcursor(c) return rs def UpdateBlob(self,table,field,blob,where,blobtype='BLOB'): raise StandardError, 'UpdateBlob not supported' def UpdateBlobFile(self,table,field,filepath,where,blobtype='BLOB'): f = file(filepath, 'rb') data = f.read() f.close() self.UpdateBlob(table,field,data,where,blobtype) def UpdateClob(self,table,field,blob,where): self.UpdateBlob(table,field,blob,where,'CLOB') def GetRows(self,sql,params=None): return self.GetAll(sql,params) def GetArray(self,sql,params=None): return self.GetAll(sql,params) def GetAll(self,sql,params=None): c = self._query(sql,params) if c == None: return None all = c.fetchall() c.close() return all def GetRow(self,sql,params=None): c = self._query(sql,params) if c == None: return None c.close() return c.fetchone() def GetRow(self,sql,params=None): c = self._query(sql,params) if c == None: return None row = c.fetchone() c.close() return row def GetOne(self,sql,params=None): c = self._query(sql,params) if c == None: return None arr = c.fetchone() c.close() if (arr == None): return None return arr[0] def GetCol(self, sql, params=None): rs = self.Execute(sql,params) arr = [] while not rs.EOF: arr.append(rs.fields[0]) rs.MoveNext() rs.Close() return arr def GetAssoc(self, sql, params=None): rs = self.Execute(sql,params) dict = {} if rs.EOF: return None if len(rs.fields) == 2: while not rs.EOF: dict[rs.fields[0]] = rs.fields[1] rs.MoveNext() elif len(rs.fields)>2: while not rs.EOF: dict[rs.fields[0]] = rs.fields[1:] rs.MoveNext() else: while not rs.EOF: dict[rs.fields[0]] = None rs.MoveNext() return dict def GetDict(self, sql, params=None): return self.GetAssoc(sql,params) def BeginTrans(self): pass def CommitTrans(self): pass def RollbackTrans(self): pass def Close(self): try: if self._conn != None: self._conn.close() except: pass self._conn = None def DBDate(self,d): return "'%s'" % d.strftime(self.fmtDate) def DBTimeStamp(self,d): return "'%s'" % d.strftime(self.fmtTimeStamp) _redate = None # compiled regex # convert iso format date to python timestamp def Date(self,s): dates = str(s) if self._redate == None: self._redate = re.compile("^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})") match = self._redate.search(dates) if not match: return None year = long(match.group(1)) month = long(match.group(2)) day = long(match.group(3)) return datetime(year, month, day) _rets = None # compiled regex # convert iso format timestamp to python timestamp def TimeStamp(self,s): ts = str(s) if self._rets == None: self._rets = re.compile("^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,5})") match = self._rets.search(ts) if not match: return self.Date(ts) year = long(match.group(1)) month = long(match.group(2)) day = long(match.group(3)) hour = long(match.group(4)) min = long(match.group(5)) sec = long(float(match.group(6).strip())) # Python type-nazis return datetime(year, month, day, hour, min, sec) def MetaType(self, dbtype): global MapTypes dbtype = dbtype.upper() if MapTypes.has_key(dbtype): return MapTypes[dbtype] return 'N' def MetaColumns(self, table): sql = self.metaColSQL % table return self.GetAll(sql) class ADOCursor: _cursor = None fields = None EOF = False _rowcount = 0 _isselect = False _insertid = 0 _conn = None def __init__(self,rs,conn,norowcount=False): self._cursor = rs self._conn = conn if norowcount: self._rowcount = -1 else: self._rowcount = rs.rowcount try: self.MoveNext() self._isselect = True except: pass # not a select statement self.EOF = (self.fields == None) def __iter__(self): iter = adodb_iter() iter.cursor = self return iter def RecordCount(self): return self._rowcount def MoveNext(self): self.fields = self._cursor.fetchone() self.EOF = (self.fields == None) return self.EOF def FetchRow(self): row = self.fields self.fields = self._cursor.fetchone() self.EOF = (self.fields == None) return row # returns a tuple of the form (name, type_code,display_size, internal_size, precision, scale,null_ok) # note: databases could return name in upper or lower-case def FetchField(self,row): #print self._cursor.description if len(self._cursor.description) <= row: return None return self._cursor.description[row] def Affected_Rows(self): if self._rowcount >= 0: return self._rowcount return 0 def Insert_ID(self): return self._insertid def Cursor(self): return self._cursor def GetRowAssoc(self,upper=1): d = {} i = 0 desc = self._cursor.description if upper: for i in xrange(0,len(self.fields)): d[desc[i][0].upper()] = self.fields[i] elif not upper: for i in xrange(0,len(self.fields)): d[desc[i][0].lower()] = self.fields[i] else: for i in xrange(0,len(self.fields)): d[desc[i][0]] = self.fields[i] return d def Close(self): if self._cursor: self._cursor.close() self._cursor = None #=========================================================== # UNIT TESTING #=========================================================== def _Test_Eq(testid, correct, testval, errmsg=''): if correct == testval: print "Passed Test: "+testid else: print "" print "********* Failed Test: "+testid print "********************** "+str(errmsg) print "********************** expected="+str(correct) print "********************** actual="+str(testval) def Test_Blob(db): import os src = 'c:/lensserver.gif' dest = 'c:/testpy1.gif' try: os.unlink(dest) except: pass saved = db.debug saveb = db.getLOBs db.debug = True db.getLOBs = True db.UpdateBlobFile('photos','photo',src,'id=1') data = db.GetOne('select photo from photos where id=1') f = file(dest,'wb') f.write(data) f.close() rs = db.Execute('select * from photos') while not rs.EOF: print 'Fields=',rs.fields rs.MoveNext() print "=======================" rows = db.GetAll('select * from photos where id<=1') print rows db.getLOBs = saveb db.debug = saved def Test(db,debug=False): db.DriverInfo() if False: d = db.Date('2004-03-21') print '2004-03-21=',d d = db.TimeStamp('2004-03-22 12:50:51') print '2004-03-22 12:50:51=',d print "DBTimeStamp=", db.DBTimeStamp(d) db.useExceptions = True # use adodb error handling try: sql = 'select * from xadoxyz where 0 < id and id < 3' rs = db.Execute(sql) _Test_Eq('Bad SQL',None, rs, sql) except: print "And you should see an error message indicating bad table was defined: " print "err=",db.ErrorMsg() print "-----" rs = db.Execute('select * from ADOXYZ where 0 < id and id < 3 order by id') while not rs.EOF: print rs.fields rs.MoveNext() print "You should see 2 rows of data here:" rs = db.Execute('select * from adoxyz where 0 < id and id < 3 order by id') print "rows=",rs.RecordCount() while (not rs.EOF): print rs.GetRowAssoc() rs.MoveNext() print "-----" rs = db.Execute('select id,firstname from adoxyz where 0 < id and id < 3 order by id') _Test_Eq("Test FetchField",'FIRSTNAME',rs.FetchField(1)[0].upper()) if (debug): print rs.FetchField(1) cnt = 0 while 1: arr=rs.FetchRow() if arr == None: break cnt += 1 _Test_Eq('Execute 2.0',cnt,arr[0]) _Test_Eq('Execute 2.1',2,cnt) if rs.RecordCount() == -1: print "*** RecordCount not supported: -1" else: _Test_Eq('Execute 2.1 RecordCount',2,rs.RecordCount()) rs = db.Execute("delete from adoxyz where id=997") cnt = rs.Affected_Rows() _Test_Eq('Affected_Rows',1,cnt) ok = db.Execute("insert into adoxyz (id, firstname,lastname) values (997,'python','snake')") if not ok: _Test_Eq('DELETE/INSERT','inserted row','failed insert') row = db.GetRow("select id,firstname from adoxyz where id=997"); _Test_Eq('GetRow',str(997)+' '+'python',str(int(row[0]))+' '+row[1].rstrip(),row) row = db.GetOne("select id,firstname from adoxyz where id=997"); _Test_Eq('GetOne',997,row) rs = db.SelectLimit("select id,firstname from adoxyz",3) cnt = 0 try: for row in rs: cnt += 1 #print rs.fields _Test_Eq('SelectLimit',3,cnt) except: print "Failed Iteration" print sys.exc_info()[1] d = db.GetOne('select created from adoxyz where id=1') d2 = db.TimeStamp(d) _Test_Eq('DBDate',str(d)[:19],str(d2)) if (db.qstr("\\show'boat") != "'\\\\show\\'boat'" and db.qstr("\\show'boat") != "'\\show''boat'"): _Test_Eq('qstr',"qstr(\\show'boat)", db.qstr("\\show'boat")) else: _Test_Eq('qstr','1','1') try: db.debug=True print "Testing GetAssoc" arr = db.GetAssoc('select firstname,lastname from adoxyz') print arr print "Testing GetCol" arr = db.GetCol('select firstname from adoxyz') print arr except: print sys.exc_info()[1] try: print "MetaColumns:" rows = db.MetaColumns('adoxyz') print rows except: print "Failed MetaColumns" print sys.exc_info()[1] try: db.BeginTrans() ok = db.Execute("insert into adoxyz (id, firstname,lastname) values (1997,'python','snake')") db.RollbackTrans() val = db.GetOne('select * from adoxyz where id=1997') _Test_Eq('Rollback Test',None,val) except: print "Failed Rollback Test" print sys.exc_info()[1]python-adodb-2.10/adodb/__init__.py0000644000175000017500000000005410253541770015631 0ustar dgildgil#!/usr/bin/env python from adodb import *python-adodb-2.10/adodb/adodb_oci8.py0000644000175000017500000001355511037372264016100 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb from adodb import ADOConnection,ADOCursor import cx_Oracle # threadsafety=2 (connections) # paramstyle=named (:name) try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_oci8(adodb.ADOConnection): databaseType = 'oci8' dataProvider = 'oci8' replaceQuote = "''" metaColSQL = "select cname,coltype,width from col where tname='%s' order by colno" sysDate = 'trunc(SYSDATE)' sysTimeStamp = 'SYSDATE' NLS_DATE_FORMAT = 'YYYY-MM-DD' ## To include time, use 'RRRR-MM-DD HH24:MI:SS' def __init__(self): pass def Module(self): return cx_Oracle def _connect(self,host=None,user=None,password=None,database=None): if user == None and password == None and database == None: self._conn = cx_Oracle.connect('','',host) else: if host == None: self._conn = cx_Oracle.connect(user,password) else: self._conn = cx_Oracle.connect(user,password,host) self._query("ALTER SESSION SET NLS_DATE_FORMAT='"+self.NLS_DATE_FORMAT+"'") def _newcursor(self,rs): if self._autocommit: self._conn.commit() rs = cursor_oci8(rs,self) if rs._isselect: rs._rowcount = -1 # oci8 does not return recordcount return rs def BeginTrans(self): if self._autocommit: self._autocommit = False def RollbackTrans(self): self._conn.rollback() self._autocommit = True def CommitTrans(self): self._conn.commit() self._autocommit = True # offset not supported def SelectLimit(self,sql,limit,offset=-1,params=None): if offset == -1: return self.Execute("select * from ("+sql+") where rownum <= "+str(limit), params) else: raise StandardError, "SelectLimit does not support offset: " + sql def DBDate(self,d): if d == None: return 'null' return "TO_DATE(%s,'%s')" % (d.strftime(self.fmtDate),self.NLS_DATE_FORMAT) def DBTimeStamp(self,d): if d == None: return 'null' return "TO_DATE(%s,'%s')" % (d.strftime(self.fmtTimeStamp),self.NLS_DATE_FORMAT) def UpdateBlob(self,table,field,blob,where,blobtype='BLOB'): cursor = self._conn.cursor() #self.debug = True if blobtype == 'BLOB': bt = cx_Oracle.BLOB else: bt = cx_Oracle.CLOB cursor.setinputsizes(adodblob = bt) sql = "update %s set %s=:%s WHERE %s" % (table,field,'adodblob',where) self._query(sql,{'adodblob': blob},_cursor = cursor) def GetAll(self,sql,params=None): c = self._query(sql,params) if c == None: return None if self.getLOBs: rows = [] while 1: row = c.fetchone() if row == None: break rows.append(self._fixblobs(c.description,row)) return rows else: return c.fetchall() def GetRow(self,sql,params=None): c = self._query(sql,params) if c == None: return None arr = c.fetchone() return self._fixblobs(c.description,arr) def GetOne(self,sql,params=None): c = self._query(sql,params) if c == None: return None arr = c.fetchone() if (arr == None): return None if (c.description[0][1] == cx_Oracle.BLOB or c.description[0][1] == cx_Oracle.CLOB): return arr[0].read() return arr[0] def _hasblobs(self,description): for fld in description: t = fld[1] if t == cx_Oracle.BLOB or t == cx_Oracle.CLOB: return True return False def _fixblobs(self,description,row): if not row: return row arr = [] i = 0 for fld in description: t = fld[1] if t == cx_Oracle.BLOB or t == cx_Oracle.CLOB: try: lob_fld=row.read() except: arr.append(None) else: arr.append(lob_fld) else: arr.append(row[i]) i += 1 return arr def MetaType(self, dtype): dtype = dtype.upper() if dtype == 'DATE': return 'T' return ADOConnection.MetaType(self, dtype) def MetaColumns(self, table): sql = self.metaColSQL % table.upper() return self.GetAll(sql) class cursor_oci8(adodb.ADOCursor): getLOBs = None def __init__(self,rs,conn): if conn.getLOBs and rs.description: # print rs.description self.getLOBs = conn._hasblobs(rs.description) else: self.getLOBs = False ADOCursor.__init__(self,rs,conn) def MoveNext(self): self.fields = self._cursor.fetchone() self.EOF = (self.fields == None) if self.getLOBs and not self.EOF: self.fields = self._conn._fixblobs(self._cursor.description,self.fields) return self.EOF def FetchRow(self): row = self.fields self.fields = self._cursor.fetchone() self.EOF = (self.fields == None) if self.getLOBs and not self.EOF: self.fields = self._conn._fixblobs(self._cursor.description,self.fields) return row if __name__ == '__main__': db = adodb_oci8() db.Connect('','scott','natsoft') adodb.Test(db) print db.MetaType('date') print db.MetaType('VarChar') print db.MetaType('DECiMAL') #adodb.Test_Blob(db)python-adodb-2.10/adodb/adodb_access.py0000644000175000017500000000212311037372264016464 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,adodb_pyodbc,datetime try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_access(adodb_pyodbc.adodb_pyodbc): databaseType = 'access' dataProvider = 'pyodbc' sysDate = "FORMAT(NOW,'yyyy-mm-dd')" sysTimeStamp = 'NOW' def _newcursor(self,rs): return cursor_access(rs,self) class cursor_access(adodb_pyodbc.cursor_pyodbc): def __init__(self,rs,conn): adodb_pyodbc.cursor_pyodbc.__init__(self,rs,conn) self._rowcount = rs.rowcount if __name__ == '__main__': db = adodb_access() db.Connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\inetpub\\adodb\\northwind.mdb;Uid=Admin;Pwd=;") adodb.Test(db)python-adodb-2.10/adodb/adodb_vfp.py0000644000175000017500000000225411037372264016023 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,adodb_pyodbc,datetime try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_vfp(adodb_pyodbc.adodb_pyodbc): databaseType = 'vfp' dataProvider = 'mxodbc' sysDate = 'date()' sysTimeStamp = 'datetime()' replaceQuote = "'+chr(39)+'" def _newcursor(self,rs): return cursor_vfp(rs,self) class cursor_vfp(adodb_pyodbc.cursor_pyodbc): def __init__(self,rs,conn): adodb_pyodbc.cursor_pyodbc.__init__(self,rs,conn) self._rowcount = rs.rowcount if __name__ == '__main__': db = adodb_vfp() db.Connect("Driver=Microsoft Visual FoxPro Driver;UID=;PWD=;SourceDB=D:\\inetpub\\adodb\\adoxyz.DBC;SourceType=DBC;Exclusive=No;BackgroundFetch=No;Collate=Machine;Null=Yes;Deleted=Yes;") adodb.Test(db)python-adodb-2.10/adodb/adodb_odbc.py0000644000175000017500000000566311037372264016146 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb import odbc,time,re,datetime #Thread Safety= ? undefined #Param Style = ? undefined try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_odbc(adodb.ADOConnection): databaseType = 'odbc' databaseProvider = 'odbc' hasRowCount = False replaceQuote = "''" def __init__(self): pass def Module(self): return odbc #host=host1 user=user1 password=secret port=4341 def _connect(self,host=None,user=None,password=None,database=None): if user == None and password == None and database == None: dsn = host else: dsn = 'dsn='+self.addq(host) if (user != None): dsn += '; uid='+self.addq(user) if (password != None): dsn += '; pwd='+self.addq(password) if (database != None): dsn += '; database='+self.addq(database) self._conn = odbc.odbc(dsn) self._conn.setautocommit(1) def _newcursor(self,rs): return cursor_odbc(rs,self) hasTop = 'TOP' _retop = None def SelectLimit(self,sql,limit,offset=-1,params=None): if self._retop == None: self._retop = re.compile(r'(^\s*select\s+(distinctrow|distinct)?)',re.IGNORECASE) sql = self._retop.sub('\\1 '+self.hasTop+' '+str(limit)+' ',sql) return self.Execute(sql) def BeginTrans(self): if self._autocommit: self._autocommit = False self._conn.setautocommit(0) def RollbackTrans(self): self._conn.rollback() self._autocommit = True def CommitTrans(self): self._conn.commit() self._autocommit = True # (1997, 12, 19, 1, 51, 53) def Date(self,d): return datetime.datetime(long(d[0]),long(d[1]),long(d[2])) def TimeStamp(self,d): d = time.localtime(d) return datetime.datetime(long(d[0]),long(d[1]),long(d[2]),long(d[3]),long(d[4]),long(d[5])) def MetaColumns(self, table): rs = self.Execute("select * from "+table) arr = [] cnt = 0 for ff in rs.fields: f = rs.FetchField(cnt) arr.append((f[0], self.MetaType(f[1]), f[2])) cnt += 1 return arr class cursor_odbc(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn,norowcount=True) if __name__ == '__main__': db = adodb_odbc() db.Connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\inetpub\\adodb\\northwind.mdb;Uid=Admin;Pwd=;") adodb.Test(db)python-adodb-2.10/adodb/adodb_mysql.py0000644000175000017500000000620411037372264016374 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,re import MySQLdb #Thread Safety= 1 module #Param Style = format try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_mysql(adodb.ADOConnection): databaseType = 'mysql' dataProvider = 'mysql' metaColSQL = "SHOW COLUMNS FROM %s" sysDate = 'CURDATE()' sysTimeStamp = 'NOW()' def __init__(self): pass def Module(self): return MySQLdb def _connect(self,host=None,user=None,password=None,database=None): self._conn = MySQLdb.connect(host, user, password, database) def _newcursor(self,rs): return cursor_mysql(rs,self) def BeginTrans(self): if self._autocommit: self._autocommit = False self.Execute('set autocommit=0') #self._conn.Execute('begin') def RollbackTrans(self): self.Execute('rollback') self.Execute('set autocommit=1') self._autocommit = True def SelectLimit(self,sql,limit,offset=-1,params=None): if (offset >= 0): offset = str(offset)+"," else: offset = "" return self.Execute(sql+" LIMIT "+offset+str(limit),params) def CommitTrans(self): self.Execute('commit') self.Execute('set autocommit=1') self._autocommit = True def UpdateBlob(self,table,field,blob,where,blobtype='BLOB'): self.Execute("update %s set %s='%s' WHERE %s" % (table,field,self.addq(blob),where)) def qstr(self,s): return "'%s'" % self._conn.escape_string(s) def MetaColumns(self, table): sql = self.metaColSQL % table rs = self.Execute(sql) arr = [] reFloat = re.compile("^(.+)\\((\\d+),(\\d+)") reInt = re.compile("^(.+)\\((\\d+)") while not rs.EOF: typeF = rs.fields[1] if typeF.find('(')>=0: if typeF.find(',')>=0: m = reFloat.search(typeF) else: m = reInt.search(typeF) if m: gps = m.groups() type = gps[0] size = gps[1] else: type = typeF size = -1 else: type = typeF size = -1 arr.append((rs.fields[0],type,size)) rs.MoveNext() return arr class cursor_mysql(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn) #self._insertid = rs.insert_id() self._insertid = rs.lastrowid if __name__ == '__main__': db = adodb.NewADOConnection('mysql') db.Connect('localhost','root','','northwind') for r in db.Execute('select * from adoxyz'): print r adodb.Test(db)python-adodb-2.10/adodb/adodb_mssql.py0000644000175000017500000000243111037372236016363 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,adodb_pyodbc,datetime try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_mssql(adodb_pyodbc.adodb_pyodbc): databaseType = 'mssql' dataProvider = 'pyodbc' sysDate = 'convert(datetime,convert(char,GetDate(),102),102)' sysTimeStamp = 'GetDate()' replaceQuote = "''" def _newcursor(self,rs): return cursor_mssql(rs,self) class cursor_mssql(adodb_pyodbc.cursor_pyodbc): def __init__(self,rs,conn): adodb_pyodbc.cursor_pyodbc.__init__(self,rs,conn) def Affected_Rows(self): return self._conn.GetOne('select @@rowcount') def Insert_ID(self): return self._conn.GetOne('select @@IDENTITY') if __name__ == '__main__': db = adodb_mssql() db.Connect("PROVIDER=MSDASQL;DRIVER={SQL Server};SERVER=sherkhan;DATABASE=NorthWind;UID=adodb;PWD=natsoft;Trusted_Connection=No") adodb.Test(db)python-adodb-2.10/adodb/adodb_sqlite.py0000644000175000017500000000674210603177312016532 0ustar dgildgil######################################################################## # Vers 2.01 5 May 2006, (c)2005 GlennWashburn (crass#berlios.de) and John Lim # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload # # Requires http://initd.org/tracker/pysqlite # Currently, the host, user, and password connection parameters are ignored and # Affected_Rows() does not return the correct value ######################################################################## import adodb try: import sqlite3 as sqlite except: import pysqlite2.dbapi2 as sqlite try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 # Thread Safety= 2 connections # Param Style = pyformat "%(name)s" class adodb_sqlite(adodb.ADOConnection): databaseType = 'sqlite' dataProvider = 'sqlite' sysDate = "date('now')" sysTimeStamp = "(date('now') || ' ' || time('now'))" metaColSQL = """PRAGMA table_info(%s)""" def __init__(self): pass def Module(self): return sqlite def _connect(self,host=None,user=None,password=None,database=None): # sqlite doesn't use host, user, or password dsn = database self._conn = sqlite.connect(dsn, detect_types=sqlite.PARSE_DECLTYPES) self._autocommit_conn(1) def _newcursor(self,rs): return cursor_sqlite(rs,self) def _autocommit_conn(self, level=1): if level: self._prev_iso_level = self._conn.isolation_level; self._conn.isolation_level = None; else: self._conn.isolation_level = self._prev_iso_level; def SelectLimit(self,sql,limit,offset=-1,params=None): if (offset >= 0): offset = " OFFSET "+str(offset) else: offset = "" return self.Execute(sql+" LIMIT "+str(limit)+offset,params) def BeginTrans(self): if self._autocommit: self._autocommit = False self._autocommit_conn(0) def RollbackTrans(self): self._conn.rollback() self._autocommit = True self._autocommit_conn(1) def CommitTrans(self): self._conn.commit() self._autocommit = True self._autocommit_conn(1) def UpdateBlob(self,table,field,blob,where,blobtype='BLOB'): self.Execute("update %s set %s = ? WHERE %s" % (table,field,where), (sqlite.Binary(blob),)) class cursor_sqlite(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn) self._insertid = rs.lastrowid if __name__ == '__main__': db = adodb_sqlite() db.Connect('localhost','tester','test','test.sqlite') #~ db.Execute('create table adoxyz (id int, firstname text, lastname text, created timestamp default "2005-11-02");') #~ db.Execute("insert into adoxyz values (0, 'test1', 'ltest1', date(\"now\"));") #~ db.Execute("insert into adoxyz values (1, 'test2', 'ltest2', date(\"now\"));") #~ db.Execute("insert into adoxyz values (2, 'test3', 'ltest3', date(\"now\"));") #~ db.Execute("insert into adoxyz values (3, 'test4', 'ltest4', date(\"now\"));") #~ cur = db.Execute("select * from sqlite_master;") #~ print [r for r in cur]; #~ cur = db.Execute("pragma table_info(adoxyz);") #~ print [r for r in cur]; adodb.Test(db) #~ db.Execute('create table photos (id int, photo blob);') #~ db.Execute("insert into photos values (1, NULL);") adodb.Test_Blob(db) python-adodb-2.10/adodb/adodb_pyodbc.py0000644000175000017500000000601411037372264016506 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ####################################################################### import adodb,adodb_odbc,sys ##if sys.platform.find('win32') >= 0: ## import mx.ODBC.Windows ## mxODBC = mx.ODBC.Windows ##else: ## import mx.ODBC.iODBC ## mxODBC = mx.ODBC.iODBC import pyodbc try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_pyodbc(adodb.ADOConnection): databaseType = 'pyodbc' dataProvider = 'pyodbc' hasRowCount = False def __init__(self): pass def Module(self): global mxODBC return mxODBC #host=host1 user=user1 password=secret port=4341 def _connect(self,host=None,user=None,password=None,database=None): if user == None and password == None and database == None: dsn = host else: dsn = 'dsn='+self.addq(host)+';' if (user != None): dsn += ' uid='+self.addq(user)+';' if (password != None): dsn += ' pwd='+self.addq(password)+';' if (database != None): dsn += ' database='+self.addq(database)+';' self._conn = pyodbc.connect(dsn) self._conn.autocommit = True #self._conn.setconnectoption(mxODBC.SQL.AUTOCOMMIT, mxODBC.SQL.AUTOCOMMIT_ON) def _newcursor(self,rs): return cursor_pyodbc(rs,self) def BeginTrans(self): global mxODBC if self._autocommit: self._autocommit = False self._conn.autocommit = self._autocommit def RollbackTrans(self): global mxODBC self._conn.rollback() self._autocommit = True self._conn.autocommit = self._autocommit def CommitTrans(self): global mxODBC self._conn.commit() self._autocommit = True self._conn.autocommit = self._autocommit def MetaColumns(self, table): curs = self._conn.cursor() curs.columns(table) # columns('%', '%', table) ? rs = self._newcursor(curs) arr = [] table = table.upper() while not rs.EOF: if rs.fields[2].upper() == table: arr.append((rs.fields[3],rs.fields[5],rs.fields[6])) rs.MoveNext() return arr class cursor_pyodbc(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn) rs.arraysize=10 if __name__ == '__main__': db = adodb_pyodbc() #db.Connect("Driver=Microsoft Visual FoxPro Driver;UID=;PWD=;SourceDB=D:\\inetpub\\adodb\\adoxyz.DBC;SourceType=DBC;Exclusive=No;BackgroundFetch=No;Collate=Machine;Null=Yes;Deleted=Yes;") db.Connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\inetpub\\adodb\\northwind.mdb;Uid=Admin;Pwd=;") adodb.Test(db) python-adodb-2.10/adodb/adodb_mxoracle.py0000644000175000017500000000326011037372264017040 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,adodb_mxodbc,datetime from adodb import ADOConnection,ADOCursor try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_mxoracle(adodb_mxodbc.adodb_mxodbc): databaseType = 'mxoracle' dataProvider = 'mxodbc' sysDate = 'trunc(SysDate)' sysTimeStamp = 'SysDate' replaceQuote = "''" def _newcursor(self,rs): return cursor_mxoracle(rs,self) # offset not supported def SelectLimit(self,sql,limit,offset=-1,params=None): if offset == -1: return self.Execute("select * from ("+sql+") where rownum <= "+str(limit), params) else: raise StandardError, "SelectLimit does not support offset: " + sql def DBDate(self,d): if d == None: return 'null' return "TO_DATE(%s,'%s')" % (d.strftime(self.fmtDate),self.NLS_DATE_FORMAT) def DBTimeStamp(self,d): if d == None: return 'null' return "TO_DATE(%s,'%s')" % (d.strftime(self.fmtTimeStamp),self.NLS_DATE_FORMAT) class cursor_mxoracle(adodb_mxodbc.cursor_mxodbc): def __init__(self,rs,conn): adodb_mxodbc.cursor_mxodbc.__init__(self,rs,conn) if __name__ == '__main__': db = adodb_mxoracle() db.Connect('sherkhan','scott','natsoft') #"dsn=sherkhan;uid=scott;pwd=natsoft") adodb.Test(db)python-adodb-2.10/adodb/adodb_postgres.py0000644000175000017500000000642511037372264017102 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb import psycopg try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 # Thread Safety= 2 connections # Param Style = pyformat "%(name)s" class adodb_postgres(adodb.ADOConnection): databaseType = 'postgres' dataProvider = 'postgres' sysDate = "CURRENT_DATE" sysTimeStamp = "CURRENT_TIMESTAMP" metaColSQL = """SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum FROM pg_class c, pg_attribute a,pg_type t WHERE relkind = 'r' AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%' AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum""" def __init__(self): pass def Module(self): return psycopg #host=host1 user=user1 password=secret port=4341 def _connect(self,host=None,user=None,password=None,database=None): if user == None and password == None and database == None: dsn = host else: dsn = 'host='+self.addq(host) if (user != None): dsn += ' user='+self.addq(user) if (password != None): dsn += ' password='+self.addq(password) if (database != None): dsn += ' dbname='+self.addq(database) self._conn = psycopg.connect(dsn) self._conn.autocommit(1) def _newcursor(self,rs): return cursor_postgres(rs,self) def SelectLimit(self,sql,limit,offset=-1,params=None): if (offset >= 0): offset = " OFFSET "+str(offset) else: offset = "" return self.Execute(sql+" LIMIT "+str(limit)+offset,params) def BeginTrans(self): if self._autocommit: self._autocommit = False self._conn.autocommit(0) def RollbackTrans(self): self._conn.rollback() self._autocommit = True self._conn.autocommit(1) def CommitTrans(self): self._conn.commit() self._autocommit = True self._conn.autocommit(1) def _blobencode(self,blob): blob = str(blob) #92=backslash, 0=null, 39=single-quote return blob.replace(chr(92),r'\\134').replace(chr(0),r'\\000').replace(chr(39),r'\\047') def UpdateBlob(self,table,field,blob,where,blobtype='BLOB'): if (blobtype == 'BLOB'): self.Execute("update %s set %s='%s' WHERE %s" % (table,field,self._blobencode(blob),where)) else: self.Execute("update %s set %s='%s' WHERE %s" % (table,field,self.addq(blob),where)) def MetaColumns(self, table): #print self.metaColSQL sql = self.metaColSQL % (table,table) return self.GetAll(sql) class cursor_postgres(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn) if __name__ == '__main__': db = adodb_postgres() db.Connect('localhost','tester','test','test') adodb.Test(db) #adodb.Test_Blob(db)python-adodb-2.10/adodb/adodb_mxodbc.py0000644000175000017500000000613311037372244016502 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ####################################################################### import adodb,adodb_odbc,sys if sys.platform.find('win32') >= 0: import mx.ODBC.Windows mxODBC = mx.ODBC.Windows else: import mx.ODBC.iODBC mxODBC = mx.ODBC.iODBC try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_mxodbc(adodb.ADOConnection): databaseType = 'mxodbc' dataProvider = 'mxodbc' hasRowCount = False def __init__(self): pass def Module(self): global mxODBC return mxODBC #host=host1 user=user1 password=secret port=4341 def _connect(self,host=None,user=None,password=None,database=None): global mxODBC if user == None and password == None and database == None: dsn = host else: dsn = 'dsn='+self.addq(host)+';' if (user != None): dsn += ' uid='+self.addq(user)+';' if (password != None): dsn += ' pwd='+self.addq(password)+';' if (database != None): dsn += ' database='+self.addq(database)+';' self._conn = mxODBC.DriverConnect(dsn) self._conn.setconnectoption(mxODBC.SQL.AUTOCOMMIT, mxODBC.SQL.AUTOCOMMIT_ON) def _newcursor(self,rs): return cursor_mxodbc(rs,self) def BeginTrans(self): global mxODBC if self._autocommit: self._autocommit = False self._conn.setconnectoption(mxODBC.SQL.AUTOCOMMIT, mxODBC.SQL.AUTOCOMMIT_OFF) def RollbackTrans(self): global mxODBC self._conn.rollback() self._autocommit = True self._conn.setconnectoption(mxODBC.SQL.AUTOCOMMIT, mxODBC.SQL.AUTOCOMMIT_ON) def CommitTrans(self): global mxODBC self._conn.commit() self._autocommit = True self._conn.setconnectoption(mxODBC.SQL.AUTOCOMMIT, mxODBC.SQL.AUTOCOMMIT_ON) def MetaColumns(self, table): curs = self._conn.cursor() curs.columns(None, None, table) # columns('%', '%', table) ? rs = self._newcursor(curs) arr = [] table = table.upper() while not rs.EOF: if rs.fields[2].upper() == table: arr.append((rs.fields[3],rs.fields[5],rs.fields[6])) rs.MoveNext() return arr class cursor_mxodbc(adodb.ADOCursor): def __init__(self,rs,conn): adodb.ADOCursor.__init__(self,rs,conn) rs.arraysize=10 if __name__ == '__main__': db = adodb_mxodbc() #db.Connect("Driver=Microsoft Visual FoxPro Driver;UID=;PWD=;SourceDB=D:\\inetpub\\adodb\\adoxyz.DBC;SourceType=DBC;Exclusive=No;BackgroundFetch=No;Collate=Machine;Null=Yes;Deleted=Yes;") db.Connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\inetpub\\adodb\\northwind.mdb;Uid=Admin;Pwd=;") adodb.Test(db) python-adodb-2.10/adodb/adodb_odbc_mssql.py0000644000175000017500000000231711037372264017356 0ustar dgildgil######################################################################## # Vers 2.10 16 July 2008, (c)2004-2008 John Lim (jlim#natsoft.com) All Rights Reserved # Released under a BSD-style license. See LICENSE.txt. # Download: http://adodb.sourceforge.net/#pydownload ######################################################################## import adodb,adodb_odbc,datetime try: True, False except NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0 class adodb_odbc_mssql(adodb_odbc.adodb_odbc): databaseType = 'odbc_mssql' dataProvider = 'odbc' sysDate = 'convert(datetime,convert(char,GetDate(),102),102)' sysTimeStamp = 'GetDate()' def _newcursor(self,rs): return cursor_odbc_mssql(rs,self) class cursor_odbc_mssql(adodb_odbc.cursor_odbc): def __init__(self,rs,conn): adodb_odbc.cursor_odbc.__init__(self,rs,conn) def Affected_Rows(self): return self._conn.GetOne('select @@rowcount') def Insert_ID(self): return self._conn.GetOne('select @@IDENTITY') if __name__ == '__main__': db = adodb_odbc_mssql() db.Connect("Driver={SQL Server};Server=localhost;Database=northwind;") adodb.Test(db)python-adodb-2.10/setup.py0000644000175000017500000000176111037373572014173 0ustar dgildgil#!/usr/bin/env python from distutils.core import setup setup(name="adodb", version="2.10", description="ADOdb Python", author="John Lim", author_email="jlim#natsoft.com", packages=["adodb"], url="http://adodb.sourceforge.net/#pydownload", ) import sys,os def trydel(f): try: os.unlink(f) print "Deleted %s" % f except: pass try: os.unlink(f+'c') except: pass for p in sys.path: if p.find('site-packages')>0: trydel(p+os.sep+'adodb.py') trydel(p+os.sep+'adodb_access.py') trydel(p+os.sep+'adodb_mssql.py') trydel(p+os.sep+'adodb_mxodbc.py') trydel(p+os.sep+'adodb_mxoracle.py') trydel(p+os.sep+'adodb_mysql.py') trydel(p+os.sep+'adodb_oci8.py') trydel(p+os.sep+'adodb_odbc.py') trydel(p+os.sep+'adodb_odbc_mssql.py') trydel(p+os.sep+'adodb_postgres.py') trydel(p+os.sep+'adodb_vfp.py')python-adodb-2.10/README.txt0000644000175000017500000000147611037373626014162 0ustar dgildgilAbout This Package ================== ADOdb is a database abstraction library (modelled on Microsoft's database API's). ADOdb was originally developed for PHP, and ported to Python. The Python version implements a subset of the PHP version. ADOdb is licensed using a BSD-style license. See LICENSE.txt. Installation ============ Run from the command prompt: > python setup.py install This will perform the adodb package installation. You will need to install database specific extensions to use ADOdb for Python. See HTML documentation below for further info. Documentation ============= See adodb-py-docs.htm Author ====== jlim#natsoft.com Download ======== http://adodb.sourceforge,net/ Forums and Help =============== http://phplens.com/lens/lensforum/topics.php?id=4python-adodb-2.10/adodb-py-docs.htm0000644000175000017500000006614011044072550015610 0ustar dgildgil ADOdb for Python

ADOdb for Python

(c) 2004-2008 John Lim (jlim#natsoft.com) This software is licensed under a BSD-style license. See LICENSE.txt.

Introduction
Databases Supported
Bug Reports and Help
Installation
Tutorial
Connection Examples
Function Reference
Error Handling
Bind Parameters
Changelog

Introduction

ADOdb is a database abstraction library (modelled on Microsoft's database API's). ADOdb was originally developed for PHP, and ported to Python. The Python version implements a subset of the PHP version. ADOdb is licensed using a BSD-style license.

Download:  Python version  PHP version

You might ask why Python needs a database abstraction library when Python provides the official DB API. Unfortunately the DB API does not encapsulate differences in the database implementations. For example, to select a limited number of rows, say 10 rows, you would have to use very different SQL for different databases:

MS SQL select top 10 from table
MySQL and PostgreSQL select * from table limit 10
Oracle select * from (select * from table) where rownum <= 10

These differences are handled by ADOdb (using SelectLimit), but not by the Python DB API. Other important database differences transparently handled by ADOdb include date-formating, associative arrays (records as dictionaries) and LOB-handling.

This class library assumes you are using Python 2.3 or later. Internally it uses the standard Python 2.3 datetime class.

Databases Supported

PHP bundles most database extensions in the official release. In Python, most database extensions are not part of the official release. You have to manually download and install the extensions yourself. The requirements are listed below:

Class Requirements Notes
odbc Download PythonWin extension

No support for SelectLimit, UpdateBlob, UpdateBlobFile, Insert_ID, RecordCount and Affected_Rows.

access Requires pyodbc.  Only SelectLimit( ) with no offset parameter supported. RecordCount( ) not supported.
mssql Requires pyodbc.  Only SelectLimit( ) with no offset parameter supported. RecordCount( ) not supported.
mysql Download MySQL-python extension  

SelectLimit( ) not supported. RecordCount( ) not supported.

mxodbc Superior odbc extension. Licensing fee required for commercial use.
Switch to pyodbc if you want an open source odbc extension.

SelectLimit( ) not supported. RecordCount( ) not supported.

mxoracle
Requires mxodbc. Connect to Oracle using ODBC.
Only SelectLimit( ) with no offset parameter supported. Requires Oracle client installed. RecordCount( ) not supported.
oci8 Download cx_Oracle extension. Also requires Oracle client to be installed.

Despite the name, it works with Oracle 8, 9 and later. SelectLimit( ) does not support the offset parameter. RecordCount( ) not supported.

odbc Download PythonWin extension

SelectLimit( ) only works with Access,VFP and Microsoft SQL Server. The offset parameter is not supported.

No support for UpdateBlob, UpdateBlobFile, Insert_ID, RecordCount and Affected_Rows.

odbc_mssql Download PythonWin extension

Same limitations as adodb_odbc extension, except that Insert_ID and Affected_Rows supported.

postgres Download psycopg extension  
pyodbc Superior open source odbc extension.
vfp Requires pyodbc.  
sqlite
Requires pysqlite.
Contributed by Glenn Washburn.

Installation

Run from the command prompt:

> python setup.py install

This will perform the adodb package installation.

You will need to install database specific extensions to use ADOdb for Python.

Bug Reports and Help

To report bugs, discuss ADOdb, and ask for help, post to the forums at: http://phplens.com/lens/lensforum/topics.php?id=4

Tutorial

The easiest way to learn how to use ADOdb for python is with a few examples. Here's one that contrasts PHP with Python. This example select some data from a table, prints each row, then closes the connection.

PHP Python
include "adodb.inc.php";
$conn = adodb.NewADOConnection('mysql');
$conn->Connect('server','user','pwd','db');
$rs = $conn->Execute('select * from table');

while (!$rs->EOF) {
print_r($rs->fields);
$rs->MoveNext();
}
$rs->Close();
$conn->Close();
import adodb;
conn = adodb.NewADOConnection('mysql')
conn.Connect('server','user','pwd','db')
cursor = conn.Execute('select * from table')

while not cursor.EOF:
print cursor.fields
cursor.MoveNext()

cursor.Close()
conn.Close()

First we create a database connection object, conn. Then we login to the database using Connect( ). We now call Execute( ) to compile and execute the given SQL. The will return a recordset or cursor that will hold the current row in the fields property. Fields are numerically indexed, starting at index zero. When we want to move to the next record, we call MoveNext( ) which also updates the fields property. Lastly, we check to see whether there are any more records left to process by monitoring the EOF property.

As you can see, the PHP and Python code is very similar. The main difference is Execute( ) returns a recordset in PHP, while a cursor is returned in Python. A PHP recordset and Python cursor work identically with SELECT statements. However Python cursors work differently with INSERT/UPDATE/DELETE statements. You can see that below:

PHP Python
$sql = "update table set col='abc'";
$rs = $conn->Execute($sql);
$rows = $conn->Affected_Rows();
sql = "update table set col='abc'"
cursor = conn.Execute($sql)
rows = cursor.Affected_Rows()

In PHP, Affected_Rows( ) runs in the connection. In Python, all information related to an Execute( ) is retrieved from the cursor. This is because Python is multi-threaded, so it is no longer possible to store the affected_rows globally in the connection. Similarly, Insert_ID( ) is called from the cursor in Python.

We support the iterator protocol, which allows you to iterate through the data using a for-loop:

cursor = conn.Execute('select * from table')
for row in cursor: print row for row in conn.Execute('select id from table'): dofunction(row[0])

And we support associative arrays (dictionaries), where the keys are the field names:

cursor = conn.Execute('select id,name from table')
while not cursor.EOF:
arr = cursor.GetRowAssoc(0) # 0 is lower, 1 is upper-case
print 'id=',arr['id'],' name=',arr['name']
cursor.MoveNext()

Connection Examples

# Oracle connection
import adodb
conn = adodb.NewADOConnection('oci8')
conn.Connect('scott/tiger@tns')
conn.Connect('tns', 'scott', 'tiger')

# Oracle using connection string
import adodb
conn = adodb.NewADOConnection('oci8://scott:tiger@tns/')

# MySQL
import adodb
conn = adodb.NewADOConnection('mysql')
conn.Connect('server', 'user', 'pwd', 'db')

# MySQL using connection string
import adodb
conn = adodb.NewADOConnection('mysql://user:pwd@server/db')

# PostgreSQL
import adodb
conn = adodb.NewADOConnection('postgres')
conn.Connect('server', 'user', 'pwd', 'db')
conn.Connect('host=server user=user password=pwd dbname=db port=4341')

# ODBC
import adodb
conn = adodb.NewADOConnection('access') # mxodbc required
dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\inetpub\\adodb\\northwind.mdb;"
conn.Connect(dsn)

# ODBC for mssql
import adodb
conn = adodb.NewADOConnection('mssql') # mxodbc required
conn.Connect("Driver={SQL Server};Server=localhost;Database=northwind;")

# sqlite
import adodb
conn = adodb.NewADOConnection('sqlite') # pysqlite required
conn.Connect(database = "c:\\sqlite\\mydata.db")

Other drivers such as "vfp" for foxpro are included.

Function Reference

Connection Class Description
Execute(sql, [params]) Execute sql, returning a cursor object. The optional params is a dictionary that contains the bind variables. All blob fields are automatically and transparently retrieved for you.
SelectLimit(sql, limit, [offset]) Execute sql, retrieving only limit rows, an optional offset from the beginning of the recordset, returning a cursor object.

UpdateBlob(table, field, blob,
      whereclause, blobtype='BLOB')

Executes the equivalent following sql statement:

UPDATE table SET field = blob WHERE whereclause

The blobtype field should be set to either 'BLOB' or 'CLOB'. Any special encoding required for the blob is applied transparently.

UpdateBlobFile(table, field, filepath,
      whereclause, blobtype='BLOB')

Loads the binary file filepath into blob. Then calls UpdateBlob( ).

ErrorMsg( ) Returns last database error message. This function is not thread-safe.
IsConnected( ) Returns boolean indicating whether connected.
qstr(str) Quotes a varchar or char variable.
quote(str) Synonym for qstr( )
GetAll(sql) Execute sql and return 2-dimensional array of tuples, the data recordset.
GetArray(sql) Synonym for GetAll(sql).
GetRow(sql) Execute sql and return first row of recordset as a tuple.
GetOne(sql) Execute sql and return 1 element of first row of recordset.
GetAssoc(sql) Returns a dictionary, with the first columns as the keys to the dictionary. If more than 2 columns are returned, then the dictionary values is a tuple of the 2nd to last columns. If 2 columns are returned, then the 2nd column becomes the dictionary values. If one column is returned, then the values are set to None.
GetDict(sql) Synonym for GetAssoc().
GetCol(sql) Returns the first column of each row as an array.
MetaType(fieldtype) Returns the ADOdb metatype of a native field type.
  • C: character fields that fit into a text input field.
  • X: larger character fields that fit into a textarea.
  • B: Blobs, or Binary Large Objects. Typically images.
  • D: Date field
  • T: Timestamp field
  • L: Logical field (boolean or bit-field)
  • I:  Integer field
  • N: Numeric field. Includes autoincrement, numeric, floating point, real and integer.
MetaColumns(table) Returns a 2-dimensional array containing information on the fields of a table. Each row contains [fieldname, fieldtype, maxlength]. Maxlength can be -1, indicating that the maximum length is not known.

Note that some databases return more information in each row.

DBDate(datetime) Given a Python 2.3 datetime object, convert into a date string acceptable to the database.
DBTimeStamp(datetime) Given a Python 2.3 datetime object, convert into a timestamp string acceptable to the database.
Date(field) Converts a date returned by a select statement into a Python 2.3 datetime object
TimeStamp(field) Converts a timestamp returned by a select statement into a Python 2.3 datetime object
BeginTrans( ) ADOdb defaults to auto-commit mode. Call BeginTrans( ) to start a transaction. This might not be thread-safe.
RollbackTrans( ) Rollback transaction initiated by BeginTrans( ).
CommitTrans( ) Commit transaction initiated by BeginTrans( ).
Close( ) Close database connection. This is optional, as the connection is closed when the object is freed.
Module( ) Returns the DB module object.
Conn( ) Returns DB connection object.
DriverInfo( ) Returns the threadsafety, apilevel and paramstyle values

Connection Class Properties Description
debug Set to 1 to output SQL generated to stdout. Set to 2 to output to stdout as HTML. Set to a filepath (a string) if you want the debug output to be logged into a file.
getLOBs Boolean that determines whether LOBs (large data objects) are loaded automatically. Default is True, autoload. For best performance (especially for cursors with no LOBs), set this to False.
sysDate SQL to generate current date.
sysTimeStamp SQL to generate current timestamp.

Cursor Class Functions Description
RecordCount( ) Number of rows returned by SELECT statement, or number of rows affected by INSERT/UPDATE/DELETE. Returns -1 if not supported.
Affected_Rows( ) Synonym for RecordCount( ).
MoveNext( ) Move to next row of recordset. Returns current EOF value.
FetchRow( ) Retrieves the current row of the recordset, then moves to the next row. The row retrieved is returned as a tuple.
GetRowAssoc(upper=1) Returns the current row as a dictionary, with the key's being the field names. Setting upper = 0 will lower-case the keys. Setting upper=1 will upper-case the keys. Setting upper to any other value, and the keys will be left in the natural case.
Insert_ID( ) Returns last insert id generated by an auto-incrementing field. Only supported by mysql and odbc_mssql drivers currently.
FetchField(fieldoffset)

Returns field information from a SELECT statement. The fieldoffset is zero-based, so to retrieve info on the 1st field use FetchField(0). A tuple is returned, consisting of:

(name, type_code,display_size, internal_size, precision, scale,null_ok).

Close( ) Close cursor. This is optional, as the cursor is closed when the object is freed.
Cursor( ) Returns DB cursor object.

Cursor Class Properties Description
fields Property that holds the current row of the recordset as a tuple (or list).
EOF When moving true the recordset, EOF is set to True after we pass the last row.

Error Handling

ADOdb for Python by default relies on the standard Python exception mechanism. Here's how to capture an error:

try:
curs = conn.Execute('select * from badtable'); # table does not exist
except:
print sys.exc_info()[1]; # retrieve the error message returned by database

Alternatively, you can use PHP style ErrorMsg( ) by setting the connection.useExceptions flag to True. ErrorMsg( ) is not thread-safe.

conn.useExceptions = False
curs = conn.Execute('select * from badtable'); # table does not exist
if curs == None:
print conn.ErrorMsg()

Bind Parameters

Python drivers do not use a consistent bind parameter convention. Here is a brief summary of some drivers, obtained by running Connection.DriverInfo( ), which outputs the following to the console:

Driver       = mysql
API Level = 2.0
Param Style = format
Thread Safety= 1 (0=none, 1=module, 2=connections, 3=cursors)

Driver = oci8
API Level = 2.0
Param Style = named
Thread Safety= 2 (0=none, 1=module, 2=connections, 3=cursors)

Driver = postgres
API Level = 2.0
Param Style = pyformat
Thread Safety= 2 (0=none, 1=module, 2=connections, 3=cursors)

Driver = mssql (and all odbc drivers)
API Level = 2.0
Param Style = qmark
The bind format you use is defined in Param Style. From the Python DB API docs:
        paramstyle

String constant stating the type of parameter marker
formatting expected by the interface. Possible values are
[2]:

'qmark' Question mark style,
e.g. '...WHERE name=?'
'numeric' Numeric, positional style,
e.g. '...WHERE name=:1'
'named' Named style,
e.g. '...WHERE name=:name'
'format' ANSI C printf format codes,
e.g. '...WHERE name=%s'
'pyformat' Python extended format codes,
e.g. '...WHERE name=%(name)s'

So for mysql:

	cur_name = "snake"
new_name = "turtle"
connection.Execute ("UPDATE animal SET name = %s WHERE name = %s", (new_name, cur_name))

For oci8, the cx_oracle docs say:

Parameters may be passed as a dictionary or sequence or as keyword arguments. If the arguments are a dictionary, the values will be bound by name and if the arguments are a sequence the values will be bound by position.

For odbc, the paramstyle is qmark, eg.

	connection.Execute('select * from table where id=?',(100,));

Change Log

Todo: add support for sequences. Need to add SelectLimit support for mxodbc derived classes.

2.10 July 2008
* Added support for pyodbc. Switched to using pyodbc for vfp, access and mssql drivers.

* Added minimal support for MetaColumns in odbc drivers.

2.02 21 May 2007

Added sqlite3 support for python 2.5.

Fixed GetRow _fixblob bug in oci8.

2.01 5 May 2006
Added lastrowid support to sqlite.

A _fixblob error in oci8, row.read( ) has been patched.

Odbc dsn generation problem, ";" not generated correctly. fixed.

2.00 Nov 2005
Added sqlite support, thanks to Glenn Washburn. Improved installation with setup.py

1.13 6 May 2005

Fixed oci8 blob bugs. Also updateclob( ) was not working.

Close calls close( ) before freeing connectoin object.

1.12  24 March 2005

Added mxoracle driver (mxodbc for oracle)..

Fixed cursor iterator bug in mxodbc driver.

1.11 23 Feb 2005

Fixed commit code for mysql driver.

1.10 21 Dec 2004

Added sysDate and sysTimeStamp to mysql driver.

Added support for connection strings of the form driver://user:pwd@server/database in NewADOConnection.

DriverInfo( ) now checks paramStyle before thread safety, as some drivers do not implement thread safety.

MySQL insert_id() changed to lastrowid as insert_id() deprecated. Thx Alex Verstraeten.

GetRow() now closes cursor. Thx Guoda Rugeviciute

Postgresql metacolumns() did not work - not a tuple. Fixed. Thx Simon Hedberg.

1.01 30 July 2004
A debugging print in oci8 was removed.

1.00 12 July 2004

GetRowAssoc(), upper = False not implemented correctly. Fixed.

Tested with psyco. Works fine.

0.90 15 Apr 2004

Added ADONewConnection and NewADOConnection.

Added GetAssoc, GetDict, GetArray and GetCol.

Added mxodbc driver. Also vfp, access and mssql classes that inherit from mxodbc. Tested only on Windows.

Added MetaColumns and MetaType support for Oracle, mxODBC, MySQL

Perform explicit close for Get* functions.

0.03 31 Jan 2004

Implemented setup.py installer.

Some postgres bugs fixed.

0.02 28 Jan 2004

Revised GetRowAssoc( ).

Fixed use of false - should be False.

0.01 25 Jan 2004
First Release. MySQL, Oracle, PostgreSQL, generic ODBC and ODBC for MSSQL drivers.