--- BDB/BDB.xs 2007/02/05 23:46:15 1.5 +++ BDB/BDB.xs 2007/02/06 01:09:04 1.6 @@ -58,7 +58,7 @@ return s ? strdup (s) : 0; } -inline void +static inline void sv_to_dbt (DBT *dbt, SV *sv) { STRLEN len; @@ -67,13 +67,18 @@ dbt->data = malloc (len); memcpy (dbt->data, data, len); dbt->size = len; + dbt->flags = DB_DBT_REALLOC; } -inline void +static inline void dbt_to_sv (SV *sv, DBT *dbt) { - SvREADONLY_off (sv); - sv_setpvn_mg (sv, dbt->data, dbt->size); + if (sv) + { + SvREADONLY_off (sv); + sv_setpvn_mg (sv, dbt->data, dbt->size); + SvREFCNT_dec (sv); + } free (dbt->data); } @@ -81,8 +86,9 @@ enum { REQ_QUIT, REQ_ENV_OPEN, REQ_ENV_CLOSE, - REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT, REQ_DB_GET, REQ_DB_PGET, + REQ_DB_OPEN, REQ_DB_CLOSE, REQ_DB_COMPACT, REQ_DB_SYNC, REQ_DB_PUT, REQ_DB_GET, REQ_DB_PGET, REQ_DB_DEL, REQ_TXN_COMMIT, REQ_TXN_ABORT, + REQ_C_CLOSE, REQ_C_COUNT, REQ_C_PUT, REQ_C_GET, REQ_C_PGET, REQ_C_DEL, }; typedef struct aio_cb @@ -94,11 +100,13 @@ DB_ENV *env; DB *db; DB_TXN *txn; - DBC *cursor; + DBC *dbc; + + UV uv1; int int1, int2; U32 uint1, uint2; char *buf1, *buf2; - SV *sv1, *sv2; + SV *sv1, *sv2, *sv3; DBT dbt1, dbt2, dbt3; } aio_cb; @@ -291,14 +299,20 @@ switch (req->type) { + case REQ_DB_CLOSE: + SvREFCNT_dec (req->sv1); + break; + case REQ_DB_GET: case REQ_DB_PGET: - dbt_to_sv (req->sv1, &req->dbt3); - SvREFCNT_dec (req->sv1); + dbt_to_sv (req->sv3, &req->dbt3); break; - case REQ_DB_CLOSE: - SvREFCNT_dec (req->sv1); + case REQ_C_GET: + case REQ_C_PGET: + dbt_to_sv (req->sv1, &req->dbt1); + dbt_to_sv (req->sv2, &req->dbt2); + dbt_to_sv (req->sv3, &req->dbt3); break; } @@ -656,6 +670,10 @@ req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); break; + case REQ_DB_DEL: + req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1); + break; + case REQ_TXN_COMMIT: req->result = req->txn->commit (req->txn, req->uint1); break; @@ -664,6 +682,34 @@ req->result = req->txn->abort (req->txn); break; + case REQ_C_CLOSE: + req->result = req->dbc->c_close (req->dbc); + break; + + case REQ_C_COUNT: + { + db_recno_t recno; + req->result = req->dbc->c_count (req->dbc, &recno, req->uint1); + req->uv1 = recno; + } + break; + + case REQ_C_PUT: + req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1); + break; + + case REQ_C_GET: + req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1); + break; + + case REQ_C_PGET: + req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); + break; + + case REQ_C_DEL: + req->result = req->dbc->c_del (req->dbc, req->uint1); + break; + default: req->result = ENOSYS; break; @@ -861,6 +907,7 @@ const_iv (CONSUME) const_iv (CONSUME_WAIT) const_iv (GET_BOTH) + const_iv (GET_BOTH_RANGE) //const_iv (SET_RECNO) //const_iv (MULTIPLE) const_iv (SNAPSHOT) @@ -875,6 +922,7 @@ const_iv (OLD_VERSION) const_iv (REP_HANDLE_DEAD) const_iv (REP_LOCKOUT) + const_iv (SECONDARY_BAD) const_iv (FREE_SPACE) const_iv (FREELIST_ONLY) @@ -889,6 +937,23 @@ const_iv (SET_LOCK_TIMEOUT) const_iv (SET_TXN_TIMEOUT) + + const_iv (JOIN_ITEM) + const_iv (FIRST) + const_iv (NEXT) + const_iv (NEXT_DUP) + const_iv (NEXT_NODUP) + const_iv (PREV) + const_iv (PREV_NODUP) + const_iv (SET) + const_iv (SET_RANGE) + const_iv (LAST) + const_iv (BEFORE) + const_iv (AFTER) + const_iv (CURRENT) + const_iv (KEYFIRST) + const_iv (KEYLAST) + const_iv (NODUPDATA) }; for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) @@ -1077,7 +1142,7 @@ { errno = db_create (&RETVAL, env, flags); if (errno) - croak ("db_env_create: %s", db_strerror (errno)); + croak ("db_create: %s", db_strerror (errno)); if (RETVAL) RETVAL->app_private = (void *)newSVsv (ST (0)); @@ -1155,11 +1220,10 @@ dREQ (REQ_DB_GET); req->db = db; req->txn = txn; + req->uint1 = flags; sv_to_dbt (&req->dbt1, key); req->dbt3.flags = DB_DBT_MALLOC; - req->uint1 = flags; - req->sv1 = SvREFCNT_inc (data); - SvREADONLY_on (data); + req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); REQ_SEND; } @@ -1170,12 +1234,23 @@ dREQ (REQ_DB_PGET); req->db = db; req->txn = txn; + req->uint1 = flags; sv_to_dbt (&req->dbt1, key); sv_to_dbt (&req->dbt2, pkey); req->dbt3.flags = DB_DBT_MALLOC; + req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); + REQ_SEND; +} + +void +db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_DB_DEL); + req->db = db; + req->txn = txn; req->uint1 = flags; - req->sv1 = SvREFCNT_inc (data); - SvREADONLY_on (data); + sv_to_dbt (&req->dbt1, key); REQ_SEND; } @@ -1200,6 +1275,101 @@ ptr_nuke (ST (0)); } +void +db_c_close (DBC *dbc, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_CLOSE); + req->dbc = dbc; + REQ_SEND; + ptr_nuke (ST (0)); +} + +void +db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_COUNT); + req->dbc = dbc; + req->sv1 = SvREFCNT_inc (count); + REQ_SEND; +} + +void +db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_PUT); + req->dbc = dbc; + sv_to_dbt (&req->dbt1, key); + sv_to_dbt (&req->dbt2, data); + req->uint1 = flags; + REQ_SEND; +} + +void +db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_GET); + req->dbc = dbc; + req->uint1 = flags; + if ((flags & DB_SET) == DB_SET + || (flags & DB_SET_RANGE) == DB_SET_RANGE) + sv_to_dbt (&req->dbt1, key); + else + req->dbt1.flags = DB_DBT_MALLOC; + + req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key); + + if ((flags & DB_GET_BOTH) == DB_GET_BOTH + || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE) + sv_to_dbt (&req->dbt3, data); + else + req->dbt3.flags = DB_DBT_MALLOC; + + req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); + REQ_SEND; +} + +void +db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_PGET); + req->dbc = dbc; + req->uint1 = flags; + if ((flags & DB_SET) == DB_SET + || (flags & DB_SET_RANGE) == DB_SET_RANGE) + sv_to_dbt (&req->dbt1, key); + else + req->dbt1.flags = DB_DBT_MALLOC; + + req->sv1 = SvREFCNT_inc (key); SvREADONLY_on (key); + + req->dbt2.flags = DB_DBT_MALLOC; + req->sv2 = SvREFCNT_inc (pkey); SvREADONLY_on (pkey); + + if ((flags & DB_GET_BOTH) == DB_GET_BOTH + || (flags & DB_GET_BOTH_RANGE) == DB_GET_BOTH_RANGE) + sv_to_dbt (&req->dbt3, data); + else + req->dbt3.flags = DB_DBT_MALLOC; + + req->sv3 = SvREFCNT_inc (data); SvREADONLY_on (data); + REQ_SEND; +} + +void +db_c_del (DBC *dbc, U32 flags = 0, SV *callback = &PL_sv_undef) + CODE: +{ + dREQ (REQ_C_DEL); + req->dbc = dbc; + req->uint1 = flags; + REQ_SEND; +} + MODULE = BDB PACKAGE = BDB::Env @@ -1238,7 +1408,7 @@ CODE: errno = env->txn_begin (env, parent, &RETVAL, flags); if (errno) - croak ("txn_begin: %s", db_strerror (errno)); + croak ("DB_ENV->txn_begin: %s", db_strerror (errno)); OUTPUT: RETVAL @@ -1327,6 +1497,16 @@ OUTPUT: RETVAL +DBC * +cursor (DB *db, DB_TXN_ornull *txn = 0, U32 flags = 0) + CODE: + errno = db->cursor (db, txn, &RETVAL, flags); + if (errno) + croak ("DB->cursor: %s", db_strerror (errno)); + OUTPUT: + RETVAL + + MODULE = BDB PACKAGE = BDB::Txn void @@ -1342,3 +1522,11 @@ RETVAL +MODULE = BDB PACKAGE = BDB::Cursor + +void +DESTROY (DBC_ornull *dbc) + CODE: + if (dbc) + dbc->c_close (dbc); +