G:/ScriptBasic/source/extensions/bdb/interface.c

Go to the documentation of this file.
00001 /* 
00002 
00003   FILE   : interface.c
00004   HEADER : interface.h
00005   AUTHOR: Peter Verhas
00006 
00007   for the ScriptBasic extension module to access Berkeley DB files.
00008 
00009   v2.0
00010 
00011 
00012 These lines are needed by the configurator to generate the file 'libraries.jim'
00013 NTLIBS: libdb41s.lib
00014 UXLIBS: -lbdb
00015 
00016 */
00017 #include <sys/types.h>
00018 
00019 #include <errno.h>
00020 #include <stddef.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 #include <db.h>
00026 
00027 #include "../../basext.h"
00028 
00029 
00030 #define BDB_ERROR_INVALID_FILE_NAME      0x00080001
00031 #define BDB_ERROR_INVALID_DB_HANDLE      0x00080002
00032 #define BDB_ERROR_TRANSACTION_NOT_CLOSED 0x00080003
00033 #define BDB_ERROR_TRANSACTION_NOT_OPENED 0x00080004
00034 #define BDB_ERROR_KEY_NOT_FOUND          0x00080005
00035 #define BDB_INCOMPLETE                   0x00080006
00036 #define BDB_KEYEMPTY                     0x00080007
00037 #define BDB_KEYEXIST                     0x00080008
00038 #define BDB_LOCK_DEADLOCK                0x00080009
00039 #define BDB_LOCK_NOTGRANTED              0x0008000A
00040 #define BDB_NOTFOUND                     0x0008000B
00041 #define BDB_OLD_VERSION                  0x0008000C
00042 #define BDB_RUNRECOVERY                  0x0008000D
00043 #define BDB_DELETED                      0x0008000E
00044 #define BDB_NEEDSPLIT                    0x0008000F
00045 #define BDB_SWAPBYTES                    0x00080010
00046 #define BDB_TXN_CKP                      0x00080011
00047 
00048 typedef struct _MyDb {
00049   DB *pdb;
00050   DBC *pCursor;
00051   DB_TXN *txnid;
00052 
00053   struct _MyDb *next,*prev;
00054   } MyDb, *pMyDb;
00055 
00056 /*
00057  The module object that the module pointer points to. This
00058 stores the "global" variables for the actual interpreter
00059 thread. The name BdbObject stands for Berkeley Data Base Object.
00060 */
00061 typedef struct _BdbObject {
00062   DB_ENV *dbenv;
00063   u_int32_t flags;
00064   int UnixMode;
00065   int InTransaction; /* true if we are in a transaction*/
00066   pMyDb pDbList;
00067   } BdbObject, *pBdbObject;
00068 
00069 static unsigned long ConvertBdbErrors(int BdbError){
00070   switch( BdbError ){
00071 #ifdef DB_INCOMPLETE
00072     case DB_INCOMPLETE       : return BDB_INCOMPLETE      ;
00073 #endif
00074     case DB_KEYEMPTY         : return BDB_KEYEMPTY        ;
00075     case DB_KEYEXIST         : return BDB_KEYEXIST        ;
00076     case DB_LOCK_DEADLOCK    : return BDB_LOCK_DEADLOCK   ;
00077     case DB_LOCK_NOTGRANTED  : return BDB_LOCK_NOTGRANTED ;
00078     case DB_NOTFOUND         : return BDB_NOTFOUND        ;
00079     case DB_OLD_VERSION      : return BDB_OLD_VERSION     ;
00080     case DB_RUNRECOVERY      : return BDB_RUNRECOVERY     ;
00081     case DB_DELETED          : return BDB_DELETED         ;
00082     case DB_NEEDSPLIT        : return BDB_NEEDSPLIT       ;
00083     case DB_SWAPBYTES        : return BDB_SWAPBYTES       ;
00084     case DB_TXN_CKP          : return BDB_TXN_CKP         ;
00085     }
00086   return (unsigned long)BdbError;
00087   }
00088 
00089 besVERSION_NEGOTIATE
00090 
00091   return (int)INTERFACE_VERSION;
00092 
00093 besEND
00094 
00095 /*
00096 int
00097 db_appinit(char *db_home,
00098     char * const *db_config, DB_ENV *dbenv, u_int32_t flags);
00099 
00100 
00101 */
00102 besSUB_START
00103   pBdbObject p;
00104   char *pszConfigBdbHome,*s;
00105   int iConfigLines,i;
00106 
00107   besMODULEPOINTER = besALLOC(sizeof(BdbObject));
00108   if( besMODULEPOINTER == NULL )return COMMAND_ERROR_MEMORY_LOW;
00109   p = (pBdbObject)besMODULEPOINTER;
00110 
00111   p->InTransaction = 0;
00112   p->pDbList = NULL;
00113 
00114   if( s = besCONFIG("bdb.mode") )
00115     p->UnixMode = atoi(s);
00116   else
00117     p->UnixMode = 0;
00118 
00119 #define X(A,B) A = besCONFIG(B);\
00120                if( A && !*A )A=NULL;\
00121                if( A )iConfigLines++;
00122 
00123   iConfigLines = 0;
00124   X(pszConfigBdbHome   ,"bdb.dir.home")
00125 
00126   p->flags = 0;
00127 #undef X
00128 #define X(A,B) if( besCONFIG(B) && !strcmp(besCONFIG(B),"yes") )p->flags |= A;
00129 
00130   X(DB_CREATE          ,"bdb.flags.create")
00131   X(DB_INIT_CDB        ,"bdb.flags.init_cdb")
00132   X(DB_INIT_LOCK       ,"bdb.flags.init_lock")
00133   X(DB_INIT_LOG        ,"bdb.flags.init_log")
00134   X(DB_INIT_MPOOL      ,"bdb.flags.init_mpool")
00135   X(DB_INIT_TXN        ,"bdb.flags.init_txn")
00136   X(DB_PRIVATE         ,"bdb.flags.private")
00137   X(DB_NOMMAP          ,"bdb.flags.nommap")
00138   X(DB_RECOVER         ,"bdb.flags.recover")
00139   X(DB_RECOVER_FATAL   ,"bdb.flags.recover_fatal")
00140   X(DB_THREAD          ,"bdb.flags.thread")
00141   X(DB_TXN_NOSYNC      ,"bdb.flags.txn_nosync")
00142   X(DB_USE_ENVIRON     ,"bdb.flags.use_environ")
00143   X(DB_USE_ENVIRON_ROOT,"bdb.flags.use_environ_root")
00144   X(DB_LOCKDOWN        ,"bdb.flags.lockdown")
00145   X(DB_SYSTEM_MEM      ,"bdb.flags.system_mem")
00146 
00147   p->dbenv = NULL;
00148   if( i = db_env_create(&(p->dbenv),0) ){
00149     return i|0x80000000; 
00150     }
00151 
00152 #undef X
00153 #define X(A,B) if( s=besCONFIG(A) )p->dbenv->B = atol(s);
00154 #ifdef DB_INCOMPLETE
00155   X("bdb.limits.lg_max"     ,lg_max)
00156 #else
00157   if( s=besCONFIG("bdb.limits.lg_max") )p->dbenv->set_lg_max(p->dbenv,atol(s));
00158 #endif
00159   X("bdb.limits.mp_mmapsize",mp_mmapsize)
00160   X("bdb.limits.mp_size"    ,mp_size)
00161   X("bdb.limits.tx_max"     ,tx_max)
00162   X("bdb.limits.lk_max"     ,lk_max)
00163 
00164 #undef X
00165 
00166   if( s=besCONFIG("bdb.lockstrategy") ){
00167     if( !strcmp(s,"default" ) )p->dbenv->lk_detect = DB_LOCK_DEFAULT; else
00168     if( !strcmp(s,"oldest"  ) )p->dbenv->lk_detect = DB_LOCK_OLDEST;  else
00169     if( !strcmp(s,"random"  ) )p->dbenv->lk_detect = DB_LOCK_RANDOM;  else
00170     if( !strcmp(s,"youngest") )p->dbenv->lk_detect = DB_LOCK_YOUNGEST;
00171     }
00172 
00173   if( s = besCONFIG("bdb.dir.data") )
00174     p->dbenv->set_data_dir(p->dbenv,s);
00175   if( s = besCONFIG("bdb.dir.log") )
00176     p->dbenv->set_lg_dir(p->dbenv,s);
00177   if( s = besCONFIG("bdb.dir.temp") )
00178     p->dbenv->set_tmp_dir(p->dbenv,s);
00179 
00180   if( i=p->dbenv->open(p->dbenv,pszConfigBdbHome,p->flags,p->UnixMode) ){
00181     besMODULEPOINTER = NULL;
00182     besFREE(p);
00183     return i|0x80000000;
00184     }
00185 
00186   return 0;
00187 besEND
00188 
00189 besSUB_FINISH
00190   pBdbObject p;
00191   pMyDb pTable;
00192 
00193   p = (pBdbObject)besMODULEPOINTER;
00194 
00195   if( p == NULL )return 0;
00196 
00197   /* if an unhandled error occured or databse remained open */
00198   pTable = p->pDbList;
00199   while( pTable ){
00200     if( pTable->txnid )txn_abort(pTable->txnid);
00201     pTable->txnid = NULL;
00202     if( pTable->pCursor )
00203       pTable->pCursor->c_close(pTable->pCursor);
00204     if( pTable->pdb )
00205       pTable->pdb->close(pTable->pdb,0);
00206     pTable = pTable->next;
00207     }
00208 
00209   p->dbenv->close(p->dbenv,0);
00210 
00211   return 0;
00212 besEND
00213 
00214 /*
00215 
00216 int
00217 db_open(const char *file,
00218         DBTYPE type,  // DB_BTREE, DB_HASH, DB_RECNO or DB_UNKNOWN (should exist)
00219         u_int32_t flags, // DB_CREATE, DB_NOMMAP, DB_RDONLY, DB_THREAD, DB_TRUNCATE
00220         int mode, // unix access mode bits
00221         DB_ENV *dbenv,
00222         DB_INFO *dbinfo,
00223         DB **dbpp);
00224 
00225 */
00226 besFUNCTION(sb_db_open)
00227   pBdbObject p;
00228   VARIABLE Argument;
00229   char *pszFileName;
00230   long lflags;
00231   u_int32_t flags;
00232   DBTYPE type;
00233   int mode;
00234   DB *dbpp;
00235   pMyDb pTable;
00236   int ret;
00237 
00238 
00239   p = (pBdbObject)besMODULEPOINTER;
00240 
00241   /* get the file name */
00242   Argument = besARGUMENT(1);
00243   besDEREFERENCE(Argument);
00244   if( Argument == NULL ){
00245     besRETURNVALUE = NULL;
00246     return BDB_ERROR_INVALID_FILE_NAME;
00247     }
00248   besCONVERT2ZCHAR(Argument,pszFileName);
00249 
00250   /* get the type */
00251   Argument = besARGUMENT(2);
00252   besDEREFERENCE(Argument);
00253   besCONVERT2LONG(Argument);
00254   if( Argument )
00255     type = (DBTYPE)LONGVALUE(Argument);
00256   else
00257     type = 0;
00258   switch( type ){
00259     case 1: type = DB_BTREE;   break;
00260     case 2: type = DB_HASH;    break;
00261     case 4: type = DB_RECNO;   break;
00262     case 8: type = DB_QUEUE;   break;
00263     default:
00264     case 16: type = DB_UNKNOWN; break;
00265     }
00266 
00267   /* get the flags */
00268   Argument = besARGUMENT(3);
00269   besDEREFERENCE(Argument);
00270   besCONVERT2LONG(Argument);
00271   if( Argument )
00272     lflags = ~ LONGVALUE(Argument);
00273   else
00274     lflags = 0;
00275   flags = 0;
00276   if( lflags & 0x01 )flags |= DB_CREATE;
00277   if( lflags & 0x02 )flags |= DB_NOMMAP;
00278   if( lflags & 0x04 )flags |= DB_RDONLY;
00279   if( lflags & 0x08 )flags |= DB_THREAD;
00280   if( lflags & 0x10 )flags |= DB_TRUNCATE;
00281   if( lflags & 0x20 )flags |= DB_EXCL;
00282 
00283   /* get the file mode */
00284   Argument = besARGUMENT(4);
00285   besDEREFERENCE(Argument);
00286   besCONVERT2LONG(Argument);
00287   if( Argument )
00288     mode = (int)LONGVALUE(Argument);
00289   else
00290     mode = p->UnixMode;
00291 
00292   ret = db_create(&dbpp,p->dbenv,0);
00293   if( ret ){
00294     besFREE(pszFileName);
00295     besRETURNVALUE = NULL;
00296     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00297     }
00298 
00299   dbpp->set_flags( dbpp,DB_DUP );
00300   ret = dbpp->open(dbpp,
00301 #ifndef DB_INCOMPLETE
00302                    NULL,
00303 #endif
00304                    pszFileName,
00305                    NULL, /* sub databases are not supported yet */
00306                    type,
00307                    flags,
00308                    mode);
00309   besFREE(pszFileName);
00310   if( ret ){
00311     besRETURNVALUE = NULL;
00312     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00313     }
00314   pTable = besALLOC(sizeof(MyDb));
00315   if( pTable == NULL )return COMMAND_ERROR_MEMORY_LOW;
00316 
00317   pTable->next = p->pDbList;
00318   if( pTable->next )pTable->next->prev = pTable;
00319   p->pDbList = pTable;
00320   pTable->prev = NULL;
00321 
00322   if( p->InTransaction ){
00323     ret = txn_begin(p->dbenv, NULL, &(pTable->txnid),0);
00324     if( ret )
00325       return ConvertBdbErrors(ret);
00326     }else{
00327     pTable->txnid = NULL;
00328     }
00329 
00330   pTable->pdb = dbpp;
00331   ret = dbpp->cursor(pTable->pdb,pTable->txnid,&(pTable->pCursor),0);
00332   if( ret ){
00333     besRETURNVALUE = NULL;
00334     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00335     }
00336   besALLOC_RETURN_STRING(sizeof(pMyDb));
00337   memcpy(STRINGVALUE(besRETURNVALUE),&pTable,sizeof(DB *));
00338   return COMMAND_ERROR_SUCCESS;
00339 besEND
00340 
00341 /* int
00342 DB->close(DB *db, u_int32_t flags);
00343 
00344 */
00345 besFUNCTION(sb_db_close)
00346   VARIABLE Argument;
00347   DB *dbpp;
00348   int ret;
00349   pMyDb pTable;
00350   pBdbObject p;
00351 
00352   p = (pBdbObject)besMODULEPOINTER;
00353 
00354   besRETURNVALUE = NULL;
00355 
00356   /* get the db argument */
00357   Argument = besARGUMENT(1);
00358   besDEREFERENCE(Argument);
00359   if( Argument == NULL ||
00360       Argument->vType != VTYPE_STRING ||
00361       STRLEN(Argument) != sizeof(DB*) ){
00362     return BDB_ERROR_INVALID_DB_HANDLE;
00363     }
00364   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00365   dbpp = pTable->pdb;
00366   if( pTable->pCursor )
00367     pTable->pCursor->c_close(pTable->pCursor);
00368   ret = dbpp->close(dbpp,0);
00369 
00370   if( pTable->prev )
00371     pTable->prev = pTable->next;
00372   else
00373     p->pDbList = pTable->next;
00374   if( pTable->next )pTable->next = pTable->prev;
00375 
00376   /* if a table is closed with open transaction then the transaction is aborted */
00377   if( pTable->txnid )txn_abort(pTable->txnid);
00378 
00379   besFREE(pTable);
00380   if( ret )
00381     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00382   return COMMAND_ERROR_SUCCESS;
00383 besEND
00384 
00385 /*
00386 
00387 int
00388 DB->put(DB *db,
00389     DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
00390 
00391 */
00392 besFUNCTION(sb_db_put)
00393   pBdbObject p;
00394   VARIABLE Argument;
00395   DB *dbpp;
00396   int ret;
00397   DBT key,data;
00398   pMyDb pTable;
00399   long lflags;
00400   u_int32_t flags;
00401 
00402   p = (pBdbObject)besMODULEPOINTER;
00403   besRETURNVALUE = NULL;
00404 
00405   /* get the db argument */
00406   Argument = besARGUMENT(1);
00407   besDEREFERENCE(Argument);
00408   if( Argument == NULL ||
00409       Argument->vType != VTYPE_STRING ||
00410       STRLEN(Argument) != sizeof(DB*) ){
00411     return BDB_ERROR_INVALID_DB_HANDLE;
00412     }
00413   memcpy(&pTable,STRINGVALUE(Argument),sizeof(pMyDb));
00414   dbpp = pTable->pdb;
00415 
00416   memset(&key, 0, sizeof(DBT));
00417         memset(&data, 0, sizeof(DBT));
00418   /* get the key */
00419   Argument = besARGUMENT(2);
00420   besDEREFERENCE(Argument);
00421   if( Argument == NULL ){
00422     key.data = "";
00423     key.size = 0;
00424     }else{
00425     Argument = besCONVERT2STRING(Argument);
00426     key.data = STRINGVALUE(Argument);
00427     key.size = STRLEN(Argument);
00428     }
00429 
00430   /* get the data */
00431   Argument = besARGUMENT(3);
00432   besDEREFERENCE(Argument);
00433   if( Argument == NULL ){
00434     data.data = "";
00435     data.size = 0;
00436     }else{
00437     Argument = besCONVERT2STRING(Argument);
00438     data.data = STRINGVALUE(Argument);
00439     data.size = STRLEN(Argument);
00440     }
00441 
00442   /* get the flags */
00443   Argument = besARGUMENT(4);
00444   besDEREFERENCE(Argument);
00445   besCONVERT2LONG(Argument);
00446   if( Argument )
00447     lflags = ~ LONGVALUE(Argument);
00448   else
00449     lflags = 0;
00450   flags = 0;
00451   if( lflags & 0x01 )flags |= DB_APPEND;
00452   if( lflags & 0x02 )flags |= DB_NOOVERWRITE;
00453 
00454   /* here we call "put" to update the last read record */
00455   ret = dbpp->put(dbpp,pTable->txnid,&key,&data,flags);
00456 
00457   if( ret )
00458     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00459 
00460   return COMMAND_ERROR_SUCCESS;
00461 besEND
00462 
00463 besFUNCTION(sb_db_get)
00464   pBdbObject p;
00465   VARIABLE Argument;
00466   DB *dbpp;
00467   int ret;
00468   DBT key,data;
00469   pMyDb pTable;
00470   u_int32_t flags;
00471 
00472   flags = DB_SET_RANGE;
00473   p = (pBdbObject)besMODULEPOINTER;
00474   besRETURNVALUE = NULL;
00475 
00476   /* get the db argument */
00477   Argument = besARGUMENT(1);
00478   besDEREFERENCE(Argument);
00479   if( Argument == NULL ||
00480       Argument->vType != VTYPE_STRING ||
00481       STRLEN(Argument) != sizeof(DB*) ){
00482     return BDB_ERROR_INVALID_DB_HANDLE;
00483     }
00484   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00485   dbpp = pTable->pdb;
00486 
00487   memset(&key, 0, sizeof(DBT));
00488   /* get the key */
00489   Argument = besARGUMENT(2);
00490   besDEREFERENCE(Argument);
00491   if( Argument == NULL ){
00492     flags = DB_FIRST;
00493     key.data = "";
00494     key.size =  0;
00495     }else{
00496     Argument = besCONVERT2STRING(Argument);
00497     key.data = STRINGVALUE(Argument);
00498     key.size = STRLEN(Argument);
00499     }
00500 
00501   if( pTable->txnid )flags |= DB_RMW;
00502 
00503         memset(&data, 0, sizeof(DBT));
00504   data.data = NULL;
00505   data.ulen = 0;
00506   data.flags = DB_DBT_USERMEM;
00507 
00508   /* here we call "get" to retrieve the neccessary size. Get should return ENOMEM */
00509   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,flags);
00510   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00511   if( ret && ret != ENOMEM )
00512     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00513 
00514   besALLOC_RETURN_STRING(data.size);
00515   data.data = STRINGVALUE(besRETURNVALUE);
00516   data.ulen = STRLEN(besRETURNVALUE);
00517   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,flags);
00518   if( ret )
00519     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00520 
00521   return COMMAND_ERROR_SUCCESS;
00522 besEND
00523 
00524 besFUNCTION(sb_db_next)
00525   pBdbObject p;
00526   VARIABLE Argument;
00527   DB *dbpp;
00528   int ret;
00529   DBT key,data;
00530   pMyDb pTable;
00531 
00532   p = (pBdbObject)besMODULEPOINTER;
00533   besRETURNVALUE = NULL;
00534 
00535   /* get the db argument */
00536   Argument = besARGUMENT(1);
00537   besDEREFERENCE(Argument);
00538   if( Argument == NULL ||
00539       Argument->vType != VTYPE_STRING ||
00540       STRLEN(Argument) != sizeof(DB*) ){
00541     return BDB_ERROR_INVALID_DB_HANDLE;
00542     }
00543   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00544   dbpp = pTable->pdb;
00545 
00546   memset(&key, 0, sizeof(DBT));
00547   /* get the key */
00548   Argument = besARGUMENT(2);
00549   besDEREFERENCE(Argument);
00550   if( Argument == NULL ){
00551     key.data = "";
00552     key.size =  0;
00553     }else{
00554     Argument = besCONVERT2STRING(Argument);
00555     key.data = STRINGVALUE(Argument);
00556     key.size = STRLEN(Argument);
00557     }
00558 
00559         memset(&data, 0, sizeof(DBT));
00560   data.data = NULL;
00561   data.ulen = 0;
00562   data.flags = DB_DBT_USERMEM;
00563 
00564   /* here we call "get" to retrieve the neccessary size. Get should return ENOMEM */
00565   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_NEXT);
00566   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00567   if( ret && ret != ENOMEM )
00568     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00569 
00570   besALLOC_RETURN_STRING(data.size);
00571   data.data = STRINGVALUE(besRETURNVALUE);
00572   data.ulen = STRLEN(besRETURNVALUE);
00573   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_NEXT);
00574   if( ret )
00575     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00576 
00577   return COMMAND_ERROR_SUCCESS;
00578 besEND
00579 
00580 /* return the key of the current record */
00581 besFUNCTION(sb_db_key)
00582   pBdbObject p;
00583   VARIABLE Argument;
00584   DB *dbpp;
00585   int ret;
00586   DBT key,data;
00587   pMyDb pTable;
00588 
00589   p = (pBdbObject)besMODULEPOINTER;
00590   besRETURNVALUE = NULL;
00591 
00592   /* get the db argument */
00593   Argument = besARGUMENT(1);
00594   besDEREFERENCE(Argument);
00595   if( Argument == NULL ||
00596       Argument->vType != VTYPE_STRING ||
00597       STRLEN(Argument) != sizeof(DB*) ){
00598     return BDB_ERROR_INVALID_DB_HANDLE;
00599     }
00600   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00601   dbpp = pTable->pdb;
00602 
00603   memset(&key, 0, sizeof(DBT));
00604   key.data = NULL;
00605   key.ulen =  0;
00606   key.flags = DB_DBT_USERMEM;
00607 
00608         memset(&data, 0, sizeof(DBT));
00609   data.data = NULL;
00610   data.ulen = 0;
00611   data.flags = DB_DBT_USERMEM;
00612 
00613   /* here we call "get" to retrieve the neccessary size. Get should return ENOMEM */
00614   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_CURRENT);
00615   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00616   if( ret && ret != ENOMEM )
00617     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00618 
00619   besALLOC_RETURN_STRING(key.size);
00620   key.data = STRINGVALUE(besRETURNVALUE);
00621   key.ulen = STRLEN(besRETURNVALUE);
00622 
00623   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_CURRENT);
00624   if( ret && ret != ENOMEM )
00625     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00626 
00627   return COMMAND_ERROR_SUCCESS;
00628 besEND
00629 
00630 
00631 besFUNCTION(sb_db_prev)
00632   pBdbObject p;
00633   VARIABLE Argument;
00634   DB *dbpp;
00635   int ret;
00636   DBT key,data;
00637   pMyDb pTable;
00638 
00639   p = (pBdbObject)besMODULEPOINTER;
00640   besRETURNVALUE = NULL;
00641 
00642   /* get the db argument */
00643   Argument = besARGUMENT(1);
00644   besDEREFERENCE(Argument);
00645   if( Argument == NULL ||
00646       Argument->vType != VTYPE_STRING ||
00647       STRLEN(Argument) != sizeof(DB*) ){
00648     return BDB_ERROR_INVALID_DB_HANDLE;
00649     }
00650   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00651   dbpp = pTable->pdb;
00652 
00653   memset(&key, 0, sizeof(DBT));
00654   /* get the key */
00655   Argument = besARGUMENT(2);
00656   besDEREFERENCE(Argument);
00657   if( Argument == NULL ){
00658     key.data = "";
00659     key.size =  0;
00660     }else{
00661     Argument = besCONVERT2STRING(Argument);
00662     key.data = STRINGVALUE(Argument);
00663     key.size = STRLEN(Argument);
00664     }
00665 
00666         memset(&data, 0, sizeof(DBT));
00667   data.data = NULL;
00668   data.ulen = 0;
00669   data.flags = DB_DBT_USERMEM;
00670 
00671   /* here we call "get" to retrieve the neccessary size. Get should return ENOMEM */
00672   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_PREV);
00673   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00674   if( ret && ret != ENOMEM )
00675     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00676 
00677   besALLOC_RETURN_STRING(data.size);
00678   data.data = STRINGVALUE(besRETURNVALUE);
00679   data.ulen = STRLEN(besRETURNVALUE);
00680   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_PREV);
00681   if( ret )
00682     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00683 
00684   return COMMAND_ERROR_SUCCESS;
00685 besEND
00686 
00687 besFUNCTION(sb_db_last)
00688   pBdbObject p;
00689   VARIABLE Argument;
00690   DB *dbpp;
00691   int ret;
00692   DBT key,data;
00693   pMyDb pTable;
00694 
00695   p = (pBdbObject)besMODULEPOINTER;
00696   besRETURNVALUE = NULL;
00697 
00698   /* get the db argument */
00699   Argument = besARGUMENT(1);
00700   besDEREFERENCE(Argument);
00701   if( Argument == NULL ||
00702       Argument->vType != VTYPE_STRING ||
00703       STRLEN(Argument) != sizeof(DB*) ){
00704     return BDB_ERROR_INVALID_DB_HANDLE;
00705     }
00706   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00707   dbpp = pTable->pdb;
00708 
00709   memset(&key, 0, sizeof(DBT));
00710 
00711         memset(&data, 0, sizeof(DBT));
00712   data.data = NULL;
00713   data.ulen = 0;
00714   data.flags = DB_DBT_USERMEM;
00715 
00716   /* here we call "get" to retrieve the neccessary size. Get should return ENOMEM */
00717   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_LAST);
00718   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00719   if( ret && ret != ENOMEM )
00720     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00721 
00722   besALLOC_RETURN_STRING(data.size);
00723   data.data = STRINGVALUE(besRETURNVALUE);
00724   data.ulen = STRLEN(besRETURNVALUE);
00725   ret = pTable->pCursor->c_get(pTable->pCursor,&key,&data,DB_LAST);
00726   if( ret )
00727     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00728 
00729   return COMMAND_ERROR_SUCCESS;
00730 besEND
00731 
00732 /*
00733 int
00734 DB->del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags);
00735 */
00736 besFUNCTION(sb_db_del)
00737   pBdbObject p;
00738   VARIABLE Argument;
00739   DB *dbpp;
00740   int ret;
00741   DBT key;
00742   pMyDb pTable;
00743 
00744   p = (pBdbObject)besMODULEPOINTER;
00745   besRETURNVALUE = NULL;
00746 
00747   /* get the db argument */
00748   Argument = besARGUMENT(1);
00749   besDEREFERENCE(Argument);
00750   if( Argument == NULL ||
00751       Argument->vType != VTYPE_STRING ||
00752       STRLEN(Argument) != sizeof(DB*) ){
00753     return BDB_ERROR_INVALID_DB_HANDLE;
00754     }
00755   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00756   dbpp = pTable->pdb;
00757 
00758   memset(&key, 0, sizeof(DBT));
00759   /* get the key */
00760   Argument = besARGUMENT(2);
00761   besDEREFERENCE(Argument);
00762   if( Argument == NULL ){
00763     return COMMAND_ERROR_SUCCESS;
00764     }else{
00765     Argument = besCONVERT2STRING(Argument);
00766     key.data = STRINGVALUE(Argument);
00767     key.size = STRLEN(Argument);
00768     }
00769 
00770   ret = dbpp->del(dbpp,pTable->txnid,&key,0);
00771   if( ret == DB_NOTFOUND )return BDB_ERROR_KEY_NOT_FOUND;
00772   if( ret == EINVAL )return COMMAND_ERROR_SUCCESS;
00773   if( ret )
00774     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00775 
00776   return COMMAND_ERROR_SUCCESS;
00777 besEND
00778 
00779 /*
00780 int
00781 DBcursor->c_del(DBC *cursor, u_int32_t flags);
00782 */
00783 besFUNCTION(sb_db_eracrec)
00784   pBdbObject p;
00785   VARIABLE Argument;
00786   DB *dbpp;
00787   int ret;
00788   pMyDb pTable;
00789 
00790   p = (pBdbObject)besMODULEPOINTER;
00791   besRETURNVALUE = NULL;
00792 
00793   /* get the db argument */
00794   Argument = besARGUMENT(1);
00795   besDEREFERENCE(Argument);
00796   if( Argument == NULL ||
00797       Argument->vType != VTYPE_STRING ||
00798       STRLEN(Argument) != sizeof(DB*) ){
00799     return BDB_ERROR_INVALID_DB_HANDLE;
00800     }
00801   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00802   dbpp = pTable->pdb;
00803 
00804   ret = pTable->pCursor->c_del(pTable->pCursor,0);
00805   if( ret )
00806     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00807 
00808   return COMMAND_ERROR_SUCCESS;
00809 besEND
00810 
00811 besFUNCTION(sb_db_update)
00812   pBdbObject p;
00813   VARIABLE Argument;
00814   DB *dbpp;
00815   int ret;
00816   DBT key,data;
00817   pMyDb pTable;
00818 
00819   p = (pBdbObject)besMODULEPOINTER;
00820   besRETURNVALUE = NULL;
00821 
00822   /* get the db argument */
00823   Argument = besARGUMENT(1);
00824   besDEREFERENCE(Argument);
00825   if( Argument == NULL ||
00826       Argument->vType != VTYPE_STRING ||
00827       STRLEN(Argument) != sizeof(DB*) ){
00828     return BDB_ERROR_INVALID_DB_HANDLE;
00829     }
00830   memcpy(&pTable,STRINGVALUE(Argument),sizeof(DB *));
00831   dbpp = pTable->pdb;
00832 
00833   memset(&key, 0, sizeof(DBT));
00834         memset(&data, 0, sizeof(DBT));
00835 
00836   /* get the data */
00837   Argument = besARGUMENT(2);
00838   besDEREFERENCE(Argument);
00839   if( Argument == NULL ){
00840     data.data = "";
00841     data.size = 0;
00842     }else{
00843     Argument = besCONVERT2STRING(Argument);
00844     data.data = STRINGVALUE(Argument);
00845     data.size = STRLEN(Argument);
00846     }
00847 
00848   /* here we call "put" to update the last read record */
00849   ret = pTable->pCursor->c_put(pTable->pCursor,&key,&data,DB_CURRENT);
00850   if( ret == DB_KEYEMPTY || ret == DB_NOTFOUND )return COMMAND_ERROR_SUCCESS;
00851   if( ret && ret != ENOMEM )
00852     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00853 
00854   if( ret )
00855     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00856 
00857   return COMMAND_ERROR_SUCCESS;
00858 besEND
00859 
00860 besFUNCTION(sb_db_remove)
00861   pBdbObject p;
00862   VARIABLE Argument;
00863   DB *dbpp;
00864   int ret;
00865   char *pszDataBase;
00866 
00867   p = (pBdbObject)besMODULEPOINTER;
00868   besRETURNVALUE = NULL;
00869 
00870   ret = db_create(&dbpp,p->dbenv,0);
00871   if( ret )
00872     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00873 
00874   /* get the database name */
00875   Argument = besARGUMENT(1);
00876   besDEREFERENCE(Argument);
00877   if( Argument == NULL ){
00878     return BDB_ERROR_INVALID_FILE_NAME;
00879     }else{
00880     Argument = besCONVERT2STRING(Argument);
00881     besCONVERT2ZCHAR(Argument,pszDataBase);
00882     }
00883 
00884   ret = dbpp->remove(dbpp,pszDataBase,NULL,0);
00885   if( ret )
00886     return ConvertBdbErrors(ret);/* high bit set is needed to separate from scriba errors */
00887 
00888   return COMMAND_ERROR_SUCCESS;
00889 besEND
00890 
00891 
00892 /*
00893 int
00894 txn_begin(DB_TXNMGR *txnp, DB_TXN *parent, DB_TXN **tid);
00895 
00896 */
00897 besFUNCTION(sb_db_transact)
00898   pBdbObject p;
00899   int ret;
00900   pMyDb pTable;
00901 
00902   p = (pBdbObject)besMODULEPOINTER;
00903   besRETURNVALUE = NULL;
00904   if( p->InTransaction )return BDB_ERROR_TRANSACTION_NOT_CLOSED;
00905 
00906   pTable = p->pDbList;
00907   while( pTable ){
00908     ret = txn_begin(p->dbenv, NULL, &(pTable->txnid),0);
00909     if( ret )
00910       return ConvertBdbErrors(ret);
00911     pTable = pTable->next;
00912     }
00913   p->InTransaction = 1;
00914   return COMMAND_ERROR_SUCCESS;
00915 besEND
00916 
00917 besFUNCTION(sb_db_trcommit)
00918   pBdbObject p;
00919   pMyDb pTable;
00920 
00921   p = (pBdbObject)besMODULEPOINTER;
00922   besRETURNVALUE = NULL;
00923   if( ! p->InTransaction )return BDB_ERROR_TRANSACTION_NOT_OPENED;
00924 
00925   pTable = p->pDbList;
00926   while( pTable ){
00927     txn_commit(pTable->txnid,0);
00928     pTable->txnid = NULL;
00929     if( pTable->pCursor )
00930       pTable->pCursor->c_close(pTable->pCursor);
00931     pTable->pCursor = NULL;
00932     pTable->pdb->cursor(pTable->pdb,pTable->txnid,&(pTable->pCursor),0);
00933     pTable = pTable->next;
00934     }
00935   p->InTransaction = 0;
00936   return COMMAND_ERROR_SUCCESS;
00937 besEND
00938 
00939 besFUNCTION(sb_db_trabort)
00940   pBdbObject p;
00941   pMyDb pTable;
00942 
00943   p = (pBdbObject)besMODULEPOINTER;
00944   besRETURNVALUE = NULL;
00945   if( ! p->InTransaction )return BDB_ERROR_TRANSACTION_NOT_OPENED;
00946 
00947   pTable = p->pDbList;
00948   while( pTable ){
00949     txn_abort(pTable->txnid);
00950     pTable->txnid = NULL;
00951     if( pTable->pCursor )
00952       pTable->pCursor->c_close(pTable->pCursor);
00953     pTable->pCursor = NULL;
00954     pTable->pdb->cursor(pTable->pdb,pTable->txnid,&(pTable->pCursor),0);
00955     pTable = pTable->next;
00956     }
00957   p->InTransaction = 0;
00958   return COMMAND_ERROR_SUCCESS;
00959 besEND

Generated on Sun Mar 12 23:56:28 2006 for ScriptBasic by  doxygen 1.4.6-NO