From: Richard T. <hi...@us...> - 2002-11-29 16:49:34
|
Update of /cvsroot/synce/pyrapi/src In directory sc8-pr-cvs1:/tmp/cvs-serv2629/src Modified Files: database.py pyrapi_wrap.i rapi.py Removed Files: pyrapi.c Log Message: Lots of changes. Added support for most of the database functions. Fixed CeWriteRecordProps interface. Added unittest for most of the implemented functions. Updated the README install instructions. Index: database.py =================================================================== RCS file: /cvsroot/synce/pyrapi/src/database.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- database.py 27 Sep 2002 15:51:57 -0000 1.1 +++ database.py 29 Nov 2002 16:49:29 -0000 1.2 @@ -7,53 +7,130 @@ import pyrapi +def get_field_value(field): + if field.type == pyrapi.CEVT_I2: + return field.val.iVal + if field.type == pyrapi.CEVT_I4: + return field.val.lVal + if field.type == pyrapi.CEVT_R8: + return field.val.dblVal + if field.type == pyrapi.CEVT_BOOL: + return field.val.boolVal + if field.type == pyrapi.CEVT_UI2: + return field.val.uiVal + if field.type == pyrapi.CEVT_UI4: + return field.val.ulVal + if field.type == pyrapi.CEVT_LPWSTR: + return field.val.lpwstr + if field.type == pyrapi.CEVT_FILETIME: + return field.val.filetime + if field.type == pyrapi.CEVT_BLOB: + # Not yet implemented + return "BLOB" + #return repr(field.blob) + +def set_field_value(field,value): + if field.type == pyrapi.CEVT_I2: + field.val.iVal = value + if field.type == pyrapi.CEVT_I4: + field.val.lVal = value + if field.type == pyrapi.CEVT_R8: + field.val.dblVal = value + if field.type == pyrapi.CEVT_BOOL: + field.val.boolVal = value + if field.type == pyrapi.CEVT_UI2: + field.val.uiVal = value + if field.type == pyrapi.CEVT_UI4: + field.val.ulVal = value + if field.type == pyrapi.CEVT_LPWSTR: + field.val.lpwstr = value + if field.type == pyrapi.CEVT_FILETIME: + field.val.filetime = value + if field.type == pyrapi.CEVT_BLOB: + field.blob = value + + class CeRecord(object): """ Base class for CeDatabase records. """ - def __init__(self, record,field_mapping=None): + def __init__(self, dbh, record,field_mapping=None): """ record - the return from the CeReadRecordProps call. """ + print "Record -> ", repr(record) + self._dbh = dbh self._oid = record[0] self._record = record[1] self._field_mapping = field_mapping + + self._field_ids = [field.propid for field in self._record] + print "field ids: ", self._field_ids self._reverse_mapping = {} for mapping in self._field_mapping: - if self._field_mapping[mapping] in self._record.keys(): + if self._field_mapping[mapping] in self._field_ids: self._reverse_mapping[self._field_mapping[mapping]] = mapping - print "Reverse mapping -> ",repr(self._reverse_mapping) - print "Record -> ", repr(self._record) def getoid(self): return self._oid def keys(self): if self._field_mapping == None: - return self._record.keys() + return self._field_ids return self._reverse_mapping.values() + + def _lookup_field(self,field_oid): + field = None + + if self._field_mapping.has_key(field_oid): + # field_oid is a string name + candidate_fields = [field for field in self._record if field.propid == self._field_mapping[field_oid]] + if len(candidate_fields) != 0: field = candidate_fields[0] + else: + candidate_fields = [field for field in self._record if field.propid == field_oid] + if len(candidate_fields) != 0: field = candidate_fields[0] + + return field def __getitem__(self,field_oid): """ Accessor function so that record can be treated as a dictionary. """ - if self._field_mapping.has_key(field_oid): - # field_oid is a string name - return self._record[self._field_mapping[field_oid]][1] - self._record[field_oid][1] + field = self._lookup_field(field_oid) + + return get_field_value(field) + + def __setitem__(self,field_oid,new_value): + """ + Setter function so that record can be treated as a dictionary. + """ + field = self._lookup_field(field_oid) + + if field == None: + pass # Not yet implemented + + set_field_value(field,new_value) + + + def update(self): + """ + Write any changes back to the database. + """ + print self._dbh,self._oid,self._record + return pyrapi.CeWriteRecordProps(self._dbh,self._oid,self._record) def next(self): """ Return the next field in the record. """ - for field in self._record.values(): - yield field[1] + for field in self._record: + yield field raise StopIteration @@ -62,16 +139,19 @@ def __repr__(self): s = "Record oid = %s\n" % (str(self._oid),) - s += "oid\t name\t type\t value\n\n" - for oid,field in self._record.items(): + s += "oid \tname \ttype \tvalue\n\n" + for field in self._record: if self._field_mapping == None: - s += "%s\t None\t %s\t %s\n" % (oid,field[0],field[1]) + s += "%s\t None\t %d\t " % (str(self._oid),field.propid) else: field_name = "Unknown" for mapping in self._field_mapping: - if self._field_mapping[mapping] == oid: + if self._field_mapping[mapping] == field.propid: field_name = mapping - s += "%s\t %s\t %s\t %s\n" % (str(oid),field_name,field[0],str(field[1])) + s += "%s\t %s\t %d\t" % (str(self._oid),field_name,field.propid) + s += str(get_field_value(field)) + s += "\n" + return s @@ -96,8 +176,8 @@ CeDatabase._database_list=pyrapi.CeFindAllDatabases() for db in CeDatabase._database_list: - if db[0] == self._database_name: - self._database_oid = pyrapi.CeOpenDatabase(db) + if db.DbInfo.szDbaseName == self._database_name: + self._database_oid = pyrapi.CeOpenDatabase(db.OidDb,db.DbInfo.szDbaseName) def getFieldMapping(self): return self._field_mapping @@ -115,7 +195,7 @@ if record == None: raise StopIteration - return self._record_class(record,self._field_mapping) + return self._record_class(self._database_oid,record,self._field_mapping) # list of task fields taken from Index: pyrapi_wrap.i =================================================================== RCS file: /cvsroot/synce/pyrapi/src/pyrapi_wrap.i,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pyrapi_wrap.i 27 Nov 2002 08:48:00 -0000 1.3 +++ pyrapi_wrap.i 29 Nov 2002 16:49:29 -0000 1.4 @@ -183,15 +183,15 @@ WCHARGETSET(CE_FIND_DATA,cFileName) -%typemap(python,argout) LPLPCE_FIND_DATA { +%typemap(python,argout) (LPDWORD lpdwFoundCount, LPLPCE_FIND_DATA ppFindDataArray) { PyObject *return_tuple, *o2, *o3; int i; LPCE_FIND_DATA entry; - return_tuple = PyTuple_New(*arg3); + return_tuple = PyTuple_New(*$1); //printf("Number of files: %u\n", *arg3); - entry = *$1; - for (i = 0; i < *arg3; i++) { + entry = *$2; + for (i = 0; i < *$1; i++) { if (PyTuple_SetItem(return_tuple, i, SWIG_NewPointerObj((void *)entry++, SWIGTYPE_p_CE_FIND_DATA, 0))) { PyErr_SetString(PyExc_TypeError, "failed to build return tuple."); @@ -217,17 +217,24 @@ } } -%typemap(in,numinputs=0) LPLPCE_FIND_DATA ppFindDataArray (LPCE_FIND_DATA temp) { - $1 = &temp; + +%typemap(in,numinputs=0) (LPDWORD lpdwFoundCount, LPLPCE_FIND_DATA ppFindDataArray) + (DWORD temp1, LPCE_FIND_DATA temp2) { + $1 = &temp1; + $2 = &temp2; } -%apply unsigned int *OUTPUT { LPDWORD lpdwFoundCount }; +//%apply unsigned int *OUTPUT { LPDWORD lpdwFoundCount }; %typemap(python,out) BOOL { - if (result != 1) { - PyErr_SetString(PyExc_RuntimeError, "bad return value."); - return NULL; + if (result < 1) { + { + char err[256]; + snprintf(err, sizeof(err), "Rapi function failed, last error code was: %d", CeGetLastError()); + PyErr_SetString(PyExc_RuntimeError, err); + return NULL; + } } { $result = Py_None; // Ignore a correct return @@ -250,7 +257,8 @@ HANDLE hTemplateFile = 0); -%typemap(python,in) (LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead){ +%typemap(python,in) (LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead)(DWORD tmp){ + $3 = &tmp; if (PyInt_Check($input)) { $2 = PyInt_AsLong($input); if (!($1 = ($1_ltype) malloc($2))){ @@ -264,7 +272,12 @@ } %typemap(python,argout) (LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead){ - $result = Py_BuildValue("(s#,i)",(char *)$1,*$3,*$3); + if ( *$3 == 0 ){ + $result = Py_None; + } + else { + $result = Py_BuildValue("s#",(char *)$1,*$3); + } free($1); } @@ -275,14 +288,16 @@ LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped = NULL); -%typemap(python,in) (LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten){ +%typemap(python,in) (LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten) (DWORD tmp){ + $3 = &tmp; if (PyString_Check($input)) { $1 = PyString_AsString($input); $2 = strlen($1); } else { - PyErr_SetString(PyExc_TypeError, "expected a int."); + PyErr_SetString(PyExc_TypeError, "expected a string."); return NULL; } + printf("CeWriteFile writing string (length %d): %s\n", $2, $1); } %typemap(python,argout) (LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten){ @@ -302,9 +317,10 @@ LPCSTR lpNewFileName, BOOL bFailIfExists); +//FAF_NAME|FAF_ATTRIBUTES|FAF_CREATION_TIME|FAF_LASTACCESS_TIME|FAF_LASTWRITE_TIME|FAF_SIZE_LOW, BOOL CeFindAllFiles( LPCWSTR szPath, - DWORD dwFlags = FAF_NAME|FAF_ATTRIBUTES|FAF_CREATION_TIME|FAF_LASTACCESS_TIME|FAF_LASTWRITE_TIME|FAF_SIZE_LOW, + DWORD dwFlags, LPDWORD lpdwFoundCount, LPLPCE_FIND_DATA ppFindDataArray); @@ -318,15 +334,48 @@ BOOL CeCreateDirectory( LPCWSTR lpPathName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes); + LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL); BOOL CeDeleteFile( LPCWSTR lpFileName); +%typemap(python,argout) (LPCWSTR lpFileName, LPCE_FIND_DATA lpFindFileData) { + PyObject *find_data, *o2, *o3; + + find_data = SWIG_NewPointerObj($2, SWIGTYPE_LPCE_FIND_DATA, 1); + + if ((!result) || ($result == Py_None)) { + $result = find_data; + } else { + if (!PyTuple_Check($result)) { + PyObject *o2 = $result; + $result = PyTuple_New(1); + PyTuple_SetItem($result,0,o2); + } + o3 = PyTuple_New(1); + PyTuple_SetItem(o3,0,find_data); + o2 = $result; + $result = PySequence_Concat(o2,o3); + Py_DECREF(o2); + Py_DECREF(o3); + } +} + +%typemap(in,numinputs=0) (LPCE_FIND_DATA lpFindFileData) { + $1 = (LPCE_FIND_DATA) malloc(sizeof(CE_FIND_DATA)); +} + + HANDLE CeFindFirstFile( LPCWSTR lpFileName, LPCE_FIND_DATA lpFindFileData); +%typemap(python,argout) (HANDLE hFindFile, LPCE_FIND_DATA lpFindFileData) { + PyObject *find_data; + + $result = SWIG_NewPointerObj($2, SWIGTYPE_LPCE_FIND_DATA, 1); +} + BOOL CeFindNextFile( HANDLE hFindFile, LPCE_FIND_DATA lpFindFileData); @@ -392,12 +441,13 @@ WCHARGETSET(CEVALUNION,lpwstr) typedef struct _CEPROPVAL { - CEPROPID propid; + //CEPROPID propid; WORD wLenData; WORD wFlags; CEVALUNION val; %extend { - const unsigned int type; + unsigned int type; + unsigned int propid; } } CEPROPVAL; @@ -406,7 +456,16 @@ return ptr->propid & 0xFFFF; } void CEPROPVAL_type_set(CEPROPVAL *ptr, const unsigned int value) { - // Should raise an exception. + printf("Setting propid to: %d\n", value); + ptr->propid = (ptr->propid & 0xFFFF0000) | value; + printf("propid set to: %d\n", ptr->propid); + } + const unsigned int CEPROPVAL_propid_get(CEPROPVAL *ptr) { + return (ptr->propid >> 16); + } + void CEPROPVAL_propid_set(CEPROPVAL *ptr, const unsigned int value) { + CEPROPID tmp = (CEPROPID)value; + ptr->propid = (tmp << 16) | ( ptr->propid & 0xFFFF); } %} @@ -443,9 +502,9 @@ CEOID CeCreateDatabase( LPWSTR lpszName, - DWORD dwDbaseType, - WORD wNumSortOrder, - SORTORDERSPEC *rgSortSpecs); + DWORD dwDbaseType = 0, + WORD wNumSortOrder = 0, + SORTORDERSPEC *rgSortSpecs = NULL); BOOL CeDeleteDatabase( CEOID oid); @@ -528,13 +587,19 @@ DWORD dwFlags = CEDB_AUTOINCREMENT, HWND hwndNotify); -%typemap(in,numinputs=0) (LPWORD lpcPropID, - CEPROPID *rgPropID, - LPBYTE *lplpBuffer, - LPDWORD lpcbBuffer) (WORD temp1, - CEPROPID temp2, - BYTE *temp3, - DWORD temp4){ + +/* + * typemaps to support CeReadRecordProps + */ + +%typemap(in,numinputs=0) + (LPWORD lpcPropID, + CEPROPID *rgPropID, + LPBYTE *lplpBuffer, + LPDWORD lpcbBuffer) (WORD temp1, + CEPROPID temp2, + BYTE *temp3, + DWORD temp4){ $1 = &temp1; $2 = NULL; $3 = &temp3; @@ -546,17 +611,21 @@ PyObject *return_tuple, *o2, *o3; int i; PCEPROPVAL entry; - return_tuple = PyTuple_New(*arg3); - //printf("Number of databases: %u\n", *arg3); - entry = ( PCEPROPVAL )*$1; - for (i = 0; i < *arg3; i++) { - if (PyTuple_SetItem(return_tuple, i, - SWIG_NewPointerObj((void *)entry++, SWIGTYPE_p_CEPROPVAL, 0))) { - PyErr_SetString(PyExc_TypeError, "failed to build return tuple."); - return NULL; - } + if ( *arg3 > 0 ) { + return_tuple = PyTuple_New(*arg3); + + entry = ( PCEPROPVAL )*$1; + for (i = 0; i < *arg3; i++) { + if (PyTuple_SetItem(return_tuple, i, + SWIG_NewPointerObj((void *)entry++, SWIGTYPE_p_CEPROPVAL, 0))) { + PyErr_SetString(PyExc_TypeError, "failed to build return tuple."); + return NULL; + } + } + } else { + return_tuple = Py_None; } if ((!result) || ($result == Py_None)) { @@ -589,6 +658,49 @@ DWORD dwSeekType, DWORD dwValue, LPDWORD lpdwIndex); + +/* + * typemaps to support CeWriteRecordProps + * + * CeWriteRecordProps (dbh, rec_oid, values) + * Returns the rec_oid for success 0 for failure. + * values is a tuple of of CEPROPVAL classes. + */ + +%typemap(in) (WORD cPropID, + CEPROPVAL *rgPropVal) { + + int i; + CEPROPVAL * tmp; + + if (PyTuple_Check($input)) { + /* get size of tuple */ + $1 = PyTuple_Size($input); + + printf("Got %d fields to write.", $1); + + /* create array of CEPROPVAL elements */ + $2 = (CEPROPVAL *) malloc($1*sizeof(CEPROPVAL)); + + /* unpack argument tuple into array */ + for ( i = 0; i < $1; i++) { + if ((SWIG_ConvertPtr(PyTuple_GetItem($input,i),(void **) &tmp, + SWIGTYPE_p_CEPROPVAL,SWIG_POINTER_EXCEPTION | 0 )) == -1) + SWIG_fail; + memcpy(&($2[i]),tmp, sizeof(CEPROPVAL)); + printf ("propid & 0xFFFF = %d\n", ($2[i].propid & 0xFFFF)); + printf ("propid >> 16 = %d\n", ($2[i].propid >> 16)); + } + for ( i = 0; i < $1; i++) { + printf ("real propid & 0xFFFF = %d\n", (($2[i].propid) & 0xFFFF)); + printf ("real propid >> 16 = %d\n", (($2[i].propid) >> 16)); + } + } else { + PyErr_SetString(PyExc_TypeError, "expected a tuple."); + return NULL; + } +} + CEOID CeWriteRecordProps( HANDLE hDbase, Index: rapi.py =================================================================== RCS file: /cvsroot/synce/pyrapi/src/rapi.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- rapi.py 23 Sep 2002 17:52:27 -0000 1.1.1.1 +++ rapi.py 29 Nov 2002 16:49:29 -0000 1.2 @@ -15,8 +15,14 @@ mode must be 'w' for writing to a file and 'r' for reading from a file. Returns a CeFile object. Raises an exception if the file could not be opened.""" + + if mode == 'r': + file_handle = pyrapi.CeCreateFile(file_name,pyrapi.GENERIC_READ) + elif mode == 'w': + file_handle = pyrapi.CeCreateFile(file_name,pyrapi.GENERIC_WRITE, 0, pyrapi.CREATE_ALWAYS) + else: + raise RapiException, "Unknown file mode" - file_handle = pyrapi.CeCreateFile(file_name,mode) return CeFile(file_handle,mode) @@ -47,9 +53,8 @@ buf = '' while 1: res = pyrapi.CeReadFile(self._file_handle,self._read_buffer_size) - if res == None: break - - buf = buf + res[0] + if res == None or res == "": break + buf = buf + res return buf @@ -57,12 +62,13 @@ """Write the contents of buffer to the file.""" if self._mode != 'w': raise RapiException,"Attempt to write to file not in write mode" - + return pyrapi.CeWriteFile(self._file_handle,buffer) def close(self): """Close the open file handle.""" - pyrapi.CeCloseHandle(self._file_handle) + if self._file_handle != -1: + pyrapi.CeCloseHandle(self._file_handle) self._set_defaults() --- pyrapi.c DELETED --- |