📄 pblisam.c
字号:
okeylen = 8; } else if( okeylen == 18 ) { okeylen = 17; } okey[ okeylen ] = 0; /* * position the current record of the main file to the allkeys record */ datalen = pblKfFind( isam->mainfile, PBLFI, okey, okeylen, 0, 0 ); if( datalen < 0 ) { pbl_errno = PBL_ERROR_BAD_FILE; return( -1 ); } } pbl_errno = saveerrno; return( 0 );}/** * insert a new record with the given keys and data into the isam file, * * the current record of the file will be set to the new record * * <P> * <B>RESTRICTIONS</B>: * <BR> - the file must be open for update, * <BR> - allkeys must point to the keys to be inserted, * <BR> - allkeyslen must be bigger than 0 and smaller than 1024, * <BR> - data must point to the data be inserted, * <BR> - datalen must not be negative, * <BR> - if datalen == 0, the pointer data is not evaluated at all * * Parameter <I>allkeys</I> must contain all values for all keys * of the record. The values have to be prepended by one byte giving * the length of the following value. All values have to be concatenated * into one string. * * Example: * <PRE> 4isam4file3key </PRE> * with the numbers as binary values and the letters ascii, * specifies three keys with the values "isam", "file" and "key". * * @return int rc == 0: call went ok * @return int rc != 0: some error occured, see pbl_errno */int pblIsamInsert(pblIsamFile_t * isamfile, /** ISAM file to insert to */unsigned char * allkeys, /** pointers to all keys to insert */int allkeyslen, /** total length of all keys to insert */unsigned char * data, /** data to insert */long datalen /** length of the data */){ PBLISAMFILE_t * isam = ( PBLISAMFILE_t * ) isamfile; unsigned long lastkeyhigh = 0; unsigned long lastkeylow = 0; char rkey[ PBLKEYLENGTH ]; int rkeylen; char okey[ PBLKEYLENGTH ]; int okeylen; int ndatarecords = 0; int n = 0; int rc; unsigned char * ldata; long ldatalen; unsigned char * key; int keylen; /* * start a transaction */ pblIsamStartTransaction( 1, &isamfile ); /* * the sum of the length of all keys * cannot be longer than a single data record */ if( allkeyslen > PBLDATALENGTH ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_PARAM_KEYLEN; return( -1 ); } /* * find out the last key used in the main file */ if( pblKfLast( isam->mainfile, okey, &okeylen ) < 0 ) { if( pbl_errno != PBL_ERROR_NOT_FOUND ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); return( -1 ); } /* * 00000000 is the smallest key we use in the main file */ strcpy( okey, "00000000" ); okeylen = 8; } /* * generate the next key, a 64 bit logic is used in order to make * sure we never run out of new keys */ if( *okey == 'g' ) { /* * values over unsigned 0xffffffff are represented * as 17 byte strings with a preceding "g" */ okey[ 17 ] = 0; lastkeylow = strtoul( okey + 9, 0, 16 ); okey[ 9 ] = 0; lastkeyhigh = strtoul( okey + 1, 0, 16 ); } else { /* * values below unsigned 0xffffffff are represented * as 8 byte strings we no prefix */ okey[ 8 ] = 0; lastkeylow = strtoul( okey, 0, 16 ); } if( lastkeylow == 0xffffffff ) { /* * 32 bit overflow */ lastkeylow = 0; lastkeyhigh += 1; } else { lastkeylow += 1; } if( lastkeyhigh ) { snprintf( okey, PBLKEYLENGTH, "g%08lx%08lx", lastkeyhigh, lastkeylow ); } else { snprintf( okey, PBLKEYLENGTH, "%08lx", lastkeylow ); } okeylen = strlen( okey ); /* * create the reference key used as link to the main file */ rkeylen = pblMainKey2RKey( okey, okeylen, rkey ); if( rkeylen < 1 ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); return( -1 ); } /* * insert all the keys into the key files */ for( key = allkeys, n = 0; n < isam->nkeys; n++ ) { keylen = 0xff & *key++; if( keylen < 1 ) { /* * non duplicate keys cannot be empty */ if( !isam->keydup[ n ] ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_PARAM_KEY; return( -1 ); } } /* * check the sanity of the allkeys record given */ if( key + keylen > allkeys + allkeyslen ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_PARAM_KEY; return( -1 ); } /* * if the key is allowing duplicates */ if( isam->keydup[ n ] ) { unsigned char ikey[ PBLKEYLENGTH ]; /* * create a unique key for the insert */ if( keylen + rkeylen > PBLKEYLENGTH ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_PARAM_KEYLEN; return( -1 ); } /* * concatenate the key and the reference key * the reference key is used as postfix of the index key */ if( keylen ) { memcpy( ikey, key, keylen ); } memcpy( ikey + keylen, rkey, rkeylen ); /* * make sure any user defined key compare function gets used */ pblkeycompare = isam->keycompare[ n ]; /* * search for the key in the file */ if( pblKfFind( isam->keyfiles[ n ], PBLEQ, ikey, keylen + rkeylen, 0, 0 ) >= 0 ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_EXISTS; return( -1 ); } /* * insert the key to the file */ if( pblKfInsert( isam->keyfiles[ n ], ikey, keylen + rkeylen, 0, 0 )) { int saveerrno = pbl_errno; /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = saveerrno; return( -1 ); } } else { /* * search for the key in the file */ if( pblKfFind( isam->keyfiles[ n ], PBLEQ, key, keylen, 0, 0 ) >= 0 ) { /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_EXISTS; return( -1 ); } /* * insert the key to the file * the reference key is the data of the record in the index */ if( pblKfInsert( isam->keyfiles[ n ], key, keylen, rkey, rkeylen )) { int saveerrno = pbl_errno; /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = saveerrno; return( -1 ); } } /* * move the key along the record */ key += keylen; } /* * insert the data records into the main file */ for( ldata = data, ndatarecords = 0; ; ndatarecords++ ) { ldatalen = datalen - ndatarecords * PBLDATALENGTH; if( ldatalen < 0 ) { break; } if( ldatalen > PBLDATALENGTH ) { ldatalen = PBLDATALENGTH; } /* * the data records in the main file use a 9/18 byte * version of the main key string, including the trailing \0 * we use the trailing \0 of the main key in order to differentiate * between the allkeys record and the data records */ if( pblKfInsert( isam->mainfile, okey, okeylen + 1, ldata, ldatalen )) { int saveerrno = pbl_errno; /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = saveerrno; return( -1 ); } if( ldatalen < PBLDATALENGTH ) { break; } ldata += ldatalen; } /* * insert the record for the keys into the main file * the "allkeys" record in the main file uses the 8/17 byte main key */ rc = pblKfInsert( isam->mainfile, okey, okeylen, allkeys, allkeyslen ); if( rc ) { int saveerrno = pbl_errno; /* * rollback all changes */ pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = saveerrno; return( -1 ); } /* * commit all changes */ if( pblIsamCommit( 1, &isamfile, 0 )) { return( -1 ); } return( 0 );}/** * delete the current record of the ISAM file. * * the current record of the file is set to the next record or * if the last record is deleted, to the previous record, * * if there are no more records in the file after the delete * the current record is of course unpositioned * * <P> * <B>RESTRICTIONS</B>: * <BR> - the file must be open for update, * * @return int rc == 0: call went ok * @return int rc != 0: some error occured, see pbl_errno */int pblIsamDelete(pblIsamFile_t * isamfile /** ISAM file to delete from */){ PBLISAMFILE_t * isam = ( PBLISAMFILE_t * ) isamfile; char okey[ PBLKEYLENGTH ]; int okeylen; char rkey[ PBLKEYLENGTH ]; int rkeylen = -1; unsigned char * key; int keylen; unsigned char data[ PBLDATALENGTH ]; long datalen; long rc; int n; int retval = 0; /* * start a transaction */ pblIsamStartTransaction( 1, &isamfile ); /* * read the key of the current record in the main file */ datalen = pblKfThis( isam->mainfile, okey, &okeylen ); if( datalen < 0 ) { pblIsamCommit( 1, &isamfile, 1 ); return( -1 ); } /* * length 8 or 17 is for allkeys records * if the length is 9 or 18, the record is a data record */ if( okeylen != 8 && okeylen != 17 ) { pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_POSITION; return( -1 ); } okey[ okeylen ] = 0; /* * the allkeys record can not be longer than a single data record */ if( datalen > PBLDATALENGTH ) { pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_BAD_FILE; return( -1 ); } /* * read all the keys */ rc = pblKfRead( isam->mainfile, data, datalen ); if( rc < 0 ) { pblIsamCommit( 1, &isamfile, 1 ); return( -1 ); } else if( rc != datalen ) { pblIsamCommit( 1, &isamfile, 1 ); pbl_errno = PBL_ERROR_BAD_FILE; return( -1 ); } /* * delete all the keys from the key files */ for( key = data, n = 0; n < isam->nkeys; n++ ) { keylen = 0xff & *key++; /* * check the sanity of the allkeys record given */ if( key + keylen > data + datalen ) { pbl_errno = PBL_ERROR_BAD_FILE; retval = -1; continue; } /* * if the key is allowing duplicates */ if( isam->keydup[ n ] ) { unsigned char ikey[ PBLKEYLENGTH ]; /* * a non unique key is deleted, we need the reference key */ if( rkeylen < 0 ) { rkeylen = pblMainKey2RKey( okey, okeylen, rkey ); } if( rkeylen < 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -