mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
BDB 4.1.24
This commit is contained in:
@ -1,14 +1,14 @@
|
||||
/*-
|
||||
* See the file LICENSE for redistribution information.
|
||||
*
|
||||
* Copyright (c) 1999, 2000
|
||||
* Copyright (c) 1999-2001
|
||||
* Sleepycat Software. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "db_config.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char revid[] = "$Id: tcl_dbcursor.c,v 11.26 2001/01/11 18:19:55 bostic Exp $";
|
||||
static const char revid[] = "$Id: tcl_dbcursor.c,v 11.51 2002/08/06 06:20:59 bostic Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NO_SYSTEM_INCLUDES
|
||||
@ -20,14 +20,14 @@ static const char revid[] = "$Id: tcl_dbcursor.c,v 11.26 2001/01/11 18:19:55 bos
|
||||
#endif
|
||||
|
||||
#include "db_int.h"
|
||||
#include "tcl_db.h"
|
||||
#include "dbinc/tcl_db.h"
|
||||
|
||||
/*
|
||||
* Prototypes for procedures defined later in this file:
|
||||
*/
|
||||
static int tcl_DbcDup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
static int tcl_DbcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
static int tcl_DbcPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
static int tcl_DbcDup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
static int tcl_DbcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *, int));
|
||||
static int tcl_DbcPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
|
||||
/*
|
||||
* PUBLIC: int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
|
||||
@ -37,12 +37,15 @@ static int tcl_DbcPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBC *));
|
||||
*/
|
||||
int
|
||||
dbc_Cmd(clientData, interp, objc, objv)
|
||||
ClientData clientData; /* Cursor handle */
|
||||
Tcl_Interp *interp; /* Interpreter */
|
||||
int objc; /* How many arguments? */
|
||||
Tcl_Obj *CONST objv[]; /* The argument objects */
|
||||
ClientData clientData; /* Cursor handle */
|
||||
Tcl_Interp *interp; /* Interpreter */
|
||||
int objc; /* How many arguments? */
|
||||
Tcl_Obj *CONST objv[]; /* The argument objects */
|
||||
{
|
||||
static char *dbccmds[] = {
|
||||
#if CONFIG_TEST
|
||||
"pget",
|
||||
#endif
|
||||
"close",
|
||||
"del",
|
||||
"dup",
|
||||
@ -51,6 +54,9 @@ dbc_Cmd(clientData, interp, objc, objv)
|
||||
NULL
|
||||
};
|
||||
enum dbccmds {
|
||||
#if CONFIG_TEST
|
||||
DBCPGET,
|
||||
#endif
|
||||
DBCCLOSE,
|
||||
DBCDELETE,
|
||||
DBCDUP,
|
||||
@ -87,6 +93,11 @@ dbc_Cmd(clientData, interp, objc, objv)
|
||||
TCL_EXACT, &cmdindex) != TCL_OK)
|
||||
return (IS_HELP(objv[1]));
|
||||
switch ((enum dbccmds)cmdindex) {
|
||||
#if CONFIG_TEST
|
||||
case DBCPGET:
|
||||
result = tcl_DbcGet(interp, objc, objv, dbc, 1);
|
||||
break;
|
||||
#endif
|
||||
case DBCCLOSE:
|
||||
/*
|
||||
* No args for this. Error if there are some.
|
||||
@ -97,7 +108,8 @@ dbc_Cmd(clientData, interp, objc, objv)
|
||||
}
|
||||
_debug_check();
|
||||
ret = dbc->c_close(dbc);
|
||||
result = _ReturnSetup(interp, ret, "dbc close");
|
||||
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
|
||||
"dbc close");
|
||||
if (result == TCL_OK) {
|
||||
(void)Tcl_DeleteCommand(interp, dbip->i_name);
|
||||
_DeleteInfo(dbip);
|
||||
@ -113,13 +125,14 @@ dbc_Cmd(clientData, interp, objc, objv)
|
||||
}
|
||||
_debug_check();
|
||||
ret = dbc->c_del(dbc, 0);
|
||||
result = _ReturnSetup(interp, ret, "dbc delete");
|
||||
result = _ReturnSetup(interp, ret, DB_RETOK_DBCDEL(ret),
|
||||
"dbc delete");
|
||||
break;
|
||||
case DBCDUP:
|
||||
result = tcl_DbcDup(interp, objc, objv, dbc);
|
||||
break;
|
||||
case DBCGET:
|
||||
result = tcl_DbcGet(interp, objc, objv, dbc);
|
||||
result = tcl_DbcGet(interp, objc, objv, dbc, 0);
|
||||
break;
|
||||
case DBCPUT:
|
||||
result = tcl_DbcPut(interp, objc, objv, dbc);
|
||||
@ -139,14 +152,26 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
DBC *dbc; /* Cursor pointer */
|
||||
{
|
||||
static char *dbcutopts[] = {
|
||||
"-after", "-before", "-current",
|
||||
"-keyfirst", "-keylast", "-nodupdata",
|
||||
#if CONFIG_TEST
|
||||
"-nodupdata",
|
||||
#endif
|
||||
"-after",
|
||||
"-before",
|
||||
"-current",
|
||||
"-keyfirst",
|
||||
"-keylast",
|
||||
"-partial",
|
||||
NULL
|
||||
};
|
||||
enum dbcutopts {
|
||||
DBCPUT_AFTER, DBCPUT_BEFORE, DBCPUT_CURRENT,
|
||||
DBCPUT_KEYFIRST,DBCPUT_KEYLAST, DBCPUT_NODUPDATA,
|
||||
#if CONFIG_TEST
|
||||
DBCPUT_NODUPDATA,
|
||||
#endif
|
||||
DBCPUT_AFTER,
|
||||
DBCPUT_BEFORE,
|
||||
DBCPUT_CURRENT,
|
||||
DBCPUT_KEYFIRST,
|
||||
DBCPUT_KEYLAST,
|
||||
DBCPUT_PART
|
||||
};
|
||||
DB *thisdbp;
|
||||
@ -154,12 +179,14 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
DBTCL_INFO *dbcip, *dbip;
|
||||
DBTYPE type;
|
||||
Tcl_Obj **elemv, *res;
|
||||
void *dtmp, *ktmp;
|
||||
db_recno_t recno;
|
||||
u_int32_t flag;
|
||||
int elemc, i, itmp, optindex, result, ret;
|
||||
int elemc, freekey, freedata, i, optindex, result, ret;
|
||||
|
||||
result = TCL_OK;
|
||||
flag = 0;
|
||||
freekey = freedata = 0;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key?");
|
||||
@ -190,6 +217,12 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
}
|
||||
i++;
|
||||
switch ((enum dbcutopts)optindex) {
|
||||
#if CONFIG_TEST
|
||||
case DBCPUT_NODUPDATA:
|
||||
FLAG_CHECK(flag);
|
||||
flag = DB_NODUPDATA;
|
||||
break;
|
||||
#endif
|
||||
case DBCPUT_AFTER:
|
||||
FLAG_CHECK(flag);
|
||||
flag = DB_AFTER;
|
||||
@ -210,10 +243,6 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
FLAG_CHECK(flag);
|
||||
flag = DB_KEYLAST;
|
||||
break;
|
||||
case DBCPUT_NODUPDATA:
|
||||
FLAG_CHECK(flag);
|
||||
flag = DB_NODUPDATA;
|
||||
break;
|
||||
case DBCPUT_PART:
|
||||
if (i > (objc - 2)) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
@ -233,12 +262,10 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
break;
|
||||
}
|
||||
data.flags |= DB_DBT_PARTIAL;
|
||||
result = Tcl_GetIntFromObj(interp, elemv[0], &itmp);
|
||||
data.doff = itmp;
|
||||
result = _GetUInt32(interp, elemv[0], &data.doff);
|
||||
if (result != TCL_OK)
|
||||
break;
|
||||
result = Tcl_GetIntFromObj(interp, elemv[1], &itmp);
|
||||
data.dlen = itmp;
|
||||
result = _GetUInt32(interp, elemv[1], &data.dlen);
|
||||
/*
|
||||
* NOTE: We don't check result here because all we'd
|
||||
* do is break anyway, and we are doing that. If you
|
||||
@ -269,7 +296,7 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
return (result);
|
||||
}
|
||||
thisdbp = dbip->i_dbp;
|
||||
type = thisdbp->get_type(thisdbp);
|
||||
(void)thisdbp->get_type(thisdbp, &type);
|
||||
}
|
||||
/*
|
||||
* When we get here, we better have:
|
||||
@ -300,29 +327,45 @@ tcl_DbcPut(interp, objc, objv, dbc)
|
||||
goto out;
|
||||
}
|
||||
if (type == DB_RECNO || type == DB_QUEUE) {
|
||||
result = Tcl_GetIntFromObj(interp, objv[objc-2], &itmp);
|
||||
recno = itmp;
|
||||
result = _GetUInt32(interp, objv[objc-2], &recno);
|
||||
if (result == TCL_OK) {
|
||||
key.data = &recno;
|
||||
key.size = sizeof(db_recno_t);
|
||||
} else
|
||||
return (result);
|
||||
} else {
|
||||
key.data = Tcl_GetByteArrayFromObj(objv[objc-2], &itmp);
|
||||
key.size = itmp;
|
||||
ret = _CopyObjBytes(interp, objv[objc-2], &ktmp,
|
||||
&key.size, &freekey);
|
||||
if (ret != 0) {
|
||||
result = _ReturnSetup(interp, ret,
|
||||
DB_RETOK_DBCPUT(ret), "dbc put");
|
||||
return (result);
|
||||
}
|
||||
key.data = ktmp;
|
||||
}
|
||||
}
|
||||
data.data = Tcl_GetByteArrayFromObj(objv[objc-1], &itmp);
|
||||
data.size = itmp;
|
||||
ret = _CopyObjBytes(interp, objv[objc-1], &dtmp,
|
||||
&data.size, &freedata);
|
||||
data.data = dtmp;
|
||||
if (ret != 0) {
|
||||
result = _ReturnSetup(interp, ret,
|
||||
DB_RETOK_DBCPUT(ret), "dbc put");
|
||||
goto out;
|
||||
}
|
||||
_debug_check();
|
||||
ret = dbc->c_put(dbc, &key, &data, flag);
|
||||
result = _ReturnSetup(interp, ret, "dbc put");
|
||||
if (ret == 0 && (flag == DB_AFTER || flag == DB_BEFORE)
|
||||
&& type == DB_RECNO) {
|
||||
res = Tcl_NewIntObj(*(db_recno_t *)key.data);
|
||||
result = _ReturnSetup(interp, ret, DB_RETOK_DBCPUT(ret),
|
||||
"dbc put");
|
||||
if (ret == 0 &&
|
||||
(flag == DB_AFTER || flag == DB_BEFORE) && type == DB_RECNO) {
|
||||
res = Tcl_NewLongObj((long)*(db_recno_t *)key.data);
|
||||
Tcl_SetObjResult(interp, res);
|
||||
}
|
||||
out:
|
||||
if (freedata)
|
||||
(void)__os_free(NULL, dtmp);
|
||||
if (freekey)
|
||||
(void)__os_free(NULL, ktmp);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -330,13 +373,20 @@ out:
|
||||
* tcl_dbc_get --
|
||||
*/
|
||||
static int
|
||||
tcl_DbcGet(interp, objc, objv, dbc)
|
||||
tcl_DbcGet(interp, objc, objv, dbc, ispget)
|
||||
Tcl_Interp *interp; /* Interpreter */
|
||||
int objc; /* How many arguments? */
|
||||
Tcl_Obj *CONST objv[]; /* The argument objects */
|
||||
DBC *dbc; /* Cursor pointer */
|
||||
int ispget; /* 1 for pget, 0 for get */
|
||||
{
|
||||
static char *dbcgetopts[] = {
|
||||
#if CONFIG_TEST
|
||||
"-dirty",
|
||||
"-get_both_range",
|
||||
"-multi",
|
||||
"-multi_key",
|
||||
#endif
|
||||
"-current",
|
||||
"-first",
|
||||
"-get_both",
|
||||
@ -356,6 +406,12 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
NULL
|
||||
};
|
||||
enum dbcgetopts {
|
||||
#if CONFIG_TEST
|
||||
DBCGET_DIRTY,
|
||||
DBCGET_BOTH_RANGE,
|
||||
DBCGET_MULTI,
|
||||
DBCGET_MULTI_KEY,
|
||||
#endif
|
||||
DBCGET_CURRENT,
|
||||
DBCGET_FIRST,
|
||||
DBCGET_BOTH,
|
||||
@ -374,16 +430,18 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
DBCGET_SETRECNO
|
||||
};
|
||||
DB *thisdbp;
|
||||
DBT key, data;
|
||||
DBT key, data, pdata;
|
||||
DBTCL_INFO *dbcip, *dbip;
|
||||
DBTYPE type;
|
||||
DBTYPE ptype, type;
|
||||
Tcl_Obj **elemv, *myobj, *retlist;
|
||||
db_recno_t recno;
|
||||
u_int32_t flag;
|
||||
int elemc, i, itmp, optindex, result, ret;
|
||||
void *dtmp, *ktmp;
|
||||
db_recno_t precno, recno;
|
||||
u_int32_t flag, op;
|
||||
int bufsize, elemc, freekey, freedata, i, optindex, result, ret;
|
||||
|
||||
result = TCL_OK;
|
||||
flag = 0;
|
||||
freekey = freedata = 0;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key?");
|
||||
@ -413,63 +471,101 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
}
|
||||
i++;
|
||||
switch ((enum dbcgetopts)optindex) {
|
||||
#if CONFIG_TEST
|
||||
case DBCGET_DIRTY:
|
||||
flag |= DB_DIRTY_READ;
|
||||
break;
|
||||
case DBCGET_BOTH_RANGE:
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_GET_BOTH_RANGE;
|
||||
break;
|
||||
case DBCGET_MULTI:
|
||||
flag |= DB_MULTIPLE;
|
||||
result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);
|
||||
if (result != TCL_OK)
|
||||
goto out;
|
||||
i++;
|
||||
break;
|
||||
case DBCGET_MULTI_KEY:
|
||||
flag |= DB_MULTIPLE_KEY;
|
||||
result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);
|
||||
if (result != TCL_OK)
|
||||
goto out;
|
||||
i++;
|
||||
break;
|
||||
#endif
|
||||
case DBCGET_RMW:
|
||||
flag |= DB_RMW;
|
||||
break;
|
||||
case DBCGET_CURRENT:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_CURRENT;
|
||||
break;
|
||||
case DBCGET_FIRST:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_FIRST;
|
||||
break;
|
||||
case DBCGET_LAST:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_LAST;
|
||||
break;
|
||||
case DBCGET_NEXT:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_NEXT;
|
||||
break;
|
||||
case DBCGET_PREV:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_PREV;
|
||||
break;
|
||||
case DBCGET_PREVNODUP:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_PREV_NODUP;
|
||||
break;
|
||||
case DBCGET_NEXTNODUP:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_NEXT_NODUP;
|
||||
break;
|
||||
case DBCGET_NEXTDUP:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_NEXT_DUP;
|
||||
break;
|
||||
case DBCGET_BOTH:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_GET_BOTH;
|
||||
break;
|
||||
case DBCGET_RECNO:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_GET_RECNO;
|
||||
break;
|
||||
case DBCGET_JOIN:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_JOIN_ITEM;
|
||||
break;
|
||||
case DBCGET_SET:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_SET;
|
||||
break;
|
||||
case DBCGET_SETRANGE:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_SET_RANGE;
|
||||
break;
|
||||
case DBCGET_SETRECNO:
|
||||
FLAG_CHECK2(flag, DB_RMW);
|
||||
FLAG_CHECK2(flag,
|
||||
DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
|
||||
flag |= DB_SET_RECNO;
|
||||
break;
|
||||
case DBCGET_PART:
|
||||
@ -491,12 +587,10 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
break;
|
||||
}
|
||||
data.flags |= DB_DBT_PARTIAL;
|
||||
result = Tcl_GetIntFromObj(interp, elemv[0], &itmp);
|
||||
data.doff = itmp;
|
||||
result = _GetUInt32(interp, elemv[0], &data.doff);
|
||||
if (result != TCL_OK)
|
||||
break;
|
||||
result = Tcl_GetIntFromObj(interp, elemv[1], &itmp);
|
||||
data.dlen = itmp;
|
||||
result = _GetUInt32(interp, elemv[1], &data.dlen);
|
||||
/*
|
||||
* NOTE: We don't check result here because all we'd
|
||||
* do is break anyway, and we are doing that. If you
|
||||
@ -518,9 +612,10 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
* a string.
|
||||
*/
|
||||
dbcip = _PtrToInfo(dbc);
|
||||
if (dbcip == NULL)
|
||||
if (dbcip == NULL) {
|
||||
type = DB_UNKNOWN;
|
||||
else {
|
||||
ptype = DB_UNKNOWN;
|
||||
} else {
|
||||
dbip = dbcip->i_parent;
|
||||
if (dbip == NULL) {
|
||||
Tcl_SetResult(interp, "Cursor without parent database",
|
||||
@ -529,15 +624,25 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
goto out;
|
||||
}
|
||||
thisdbp = dbip->i_dbp;
|
||||
type = thisdbp->get_type(thisdbp);
|
||||
(void)thisdbp->get_type(thisdbp, &type);
|
||||
if (ispget && thisdbp->s_primary != NULL)
|
||||
(void)thisdbp->
|
||||
s_primary->get_type(thisdbp->s_primary, &ptype);
|
||||
else
|
||||
ptype = DB_UNKNOWN;
|
||||
}
|
||||
/*
|
||||
* When we get here, we better have:
|
||||
* 2 args, key and data if GET_BOTH was specified.
|
||||
* 2 args, key and data if GET_BOTH/GET_BOTH_RANGE was specified.
|
||||
* 1 arg if -set, -set_range or -set_recno
|
||||
* 0 in all other cases.
|
||||
*/
|
||||
if ((flag & DB_OPFLAGS_MASK) == DB_GET_BOTH) {
|
||||
op = flag & DB_OPFLAGS_MASK;
|
||||
switch (op) {
|
||||
case DB_GET_BOTH:
|
||||
#if CONFIG_TEST
|
||||
case DB_GET_BOTH_RANGE:
|
||||
#endif
|
||||
if (i != (objc - 2)) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
"?-args? -get_both key data");
|
||||
@ -545,82 +650,158 @@ tcl_DbcGet(interp, objc, objv, dbc)
|
||||
goto out;
|
||||
} else {
|
||||
if (type == DB_RECNO || type == DB_QUEUE) {
|
||||
result = Tcl_GetIntFromObj(
|
||||
interp, objv[objc-2], &itmp);
|
||||
recno = itmp;
|
||||
result = _GetUInt32(
|
||||
interp, objv[objc-2], &recno);
|
||||
if (result == TCL_OK) {
|
||||
key.data = &recno;
|
||||
key.size = sizeof(db_recno_t);
|
||||
} else
|
||||
goto out;
|
||||
} else {
|
||||
key.data = Tcl_GetByteArrayFromObj(
|
||||
objv[objc - 2], &itmp);
|
||||
key.size = itmp;
|
||||
/*
|
||||
* Some get calls (SET_*) can change the
|
||||
* key pointers. So, we need to store
|
||||
* the allocated key space in a tmp.
|
||||
*/
|
||||
ret = _CopyObjBytes(interp, objv[objc-2],
|
||||
&ktmp, &key.size, &freekey);
|
||||
if (ret != 0) {
|
||||
result = _ReturnSetup(interp, ret,
|
||||
DB_RETOK_DBCGET(ret), "dbc get");
|
||||
return (result);
|
||||
}
|
||||
key.data = ktmp;
|
||||
}
|
||||
if (ptype == DB_RECNO || ptype == DB_QUEUE) {
|
||||
result = _GetUInt32(
|
||||
interp, objv[objc-1], &precno);
|
||||
if (result == TCL_OK) {
|
||||
data.data = &precno;
|
||||
data.size = sizeof(db_recno_t);
|
||||
} else
|
||||
goto out;
|
||||
} else {
|
||||
ret = _CopyObjBytes(interp, objv[objc-1],
|
||||
&dtmp, &data.size, &freedata);
|
||||
if (ret != 0) {
|
||||
result = _ReturnSetup(interp, ret,
|
||||
DB_RETOK_DBCGET(ret), "dbc get");
|
||||
goto out;
|
||||
}
|
||||
data.data = dtmp;
|
||||
}
|
||||
data.data =
|
||||
Tcl_GetByteArrayFromObj(objv[objc - 1], &itmp);
|
||||
data.size = itmp;
|
||||
}
|
||||
} else if ((flag & DB_OPFLAGS_MASK) == DB_SET ||
|
||||
(flag & DB_OPFLAGS_MASK) == DB_SET_RANGE ||
|
||||
(flag & DB_OPFLAGS_MASK) == DB_SET_RECNO) {
|
||||
break;
|
||||
case DB_SET:
|
||||
case DB_SET_RANGE:
|
||||
case DB_SET_RECNO:
|
||||
if (i != (objc - 1)) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?-args? key");
|
||||
result = TCL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
data.flags |= DB_DBT_MALLOC;
|
||||
if ((flag & DB_OPFLAGS_MASK) == DB_SET_RECNO ||
|
||||
if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) {
|
||||
(void)__os_malloc(NULL, bufsize, &data.data);
|
||||
data.ulen = bufsize;
|
||||
data.flags |= DB_DBT_USERMEM;
|
||||
} else
|
||||
data.flags |= DB_DBT_MALLOC;
|
||||
if (op == DB_SET_RECNO ||
|
||||
type == DB_RECNO || type == DB_QUEUE) {
|
||||
result = Tcl_GetIntFromObj(interp,
|
||||
objv[objc - 1], (int *)&recno);
|
||||
result = _GetUInt32(interp, objv[objc - 1], &recno);
|
||||
key.data = &recno;
|
||||
key.size = sizeof(db_recno_t);
|
||||
} else {
|
||||
key.data =
|
||||
Tcl_GetByteArrayFromObj(objv[objc - 1], &itmp);
|
||||
key.size = itmp;
|
||||
/*
|
||||
* Some get calls (SET_*) can change the
|
||||
* key pointers. So, we need to store
|
||||
* the allocated key space in a tmp.
|
||||
*/
|
||||
ret = _CopyObjBytes(interp, objv[objc-1],
|
||||
&ktmp, &key.size, &freekey);
|
||||
if (ret != 0) {
|
||||
result = _ReturnSetup(interp, ret,
|
||||
DB_RETOK_DBCGET(ret), "dbc get");
|
||||
return (result);
|
||||
}
|
||||
key.data = ktmp;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
if (i != objc) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?-args?");
|
||||
result = TCL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
key.flags |= DB_DBT_MALLOC;
|
||||
data.flags |= DB_DBT_MALLOC;
|
||||
if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) {
|
||||
(void)__os_malloc(NULL, bufsize, &data.data);
|
||||
data.ulen = bufsize;
|
||||
data.flags |= DB_DBT_USERMEM;
|
||||
} else
|
||||
data.flags |= DB_DBT_MALLOC;
|
||||
}
|
||||
|
||||
_debug_check();
|
||||
ret = dbc->c_get(dbc, &key, &data, flag);
|
||||
result = _ReturnSetup(interp, ret, "dbc get");
|
||||
memset(&pdata, 0, sizeof(DBT));
|
||||
if (ispget) {
|
||||
F_SET(&pdata, DB_DBT_MALLOC);
|
||||
ret = dbc->c_pget(dbc, &key, &data, &pdata, flag);
|
||||
} else
|
||||
ret = dbc->c_get(dbc, &key, &data, flag);
|
||||
result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret), "dbc get");
|
||||
if (result == TCL_ERROR)
|
||||
goto out;
|
||||
|
||||
retlist = Tcl_NewListObj(0, NULL);
|
||||
if (ret == DB_NOTFOUND)
|
||||
goto out1;
|
||||
if ((flag & DB_OPFLAGS_MASK) == DB_GET_RECNO) {
|
||||
if (op == DB_GET_RECNO) {
|
||||
recno = *((db_recno_t *)data.data);
|
||||
myobj = Tcl_NewIntObj((int)recno);
|
||||
myobj = Tcl_NewLongObj((long)recno);
|
||||
result = Tcl_ListObjAppendElement(interp, retlist, myobj);
|
||||
} else {
|
||||
if ((type == DB_RECNO || type == DB_QUEUE) && key.data != NULL)
|
||||
result = _SetListRecnoElem(interp, retlist,
|
||||
*(db_recno_t *)key.data, data.data, data.size);
|
||||
else
|
||||
result = _SetListElem(interp, retlist,
|
||||
key.data, key.size, data.data, data.size);
|
||||
if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY))
|
||||
result = _SetMultiList(interp,
|
||||
retlist, &key, &data, type, flag);
|
||||
else if ((type == DB_RECNO || type == DB_QUEUE) &&
|
||||
key.data != NULL) {
|
||||
if (ispget)
|
||||
result = _Set3DBTList(interp, retlist, &key, 1,
|
||||
&data,
|
||||
(ptype == DB_RECNO || ptype == DB_QUEUE),
|
||||
&pdata);
|
||||
else
|
||||
result = _SetListRecnoElem(interp, retlist,
|
||||
*(db_recno_t *)key.data,
|
||||
data.data, data.size);
|
||||
} else {
|
||||
if (ispget)
|
||||
result = _Set3DBTList(interp, retlist, &key, 0,
|
||||
&data,
|
||||
(ptype == DB_RECNO || ptype == DB_QUEUE),
|
||||
&pdata);
|
||||
else
|
||||
result = _SetListElem(interp, retlist,
|
||||
key.data, key.size, data.data, data.size);
|
||||
}
|
||||
}
|
||||
if (key.flags & DB_DBT_MALLOC)
|
||||
__os_free(key.data, key.size);
|
||||
if (data.flags & DB_DBT_MALLOC)
|
||||
__os_free(data.data, data.size);
|
||||
if (key.data != NULL && F_ISSET(&key, DB_DBT_MALLOC))
|
||||
__os_ufree(dbc->dbp->dbenv, key.data);
|
||||
if (data.data != NULL && F_ISSET(&data, DB_DBT_MALLOC))
|
||||
__os_ufree(dbc->dbp->dbenv, data.data);
|
||||
if (pdata.data != NULL && F_ISSET(&pdata, DB_DBT_MALLOC))
|
||||
__os_ufree(dbc->dbp->dbenv, pdata.data);
|
||||
out1:
|
||||
if (result == TCL_OK)
|
||||
Tcl_SetObjResult(interp, retlist);
|
||||
out:
|
||||
if (data.data != NULL && flag & (DB_MULTIPLE|DB_MULTIPLE_KEY))
|
||||
__os_free(dbc->dbp->dbenv, data.data);
|
||||
if (freedata)
|
||||
(void)__os_free(NULL, dtmp);
|
||||
if (freekey)
|
||||
(void)__os_free(NULL, ktmp);
|
||||
return (result);
|
||||
|
||||
}
|
||||
@ -642,7 +823,6 @@ tcl_DbcDup(interp, objc, objv, dbc)
|
||||
enum dbcdupopts {
|
||||
DBCDUP_POS
|
||||
};
|
||||
DB *thisdbp;
|
||||
DBC *newdbc;
|
||||
DBTCL_INFO *dbcip, *newdbcip, *dbip;
|
||||
Tcl_Obj *res;
|
||||
@ -709,7 +889,6 @@ tcl_DbcDup(interp, objc, objv, dbc)
|
||||
result = TCL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
thisdbp = dbip->i_dbp;
|
||||
}
|
||||
/*
|
||||
* Now duplicate the cursor. If successful, we need to create
|
||||
@ -731,7 +910,8 @@ tcl_DbcDup(interp, objc, objv, dbc)
|
||||
_SetInfoData(newdbcip, newdbc);
|
||||
Tcl_SetObjResult(interp, res);
|
||||
} else {
|
||||
result = _ReturnSetup(interp, ret, "db dup");
|
||||
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
|
||||
"db dup");
|
||||
_DeleteInfo(newdbcip);
|
||||
}
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user