# -*- coding: utf-8 -*- GlobalPVersion='0.8' # Borland API-Documentation: bde32.hlp (surtout les trucs en C) import ctypes,os,sys,datetime,time,math,types,_winreg from ponx import decodedate,decodetime,decodedatetime,forceint,forcefloat from idapi import * def cbde(): """ singleton/fermeture sur idapi.dll (+ constantes par cbde.) """ if hasattr(cbde,'dll'): return cbde.dll else: this=cbde key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Borland\\Database Engine') this.DLLPATH= _winreg.QueryValueEx(key,'DLLPath')[0]+'idapi32.dll' this.BDEVERSION = 500 this.DBIERR_NONE = 0 this.DBIMAXTBLNAMELEN = 260 this.PTYPES={ 100: 'Alpha', 200: 'Date', 322: 'Memo', 324: 'Formatted', 323: 'Binary', 326: 'Graphic', 400: 'Logical', 500: 'Smallint', 600: 'Longint', 700: 'Number', 1000: 'Time', 1100: 'Datetime', } #ouverture de IDAPI.DLL this.dll=ctypes.windll.LoadLibrary(cbde.DLLPATH) this.lasterrormessage='' this.lasterrorcode=0 def Chk(ErrorValue): ErrorValue = ctypes.c_uint16(ErrorValue) dbi_string = DBIMSG() ErrInfo = DBIErrInfo() if ErrorValue.value != this.DBIERR_NONE: print 'ErrorValue:',ErrorValue this.dll.DbiGetErrorInfo(True, ctypes.byref(ErrInfo)) if (ErrInfo.iError == ErrorValue.value): print 'szErrCode', ErrInfo.szErrCode print 'szContext1', ErrInfo.szContext1 print 'szContext2', ErrInfo.szContext2 print 'szContext3', ErrInfo.szContext3 print 'szContext4', ErrInfo.szContext4 else: this.dll.DbiGetErrorString(ErrorValue, ctypes.byref(dbi_string)) print 'ErrorString:',dbi_string.value return ErrorValue this.Chk=Chk def errorsto(ErrorValue): ErrorValue = ctypes.c_uint16(ErrorValue) dbi_string = DBIMSG() ErrInfo = DBIErrInfo() if ErrorValue.value != this.DBIERR_NONE: this.dll.DbiGetErrorInfo(True, ctypes.byref(ErrInfo)) if (ErrInfo.iError == ErrorValue.value): vret= ErrInfo.szErrCode vret += ' '+ErrInfo.szContext1 vret += ' '+ErrInfo.szContext2 vret += ' '+ErrInfo.szContext3 vret += ' '+ErrInfo.szContext4 else: this.dll.DbiGetErrorString(ErrorValue, ctypes.byref(dbi_string)) vret = dbi_string.value this.lasterrormessage=dbi_string.value this.lasterrorcode=ErrorValue else: this.lasterrormessage='' this.lasterrorcode=0 this.errorsto=errorsto def decodetime(t): reste,h=math.modf(t/1000.0/60.0/60.0) reste,m=math.modf(reste*60) reste,s=math.modf(reste*60) return h,m,s this.decodetime=decodetime def encodetime(t): return(t.hour*3600000+t.minute*60000+t.second*1000) this.encodetime=encodetime return this.dll class tcursor(object): def __init__(self, directory=None, tname=None): self.blobopened=[] if not(tname is None): self.open(directory, tname) def open(self, directory=None, tname=None): if directory is None: bdeDIRECTORY = os.getcwd() else: bdeDIRECTORY = directory if tname is None: self._tablename = 'tess.DB' else: self._tablename = tname self.bde=cbde() #print type(self.bde.DbiInitFn) cbde.Chk(self.bde.DbiInitFn(cbde.BDEVERSION,None)) # ouvre la database directement (sans alias) self.hDB=hDBIDb() cbde.Chk(self.bde.DbiOpenDatabase(None, None, dbiREADWRITE, dbiOPENSHARED, None, 0, None, None, ctypes.byref(self.hDB))) self.bde.DbiSetDirectory(self.hDB, bdeDIRECTORY) # ouvre la table, avec un cursor self.hCUR=hDBICur() cbde.Chk(self.bde.DbiOpenTable(self.hDB, self._tablename, None, None, None, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, True, None, ctypes.byref(self.hCUR))); # propriétés du curseur self.cPs=CURProps() cbde.Chk(self.bde.DbiGetCursorProps(self.hCUR, ctypes.byref(self.cPs))) # buffer de cursor, pour lecture d'enregistrement pRecBuf=ctypes.c_byte * self.cPs.iRecBufSize self.recbuffer=pRecBuf() #structure des champs fDArr = FLDDesc * self.cPs.iFields self.fDesc = fDArr() cbde.Chk(self.bde.DbiGetFieldDescs(self.hCUR, ctypes.byref(self.fDesc))) self.fieldnames={} self.fieldstruct=[] #print "Num, Nom, Type, sous-type, nb_digits, nb_decimales, offset, longueur, null_offset, check_validité, droits, calculé " n=0 for x in self.fDesc: n+=1 #print n,cbde.PTYPES[x.iFldType*100+x.iSubType],x.iFldType,'\t', "OFFSET=",x.iOffset, '\t',x.szName self.fieldstruct.append((n, x.szName, cbde.PTYPES[x.iFldType*100+x.iSubType], x.iSubType, x.iUnits1, x.iUnits2, x.iOffset, x.iLen-1, x.iNullOffset, x.efldvVchk, x.efldrRights, x.bCalcField, x.iFldNum)) # oté : x.iFldNum self.fieldnames[x.szName]=n-1 return tname+' est ouvert.' def emptytable(self, directory=None, tname=None): """ Vide une table (accès exclusif nécessaire) exemple: tc.emptytable('R:\\cow\\dossier','laTable.DB') """ if directory is None: bdeDIRECTORY = os.getcwd() else: bdeDIRECTORY = directory if tname is None: self._tablename = 'tess.DB' else: self._tablename = tname self.bde=cbde() #print type(self.bde.DbiInitFn) cbde.Chk(self.bde.DbiInitFn(cbde.BDEVERSION,None)) # ouvre la database directement (sans alias) self.hDB=hDBIDb() cbde.Chk(self.bde.DbiOpenDatabase(None, None, dbiREADWRITE, dbiOPENSHARED, None, 0, None, None, ctypes.byref(self.hDB))) self.bde.DbiSetDirectory(self.hDB, bdeDIRECTORY) # vide la table, avec un cursor self.hCUR=hDBICur() cbde.Chk(self.bde.DbiOpenTable(self.hDB, self._tablename, None, None, None, 0, dbiREADWRITE, dbiOPENEXCL, xltFIELD, True, None, ctypes.byref(self.hCUR))); result=cbde.Chk(self.bde.DbiEmptyTable(self.hDB, self.hCUR, None, None)); #print 149,result erreur si != c_ushort(0) cbde.Chk(self.bde.DbiCloseCursor(ctypes.byref(self.hCUR))) def copytable(self, directory=None, tname=None, tnewname=None): """ Copie une table (écrase au besoin) exemple: tc.copytable('R:\\cow\\dossier','tableorg.DB','tabldest.db') """ if directory is None: bdeDIRECTORY = os.getcwd() else: bdeDIRECTORY = directory if tname is None: self._tablename = 'tess.DB' else: self._tablename = tname self.bde=cbde() #print type(self.bde.DbiInitFn) cbde.Chk(self.bde.DbiInitFn(cbde.BDEVERSION,None)) # ouvre la database directement (sans alias) self.hDB=hDBIDb() cbde.Chk(self.bde.DbiOpenDatabase(None, None, dbiREADWRITE, dbiOPENSHARED, None, 0, None, None, ctypes.byref(self.hDB))) self.bde.DbiSetDirectory(self.hDB, bdeDIRECTORY) cbde.Chk(self.bde.DbiCopyTable(self.hDB, True, tname, 0, tnewname)) def osql(self, sql): sql = ctypes.c_char_p(sql) self.bde.DbiQExecDirect(self.hDB, qrylangSQL, sql, ctypes.byref(self.hCUR)) def emptyrecord(self): del(self.recbuffer) pRecBuf=ctypes.c_byte * self.cPs.iRecBufSize self.recbuffer=pRecBuf() def bot(self): return cbde.Chk(self.bde.DbiSetToBegin(self.hCUR)) def nextrecord(self): vret= self.bde.DbiGetNextRecord(self.hCUR, dbiNOLOCK, ctypes.byref(self.recbuffer), None) if vret: cbde.errorsto(vret) return False else: return True def priorrecord(self): vret=self.bde.DbiGetPriorRecord(self.hCUR, dbiNOLOCK, ctypes.byref(self.recbuffer), None) if vret: cbde.errorsto(vret) return False else: return True def fieldtype(self, fieldname): num=self.fieldnames[fieldname] typ=self.fieldstruct[num][2] long=self.fieldstruct[num][7] return typ #,num,long def sdaffecte(self, st): dret={} for l in st.splitlines(): try: var,valeur = l.split('=',1) var=str(var.strip()) typ=self.fieldtype(var) if typ=='Alpha': dret[var] = valeur.strip() elif typ=='Logical': dret[var] = bool(valeur) elif typ=='Number': dret[var] = forcefloat(valeur) elif typ=='Longint': dret[var] = forceint(valeur) elif typ=='Smallint': dret[var] = forceint(valeur) elif typ=='Date': dret[var] = decodedate(valeur) elif typ=='Time': dret[var] = decodetime(valeur) elif typ=='Datetime': dret[var] = decodedatetime(valeur) elif typ=='Memo': dret[var] = valeur.strip() elif typ=='Binary': dret[var] = valeur.strip() except: pass print dret def slaffecte(self, st): dret=[] for l in st.splitlines(): try: var,valeur = l.split('=',1) var=str(var.strip()) typ=self.fieldtype(var) dret.append(var) if typ=='Alpha': dret.append(valeur.strip()) elif typ=='Logical': dret.append(bool(valeur)) elif typ=='Number': dret.append(forcefloat(valeur)) elif typ=='Longint': dret.append(forceint(valeur)) elif typ=='Smallint': dret.append(forceint(valeur)) elif typ=='Date': dret.append(decodedate(valeur)) elif typ=='Time': dret.append(decodetime(valeur)) elif typ=='Datetime': dret.append(decodedatetime(valeur)) elif typ=='Memo': dret.append(valeur.strip()) elif typ=='Binary': dret.append(valeur.strip()) except: pass self.setfieldvalue(*dret) def fieldvalue(self, fieldname): num=self.fieldnames[fieldname] typ=self.fieldstruct[num][2] long=self.fieldstruct[num][7] if typ=='Alpha': buffer=ctypes.create_string_buffer(long) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return buffer.value elif typ=='Logical': buffer=ctypes.c_short(True) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return bool(buffer.value) elif typ=='Number': buffer=ctypes.c_double(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return buffer.value elif typ=='Longint': buffer=ctypes.c_long(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return buffer.value elif typ=='Smallint': buffer=ctypes.c_int16(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return buffer.value elif typ=='Date': buffer = ctypes.c_long(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return datetime.date.fromordinal(buffer.value) elif typ=='Datetime': buffer = ctypes.c_double(1) dat = ctypes.c_long(1) tim = ctypes.c_long(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) cbde.Chk(self.bde.DbiTimeStampDecode( ctypes.c_double(buffer.value), ctypes.byref(dat), ctypes.byref(tim))) return datetime.date.fromordinal(dat.value), datetime.time(*cbde.decodetime(tim.value)) elif typ=='Time': buffer = ctypes.c_long(1) cbde.Chk(self.bde.DbiGetField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffer),None)) return datetime.time(*cbde.decodetime(buffer.value)) elif typ=='Binary': cbde.Chk(self.bde.DbiOpenBlob(self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mSize = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlobSize(self.hCUR, self.recbuffer, num+1, ctypes.byref(mSize))) #print "Taille du blob",mSize.value mDest = ctypes.c_byte * mSize.value mDestbuf = mDest() mRead = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlob(self.hCUR, self.recbuffer, num+1, 0, mSize.value, ctypes.byref(mDestbuf), ctypes.byref(mRead))) s='' for c in mDestbuf[:]: if c>=0: s+=chr(c) else: s+=chr(256+c) return s elif typ=='Memo': cbde.Chk(self.bde.DbiOpenBlob(self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mSize = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlobSize(self.hCUR, self.recbuffer, num+1, ctypes.byref(mSize))) #print "Taille du blob",mSize.value mDest = ctypes.c_byte * mSize.value mDestbuf = mDest() mRead = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlob(self.hCUR, self.recbuffer, num+1, 0, mSize.value, ctypes.byref(mDestbuf), ctypes.byref(mRead))) s='' for c in mDestbuf[:]: if c>=0: s+=chr(c) else: s+=chr(256+c) return s elif typ=='Graphic': cbde.Chk(self.bde.DbiOpenBlob(self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mSize = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlobSize(self.hCUR, self.recbuffer, num+1, ctypes.byref(mSize))) #print "Taille du blob",mSize.value mDest = ctypes.c_byte * mSize.value mDestbuf = mDest() mRead = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlob(self.hCUR, self.recbuffer, num+1, 0, mSize.value, ctypes.byref(mDestbuf), ctypes.byref(mRead))) s='' for c in mDestbuf[8:]: if c>=0: s+=chr(c) else: s+=chr(256+c) return s elif typ=='Formatted': cbde.Chk(self.bde.DbiOpenBlob(self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mSize = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlobSize(self.hCUR, self.recbuffer, num+1, ctypes.byref(mSize))) #print "Taille du blob",mSize.value mDest = ctypes.c_byte * mSize.value mDestbuf = mDest() mRead = ctypes.c_uint32() cbde.Chk(self.bde.DbiGetBlob(self.hCUR, self.recbuffer, num+1, 0, mSize.value, ctypes.byref(mDestbuf), ctypes.byref(mRead))) #print "Nb octets lus",mRead.value s='' print print mDestbuf print for c in mDestbuf[44:]: if c==0: break else: if c>=0: s+=chr(c) else: s+=chr(256+c) return s def setfieldvalue(self, *data): for fieldname, valeur in zip(data[::2],data[1::2]): if type(fieldname) is types.StringType: num=self.fieldnames[fieldname] else: num=fieldname fieldname=self.fieldstruct[num][1] typ=self.fieldstruct[num][2] long=self.fieldstruct[num][7] #print 'xxxxxxxxxxxx',fieldname,typ,valeur if typ=='Alpha': self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, valeur); if typ=='Logical': buffield=ctypes.c_short(bool(valeur)) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Number': buffield=ctypes.c_double(float(valeur)) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Longint': buffield=ctypes.c_long(int(valeur)) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Smallint': buffield=ctypes.c_int16(int(valeur)) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Date': buffield=ctypes.c_long(datetime.date.toordinal(valeur)) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Time': buffield=ctypes.c_long(valeur.hour*3600000+valeur.minute*60000+valeur.second*1000) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Datetime': buffield = ctypes.c_double(1) dat=ctypes.c_long(datetime.date.toordinal(valeur[0])) tim=ctypes.c_long(valeur[1].hour*3600000+valeur[1].minute*60000+valeur[1].second*1000) cbde.Chk(self.bde.DbiTimeStampEncode( dat.value, tim.value, ctypes.byref(buffield))) self.bde.DbiPutField(self.hCUR, num+1, self.recbuffer, ctypes.byref(buffield)); if typ=='Memo': cbde.Chk(self.bde.DbiOpenBlob( self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mBuf=ctypes.c_buffer(valeur,len(valeur)) cbde.Chk(self.bde.DbiPutBlob( self.hCUR, self.recbuffer, num+1, 0, len(valeur)+1, ctypes.byref(mBuf))) self.blobopened.append(fieldname) if typ=='Binary': cbde.Chk(self.bde.DbiOpenBlob( self.hCUR, self.recbuffer, num+1, dbiREADWRITE)) mBuf=ctypes.c_buffer(valeur,len(valeur)) cbde.Chk(self.bde.DbiPutBlob( self.hCUR, self.recbuffer, num+1, 0, len(valeur), ctypes.byref(mBuf))) self.blobopened.append(fieldname) def freeblob(self): print 453 for fieldname in self.blobopened: num=self.fieldnames[fieldname] print 455,num cbde.Chk(self.bde.DbiFreeBlob( self.hCUR, self.recbuffer, num+1)) self.blobopened=[] def copytodict(self): d={} for field in self.fieldstruct: #print field[0],field[1] d[field[1]]=self.fieldvalue(field[1]) return d def copyfromdict(self, dic): for field in self.fieldstruct: self.setfieldvalue(field[1],dic[field[1]]) def copytolist(self): l=[] for field in self.fieldstruct: l.append(self.fieldvalue(field[1])) return l def copyfromlist(self, l): for num in range(len(l)): self.setfieldvalue(self.fieldstruct[num][1],l[num]) def postrecord(self): self.bde.DbiModifyRecord(self.hCUR, self.recbuffer, False) if len(self.blobopened)>0: self.freeblob() def writetofile(self, fieldname, filename): open(filename,"wb").write(self.fieldvalue(fieldname)) def readfromfile(self, fieldname, filename): self.setfieldvalue(fieldname, open(filename,'rb').read()) def insertrecord(self): self.bde.DbiInsertRecord( self.hCUR, False, self.recbuffer) def deleterecord(self): self.bde.DbiDeleteRecord( self.hCUR, self.recbuffer) def enumfieldnames(self): return [x[1] for x in self.fieldstruct] def tablename(self): return self._tablename def nrecords(self): #obtient le nombre d'enregistrements RecCount= ctypes.c_int32() cbde.Chk(self.bde.DbiGetRecordCount( self.hCUR, ctypes.byref(RecCount))) return RecCount.value def qlocate(self, *clef): for num, key in enumerate(clef): self.setfieldvalue(num,key) vret = self.bde.DbiGetRecordForKey( self.hCUR, False, ctypes.c_uint16(0), ctypes.c_uint16(0), ctypes.byref(self.recbuffer), ctypes.byref(self.recbuffer)) if vret: cbde.errorsto(vret) return False else: return True def ilocate(self, **clef): for fname in clef: self.setfieldvalue(fname,clef[fname]) vret = self.bde.DbiGetRecordForKey( self.hCUR, False, ctypes.c_uint16(0), ctypes.c_uint16(0), ctypes.byref(self.recbuffer), ctypes.byref(self.recbuffer)) if vret: cbde.errorsto(vret) return False else: return True def settokey(self, *clef): for num, key in enumerate(clef): self.setfieldvalue(num,key) # keySEARCHEQ, keySEARCHGT, or keySEARCHGEQ vret = self.bde.DbiSetToKey(self.hCUR, keySEARCHGEQ, False, ctypes.c_uint16(0), ctypes.c_uint16(0), ctypes.byref(self.recbuffer)) if vret: cbde.errorsto(vret) return False else: return True def switchindex(self, indexname): vret = self.bde.DbiSwitchToIndex(ctypes.byref(self.hCUR), indexname, None, None, True) if vret: cbde.errorsto(vret) return False else: return True def movetorecord(self, num): vret = self.bde.DbiSetToSeqNo( self.hCUR, ctypes.c_uint32(num)) if vret: cbde.errorsto(vret) return False else: self.bde.DbiGetRecord( self.hCUR, dbiNOLOCK, ctypes.byref(self.recbuffer), None) return True def recno(self): num=ctypes.c_uint32() self.bde.DbiGetSeqNo( self.hCUR, ctypes.byref(num)) return num.value def close(self): # ferme la database cbde.Chk(self.bde.DbiExit()) del(self) def cursorproperties(self): print '-'*66 print 'Taille du buffer enregistrement :',self.cPs.iRecBufSize print 'Nombre de champs :',self.cPs.iFields print self.cPs.szName ,"Specifies the table name. " print self.cPs.iFNameSize ,"Specifies the size of the buffer needed to retrieve full table name (including extension and path, if applicable)." print self.cPs.szTableType ,"Specifies the driver type. " print self.cPs.iFields ,"Specifies the number of fields in the table. The client must allocate a buffer whose size is: [iFields * sizeof(FLDDesc)] in order to get the field descriptors for the table." print self.cPs.iRecSize ,"Specifies the record size, depending on the xltMODE for the cursor. If the xltMODE is xltFIELD, iRecSize specifies the logical record size. In other words, it is the size of the record if all fields were represented as BDE logical types. If the xltMODE is xltNONE, iRecSize specifies the physical record size." print self.cPs.iRecBufSize ,"Specifies the physical record size. This is the size of the record buffer that the client must allocate in order to retrieve the records using DbiGetNextRecord, DbiGetPriorRecord, and other functions. This size can change if DbiSetFieldMap is called." print self.cPs.iKeySize ,"Specifies the key size of the current active index (if any). This is the size of the key buffer that the client must allocate in order to retrieve a key using DbiExtractKey. This size changes if DbiSwitchToIndex is called." print self.cPs.iIndexes ,"Specifies the number of currently open indexes for this cursor. The client can call DbiGetIndexDesc with iIndexSeqNo set from 1 to iIndexes, to have all the index descriptors returned. The client could also allocate a buffer whose size is [iIndexes * sizeof(IDXDesc)] and have all the index descriptors returned by calling DbiGetIndexDescs." print self.cPs.iValChecks ,"Specifies the number of validity checks existing for this table." print self.cPs.iRefIntChecks ,"Specifies the number of referential integrity constraints existing for this table." print self.cPs.iBookMarkSize ,"Specifies the size of the bookmark. Bookmarks are always allocated by the client before DbiGetBookMark is called. Note that the size of the bookmark could change if DbiSwitchToIndex is called." print self.cPs.bBookMarkStable ,"True, if this cursor supports stable bookmarks. Stable bookmarks are those that remain unchanged after another user has modified the table. For example, this value is TRUE for Paradox tables having a primary key, but FALSE for Paradox heap tables." print self.cPs.eOpenMode ,"Specifies the open mode that this cursor was opened with." print self.cPs.eShareMode ,"Specifies the share mode that this cursor was opened with:" print self.cPs.bIndexed ,"This value is TRUE if there is a current active index for this cursor. In other words, it is TRUE if there is a non-default order associated with this cursor." print self.cPs.iSeqNums ,"This is an enumerated value which is interpreted as follows: 1: This cursor supports the sequence number concept (Paradox). 0: This cursor supports the record number concept (dBASE and FoxPro). < 0 (-1, -2. . .): None (SQL and Access)" print self.cPs.bSoftDeletes ,"This value is set to TRUE if this cursor supports soft deletes (dBASE and FoxPro only)." print self.cPs.bDeletedOn ,"This value is set to TRUE if the curSOFTDELETEON property is TRUE. This field makes sense only if the cursor supports the soft delete concept. If TRUE, deleted records can be seen while using this cursor (dBASE and FoxPro only). " print self.cPs.iRefRange ,"Not currently used." print self.cPs.exltMode ,"Specifies the value of the translate mode property for this cursor." print self.cPs.iRestrVersion ,"Specifies the restructure version number for the table. (Paradox only.)" print self.cPs.bUniDirectional ,"This value is set to TRUE if this cursor is unidirectional (SQL only.)" print self.cPs.eprvRights ,"Specifies an enumerated value that gives the table-level rights for the user who opened the table." print self.cPs.iFmlRights ,"Reserved." print self.cPs.iPasswords ,"Specifies the number of auxiliary passwords for this table. (Paradox only)." print self.cPs.iCodePage ,"Specifies the code page associated with the table. If the code page is unknown, the value is 0." print self.cPs.bProtected ,"This value is set to TRUE if the table is protected by a password." print self.cPs.iTblLevel ,"Specifies the table level. This value is driver dependent." print self.cPs.szLangDriver ,"Specifies the name of the language driver associated with the table." print self.cPs.bFieldMap ,"This value is set to TRUE if a field map is active for this cursor." print self.cPs.iBlockSize ,"Specifies the value of the BLOCKSIZE for the table, in bytes." print self.cPs.bStrictRefInt ,"This value applies only to Paradox for DOS tables and the Paradox engine. If TRUE, it means that a referential integrity check has been specified and that the STRICT bit is set in the header, which makes the table inaccessible using Paradox for DOS." print self.cPs.iFilters ,"Specifies the number of filters currently on the cursor." print self.cPs.bTempTable ,"TRUE, if the cursor is on a temporary table. For queries, this means the result set is canned, rather than live. This field can be examined to determine whether the requested preference for LIVENESS in the DbiSetProp call were honored." print '-'*66 if __name__=='__main__': tc=tcursor() tc.open('D:\\Dev\\Python','test.DB') print "Nom de la table ",tc.tablename() # liste des champs print tc.enumfieldnames() tc.bot() tc.nextrecord() print print tc.fieldvalue('Cod') print tc.fieldvalue('m2') tc.close() sys.exit() # ouverture #tc=tcursor('D:\\Dev\\Python\\bde','tess.DB') tc=tcursor() tc.open('D:\\Dev\\Python\\bde','tess.DB') print "Nom de la table ",tc.tablename() print "Nb records ",tc.nrecords() # propriétés du tcursor #tc.cursorproperties() # liste des champs print tc.enumfieldnames() # début de table tc.bot() # enregistrement suivant tc.nextrecord() # affichage des données print tc.fieldvalue('Cod'), print tc.fieldvalue('Libell'), print tc.fieldvalue('Montant'), print tc.fieldvalue('Dat') """ print "datim",tc.fieldvalue('datim') tc.setfieldvalue('datim',(datetime.date(2008, 7, 6), datetime.time(23, 22, 21))) tc.postrecord() print "heure",tc.fieldvalue('heure') tc.setfieldvalue('heure',datetime.time(10,34,49)) tc.setfieldvalue('heure',datetime.time(11,35,50)) tc.postrecord() print "flag",tc.fieldvalue('flag') tc.setfieldvalue('flag',True) tc.postrecord() print "entiercourt",tc.fieldvalue('entiercourt') tc.setfieldvalue('entiercourt',123) tc.postrecord() print "souscod",tc.fieldvalue('souscod') tc.setfieldvalue('souscod',111) tc.postrecord() """ """ print '----- Memo m1 ------------' print tc.fieldvalue('m1') print '----- Memo m2 ------------' print tc.fieldvalue('m2') print '----- Binary bin ---------' print tc.fieldvalue('bin') print '--------------------------' """ """ # écriture dans un fichier (valable pour Memo, Binary, Graphic tc.writetofile('grf','tess.jpg') """ # Effectue une requête SQL sur le tcursor #tc.osql("Select * from 'Tess.db' ") tc.osql('''Select * from 'Tess.db' where entierlong>=22 and entiercourt>1''') print '---- SQL','-'*20 tc.bot() while tc.nextrecord(): print tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),' \t',tc.fieldvalue('entierlong'),tc.fieldvalue('entiercourt') else: print "Finished: ",cbde.lasterrormessage, cbde.lasterrorcode print '-'*29 """ # Recherche d'enregistrement (index secondaire) print "*"*66 if not tc.switchindex('IDX2'): print cbde.lasterrormessage, cbde.lasterrorcode if not tc.ilocate(entiercourt=3): print cbde.lasterrormessage, cbde.lasterrorcode print tc.fieldvalue('entiercourt'),tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() tc.nextrecord() print tc.fieldvalue('entiercourt'),tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() tc.nextrecord() print tc.fieldvalue('entiercourt'),tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() """ """ # Recherche d'enregistrement (par primary-key) print "*"*66 if not tc.qlocate('C',1): print cbde.lasterrormessage, cbde.lasterrorcode print tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.recno() print "*"*66 if not tc.qlocate('B',22): print cbde.lasterrormessage, cbde.lasterrorcode print tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() """ """ # Positionnement sur primary-key) print "*"*66 if not tc.settokey('B',3): print cbde.lasterrormessage, cbde.lasterrorcode tc.nextrecord() print tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() tc.nextrecord() print tc.fieldvalue('Cod'),tc.fieldvalue('souscod'),tc.fieldvalue('Libell'),tc.recno() """ """ # modification des données if tc.fieldvalue('Cod')=='B': tc.setfieldvalue('Montant','4321.89') tc.setfieldvalue('Dat',datetime.date(2008,8,1)) tc.setfieldvalue('m1','''AZERTY 12345 Z''') #tc.readfromfile('bin','b.bin') #tc.setfieldvalue('bin','BBBBBBBBBB') tc.postrecord() """ # insertion d'un enregistrement tc.emptyrecord() tc.slaffecte(''' Cod=HHHH Libell = Insertion Montant=1234.56 Dat= 11.12.13 ''') tc.insertrecord() """ # insertion d'un enregistrement tc.emptyrecord() tc.setfieldvalue('Cod','Bbb') tc.setfieldvalue('Libell', 'Suite du B') tc.setfieldvalue('Montant', 3.33) tc.setfieldvalue('Dat',datetime.date(2003,3,3)) tc.insertrecord() if not tc.qlocate('Bbbxxx'): print cbde.lasterrormessage, cbde.lasterrorcode # suppression d'un enregistrement #tc.deleterecord() """ """ # va à un enregistrement par son numéro if tc.movetorecord(4): print tc.fieldvalue('Cod') else: print cbde.lasterrormessage, cbde.lasterrorcode print 'Enregistrement num.',tc.recno() tc.priorrecord() print tc.fieldvalue('Cod') print 'Enregistrement num.',tc.recno() """ """ dic = tc.copytodict() print dic lst = tc.copytolist() print lst #tc.copyfromlist(lst) #tc.copyfromdict(di) """ tc.close()