summaryrefslogtreecommitdiff
path: root/db/tcl
diff options
context:
space:
mode:
Diffstat (limited to 'db/tcl')
-rw-r--r--db/tcl/docs/db.html2
-rw-r--r--db/tcl/docs/env.html9
-rw-r--r--db/tcl/docs/historic.html2
-rw-r--r--db/tcl/docs/index.html2
-rw-r--r--db/tcl/docs/library.html2
-rw-r--r--db/tcl/docs/lock.html2
-rw-r--r--db/tcl/docs/log.html2
-rw-r--r--db/tcl/docs/mpool.html2
-rw-r--r--db/tcl/docs/rep.html2
-rw-r--r--db/tcl/docs/test.html48
-rw-r--r--db/tcl/docs/txn.html2
-rw-r--r--db/tcl/tcl_compat.c18
-rw-r--r--db/tcl/tcl_db.c506
-rw-r--r--db/tcl/tcl_db_pkg.c389
-rw-r--r--db/tcl/tcl_dbcursor.c158
-rw-r--r--db/tcl/tcl_env.c332
-rw-r--r--db/tcl/tcl_internal.c157
-rw-r--r--db/tcl/tcl_lock.c21
-rw-r--r--db/tcl/tcl_log.c41
-rw-r--r--db/tcl/tcl_mp.c84
-rw-r--r--db/tcl/tcl_rep.c571
-rw-r--r--db/tcl/tcl_seq.c26
-rw-r--r--db/tcl/tcl_txn.c175
-rw-r--r--db/tcl/tcl_util.c266
24 files changed, 1950 insertions, 869 deletions
diff --git a/db/tcl/docs/db.html b/db/tcl/docs/db.html
index db8382b75..91a5e6542 100644
--- a/db/tcl/docs/db.html
+++ b/db/tcl/docs/db.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/env.html b/db/tcl/docs/env.html
index 3203a02b8..cb73bed10 100644
--- a/db/tcl/docs/env.html
+++ b/db/tcl/docs/env.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<html>
<head>
@@ -181,11 +181,6 @@ a deadlock</li>
</ul>
<li>
-<b>-lock_max </b>sets the maximum size of the lock table to <b><i>max </i></b>using
-the <a href="../../docs/api_c/env_set_lk_max.html">DBENV->set_lk_max</a>
-method call</li>
-
-<li>
<b>-lock_max_locks </b>sets the maximum number of locks to <b><i>max </i></b>using
the <a href="../../docs/api_c/env_set_lk_max_locks.html">DBENV->set_lk_max_locks</a>
method call</li>
@@ -241,7 +236,7 @@ DBENV->rep_master</a> call.</li>
<li>
<b>-rep_transport </b>specifies the replication transport function,
using the
-<a href="../../docs/api_c/rep_transport.html">DBENV->set_rep_transport</a>
+<a href="../../docs/api_c/rep_transport.html">DBENV->rep_set_transport</a>
call. This site's machine ID is set to <b><i>machineid</i></b> and
the send function, a Tcl proc, is set to <b><i>sendproc</i></b>.</li>
diff --git a/db/tcl/docs/historic.html b/db/tcl/docs/historic.html
index f5a43e14d..72b40b489 100644
--- a/db/tcl/docs/historic.html
+++ b/db/tcl/docs/historic.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/index.html b/db/tcl/docs/index.html
index 4f4e1e90c..7acf4d1ed 100644
--- a/db/tcl/docs/index.html
+++ b/db/tcl/docs/index.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/library.html b/db/tcl/docs/library.html
index 217213ed8..35ce8cf15 100644
--- a/db/tcl/docs/library.html
+++ b/db/tcl/docs/library.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/lock.html b/db/tcl/docs/lock.html
index 75e0bb2de..d418519ff 100644
--- a/db/tcl/docs/lock.html
+++ b/db/tcl/docs/lock.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<html>
<head>
diff --git a/db/tcl/docs/log.html b/db/tcl/docs/log.html
index 5fdd132d5..0cda2bc47 100644
--- a/db/tcl/docs/log.html
+++ b/db/tcl/docs/log.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/mpool.html b/db/tcl/docs/mpool.html
index 83c1f452c..59372aa34 100644
--- a/db/tcl/docs/mpool.html
+++ b/db/tcl/docs/mpool.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
diff --git a/db/tcl/docs/rep.html b/db/tcl/docs/rep.html
index d50b62375..2f1ee7a58 100644
--- a/db/tcl/docs/rep.html
+++ b/db/tcl/docs/rep.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<html>
<head>
diff --git a/db/tcl/docs/test.html b/db/tcl/docs/test.html
index a01140183..f714beb37 100644
--- a/db/tcl/docs/test.html
+++ b/db/tcl/docs/test.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<HTML>
<HEAD>
@@ -100,51 +100,5 @@ deletion process.</LI>
call in deletion</LI>
</UL>
-<HR WIDTH="100%">
-<BR><B>> &lt;env> mutex <I>mode nitems</I></B>
-<P>This command creates a mutex region for testing.&nbsp; It sets the mode
-of the region to <B><I>mode</I></B> and sets up for <B><I>nitems</I></B>
-number of mutex entries.&nbsp; After we successfully get a handle to a
-mutex we create a command of the form <B><I>$env.mutexX</I></B>, where
-X is an integer starting at&nbsp; 0 (e.g. <B>$env.mutex0, $env.mutex1,
-</B>etc).&nbsp;&nbsp;
-We use the <I>Tcl_CreateObjCommand()&nbsp;</I> to create the top level
-mutex function.&nbsp; It is through this handle that the user can access
-all of the commands described below.&nbsp; Internally, the mutex handle
-is sent as the <I>ClientData</I> portion of the new command set so that
-all future mutex calls access the appropriate handle.
-<P>
-<HR WIDTH="100%"><B>> &lt;mutex> close</B>
-<P>This command closes the mutex and renders the handle invalid.&nbsp;&nbsp;
-This command directly translates to the __db_r_detach function call.&nbsp;
-It returns either a 0 (for success),&nbsp; or it throws a Tcl error with
-a system message.
-<P>Additionally, since the handle is no longer valid, we will call <I>Tcl_DeleteCommand()
-</I>so
-that further uses of the handle will be dealt with properly by Tcl itself.&nbsp;
-<HR WIDTH="100%"><B>> &lt;mutex> get <I>id</I></B>
-<P>This command locks the mutex identified by <B><I>id</I></B>.&nbsp; It
-returns either a 0 (for success),&nbsp; or it throws a Tcl error with a
-system message.
-<BR>
-<HR WIDTH="100%"><B>> &lt;mutex> release <I>id</I></B>
-<P>This command releases the mutex identified by <B><I>id</I></B>.&nbsp;
-It returns either a 0 (for success),&nbsp; or it throws a Tcl error with
-a system message.
-<BR>
-<HR WIDTH="100%"><B>> &lt;mutex> getval <I>id</I></B>
-<P>This command gets the value stored for the mutex identified by <B><I>id</I></B>.&nbsp;
-It returns either the value,&nbsp; or it throws a Tcl error with a system
-message.
-<BR>
-<HR WIDTH="100%"><B>> &lt;mutex> setval <I>id val</I></B>
-<P>This command sets the value stored for the mutex identified by <B><I>id
-</I></B>to
-<B><I>val</I></B>.&nbsp;
-It returns either a 0 (for success),&nbsp; or it throws a Tcl error with
-a system message.
-<BR>
-<HR WIDTH="100%">
-<BR>&nbsp;
</BODY>
</HTML>
diff --git a/db/tcl/docs/txn.html b/db/tcl/docs/txn.html
index 8abef4b31..27892d3ea 100644
--- a/db/tcl/docs/txn.html
+++ b/db/tcl/docs/txn.html
@@ -1,4 +1,4 @@
-<!--Copyright 1999-2004 by Sleepycat Software, Inc.-->
+<!--Copyright 1999-2006 by Oracle Corporation.-->
<!--All rights reserved.-->
<html>
<head>
diff --git a/db/tcl/tcl_compat.c b/db/tcl/tcl_compat.c
index 8b518f761..79c63aa8c 100644
--- a/db/tcl/tcl_compat.c
+++ b/db/tcl/tcl_compat.c
@@ -1,28 +1,20 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_compat.c,v 11.46 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_compat.c,v 12.4 2006/08/24 14:46:32 bostic Exp $
*/
#include "db_config.h"
-
#ifdef CONFIG_TEST
+#define DB_DBM_HSEARCH 1
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#define DB_DBM_HSEARCH 1
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
/*
diff --git a/db/tcl/tcl_db.c b/db/tcl/tcl_db.c
index f60be3f43..9de948ea6 100644
--- a/db/tcl/tcl_db.c
+++ b/db/tcl/tcl_db.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_db.c,v 11.145 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_db.c,v 12.23 2006/08/24 14:46:32 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/db_page.h"
#include "dbinc/db_am.h"
#include "dbinc/tcl_db.h"
@@ -37,6 +32,11 @@ static int tcl_DbKeyRange __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
static int tcl_DbPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
static int tcl_DbStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
static int tcl_DbTruncate __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
+#ifdef CONFIG_TEST
+static int tcl_DbCompact __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB *));
+static int tcl_DbCompactStat __P((Tcl_Interp *,
+ int, Tcl_Obj * CONST*, DB *));
+#endif
static int tcl_DbCursor __P((Tcl_Interp *,
int, Tcl_Obj * CONST*, DB *, DBC **));
static int tcl_DbJoin __P((Tcl_Interp *,
@@ -99,6 +99,8 @@ db_Cmd(clientData, interp, objc, objv)
"pget",
"rpcid",
"test",
+ "compact",
+ "compact_stat",
#endif
"associate",
"close",
@@ -139,6 +141,8 @@ db_Cmd(clientData, interp, objc, objv)
DBPGET,
DBRPCID,
DBTEST,
+ DBCOMPACT,
+ DBCOMPACT_STAT,
#endif
DBASSOCIATE,
DBCLOSE,
@@ -235,6 +239,15 @@ db_Cmd(clientData, interp, objc, objv)
case DBTEST:
result = tcl_EnvTest(interp, objc, objv, dbp->dbenv);
break;
+
+ case DBCOMPACT:
+ result = tcl_DbCompact(interp, objc, objv, dbp);
+ break;
+
+ case DBCOMPACT_STAT:
+ result = tcl_DbCompactStat(interp, objc, objv, dbp);
+ break;
+
#endif
case DBASSOCIATE:
result = tcl_DbAssociate(interp, objc, objv, dbp);
@@ -539,8 +552,8 @@ tcl_DbStat(interp, objc, objv, dbp)
{
static const char *dbstatopts[] = {
#ifdef CONFIG_TEST
- "-degree_2",
- "-dirty",
+ "-read_committed",
+ "-read_uncommitted",
#endif
"-faststat",
"-txn",
@@ -548,8 +561,8 @@ tcl_DbStat(interp, objc, objv, dbp)
};
enum dbstatopts {
#ifdef CONFIG_TEST
- DBCUR_DEGREE2,
- DBCUR_DIRTY,
+ DBCUR_READ_COMMITTED,
+ DBCUR_READ_UNCOMMITTED,
#endif
DBCUR_FASTSTAT,
DBCUR_TXN
@@ -579,11 +592,11 @@ tcl_DbStat(interp, objc, objv, dbp)
i++;
switch ((enum dbstatopts)optindex) {
#ifdef CONFIG_TEST
- case DBCUR_DEGREE2:
- flag |= DB_DEGREE_2;
+ case DBCUR_READ_COMMITTED:
+ flag |= DB_READ_COMMITTED;
break;
- case DBCUR_DIRTY:
- flag |= DB_DIRTY_READ;
+ case DBCUR_READ_UNCOMMITTED:
+ flag |= DB_READ_UNCOMMITTED;
break;
#endif
case DBCUR_FASTSTAT:
@@ -775,6 +788,8 @@ tcl_DbClose(interp, objc, objv, dbp, dbip)
if (endarg)
break;
}
+ if (dbip->i_cdata != NULL)
+ __os_free(dbp->dbenv, dbip->i_cdata);
_DbInfoDelete(interp, dbip);
_debug_check();
@@ -801,7 +816,6 @@ tcl_DbPut(interp, objc, objv, dbp)
"-nodupdata",
#endif
"-append",
- "-auto_commit",
"-nooverwrite",
"-partial",
"-txn",
@@ -812,7 +826,6 @@ tcl_DbPut(interp, objc, objv, dbp)
DBGET_NODUPDATA,
#endif
DBPUT_APPEND,
- DBPUT_AUTO_COMMIT,
DBPUT_NOOVER,
DBPUT_PART,
DBPUT_TXN
@@ -828,7 +841,7 @@ tcl_DbPut(interp, objc, objv, dbp)
void *dtmp, *ktmp;
db_recno_t recno;
u_int32_t flag;
- int auto_commit, elemc, end, freekey, freedata;
+ int elemc, end, freekey, freedata;
int i, optindex, result, ret;
char *arg, msg[MSG_SIZE];
@@ -881,7 +894,6 @@ tcl_DbPut(interp, objc, objv, dbp)
* defined above.
*/
i = 2;
- auto_commit = 0;
while (i < end) {
if (Tcl_GetIndexFromObj(interp, objv[i],
dbputopts, "option", TCL_EXACT, &optindex) != TCL_OK)
@@ -909,9 +921,6 @@ tcl_DbPut(interp, objc, objv, dbp)
result = TCL_ERROR;
}
break;
- case DBPUT_AUTO_COMMIT:
- auto_commit = 1;
- break;
case DBPUT_APPEND:
FLAG_CHECK(flag);
flag = DB_APPEND;
@@ -986,8 +995,6 @@ tcl_DbPut(interp, objc, objv, dbp)
}
key.data = ktmp;
}
- if (auto_commit)
- flag |= DB_AUTO_COMMIT;
ret = _CopyObjBytes(interp, objv[objc-1], &dtmp, &data.size, &freedata);
if (ret != 0) {
result = _ReturnSetup(interp, ret,
@@ -1026,11 +1033,11 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
{
static const char *dbgetopts[] = {
#ifdef CONFIG_TEST
- "-degree2",
- "-dirty",
+ "-data_buf_size",
"-multi",
+ "-read_committed",
+ "-read_uncommitted",
#endif
- "-auto_commit",
"-consume",
"-consume_wait",
"-get_both",
@@ -1044,11 +1051,11 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
};
enum dbgetopts {
#ifdef CONFIG_TEST
- DBGET_DEGREE2,
- DBGET_DIRTY,
+ DBGET_DATA_BUF_SIZE,
DBGET_MULTI,
+ DBGET_READ_COMMITTED,
+ DBGET_READ_UNCOMMITTED,
#endif
- DBGET_AUTO_COMMIT,
DBGET_CONSUME,
DBGET_CONSUME_WAIT,
DBGET_BOTH,
@@ -1065,24 +1072,25 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
DB_TXN *txn;
Tcl_Obj **elemv, *retlist;
db_recno_t precno, recno;
- u_int32_t aflag, flag, cflag, isdup, mflag, rmw;
+ u_int32_t flag, cflag, isdup, mflag, rmw;
int elemc, end, endarg, freekey, freedata, i;
int optindex, result, ret, useglob, useprecno, userecno;
char *arg, *pattern, *prefix, msg[MSG_SIZE];
void *dtmp, *ktmp;
#ifdef CONFIG_TEST
- int bufsize;
+ int bufsize, data_buf_size;
#endif
result = TCL_OK;
freekey = freedata = 0;
- aflag = cflag = endarg = flag = mflag = rmw = 0;
+ cflag = endarg = flag = mflag = rmw = 0;
useglob = userecno = 0;
txn = NULL;
pattern = prefix = NULL;
dtmp = ktmp = NULL;
#ifdef CONFIG_TEST
COMPQUIET(bufsize, 0);
+ data_buf_size = 0;
#endif
if (objc < 3) {
@@ -1118,23 +1126,28 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
i++;
switch ((enum dbgetopts)optindex) {
#ifdef CONFIG_TEST
- case DBGET_DIRTY:
- rmw |= DB_DIRTY_READ;
- break;
- case DBGET_DEGREE2:
- rmw |= DB_DEGREE_2;
+ case DBGET_DATA_BUF_SIZE:
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
+ if (result != TCL_OK)
+ goto out;
+ i++;
break;
case DBGET_MULTI:
mflag |= DB_MULTIPLE;
- result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &bufsize);
if (result != TCL_OK)
goto out;
i++;
break;
-#endif
- case DBGET_AUTO_COMMIT:
- aflag |= DB_AUTO_COMMIT;
+ case DBGET_READ_COMMITTED:
+ rmw |= DB_READ_COMMITTED;
+ break;
+ case DBGET_READ_UNCOMMITTED:
+ rmw |= DB_READ_UNCOMMITTED;
break;
+#endif
case DBGET_BOTH:
/*
* Change 'end' and make sure we aren't already past
@@ -1276,6 +1289,22 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
result = TCL_ERROR;
goto out;
}
+#ifdef CONFIG_TEST
+ if (data_buf_size != 0 && flag == DB_GET_BOTH) {
+ Tcl_SetResult(interp,
+ "Only one of -data_buf_size or -get_both can be specified.\n",
+ TCL_STATIC);
+ result = TCL_ERROR;
+ goto out;
+ }
+ if (data_buf_size != 0 && mflag != 0) {
+ Tcl_SetResult(interp,
+ "Only one of -data_buf_size or -multi can be specified.\n",
+ TCL_STATIC);
+ result = TCL_ERROR;
+ goto out;
+ }
+#endif
if (useglob && flag == DB_GET_BOTH) {
Tcl_SetResult(interp,
"Only one of -glob or -get_both can be specified.\n",
@@ -1309,8 +1338,23 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
* instead of a cursor operation.
*/
if (pattern == NULL && (isdup == 0 || mflag != 0 ||
+#ifdef CONFIG_TEST
+ data_buf_size != 0 ||
+#endif
flag == DB_SET_RECNO || flag == DB_GET_BOTH ||
flag == DB_CONSUME || flag == DB_CONSUME_WAIT)) {
+#ifdef CONFIG_TEST
+ if (data_buf_size == 0) {
+ F_CLR(&save, DB_DBT_USERMEM);
+ F_SET(&save, DB_DBT_MALLOC);
+ } else {
+ (void)__os_malloc(
+ NULL, (size_t)data_buf_size, &save.data);
+ save.ulen = (u_int32_t)data_buf_size;
+ F_CLR(&save, DB_DBT_MALLOC);
+ F_SET(&save, DB_DBT_USERMEM);
+ }
+#endif
if (flag == DB_GET_BOTH) {
if (userecno) {
result = _GetUInt32(interp,
@@ -1327,14 +1371,14 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
* the allocated key space in a tmp.
*/
ret = _CopyObjBytes(interp, objv[objc-2],
- &ktmp, &key.size, &freekey);
+ &key.data, &key.size, &freekey);
if (ret != 0) {
result = _ReturnSetup(interp, ret,
DB_RETOK_DBGET(ret), "db get");
goto out;
}
- key.data = ktmp;
}
+ ktmp = key.data;
/*
* Already checked args above. Fill in key and save.
* Save is used in the dbp->get call below to fill in
@@ -1378,14 +1422,14 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
* the allocated key space in a tmp.
*/
ret = _CopyObjBytes(interp, objv[objc-1],
- &ktmp, &key.size, &freekey);
+ &key.data, &key.size, &freekey);
if (ret != 0) {
result = _ReturnSetup(interp, ret,
DB_RETOK_DBGET(ret), "db get");
goto out;
}
- key.data = ktmp;
}
+ ktmp = key.data;
#ifdef CONFIG_TEST
if (mflag & DB_MULTIPLE) {
if ((ret = __os_malloc(dbp->dbenv,
@@ -1417,7 +1461,7 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
} else {
_debug_check();
ret = dbp->get(dbp,
- txn, &key, &data, flag | aflag | rmw | mflag);
+ txn, &key, &data, flag | rmw | mflag);
}
result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret),
"db get");
@@ -1487,15 +1531,15 @@ tcl_DbGet(interp, objc, objv, dbp, ispget)
* key pointers. So, we need to store
* the allocated key space in a tmp.
*/
- ret = _CopyObjBytes(interp, objv[objc-1], &ktmp,
+ ret = _CopyObjBytes(interp, objv[objc-1], &key.data,
&key.size, &freekey);
if (ret != 0) {
result = _ReturnSetup(interp, ret,
DB_RETOK_DBGET(ret), "db get");
return (result);
}
- key.data = ktmp;
}
+ ktmp = key.data;
ret = dbp->cursor(dbp, txn, &dbc, 0);
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "db cursor");
if (result == TCL_ERROR)
@@ -1634,13 +1678,11 @@ tcl_DbDelete(interp, objc, objv, dbp)
DB *dbp; /* Database pointer */
{
static const char *dbdelopts[] = {
- "-auto_commit",
"-glob",
"-txn",
NULL
};
enum dbdelopts {
- DBDEL_AUTO_COMMIT,
DBDEL_GLOB,
DBDEL_TXN
};
@@ -1656,7 +1698,6 @@ tcl_DbDelete(interp, objc, objv, dbp)
result = TCL_OK;
freekey = 0;
- flag = 0;
pattern = prefix = NULL;
txn = NULL;
if (objc < 3) {
@@ -1667,17 +1708,17 @@ tcl_DbDelete(interp, objc, objv, dbp)
ktmp = NULL;
memset(&key, 0, sizeof(key));
/*
- * The first arg must be -auto_commit, -glob, -txn or a list of keys.
+ * The first arg must be -glob, -txn or a list of keys.
*/
i = 2;
while (i < objc) {
if (Tcl_GetIndexFromObj(interp, objv[i], dbdelopts, "option",
TCL_EXACT, &optindex) != TCL_OK) {
/*
- * If we don't have a -auto_commit, -glob or -txn,
- * then the remaining args must be exact keys.
- * Reset the result so we don't get an errant error
- * message if there is another error.
+ * If we don't have a -glob or -txn, then the remaining
+ * args must be exact keys. Reset the result so we
+ * don't get an errant error message if there is another
+ * error.
*/
if (IS_HELP(objv[i]) == TCL_OK)
return (TCL_OK);
@@ -1704,9 +1745,6 @@ tcl_DbDelete(interp, objc, objv, dbp)
result = TCL_ERROR;
}
break;
- case DBDEL_AUTO_COMMIT:
- flag |= DB_AUTO_COMMIT;
- break;
case DBDEL_GLOB:
/*
* Get the pattern. Get the prefix and use cursors to
@@ -1741,8 +1779,6 @@ tcl_DbDelete(interp, objc, objv, dbp)
*
* If we have a pattern AND more keys to process, there is an error.
* Either we have some number of exact keys, or we have a pattern.
- *
- * If we have a pattern and an auto commit flag, there is an error.
*/
if (pattern == NULL) {
if (i != (objc - 1)) {
@@ -1758,13 +1794,6 @@ tcl_DbDelete(interp, objc, objv, dbp)
result = TCL_ERROR;
goto out;
}
- if (flag & DB_AUTO_COMMIT) {
- Tcl_SetResult(interp,
- "Cannot use -auto_commit and patterns.\n",
- TCL_STATIC);
- result = TCL_ERROR;
- goto out;
- }
}
/*
@@ -1796,7 +1825,7 @@ tcl_DbDelete(interp, objc, objv, dbp)
key.data = ktmp;
}
_debug_check();
- ret = dbp->del(dbp, txn, &key, flag);
+ ret = dbp->del(dbp, txn, &key, 0);
/*
* If we have any error, set up return result and stop
* processing keys.
@@ -1889,8 +1918,8 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp)
{
static const char *dbcuropts[] = {
#ifdef CONFIG_TEST
- "-degree_2",
- "-dirty",
+ "-read_committed",
+ "-read_uncommitted",
"-update",
#endif
"-txn",
@@ -1898,8 +1927,8 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp)
};
enum dbcuropts {
#ifdef CONFIG_TEST
- DBCUR_DEGREE2,
- DBCUR_DIRTY,
+ DBCUR_READ_COMMITTED,
+ DBCUR_READ_UNCOMMITTED,
DBCUR_UPDATE,
#endif
DBCUR_TXN
@@ -1922,11 +1951,11 @@ tcl_DbCursor(interp, objc, objv, dbp, dbcp)
i++;
switch ((enum dbcuropts)optindex) {
#ifdef CONFIG_TEST
- case DBCUR_DEGREE2:
- flag |= DB_DEGREE_2;
+ case DBCUR_READ_COMMITTED:
+ flag |= DB_READ_COMMITTED;
break;
- case DBCUR_DIRTY:
- flag |= DB_DIRTY_READ;
+ case DBCUR_READ_UNCOMMITTED:
+ flag |= DB_READ_UNCOMMITTED;
break;
case DBCUR_UPDATE:
flag |= DB_WRITECURSOR;
@@ -1974,14 +2003,14 @@ tcl_DbAssociate(interp, objc, objv, dbp)
DB *dbp;
{
static const char *dbaopts[] = {
- "-auto_commit",
"-create",
+ "-immutable_key",
"-txn",
NULL
};
enum dbaopts {
- DBA_AUTO_COMMIT,
DBA_CREATE,
+ DBA_IMMUTABLE_KEY,
DBA_TXN
};
DB *sdbp;
@@ -2037,12 +2066,12 @@ tcl_DbAssociate(interp, objc, objv, dbp)
}
i++;
switch ((enum dbaopts)optindex) {
- case DBA_AUTO_COMMIT:
- flag |= DB_AUTO_COMMIT;
- break;
case DBA_CREATE:
flag |= DB_CREATE;
break;
+ case DBA_IMMUTABLE_KEY:
+ flag |= DB_IMMUTABLE_KEY;
+ break;
case DBA_TXN:
if (i > (objc - 1)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
@@ -2190,7 +2219,7 @@ tcl_second_call(dbp, pkey, data, skey)
Tcl_DecrRefCount(dobj);
if (result != TCL_OK) {
- __db_err(dbp->dbenv,
+ __db_errx(dbp->dbenv,
"Tcl callback function failed with code %d", result);
return (EINVAL);
}
@@ -2549,15 +2578,15 @@ tcl_DbGetOpenFlags(interp, objc, objv, dbp)
u_int32_t flag;
char *arg;
} open_flags[] = {
- { DB_AUTO_COMMIT, "-auto_commit" },
- { DB_CREATE, "-create" },
- { DB_DEGREE_2, "-degree_2" },
- { DB_DIRTY_READ, "-dirty" },
- { DB_EXCL, "-excl" },
- { DB_NOMMAP, "-nommap" },
- { DB_RDONLY, "-rdonly" },
- { DB_THREAD, "-thread" },
- { DB_TRUNCATE, "-truncate" },
+ { DB_AUTO_COMMIT, "-auto_commit" },
+ { DB_CREATE, "-create" },
+ { DB_EXCL, "-excl" },
+ { DB_NOMMAP, "-nommap" },
+ { DB_RDONLY, "-rdonly" },
+ { DB_READ_COMMITTED, "-read_committed" },
+ { DB_READ_UNCOMMITTED, "-read_uncommitted" },
+ { DB_THREAD, "-thread" },
+ { DB_TRUNCATE, "-truncate" },
{ 0, NULL }
};
@@ -2805,22 +2834,19 @@ tcl_DbTruncate(interp, objc, objv, dbp)
DB *dbp; /* Database pointer */
{
static const char *dbcuropts[] = {
- "-auto_commit",
"-txn",
NULL
};
enum dbcuropts {
- DBTRUNC_AUTO_COMMIT,
DBTRUNC_TXN
};
DB_TXN *txn;
Tcl_Obj *res;
- u_int32_t count, flag;
+ u_int32_t count;
int i, optindex, result, ret;
char *arg, msg[MSG_SIZE];
txn = NULL;
- flag = 0;
result = TCL_OK;
i = 2;
@@ -2832,9 +2858,6 @@ tcl_DbTruncate(interp, objc, objv, dbp)
}
i++;
switch ((enum dbcuropts)optindex) {
- case DBTRUNC_AUTO_COMMIT:
- flag |= DB_AUTO_COMMIT;
- break;
case DBTRUNC_TXN:
if (i == objc) {
Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
@@ -2858,7 +2881,7 @@ tcl_DbTruncate(interp, objc, objv, dbp)
goto out;
_debug_check();
- ret = dbp->truncate(dbp, txn, &count, flag);
+ ret = dbp->truncate(dbp, txn, &count, 0);
if (ret != 0)
result = _ErrorSetup(interp, ret, "db truncate");
@@ -2869,3 +2892,280 @@ tcl_DbTruncate(interp, objc, objv, dbp)
out:
return (result);
}
+
+#ifdef CONFIG_TEST
+/*
+ * tcl_DbCompact --
+ */
+static int
+tcl_DbCompact(interp, objc, objv, dbp)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB *dbp; /* Database pointer */
+{
+ static const char *dbcuropts[] = {
+ "-fillpercent",
+ "-freespace",
+ "-freeonly",
+ "-pages",
+ "-start",
+ "-stop",
+ "-timeout",
+ "-txn",
+ NULL
+ };
+ enum dbcuropts {
+ DBREORG_FILLFACTOR,
+ DBREORG_FREESPACE,
+ DBREORG_FREEONLY,
+ DBREORG_PAGES,
+ DBREORG_START,
+ DBREORG_STOP,
+ DBREORG_TIMEOUT,
+ DBREORG_TXN
+ };
+ DBTCL_INFO *ip;
+ DBT *key, end, start, stop;
+ DBTYPE type;
+ DB_TXN *txn;
+ Tcl_Obj *myobj, *retlist;
+ db_recno_t recno, srecno;
+ u_int32_t arg, fillfactor, flags, pages, timeout;
+ char *carg, msg[MSG_SIZE];
+ int freekey, i, optindex, result, ret;
+ void *kp;
+
+ flags = 0;
+ result = TCL_OK;
+ txn = NULL;
+ (void)dbp->get_type(dbp, &type);
+ memset(&start, 0, sizeof(start));
+ memset(&stop, 0, sizeof(stop));
+ memset(&end, 0, sizeof(end));
+ ip = (DBTCL_INFO *)dbp->api_internal;
+ fillfactor = pages = timeout = 0;
+
+ i = 2;
+ while (i < objc) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], dbcuropts, "option",
+ TCL_EXACT, &optindex) != TCL_OK) {
+ result = IS_HELP(objv[i]);
+ goto out;
+ }
+ i++;
+ switch ((enum dbcuropts)optindex) {
+ case DBREORG_FILLFACTOR:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp,
+ 2, objv, "?-fillfactor number?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &arg);
+ if (result != TCL_OK)
+ goto out;
+ i++;
+ fillfactor = arg;
+ break;
+ case DBREORG_FREESPACE:
+ LF_SET(DB_FREE_SPACE);
+ break;
+
+ case DBREORG_FREEONLY:
+ LF_SET(DB_FREELIST_ONLY);
+ break;
+
+ case DBREORG_PAGES:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp,
+ 2, objv, "?-pages number?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &arg);
+ if (result != TCL_OK)
+ goto out;
+ i++;
+ pages = arg;
+ break;
+ case DBREORG_TIMEOUT:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp,
+ 2, objv, "?-timeout number?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &arg);
+ if (result != TCL_OK)
+ goto out;
+ i++;
+ timeout = arg;
+ break;
+
+ case DBREORG_START:
+ case DBREORG_STOP:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-args? -start/stop key");
+ result = TCL_ERROR;
+ goto out;
+ }
+ if ((enum dbcuropts)optindex == DBREORG_START) {
+ key = &start;
+ key->data = &recno;
+ } else {
+ key = &stop;
+ key->data = &srecno;
+ }
+ if (type == DB_RECNO || type == DB_QUEUE) {
+ result = _GetUInt32(
+ interp, objv[i], key->data);
+ if (result == TCL_OK) {
+ key->size = sizeof(db_recno_t);
+ } else
+ goto out;
+ } else {
+ ret = _CopyObjBytes(interp, objv[i],
+ &key->data, &key->size, &freekey);
+ if (ret != 0)
+ goto err;
+ if (freekey == 0) {
+ if ((ret = __os_malloc(NULL,
+ key->size, &kp)) != 0)
+ goto err;
+
+ memcpy(kp, key->data, key->size);
+ key->data = kp;
+ key->ulen = key->size;
+ }
+ }
+ i++;
+ break;
+ case DBREORG_TXN:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
+ result = TCL_ERROR;
+ break;
+ }
+ carg = Tcl_GetStringFromObj(objv[i++], NULL);
+ txn = NAME_TO_TXN(carg);
+ if (txn == NULL) {
+ snprintf(msg, MSG_SIZE,
+ "Compact: Invalid txn: %s\n", carg);
+ Tcl_SetResult(interp, msg, TCL_VOLATILE);
+ result = TCL_ERROR;
+ }
+ }
+ if (result != TCL_OK)
+ break;
+ }
+ if (result != TCL_OK)
+ goto out;
+
+ if (ip->i_cdata == NULL)
+ if ((ret = __os_calloc(dbp->dbenv,
+ 1, sizeof(DB_COMPACT), &ip->i_cdata)) != 0) {
+ Tcl_SetResult(interp,
+ db_strerror(ret), TCL_STATIC);
+ goto out;
+ }
+
+ ip->i_cdata->compact_fillpercent = fillfactor;
+ ip->i_cdata->compact_timeout = timeout;
+ ip->i_cdata->compact_pages = pages;
+
+ _debug_check();
+ ret = dbp->compact(dbp, txn, &start, &stop, ip->i_cdata, flags, &end);
+ result = _ReturnSetup(interp, ret, DB_RETOK_DBCGET(ret), "dbp compact");
+ if (result == TCL_ERROR)
+ goto out;
+
+ retlist = Tcl_NewListObj(0, NULL);
+ if (ret != 0)
+ goto out;
+ if (type == DB_RECNO || type == DB_QUEUE) {
+ if (end.size == 0)
+ recno = 0;
+ else
+ recno = *((db_recno_t *)end.data);
+ myobj = Tcl_NewWideIntObj((Tcl_WideInt)recno);
+ } else
+ myobj = Tcl_NewByteArrayObj(end.data, (int)end.size);
+ result = Tcl_ListObjAppendElement(interp, retlist, myobj);
+ if (result == TCL_OK)
+ Tcl_SetObjResult(interp, retlist);
+
+ if (0) {
+err: result = _ReturnSetup(interp,
+ ret, DB_RETOK_DBCGET(ret), "dbc compact");
+ }
+out:
+ if (start.data != NULL && start.data != &recno)
+ __os_free(NULL, start.data);
+ if (stop.data != NULL && stop.data != &srecno)
+ __os_free(NULL, stop.data);
+ if (end.data != NULL)
+ __os_free(NULL, end.data);
+
+ return (result);
+}
+
+/*
+ * tcl_DbCompactStat
+ */
+static int
+tcl_DbCompactStat(interp, objc, objv, dbp)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB *dbp; /* Database pointer */
+{
+ DBTCL_INFO *ip;
+
+ COMPQUIET(objc, 0);
+ COMPQUIET(objv, NULL);
+
+ ip = (DBTCL_INFO *)dbp->api_internal;
+
+ return (tcl_CompactStat(interp, ip));
+}
+
+/*
+ * PUBLIC: int tcl_CompactStat __P((Tcl_Interp *, DBTCL_INFO *));
+ */
+int
+tcl_CompactStat(interp, ip)
+ Tcl_Interp *interp; /* Interpreter */
+ DBTCL_INFO *ip;
+{
+ DB_COMPACT *rp;
+ Tcl_Obj *res;
+ int result;
+ char msg[MSG_SIZE];
+
+ result = TCL_OK;
+ rp = NULL;
+
+ _debug_check();
+ if ((rp = ip->i_cdata) == NULL) {
+ snprintf(msg, MSG_SIZE,
+ "Compact stat: No stats available\n");
+ Tcl_SetResult(interp, msg, TCL_VOLATILE);
+ result = TCL_ERROR;
+ goto error;
+ }
+
+ res = Tcl_NewObj();
+
+ MAKE_STAT_LIST("Pages freed", rp->compact_pages_free);
+ MAKE_STAT_LIST("Pages truncated", rp->compact_pages_truncated);
+ MAKE_STAT_LIST("Pages examined", rp->compact_pages_examine);
+ MAKE_STAT_LIST("Levels removed", rp->compact_levels);
+ MAKE_STAT_LIST("Deadlocks encountered", rp->compact_deadlock);
+
+ Tcl_SetObjResult(interp, res);
+error:
+ return (result);
+}
+#endif
diff --git a/db/tcl/tcl_db_pkg.c b/db/tcl/tcl_db_pkg.c
index ce55df842..398507b4b 100644
--- a/db/tcl/tcl_db_pkg.c
+++ b/db/tcl/tcl_db_pkg.c
@@ -1,27 +1,22 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_db_pkg.c,v 11.190 2004/10/27 16:48:32 bostic Exp $
+ * $Id: tcl_db_pkg.c,v 12.36 2006/09/08 19:22:21 bostic Exp $
*/
#include "db_config.h"
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <tcl.h>
-#endif
-
#ifdef CONFIG_TEST
-#define DB_DBM_HSEARCH 1
+#define DB_DBM_HSEARCH 1
#endif
#include "db_int.h"
+#ifndef NO_SYSTEM_INCLUDES
+#include <tcl.h>
+#endif
#include "dbinc/db_page.h"
#include "dbinc/hash.h"
#include "dbinc/tcl_db.h"
@@ -41,12 +36,16 @@ static int bdb_DbOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
static int bdb_DbRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_DbRename __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_Version __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+
+#ifdef HAVE_64BIT_TYPES
static int bdb_SeqOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
DBTCL_INFO *, DB_SEQUENCE **));
+#endif
#ifdef CONFIG_TEST
static int bdb_DbUpgrade __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_DbVerify __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+static int bdb_GetConfig __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_Handles __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
static int bdb_MsgType __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
@@ -58,8 +57,6 @@ static void * tcl_db_malloc __P((size_t));
static void * tcl_db_realloc __P((void *, size_t));
static int tcl_dup_compare __P((DB *, const DBT *, const DBT *));
static u_int32_t tcl_h_hash __P((DB *, const void *, u_int32_t));
-static int tcl_rep_send __P((DB_ENV *,
- const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
#endif
/*
@@ -124,6 +121,7 @@ berkdb_Cmd(notused, interp, objc, objv)
static const char *berkdbcmds[] = {
#ifdef CONFIG_TEST
"dbverify",
+ "getconfig",
"handles",
"msgtype",
"upgrade",
@@ -133,7 +131,7 @@ berkdb_Cmd(notused, interp, objc, objv)
"env",
"envremove",
"open",
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
"sequence",
#endif
"version",
@@ -155,6 +153,7 @@ berkdb_Cmd(notused, interp, objc, objv)
enum berkdbcmds {
#ifdef CONFIG_TEST
BDB_DBVERIFY,
+ BDB_GETCONFIG,
BDB_HANDLES,
BDB_MSGTYPE,
BDB_UPGRADE,
@@ -164,7 +163,7 @@ berkdb_Cmd(notused, interp, objc, objv)
BDB_ENV,
BDB_ENVREMOVE,
BDB_OPEN,
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
BDB_SEQUENCE,
#endif
BDB_VERSION,
@@ -179,12 +178,12 @@ berkdb_Cmd(notused, interp, objc, objv)
};
static int env_id = 0;
static int db_id = 0;
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
static int seq_id = 0;
#endif
DB *dbp;
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
DB_SEQUENCE *seq;
#endif
#ifdef CONFIG_TEST
@@ -220,6 +219,9 @@ berkdb_Cmd(notused, interp, objc, objv)
case BDB_DBVERIFY:
result = bdb_DbVerify(interp, objc, objv);
break;
+ case BDB_GETCONFIG:
+ result = bdb_GetConfig(interp, objc, objv);
+ break;
case BDB_HANDLES:
result = bdb_Handles(interp, objc, objv);
break;
@@ -285,7 +287,7 @@ berkdb_Cmd(notused, interp, objc, objv)
result = TCL_ERROR;
}
break;
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
case BDB_SEQUENCE:
snprintf(newname, sizeof(newname), "seq%d", seq_id);
ip = _NewInfo(interp, NULL, newname, I_SEQ);
@@ -391,15 +393,16 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
"-cdb",
"-cdb_alldb",
"-client_timeout",
+ "-event",
"-lock",
"-lock_conflict",
"-lock_detect",
- "-lock_max",
"-lock_max_locks",
"-lock_max_lockers",
"-lock_max_objects",
"-lock_timeout",
"-log",
+ "-log_filemode",
"-log_buffer",
"-log_inmemory",
"-log_max",
@@ -409,14 +412,17 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
"-mpool_max_write",
"-mpool_mmap_size",
"-mpool_nommap",
+ "-multiversion",
"-overwrite",
"-region_init",
+ "-rep",
"-rep_client",
"-rep_master",
"-rep_transport",
"-server",
"-server_timeout",
"-set_intermediate_dir",
+ "-snapshot",
"-thread",
"-time_notgranted",
"-txn_timeout",
@@ -437,6 +443,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
"-private",
"-recover",
"-recover_fatal",
+ "-register",
"-shm_key",
"-system_mem",
"-tmp_dir",
@@ -458,15 +465,16 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
ENV_CDB,
ENV_CDB_ALLDB,
ENV_CLIENT_TO,
+ ENV_EVENT,
ENV_LOCK,
ENV_CONFLICT,
ENV_DETECT,
- ENV_LOCK_MAX,
ENV_LOCK_MAX_LOCKS,
ENV_LOCK_MAX_LOCKERS,
ENV_LOCK_MAX_OBJECTS,
ENV_LOCK_TIMEOUT,
ENV_LOG,
+ ENV_LOG_FILEMODE,
ENV_LOG_BUFFER,
ENV_LOG_INMEMORY,
ENV_LOG_MAX,
@@ -476,14 +484,17 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
ENV_MPOOL_MAX_WRITE,
ENV_MPOOL_MMAP_SIZE,
ENV_MPOOL_NOMMAP,
+ ENV_MULTIVERSION,
ENV_OVERWRITE,
ENV_REGION_INIT,
+ ENV_REP,
ENV_REP_CLIENT,
ENV_REP_MASTER,
ENV_REP_TRANSPORT,
ENV_SERVER,
ENV_SERVER_TO,
ENV_SET_INTERMEDIATE_DIR,
+ ENV_SNAPSHOT,
ENV_THREAD,
ENV_TIME_NOTGRANTED,
ENV_TXN_TIMEOUT,
@@ -504,6 +515,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
ENV_PRIVATE,
ENV_RECOVER,
ENV_RECOVER_FATAL,
+ ENV_REGISTER,
ENV_SHM_KEY,
ENV_SYSTEM_MEM,
ENV_TMP_DIR,
@@ -545,8 +557,7 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
* Meanwhile, there's no strong reason to enable DB_THREAD when not
* testing.
*/
- open_flags = DB_JOINENV;
-
+ open_flags = 0;
logmaxset = logbufset = 0;
if (objc <= 2) {
@@ -615,21 +626,13 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
* From here on we must 'goto error' in order to clean up the
* env from db_env_create.
*/
- if (server != NULL) {
- (*env)->set_errpfx((*env), ip->i_name);
- (*env)->set_errcall((*env), _ErrorFunc);
- if ((ret = (*env)->set_rpc_server((*env), NULL, server,
- client_to, server_to, 0)) != 0) {
- result = TCL_ERROR;
- goto error;
- }
- } else {
- /*
- * Create the environment handle before parsing the args
- * since we'll be modifying the environment as we parse.
- */
- (*env)->set_errpfx((*env), ip->i_name);
- (*env)->set_errcall((*env), _ErrorFunc);
+ (*env)->set_errpfx((*env), ip->i_name);
+ (*env)->set_errcall((*env), _ErrorFunc);
+ if (server != NULL &&
+ (ret = (*env)->set_rpc_server((*env), NULL, server,
+ client_to, server_to, 0)) != 0) {
+ result = TCL_ERROR;
+ goto error;
}
/* Hang our info pointer on the env handle, so we can do callbacks. */
@@ -672,14 +675,12 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
break;
case ENV_CDB:
FLD_SET(open_flags, DB_INIT_CDB | DB_INIT_MPOOL);
- FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_CDB_ALLDB:
FLD_SET(set_flags, DB_CDB_ALLDB);
break;
case ENV_LOCK:
FLD_SET(open_flags, DB_INIT_LOCK | DB_INIT_MPOOL);
- FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_CONFLICT:
/*
@@ -772,7 +773,15 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"lock_detect");
break;
- case ENV_LOCK_MAX:
+ case ENV_EVENT:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "-event eventproc");
+ result = TCL_ERROR;
+ break;
+ }
+ result = tcl_EventNotify(interp, *env, objv[i++], ip);
+ break;
case ENV_LOCK_MAX_LOCKS:
case ENV_LOCK_MAX_LOCKERS:
case ENV_LOCK_MAX_OBJECTS:
@@ -786,10 +795,6 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
if (result == TCL_OK) {
_debug_check();
switch ((enum envopen)optindex) {
- case ENV_LOCK_MAX:
- ret = (*env)->set_lk_max(*env,
- uintarg);
- break;
case ENV_LOCK_MAX_LOCKS:
ret = (*env)->set_lk_max_locks(*env,
uintarg);
@@ -838,7 +843,6 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
break;
case ENV_LOG:
FLD_SET(open_flags, DB_INIT_LOG | DB_INIT_MPOOL);
- FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_LOG_BUFFER:
if (i >= objc) {
@@ -865,6 +869,22 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
}
}
break;
+ case ENV_LOG_FILEMODE:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-log_filemode mode?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &uintarg);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret =
+ (*env)->set_lg_filemode(*env, (int)uintarg);
+ result = _ReturnSetup(interp, ret,
+ DB_RETOK_STD(ret), "log_filemode");
+ }
+ break;
case ENV_LOG_INMEMORY:
FLD_SET(set_flags, DB_LOG_INMEMORY);
break;
@@ -962,6 +982,9 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
case ENV_MPOOL_NOMMAP:
FLD_SET(set_flags, DB_NOMMAP);
break;
+ case ENV_MULTIVERSION:
+ FLD_SET(set_flags, DB_MULTIVERSION);
+ break;
case ENV_OVERWRITE:
FLD_SET(set_flags, DB_OVERWRITE);
break;
@@ -987,6 +1010,9 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
DB_RETOK_STD(ret), "set_intermediate_dir");
}
break;
+ case ENV_REP:
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
case ENV_REP_CLIENT:
rep_flags = DB_REP_CLIENT;
FLD_SET(open_flags, DB_INIT_REP);
@@ -1002,49 +1028,19 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
result = TCL_ERROR;
break;
}
-
- /*
- * Store the objects containing the machine ID
- * and the procedure name. We don't need to crack
- * the send procedure out now, but we do convert the
- * machine ID to an int, since set_rep_transport needs
- * it. Even so, it'll be easier later to deal with
- * the Tcl_Obj *, so we save that, not the int.
- *
- * Note that we Tcl_IncrRefCount both objects
- * independently; Tcl is free to discard the list
- * that they're bundled into.
- */
- result = Tcl_ListObjGetElements(interp, objv[i++],
+ result = Tcl_ListObjGetElements(interp, objv[i],
&myobjc, &myobjv);
- if (myobjc != 2) {
- Tcl_SetResult(interp,
- "List must be {envid sendproc}",
- TCL_STATIC);
- result = TCL_ERROR;
- break;
- }
-
- FLD_SET(open_flags, DB_INIT_REP);
- /*
- * Check that the machine ID is an int. Note that
- * we do want to use GetIntFromObj; the machine
- * ID is explicitly an int, not a u_int32_t.
- */
- ip->i_rep_eid = myobjv[0];
- Tcl_IncrRefCount(ip->i_rep_eid);
- result = Tcl_GetIntFromObj(interp,
- ip->i_rep_eid, &intarg);
- if (result != TCL_OK)
+ if (result == TCL_OK)
+ i++;
+ else
break;
-
- ip->i_rep_send = myobjv[1];
- Tcl_IncrRefCount(ip->i_rep_send);
- _debug_check();
- ret = (*env)->set_rep_transport(*env,
- intarg, tcl_rep_send);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "set_rep_transport");
+ result = tcl_RepTransport(interp, myobjc, myobjv,
+ *env, ip);
+ if (result == TCL_OK)
+ FLD_SET(open_flags, DB_INIT_REP);
+ break;
+ case ENV_SNAPSHOT:
+ FLD_SET(set_flags, DB_TXN_SNAPSHOT);
break;
case ENV_THREAD:
/* Enable DB_THREAD when specified in testing. */
@@ -1076,19 +1072,21 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
case ENV_TXN:
FLD_SET(open_flags, DB_INIT_LOCK |
DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN);
- FLD_CLR(open_flags, DB_JOINENV);
/* Make sure we have an arg to check against! */
- if (i < objc) {
+ while (i < objc) {
arg = Tcl_GetStringFromObj(objv[i], NULL);
if (strcmp(arg, "nosync") == 0) {
FLD_SET(set_flags, DB_TXN_NOSYNC);
i++;
- }
+ } else if (strcmp(arg, "snapshot") == 0) {
+ FLD_SET(set_flags, DB_TXN_SNAPSHOT);
+ i++;
+ } else
+ break;
}
break;
case ENV_CREATE:
FLD_SET(open_flags, DB_CREATE | DB_INIT_MPOOL);
- FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_ENCRYPT_AES:
/* Make sure we have an arg to check against! */
@@ -1145,7 +1143,6 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
break;
case ENV_PRIVATE:
FLD_SET(open_flags, DB_PRIVATE | DB_INIT_MPOOL);
- FLD_CLR(open_flags, DB_JOINENV);
break;
case ENV_RECOVER:
FLD_SET(open_flags, DB_RECOVER);
@@ -1153,6 +1150,9 @@ bdb_EnvOpen(interp, objc, objv, ip, env)
case ENV_RECOVER_FATAL:
FLD_SET(open_flags, DB_RECOVER_FATAL);
break;
+ case ENV_REGISTER:
+ FLD_SET(open_flags, DB_REGISTER);
+ break;
case ENV_SYSTEM_MEM:
FLD_SET(open_flags, DB_SYSTEM_MEM);
break;
@@ -1378,13 +1378,13 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
static const char *bdbopen[] = {
#ifdef CONFIG_TEST
"-btcompare",
- "-dirty",
"-dupcompare",
"-hashproc",
"-lorder",
"-minkey",
"-nommap",
"-notdurable",
+ "-read_uncommitted",
"-revsplitoff",
"-test",
"-thread",
@@ -1411,6 +1411,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
"-len",
"-maxsize",
"-mode",
+ "-multiversion",
"-nelem",
"-pad",
"-pagesize",
@@ -1430,13 +1431,13 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
enum bdbopen {
#ifdef CONFIG_TEST
TCL_DB_BTCOMPARE,
- TCL_DB_DIRTY,
TCL_DB_DUPCOMPARE,
TCL_DB_HASHPROC,
TCL_DB_LORDER,
TCL_DB_MINKEY,
TCL_DB_NOMMAP,
TCL_DB_NOTDURABLE,
+ TCL_DB_READ_UNCOMMITTED,
TCL_DB_REVSPLIT,
TCL_DB_TEST,
TCL_DB_THREAD,
@@ -1463,6 +1464,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
TCL_DB_LEN,
TCL_DB_MAXSIZE,
TCL_DB_MODE,
+ TCL_DB_MULTIVERSION,
TCL_DB_NELEM,
TCL_DB_PAD,
TCL_DB_PAGESIZE,
@@ -1624,9 +1626,6 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"set_bt_compare");
break;
- case TCL_DB_DIRTY:
- open_flags |= DB_DIRTY_READ;
- break;
case TCL_DB_DUPCOMPARE:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -1701,6 +1700,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
case TCL_DB_NOTDURABLE:
set_flags |= DB_TXN_NOT_DURABLE;
break;
+ case TCL_DB_READ_UNCOMMITTED:
+ open_flags |= DB_READ_UNCOMMITTED;
+ break;
case TCL_DB_REVSPLIT:
set_flags |= DB_REVSPLITOFF;
break;
@@ -1876,6 +1878,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
DB_RETOK_STD(ret), "set_h_ffactor");
}
break;
+ case TCL_DB_MULTIVERSION:
+ open_flags |= DB_MULTIVERSION;
+ break;
case TCL_DB_NELEM:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -2102,6 +2107,8 @@ bdb_DbOpen(interp, objc, objv, ip, dbp)
* arrays for the subdb.
*/
db = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(db, "") == 0)
+ db = NULL;
if (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
@@ -2169,7 +2176,7 @@ error:
return (result);
}
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
/*
* bdb_SeqOpen --
* Implements the "Seq_create/Seq_open" command.
@@ -2183,7 +2190,6 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
DB_SEQUENCE **seqp; /* DB_SEQUENCE handle */
{
static const char *seqopen[] = {
- "-auto_commit",
"-cachesize",
"-create",
"-inc",
@@ -2191,13 +2197,13 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
"-dec",
"-max",
"-min",
+ "-thread",
"-txn",
"-wrap",
"--",
NULL
} ;
enum seqopen {
- TCL_SEQ_AUTO_COMMIT,
TCL_SEQ_CACHESIZE,
TCL_SEQ_CREATE,
TCL_SEQ_INC,
@@ -2205,6 +2211,7 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
TCL_SEQ_DEC,
TCL_SEQ_MAX,
TCL_SEQ_MIN,
+ TCL_SEQ_THREAD,
TCL_SEQ_TXN,
TCL_SEQ_WRAP,
TCL_SEQ_ENDARG
@@ -2215,12 +2222,14 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
DB_TXN *txn;
db_recno_t recno;
db_seq_t min, max, value;
+ Tcl_WideInt tcl_value;
u_int32_t flags, oflags;
int cache, endarg, i, optindex, result, ret, setrange, setvalue, v;
char *arg, *db, msg[MSG_SIZE];
COMPQUIET(ip, NULL);
COMPQUIET(value, 0);
+ *seqp = NULL;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?args?");
@@ -2250,9 +2259,6 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
i++;
result = TCL_OK;
switch ((enum seqopen)optindex) {
- case TCL_SEQ_AUTO_COMMIT:
- oflags |= DB_AUTO_COMMIT;
- break;
case TCL_SEQ_CREATE:
oflags |= DB_CREATE;
break;
@@ -2276,7 +2282,9 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
break;
}
result =
- Tcl_GetWideIntFromObj(interp, objv[i++], &value);
+ Tcl_GetWideIntFromObj(
+ interp, objv[i++], &tcl_value);
+ value = tcl_value;
setvalue = 1;
break;
case TCL_SEQ_DEC:
@@ -2291,8 +2299,9 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
}
if ((result =
Tcl_GetWideIntFromObj(interp,
- objv[i++], &max)) != TCL_OK)
+ objv[i++], &tcl_value)) != TCL_OK)
goto error;
+ max = tcl_value;
setrange = 1;
break;
case TCL_SEQ_MIN:
@@ -2304,10 +2313,14 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
}
if ((result =
Tcl_GetWideIntFromObj(interp,
- objv[i++], &min)) != TCL_OK)
+ objv[i++], &tcl_value)) != TCL_OK)
goto error;
+ min = tcl_value;
setrange = 1;
break;
+ case TCL_SEQ_THREAD:
+ oflags |= DB_THREAD;
+ break;
case TCL_SEQ_TXN:
if (i > (objc - 1)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
@@ -2355,17 +2368,13 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
}
(void)dbp->get_type(dbp, &type);
- memset(&key, 0, sizeof(key));
if (type == DB_QUEUE || type == DB_RECNO) {
result = _GetUInt32(interp, objv[i++], &recno);
if (result != TCL_OK)
return (result);
- key.data = &recno;
- key.size = sizeof(recno);
- } else {
- key.data = Tcl_GetByteArrayFromObj(objv[i++], &v);
- key.size = (u_int32_t)v;
- }
+ DB_INIT_DBT(key, &recno, sizeof(recno));
+ } else
+ DB_INIT_DBT(key, Tcl_GetByteArrayFromObj(objv[i++], &v), v);
ret = db_sequence_create(seqp, dbp, 0);
if ((result = _ReturnSetup(interp,
ret, DB_RETOK_STD(ret), "sequence create")) != TCL_OK) {
@@ -2401,7 +2410,8 @@ bdb_SeqOpen(interp, objc, objv, ip, seqp)
goto error;
if (0) {
-error: (void)(*seqp)->close(*seqp, 0);
+error: if (*seqp != NULL)
+ (void)(*seqp)->close(*seqp, 0);
*seqp = NULL;
}
return (result);
@@ -2559,6 +2569,8 @@ bdb_DbRemove(interp, objc, objv)
* arrays for the subdb.
*/
db = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(db, "") == 0)
+ db = NULL;
if (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
@@ -2685,10 +2697,10 @@ bdb_DbRename(interp, objc, objv)
}
i++;
switch ((enum bdbmv)optindex) {
- case TCL_DBMV_AUTOCOMMIT:
- iflags |= DB_AUTO_COMMIT;
- _debug_check();
- break;
+ case TCL_DBMV_AUTOCOMMIT:
+ iflags |= DB_AUTO_COMMIT;
+ _debug_check();
+ break;
case TCL_DBMV_ENCRYPT:
set_flags |= DB_ENCRYPT;
_debug_check();
@@ -2766,6 +2778,8 @@ bdb_DbRename(interp, objc, objv)
* arrays for the subdb.
*/
db = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(db, "") == 0)
+ db = NULL;
if (i == objc - 2) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
@@ -3125,6 +3139,70 @@ error:
#ifdef CONFIG_TEST
/*
+ * bdb_GetConfig --
+ * Implements the getconfig command.
+ */
+#define ADD_CONFIG_NAME(name) \
+ conf = NewStringObj(name, strlen(name)); \
+ if (Tcl_ListObjAppendElement(interp, res, conf) != TCL_OK) \
+ return (TCL_ERROR);
+
+static int
+bdb_GetConfig(interp, objc, objv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+{
+ Tcl_Obj *res, *conf;
+
+ /*
+ * No args. Error if we have some
+ */
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return (TCL_ERROR);
+ }
+ res = Tcl_NewListObj(0, NULL);
+ conf = NULL;
+
+ /*
+ * This command conditionally adds strings in based on
+ * how DB is configured so that the test suite can make
+ * decisions based on that. For now only implement the
+ * configuration pieces we need.
+ */
+#ifdef DEBUG
+ ADD_CONFIG_NAME("debug");
+#endif
+#ifdef DEBUG_ROP
+ ADD_CONFIG_NAME("debug_rop");
+#endif
+#ifdef DEBUG_WOP
+ ADD_CONFIG_NAME("debug_wop");
+#endif
+#ifdef HAVE_HASH
+ ADD_CONFIG_NAME("hash");
+#endif
+#ifdef HAVE_QUEUE
+ ADD_CONFIG_NAME("queue");
+#endif
+#ifdef HAVE_REPLICATION
+ ADD_CONFIG_NAME("rep");
+#endif
+#ifdef HAVE_REPLICATION_THREADS
+ ADD_CONFIG_NAME("repmgr");
+#endif
+#ifdef HAVE_RPC
+ ADD_CONFIG_NAME("rpc");
+#endif
+#ifdef HAVE_VERIFY
+ ADD_CONFIG_NAME("verify");
+#endif
+ Tcl_SetObjResult(interp, res);
+ return (TCL_OK);
+}
+
+/*
* bdb_Handles --
* Implements the handles command.
*/
@@ -3146,8 +3224,7 @@ bdb_Handles(interp, objc, objv)
}
res = Tcl_NewListObj(0, NULL);
- for (p = LIST_FIRST(&__db_infohead); p != NULL;
- p = LIST_NEXT(p, entries)) {
+ LIST_FOREACH(p, &__db_infohead, entries) {
handle = NewStringObj(p->i_name, strlen(p->i_name));
if (Tcl_ListObjAppendElement(interp, res, handle) != TCL_OK)
return (TCL_ERROR);
@@ -3178,10 +3255,12 @@ bdb_MsgType(interp, objc, objv)
*/
static const char *msgnames[] = {
"no_type", "alive", "alive_req", "all_req",
+ "bulk_log", "bulk_page",
"dupmaster", "file", "file_fail", "file_req", "log",
"log_more", "log_req", "master_req", "newclient",
"newfile", "newmaster", "newsite", "page",
- "page_fail", "page_req", "update", "update_req",
+ "page_fail", "page_more", "page_req",
+ "rerequest", "update", "update_req",
"verify", "verify_fail", "verify_req",
"vote1", "vote2", NULL
};
@@ -3194,7 +3273,7 @@ bdb_MsgType(interp, objc, objv)
return (TCL_ERROR);
}
- ret = _CopyObjBytes(interp, objv[2], (void **)&rp, &len, &freerp);
+ ret = _CopyObjBytes(interp, objv[2], &rp, &len, &freerp);
if (ret != TCL_OK) {
Tcl_SetResult(interp,
"msgtype: bad control message", TCL_STATIC);
@@ -3387,8 +3466,7 @@ tcl_compare_callback(dbp, dbta, dbtb, procobj, errname)
* So, drop core. If we're not running with diagnostic
* mode, panic--and always return a negative number. :-)
*/
-panic: __db_err(dbp->dbenv, "Tcl %s callback failed", errname);
- DB_ASSERT(0);
+panic: __db_errx(dbp->dbenv, "Tcl %s callback failed", errname);
return (__db_panic(dbp->dbenv, DB_RUNRECOVERY));
}
@@ -3439,24 +3517,20 @@ tcl_h_hash(dbp, buf, len)
Tcl_DecrRefCount(objv[1]);
return ((u_int32_t)hval);
-panic: /*
- * We drop core on error, in diagnostic mode. See the comment in
- * tcl_compare_callback.
- */
- __db_err(dbp->dbenv, "Tcl h_hash callback failed");
- (void)__db_panic(dbp->dbenv, DB_RUNRECOVERY);
-
- DB_ASSERT(0);
+panic: __db_errx(dbp->dbenv, "Tcl h_hash callback failed");
- /* NOTREACHED */
+ (void)__db_panic(dbp->dbenv, DB_RUNRECOVERY);
return (0);
}
/*
* tcl_rep_send --
* Replication send callback.
+ *
+ * PUBLIC: int tcl_rep_send __P((DB_ENV *,
+ * PUBLIC: const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
*/
-static int
+int
tcl_rep_send(dbenv, control, rec, lsnp, eid, flags)
DB_ENV *dbenv;
const DBT *control, *rec;
@@ -3465,11 +3539,13 @@ tcl_rep_send(dbenv, control, rec, lsnp, eid, flags)
u_int32_t flags;
{
#define TCLDB_SENDITEMS 7
+#define TCLDB_MAXREPFLAGS 32
DBTCL_INFO *ip;
Tcl_Interp *interp;
Tcl_Obj *control_o, *eid_o, *flags_o, *lsn_o, *origobj, *rec_o;
- Tcl_Obj *myobjv[2], *resobj, *objv[TCLDB_SENDITEMS];
- int myobjc, result, ret;
+ Tcl_Obj *lsnobj[2], *myobjv[TCLDB_MAXREPFLAGS], *objv[TCLDB_SENDITEMS];
+ Tcl_Obj *resobj;
+ int i, myobjc, result, ret;
ip = (DBTCL_INFO *)dbenv->app_private;
interp = ip->i_interp;
@@ -3484,18 +3560,34 @@ tcl_rep_send(dbenv, control, rec, lsnp, eid, flags)
eid_o = Tcl_NewIntObj(eid);
Tcl_IncrRefCount(eid_o);
+ myobjv[myobjc = 0] = NULL;
+ if (flags == 0)
+ myobjv[myobjc++] = NewStringObj("none", strlen("none"));
+ if (LF_ISSET(DB_REP_ANYWHERE))
+ myobjv[myobjc++] = NewStringObj("any", strlen("any"));
+ if (LF_ISSET(DB_REP_NOBUFFER))
+ myobjv[myobjc++] = NewStringObj("nobuffer", strlen("nobuffer"));
if (LF_ISSET(DB_REP_PERMANENT))
- flags_o = NewStringObj("perm", strlen("perm"));
- else if (LF_ISSET(DB_REP_NOBUFFER))
- flags_o = NewStringObj("nobuffer", strlen("nobuffer"));
- else
- flags_o = NewStringObj("none", strlen("none"));
+ myobjv[myobjc++] = NewStringObj("perm", strlen("perm"));
+ if (LF_ISSET(DB_REP_REREQUEST))
+ myobjv[myobjc++] =
+ NewStringObj("rerequest", strlen("rerequest"));
+ /*
+ * If we're given an unrecognized flag send "unknown".
+ */
+ if (myobjc == 0)
+ myobjv[myobjc++] = NewStringObj("unknown", strlen("unknown"));
+ for (i = 0; i < myobjc; i++)
+ Tcl_IncrRefCount(myobjv[i]);
+ flags_o = Tcl_NewListObj(myobjc, myobjv);
Tcl_IncrRefCount(flags_o);
- myobjc = 2;
- myobjv[0] = Tcl_NewLongObj((long)lsnp->file);
- myobjv[1] = Tcl_NewLongObj((long)lsnp->offset);
- lsn_o = Tcl_NewListObj(myobjc, myobjv);
+ lsnobj[0] = Tcl_NewLongObj((long)lsnp->file);
+ Tcl_IncrRefCount(lsnobj[0]);
+ lsnobj[1] = Tcl_NewLongObj((long)lsnp->offset);
+ Tcl_IncrRefCount(lsnobj[1]);
+ lsn_o = Tcl_NewListObj(2, lsnobj);
+ Tcl_IncrRefCount(lsn_o);
objv[1] = control_o;
objv[2] = rec_o;
@@ -3520,7 +3612,7 @@ tcl_rep_send(dbenv, control, rec, lsnp, eid, flags)
* this error should only happen if the Tcl callback is
* somehow invalid, which is a fatal scripting bug.
*/
-err: __db_err(dbenv, "Tcl rep_send failure");
+err: __db_errx(dbenv, "Tcl rep_send failure");
return (EINVAL);
}
@@ -3534,7 +3626,12 @@ err: __db_err(dbenv, "Tcl rep_send failure");
Tcl_DecrRefCount(control_o);
Tcl_DecrRefCount(rec_o);
Tcl_DecrRefCount(eid_o);
+ for (i = 0; i < myobjc; i++)
+ Tcl_DecrRefCount(myobjv[i]);
Tcl_DecrRefCount(flags_o);
+ Tcl_DecrRefCount(lsnobj[0]);
+ Tcl_DecrRefCount(lsnobj[1]);
+ Tcl_DecrRefCount(lsn_o);
return (ret);
}
diff --git a/db/tcl/tcl_dbcursor.c b/db/tcl/tcl_dbcursor.c
index f0ca788f4..1e40afa83 100644
--- a/db/tcl/tcl_dbcursor.c
+++ b/db/tcl/tcl_dbcursor.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_dbcursor.c,v 11.65 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_dbcursor.c,v 12.11 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
/*
@@ -383,11 +378,13 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
{
static const char *dbcgetopts[] = {
#ifdef CONFIG_TEST
- "-degree_2",
- "-dirty",
+ "-data_buf_size",
"-get_both_range",
+ "-key_buf_size",
"-multi",
"-multi_key",
+ "-read_committed",
+ "-read_uncommitted",
#endif
"-current",
"-first",
@@ -409,11 +406,13 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
};
enum dbcgetopts {
#ifdef CONFIG_TEST
- DBCGET_DEGREE2,
- DBCGET_DIRTY,
+ DBCGET_DATA_BUF_SIZE,
DBCGET_BOTH_RANGE,
+ DBCGET_KEY_BUF_SIZE,
DBCGET_MULTI,
DBCGET_MULTI_KEY,
+ DBCGET_READ_COMMITTED,
+ DBCGET_READ_UNCOMMITTED,
#endif
DBCGET_CURRENT,
DBCGET_FIRST,
@@ -442,9 +441,9 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
u_int32_t flag, op;
int elemc, freekey, freedata, i, optindex, result, ret;
#ifdef CONFIG_TEST
- int bufsize;
+ int data_buf_size, key_buf_size;
- bufsize = 0;
+ data_buf_size = key_buf_size = 0;
#endif
COMPQUIET(dtmp, NULL);
COMPQUIET(ktmp, NULL);
@@ -452,14 +451,15 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
result = TCL_OK;
flag = 0;
freekey = freedata = 0;
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ memset(&pdata, 0, sizeof(DBT));
if (objc < 2) {
Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key?");
return (TCL_ERROR);
}
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
/*
* Get the command name index from the object based on the options
* defined above.
@@ -480,105 +480,110 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
break;
}
i++;
+
+#define FLAG_CHECK2_STDARG \
+ (DB_RMW | DB_MULTIPLE | DB_MULTIPLE_KEY | DB_READ_UNCOMMITTED)
+
switch ((enum dbcgetopts)optindex) {
#ifdef CONFIG_TEST
- case DBCGET_DEGREE2:
- flag |= DB_DEGREE_2;
- break;
- case DBCGET_DIRTY:
- flag |= DB_DIRTY_READ;
+ case DBCGET_DATA_BUF_SIZE:
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
+ if (result != TCL_OK)
+ goto out;
+ i++;
break;
case DBCGET_BOTH_RANGE:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_GET_BOTH_RANGE;
break;
+ case DBCGET_KEY_BUF_SIZE:
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &key_buf_size);
+ if (result != TCL_OK)
+ goto out;
+ i++;
+ break;
case DBCGET_MULTI:
flag |= DB_MULTIPLE;
- result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
if (result != TCL_OK)
goto out;
i++;
break;
case DBCGET_MULTI_KEY:
flag |= DB_MULTIPLE_KEY;
- result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);
+ result =
+ Tcl_GetIntFromObj(interp, objv[i], &data_buf_size);
if (result != TCL_OK)
goto out;
i++;
break;
+ case DBCGET_READ_COMMITTED:
+ flag |= DB_READ_COMMITTED;
+ break;
+ case DBCGET_READ_UNCOMMITTED:
+ flag |= DB_READ_UNCOMMITTED;
+ break;
#endif
case DBCGET_RMW:
flag |= DB_RMW;
break;
case DBCGET_CURRENT:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_CURRENT;
break;
case DBCGET_FIRST:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_FIRST;
break;
case DBCGET_LAST:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_LAST;
break;
case DBCGET_NEXT:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_NEXT;
break;
case DBCGET_PREV:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_PREV;
break;
case DBCGET_PREVNODUP:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_PREV_NODUP;
break;
case DBCGET_NEXTNODUP:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_NEXT_NODUP;
break;
case DBCGET_NEXTDUP:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_NEXT_DUP;
break;
case DBCGET_BOTH:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_GET_BOTH;
break;
case DBCGET_RECNO:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_GET_RECNO;
break;
case DBCGET_JOIN:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_JOIN_ITEM;
break;
case DBCGET_SET:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_SET;
break;
case DBCGET_SETRANGE:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_SET_RANGE;
break;
case DBCGET_SETRECNO:
- FLAG_CHECK2(flag,
- DB_RMW|DB_MULTIPLE|DB_MULTIPLE_KEY|DB_DIRTY_READ);
+ FLAG_CHECK2(flag, FLAG_CHECK2_STDARG);
flag |= DB_SET_RECNO;
break;
case DBCGET_PART:
@@ -714,9 +719,10 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
goto out;
}
#ifdef CONFIG_TEST
- if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) {
- (void)__os_malloc(NULL, (size_t)bufsize, &data.data);
- data.ulen = (u_int32_t)bufsize;
+ if (data_buf_size != 0) {
+ (void)__os_malloc(
+ NULL, (size_t)data_buf_size, &data.data);
+ data.ulen = (u_int32_t)data_buf_size;
data.flags |= DB_DBT_USERMEM;
} else
#endif
@@ -748,11 +754,20 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
result = TCL_ERROR;
goto out;
}
- key.flags |= DB_DBT_MALLOC;
#ifdef CONFIG_TEST
- if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) {
- (void)__os_malloc(NULL, (size_t)bufsize, &data.data);
- data.ulen = (u_int32_t)bufsize;
+ if (key_buf_size != 0) {
+ (void)__os_malloc(
+ NULL, (size_t)key_buf_size, &key.data);
+ key.ulen = (u_int32_t)key_buf_size;
+ key.flags |= DB_DBT_USERMEM;
+ } else
+#endif
+ key.flags |= DB_DBT_MALLOC;
+#ifdef CONFIG_TEST
+ if (data_buf_size != 0) {
+ (void)__os_malloc(
+ NULL, (size_t)data_buf_size, &data.data);
+ data.ulen = (u_int32_t)data_buf_size;
data.flags |= DB_DBT_USERMEM;
} else
#endif
@@ -760,7 +775,6 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
}
_debug_check();
- memset(&pdata, 0, sizeof(DBT));
if (ispget) {
F_SET(&pdata, DB_DBT_MALLOC);
ret = dbc->c_pget(dbc, &key, &data, &pdata, flag);
@@ -803,18 +817,26 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget)
key.data, key.size, data.data, data.size);
}
}
+out1:
+ if (result == TCL_OK)
+ Tcl_SetObjResult(interp, retlist);
+ /*
+ * If DB_DBT_MALLOC is set we need to free if DB allocated anything.
+ * If DB_DBT_USERMEM is set we need to free it because
+ * we allocated it (for data_buf_size/key_buf_size). That
+ * allocation does not apply to the pdata DBT.
+ */
+out:
if (key.data != NULL && F_ISSET(&key, DB_DBT_MALLOC))
__os_ufree(dbc->dbp->dbenv, key.data);
+ if (key.data != NULL && F_ISSET(&key, DB_DBT_USERMEM))
+ __os_free(dbc->dbp->dbenv, key.data);
if (data.data != NULL && F_ISSET(&data, DB_DBT_MALLOC))
__os_ufree(dbc->dbp->dbenv, data.data);
+ if (data.data != NULL && F_ISSET(&data, DB_DBT_USERMEM))
+ __os_free(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)
__os_free(NULL, dtmp);
if (freekey)
diff --git a/db/tcl/tcl_env.c b/db/tcl/tcl_env.c
index e513b961d..ac18c40cf 100644
--- a/db/tcl/tcl_env.c
+++ b/db/tcl/tcl_env.c
@@ -1,24 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_env.c,v 11.121 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_env.c,v 12.29 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
-#include "dbinc/db_shash.h"
#include "dbinc/lock.h"
#include "dbinc/txn.h"
#include "dbinc/tcl_db.h"
@@ -55,6 +49,8 @@ env_Cmd(clientData, interp, objc, objv)
"attributes",
"errfile",
"errpfx",
+ "event",
+ "id_reset",
"lock_detect",
"lock_id",
"lock_id_free",
@@ -71,18 +67,23 @@ env_Cmd(clientData, interp, objc, objv)
"log_get",
"log_put",
"log_stat",
+ "lsn_reset",
"mpool",
"mpool_stat",
"mpool_sync",
"mpool_trickle",
- "mutex",
+ "rep_config",
"rep_elect",
"rep_flush",
+ "rep_get_config",
"rep_limit",
"rep_process_message",
"rep_request",
"rep_start",
"rep_stat",
+ "rep_sync",
+ "rep_transport",
+ "repmgr",
"rpcid",
"set_flags",
"test",
@@ -92,6 +93,7 @@ env_Cmd(clientData, interp, objc, objv)
"txn_timeout",
"verbose",
#endif
+ "cdsgroup",
"close",
"dbremove",
"dbrename",
@@ -103,6 +105,7 @@ env_Cmd(clientData, interp, objc, objv)
"get_home",
"get_lg_bsize",
"get_lg_dir",
+ "get_lg_filemode",
"get_lg_max",
"get_lg_regionmax",
"get_lk_detect",
@@ -121,6 +124,7 @@ env_Cmd(clientData, interp, objc, objv)
"get_tx_max",
"get_tx_timestamp",
"get_verbose",
+ "set_data_dir",
"txn",
"txn_checkpoint",
NULL
@@ -130,6 +134,8 @@ env_Cmd(clientData, interp, objc, objv)
ENVATTR,
ENVERRFILE,
ENVERRPFX,
+ ENVEVENT,
+ ENVIDRESET,
ENVLKDETECT,
ENVLKID,
ENVLKFREEID,
@@ -146,18 +152,23 @@ env_Cmd(clientData, interp, objc, objv)
ENVLOGGET,
ENVLOGPUT,
ENVLOGSTAT,
+ ENVLSNRESET,
ENVMP,
ENVMPSTAT,
ENVMPSYNC,
ENVTRICKLE,
- ENVMUTEX,
+ ENVREPCONFIG,
ENVREPELECT,
ENVREPFLUSH,
+ ENVREPGETCONFIG,
ENVREPLIMIT,
ENVREPPROCMESS,
ENVREPREQUEST,
ENVREPSTART,
ENVREPSTAT,
+ ENVREPSYNC,
+ ENVREPTRANSPORT,
+ ENVREPMGR,
ENVRPCID,
ENVSETFLAGS,
ENVTEST,
@@ -167,6 +178,7 @@ env_Cmd(clientData, interp, objc, objv)
ENVTXNTIMEOUT,
ENVVERB,
#endif
+ ENVCDSGROUP,
ENVCLOSE,
ENVDBREMOVE,
ENVDBRENAME,
@@ -178,6 +190,7 @@ env_Cmd(clientData, interp, objc, objv)
ENVGETHOME,
ENVGETLGBSIZE,
ENVGETLGDIR,
+ ENVGETLGFILEMODE,
ENVGETLGMAX,
ENVGETLGREGIONMAX,
ENVGETLKDETECT,
@@ -196,12 +209,13 @@ env_Cmd(clientData, interp, objc, objv)
ENVGETTXMAX,
ENVGETTXTIMESTAMP,
ENVGETVERBOSE,
+ ENVSETDATADIR,
ENVTXN,
ENVTXNCKP
};
DBTCL_INFO *envip;
DB_ENV *dbenv;
- Tcl_Obj *res, *myobjv[3];
+ Tcl_Obj *myobjv[3], *res;
char newname[MSG_SIZE];
int cmdindex, i, intvalue1, intvalue2, ncache, result, ret;
u_int32_t bytes, gbytes, value;
@@ -209,12 +223,14 @@ env_Cmd(clientData, interp, objc, objv)
long shm_key;
time_t timeval;
const char *strval, **dirs;
+ char *strarg;
#ifdef CONFIG_TEST
DBTCL_INFO *logcip;
DB_LOGC *logc;
- char *strarg;
+ Tcl_Obj **repobjv;
u_int32_t lockid;
long newval, otherval;
+ int repobjc;
#endif
Tcl_ResetResult(interp);
@@ -246,6 +262,22 @@ env_Cmd(clientData, interp, objc, objv)
res = NULL;
switch ((enum envcmds)cmdindex) {
#ifdef CONFIG_TEST
+ case ENVEVENT:
+ /*
+ * Two args for this. Error if different.
+ */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ result = tcl_EventNotify(interp, dbenv, objv[2], envip);
+ break;
+ case ENVIDRESET:
+ result = tcl_EnvIdReset(interp, objc, objv, dbenv);
+ break;
+ case ENVLSNRESET:
+ result = tcl_EnvLsnReset(interp, objc, objv, dbenv);
+ break;
case ENVLKDETECT:
result = tcl_LockDetect(interp, objc, objv, dbenv);
break;
@@ -367,12 +399,32 @@ env_Cmd(clientData, interp, objc, objv)
case ENVMP:
result = tcl_Mp(interp, objc, objv, dbenv, envip);
break;
+ case ENVREPCONFIG:
+ /*
+ * Two args for this. Error if different.
+ */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ result = tcl_RepConfig(interp, dbenv, objv[2]);
+ break;
case ENVREPELECT:
result = tcl_RepElect(interp, objc, objv, dbenv);
break;
case ENVREPFLUSH:
result = tcl_RepFlush(interp, objc, objv, dbenv);
break;
+ case ENVREPGETCONFIG:
+ /*
+ * Two args for this. Error if different.
+ */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ result = tcl_RepGetConfig(interp, dbenv, objv[2]);
+ break;
case ENVREPLIMIT:
result = tcl_RepLimit(interp, objc, objv, dbenv);
break;
@@ -388,6 +440,23 @@ env_Cmd(clientData, interp, objc, objv)
case ENVREPSTAT:
result = tcl_RepStat(interp, objc, objv, dbenv);
break;
+ case ENVREPSYNC:
+ result = tcl_RepSync(interp, objc, objv, dbenv);
+ break;
+ case ENVREPTRANSPORT:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ result = Tcl_ListObjGetElements(interp, objv[2],
+ &repobjc, &repobjv);
+ if (result == TCL_OK)
+ result = tcl_RepTransport(interp,
+ repobjc, repobjv, dbenv, envip);
+ break;
+ case ENVREPMGR:
+ result = tcl_RepMgr(interp, objc, objv, dbenv);
+ break;
case ENVRPCID:
/*
* No args for this. Error if there are some.
@@ -427,9 +496,6 @@ env_Cmd(clientData, interp, objc, objv)
case ENVTXNTIMEOUT:
result = tcl_TxnTimeout(interp, objc, objv, dbenv);
break;
- case ENVMUTEX:
- result = tcl_Mutex(interp, objc, objv, dbenv, envip);
- break;
case ENVATTR:
result = tcl_EnvAttr(interp, objc, objv, dbenv);
break;
@@ -480,6 +546,9 @@ env_Cmd(clientData, interp, objc, objv)
result = tcl_EnvVerbose(interp, dbenv, objv[2], objv[3]);
break;
#endif
+ case ENVCDSGROUP:
+ result = tcl_CDSGroup(interp, objc, objv, dbenv, envip);
+ break;
case ENVCLOSE:
/*
* No args for this. Error if there are some.
@@ -581,6 +650,16 @@ env_Cmd(clientData, interp, objc, objv)
"env get_lg_dir")) == TCL_OK)
res = NewStringObj(strval, strlen(strval));
break;
+ case ENVGETLGFILEMODE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ ret = dbenv->get_lg_filemode(dbenv, &intvalue1);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env get_lg_filemode")) == TCL_OK)
+ res = Tcl_NewLongObj((long)intvalue1);
+ break;
case ENVGETLGMAX:
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -675,9 +754,9 @@ env_Cmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
- ret = dbenv->get_rep_limit(dbenv, &gbytes, &bytes);
+ ret = dbenv->rep_get_limit(dbenv, &gbytes, &bytes);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_rep_limit")) == TCL_OK) {
+ "env rep_get_limit")) == TCL_OK) {
myobjv[0] = Tcl_NewLongObj((long)gbytes);
myobjv[1] = Tcl_NewLongObj((long)bytes);
res = Tcl_NewListObj(2, myobjv);
@@ -698,7 +777,7 @@ env_Cmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return (TCL_ERROR);
}
- ret = dbenv->get_tas_spins(dbenv, &value);
+ ret = dbenv->mutex_get_tas_spins(dbenv, &value);
if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env get_tas_spins")) == TCL_OK)
res = Tcl_NewLongObj((long)value);
@@ -739,6 +818,18 @@ env_Cmd(clientData, interp, objc, objv)
case ENVGETVERBOSE:
result = env_GetVerbose(interp, objc, objv, dbenv);
break;
+ case ENVSETDATADIR:
+ /*
+ * One args for this. Error if different.
+ */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pfx");
+ return (TCL_ERROR);
+ }
+ strarg = Tcl_GetStringFromObj(objv[2], NULL);
+ ret = dbenv->set_data_dir(dbenv, strarg);
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env set data dir"));
case ENVTXN:
result = tcl_Txn(interp, objc, objv, dbenv, envip);
break;
@@ -1040,7 +1131,6 @@ _EnvInfoDelete(interp, envip)
case I_ENV:
case I_LOCK:
case I_LOGC:
- case I_MUTEX:
case I_NDBM:
case I_PG:
case I_SEQ:
@@ -1061,6 +1151,111 @@ _EnvInfoDelete(interp, envip)
#ifdef CONFIG_TEST
/*
+ * PUBLIC: int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
+ * PUBLIC: DB_ENV *));
+ *
+ * tcl_EnvIdReset --
+ * Implements the ENV->fileid_reset command.
+ */
+int
+tcl_EnvIdReset(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* arg count */
+ Tcl_Obj * CONST* objv; /* args */
+ DB_ENV *dbenv; /* Database pointer */
+{
+ static const char *idwhich[] = {
+ "-encrypt",
+ NULL
+ };
+ enum idwhich {
+ IDENCRYPT
+ };
+ int enc, i, result, ret;
+ u_int32_t flags;
+ char *file;
+
+ result = TCL_OK;
+ flags = 0;
+ i = 2;
+ Tcl_SetResult(interp, "0", TCL_STATIC);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
+ return (TCL_ERROR);
+ } else if (objc > 3) {
+ /*
+ * If there is an arg, make sure it is the right one.
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], idwhich, "option",
+ TCL_EXACT, &enc) != TCL_OK)
+ return (IS_HELP(objv[2]));
+ switch ((enum idwhich)enc) {
+ case IDENCRYPT:
+ flags |= DB_ENCRYPT;
+ break;
+ }
+ i = 3;
+ }
+ file = Tcl_GetStringFromObj(objv[i], NULL);
+ ret = dbenv->fileid_reset(dbenv, file, flags);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "fileid reset");
+ return (result);
+}
+
+/*
+ * PUBLIC: int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
+ * PUBLIC: DB_ENV *));
+ *
+ * tcl_EnvLsnReset --
+ * Implements the ENV->lsn_reset command.
+ */
+int
+tcl_EnvLsnReset(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* arg count */
+ Tcl_Obj * CONST* objv; /* args */
+ DB_ENV *dbenv; /* Database pointer */
+{
+ static const char *lsnwhich[] = {
+ "-encrypt",
+ NULL
+ };
+ enum lsnwhich {
+ IDENCRYPT
+ };
+ int enc, i, result, ret;
+ u_int32_t flags;
+ char *file;
+
+ result = TCL_OK;
+ flags = 0;
+ i = 2;
+ Tcl_SetResult(interp, "0", TCL_STATIC);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-encrypt? filename");
+ return (TCL_ERROR);
+ } else if (objc > 3) {
+ /*
+ * If there is an arg, make sure it is the right one.
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], lsnwhich, "option",
+ TCL_EXACT, &enc) != TCL_OK)
+ return (IS_HELP(objv[2]));
+
+ switch ((enum lsnwhich)enc) {
+ case IDENCRYPT:
+ flags |= DB_ENCRYPT;
+ break;
+ }
+ i = 3;
+ }
+ file = Tcl_GetStringFromObj(objv[i], NULL);
+ ret = dbenv->lsn_reset(dbenv, file, flags);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "lsn reset");
+ return (result);
+}
+
+/*
* PUBLIC: int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
* PUBLIC: Tcl_Obj *));
*
@@ -1076,15 +1271,17 @@ tcl_EnvVerbose(interp, dbenv, which, onoff)
static const char *verbwhich[] = {
"deadlock",
"recovery",
+ "register",
"rep",
"wait",
NULL
};
enum verbwhich {
- ENVVERB_DEAD,
- ENVVERB_REC,
- ENVVERB_REP,
- ENVVERB_WAIT
+ ENVVERB_DEADLOCK,
+ ENVVERB_RECOVERY,
+ ENVVERB_REGISTER,
+ ENVVERB_REPLICATION,
+ ENVVERB_WAITSFOR
};
static const char *verbonoff[] = {
"off",
@@ -1103,16 +1300,19 @@ tcl_EnvVerbose(interp, dbenv, which, onoff)
return (IS_HELP(which));
switch ((enum verbwhich)optindex) {
- case ENVVERB_DEAD:
+ case ENVVERB_DEADLOCK:
wh = DB_VERB_DEADLOCK;
break;
- case ENVVERB_REC:
+ case ENVVERB_RECOVERY:
wh = DB_VERB_RECOVERY;
break;
- case ENVVERB_REP:
+ case ENVVERB_REGISTER:
+ wh = DB_VERB_REGISTER;
+ break;
+ case ENVVERB_REPLICATION:
wh = DB_VERB_REPLICATION;
break;
- case ENVVERB_WAIT:
+ case ENVVERB_WAITSFOR:
wh = DB_VERB_WAITSFOR;
break;
default:
@@ -1228,6 +1428,42 @@ err:
}
/*
+ * tcl_EventNotify --
+ * Call DB_ENV->set_event_notify().
+ *
+ * PUBLIC: int tcl_EventNotify __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
+ * PUBLIC: DBTCL_INFO *));
+ *
+ * Note that this normally can/should be achieved as an argument to
+ * berkdb env, but we need to test changing the event function on
+ * the fly.
+ */
+int
+tcl_EventNotify(interp, dbenv, eobj, ip)
+ Tcl_Interp *interp; /* Interpreter */
+ DB_ENV *dbenv;
+ Tcl_Obj *eobj; /* The event proc */
+ DBTCL_INFO *ip;
+{
+ int ret;
+
+ /*
+ * We don't need to crack the event procedure out now.
+ */
+ /*
+ * If we're replacing an existing event proc, decrement it now.
+ */
+ if (ip->i_event != NULL)
+ Tcl_DecrRefCount(ip->i_event);
+ ip->i_event = eobj;
+ Tcl_IncrRefCount(ip->i_event);
+ _debug_check();
+ ret = dbenv->set_event_notify(dbenv, _EventFunc);
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env event"));
+}
+
+/*
* PUBLIC: int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
* PUBLIC: Tcl_Obj *));
*
@@ -1248,6 +1484,7 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff)
"-dsync_log",
"-log_inmemory",
"-log_remove",
+ "-multiversion",
"-nolock",
"-nommap",
"-nopanic",
@@ -1264,6 +1501,7 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff)
ENVSF_DSYNCLOG,
ENVSF_LOG_INMEMORY,
ENVSF_LOG_REMOVE,
+ ENVSF_MULTIVERSION,
ENVSF_NOLOCK,
ENVSF_NOMMAP,
ENVSF_NOPANIC,
@@ -1307,6 +1545,9 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff)
case ENVSF_LOG_REMOVE:
wh = DB_LOG_AUTOREMOVE;
break;
+ case ENVSF_MULTIVERSION:
+ wh = DB_MULTIVERSION;
+ break;
case ENVSF_NOLOCK:
wh = DB_NOLOCKING;
break;
@@ -1346,7 +1587,7 @@ tcl_EnvSetFlags(interp, dbenv, which, onoff)
}
ret = dbenv->set_flags(dbenv, wh, on);
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env set verbose"));
+ "env set flags"));
}
/*
@@ -1383,6 +1624,7 @@ tcl_EnvTest(interp, objc, objv, dbenv)
"postlogmeta",
"postopen",
"postsync",
+ "recycle",
"subdb_lock",
NULL
};
@@ -1397,6 +1639,7 @@ tcl_EnvTest(interp, objc, objv, dbenv)
ENVTEST_POSTLOGMETA,
ENVTEST_POSTOPEN,
ENVTEST_POSTSYNC,
+ ENVTEST_RECYCLE,
ENVTEST_SUBDB_LOCKS
};
int *loc, optindex, result, testval;
@@ -1446,11 +1689,11 @@ tcl_EnvTest(interp, objc, objv, dbenv)
}
switch ((enum envtestat)optindex) {
case ENVTEST_ELECTINIT:
- DB_ASSERT(loc == &dbenv->test_abort);
+ DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_ELECTINIT;
break;
case ENVTEST_ELECTVOTE1:
- DB_ASSERT(loc == &dbenv->test_abort);
+ DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_ELECTVOTE1;
break;
case ENVTEST_NONE:
@@ -1477,8 +1720,12 @@ tcl_EnvTest(interp, objc, objv, dbenv)
case ENVTEST_POSTSYNC:
testval = DB_TEST_POSTSYNC;
break;
+ case ENVTEST_RECYCLE:
+ DB_ASSERT(dbenv, loc == &dbenv->test_copy);
+ testval = DB_TEST_RECYCLE;
+ break;
case ENVTEST_SUBDB_LOCKS:
- DB_ASSERT(loc == &dbenv->test_abort);
+ DB_ASSERT(dbenv, loc == &dbenv->test_abort);
testval = DB_TEST_SUBDB_LOCKS;
break;
default:
@@ -1594,6 +1841,8 @@ env_DbRemove(interp, objc, objv, dbenv)
* arrays for the subdb.
*/
db = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(db, "") == 0)
+ db = NULL;
if (i != objc) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
@@ -1723,6 +1972,8 @@ env_DbRename(interp, objc, objv, dbenv)
* arrays for the subdb.
*/
db = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(db, "") == 0)
+ db = NULL;
if (i == objc - 2) {
subdbtmp =
Tcl_GetByteArrayFromObj(objv[i++], &subdblen);
@@ -1788,6 +2039,7 @@ env_GetFlags(interp, objc, objv, dbenv)
{ DB_DSYNC_LOG, "-dsync_log" },
{ DB_LOG_AUTOREMOVE, "-log_remove" },
{ DB_LOG_INMEMORY, "-log_inmemory" },
+ { DB_MULTIVERSION, "-multiversion" },
{ DB_NOLOCKING, "-nolock" },
{ DB_NOMMAP, "-nommap" },
{ DB_NOPANIC, "-nopanic" },
@@ -1845,20 +2097,21 @@ env_GetOpenFlag(interp, objc, objv, dbenv)
u_int32_t flag;
char *arg;
} open_flags[] = {
+ { DB_CREATE, "-create" },
{ DB_INIT_CDB, "-cdb" },
{ DB_INIT_LOCK, "-lock" },
{ DB_INIT_LOG, "-log" },
{ DB_INIT_MPOOL, "-mpool" },
{ DB_INIT_TXN, "-txn" },
- { DB_RECOVER, "-recover" },
- { DB_RECOVER_FATAL, "-recover_fatal" },
- { DB_USE_ENVIRON, "-use_environ" },
- { DB_USE_ENVIRON_ROOT, "-use_environ_root" },
- { DB_CREATE, "-create" },
{ DB_LOCKDOWN, "-lockdown" },
{ DB_PRIVATE, "-private" },
+ { DB_RECOVER, "-recover" },
+ { DB_RECOVER_FATAL, "-recover_fatal" },
+ { DB_REGISTER, "-register" },
{ DB_SYSTEM_MEM, "-system_mem" },
{ DB_THREAD, "-thread" },
+ { DB_USE_ENVIRON, "-use_environ" },
+ { DB_USE_ENVIRON_ROOT, "-use_environ_root" },
{ 0, NULL }
};
@@ -2058,6 +2311,7 @@ env_GetVerbose(interp, objc, objv, dbenv)
} verbose_flags[] = {
{ DB_VERB_DEADLOCK, "deadlock" },
{ DB_VERB_RECOVERY, "recovery" },
+ { DB_VERB_REGISTER, "register" },
{ DB_VERB_REPLICATION, "rep" },
{ DB_VERB_WAITSFOR, "wait" },
{ 0, NULL }
@@ -2086,7 +2340,7 @@ env_GetVerbose(interp, objc, objv, dbenv)
ret = dbenv->get_verbose(dbenv, which, &onoff);
err: if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
- "env get_timeout")) == 0) {
+ "env get_verbose")) == 0) {
answer = onoff ? "on" : "off";
res = NewStringObj(answer, strlen(answer));
Tcl_SetObjResult(interp, res);
diff --git a/db/tcl/tcl_internal.c b/db/tcl/tcl_internal.c
index 6927b3018..d1071c71c 100644
--- a/db/tcl/tcl_internal.c
+++ b/db/tcl/tcl_internal.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_internal.c,v 11.70 2004/10/25 18:04:44 bostic Exp $
+ * $Id: tcl_internal.c,v 12.13 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
#include "dbinc/db_page.h"
#include "dbinc/db_am.h"
@@ -59,9 +54,9 @@ _NewInfo(interp, anyp, name, type)
enum INFOTYPE type;
{
DBTCL_INFO *p;
- int i, ret;
+ int ret;
- if ((ret = __os_malloc(NULL, sizeof(DBTCL_INFO), &p)) != 0) {
+ if ((ret = __os_calloc(NULL, sizeof(DBTCL_INFO), 1, &p)) != 0) {
Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
return (NULL);
}
@@ -73,21 +68,7 @@ _NewInfo(interp, anyp, name, type)
}
p->i_interp = interp;
p->i_anyp = anyp;
- p->i_data = 0;
- p->i_data2 = 0;
p->i_type = type;
- p->i_parent = NULL;
- p->i_err = NULL;
- p->i_errpfx = NULL;
- p->i_lockobj.data = NULL;
- p->i_btcompare = NULL;
- p->i_dupcompare = NULL;
- p->i_hashproc = NULL;
- p->i_second_call = NULL;
- p->i_rep_eid = NULL;
- p->i_rep_send = NULL;
- for (i = 0; i < MAX_ID; i++)
- p->i_otherid[i] = 0;
LIST_INSERT_HEAD(&__db_infohead, p, entries);
return (p);
@@ -102,8 +83,7 @@ _NameToPtr(name)
{
DBTCL_INFO *p;
- for (p = LIST_FIRST(&__db_infohead); p != NULL;
- p = LIST_NEXT(p, entries))
+ LIST_FOREACH(p, &__db_infohead, entries)
if (strcmp(name, p->i_name) == 0)
return (p->i_anyp);
return (NULL);
@@ -118,8 +98,7 @@ _PtrToInfo(ptr)
{
DBTCL_INFO *p;
- for (p = LIST_FIRST(&__db_infohead); p != NULL;
- p = LIST_NEXT(p, entries))
+ LIST_FOREACH(p, &__db_infohead, entries)
if (p->i_anyp == ptr)
return (p);
return (NULL);
@@ -134,8 +113,7 @@ _NameToInfo(name)
{
DBTCL_INFO *p;
- for (p = LIST_FIRST(&__db_infohead); p != NULL;
- p = LIST_NEXT(p, entries))
+ LIST_FOREACH(p, &__db_infohead, entries)
if (strcmp(name, p->i_name) == 0)
return (p);
return (NULL);
@@ -167,7 +145,7 @@ _DeleteInfo(p)
LIST_REMOVE(p, entries);
if (p->i_lockobj.data != NULL)
__os_free(NULL, p->i_lockobj.data);
- if (p->i_err != NULL && p->i_err != stderr) {
+ if (p->i_err != NULL && p->i_err != stderr && p->i_err != stdout) {
(void)fclose(p->i_err);
p->i_err = NULL;
}
@@ -243,7 +221,7 @@ _SetListElemInt(interp, list, elem1, elem2)
* library, it's likely because we don't have a 64-bit type, and trying to
* use int64_t is going to result in syntax errors.
*/
-#ifdef HAVE_SEQUENCE
+#ifdef HAVE_64BIT_TYPES
/*
* PUBLIC: int _SetListElemWideInt __P((Tcl_Interp *,
* PUBLIC: Tcl_Obj *, void *, int64_t));
@@ -267,7 +245,7 @@ _SetListElemWideInt(interp, list, elem1, elem2)
return (TCL_ERROR);
return (Tcl_ListObjAppendElement(interp, list, thislist));
}
-#endif /* HAVE_SEQUENCE */
+#endif /* HAVE_64BIT_TYPES */
/*
* PUBLIC: int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *,
@@ -522,6 +500,107 @@ _ErrorFunc(dbenv, pfx, msg)
return;
}
+/*
+ * PUBLIC: void _EventFunc __P((DB_ENV *, u_int32_t, void *));
+ */
+void
+_EventFunc(dbenv, event, info)
+ DB_ENV *dbenv;
+ u_int32_t event;
+ void *info;
+{
+#define TCLDB_EVENTITEMS 2 /* Event name and any info */
+#define TCLDB_SENDEVENT 2
+ DBTCL_INFO *ip;
+ Tcl_Interp *interp;
+ Tcl_Obj *event_o, *origobj;
+ Tcl_Obj *myobjv[TCLDB_EVENTITEMS], *objv[TCLDB_SENDEVENT];
+ int i, myobjc, result;
+
+ ip = (DBTCL_INFO *)dbenv->app_private;
+ interp = ip->i_interp;
+ if (ip->i_event == NULL)
+ return;
+ objv[0] = ip->i_event;
+
+ /*
+ * Most events don't have additional info. Assume none
+ * and handle individually those that do.
+ */
+ myobjv[1] = NULL;
+ myobjc = 1;
+ switch (event) {
+ case DB_EVENT_PANIC:
+ /*
+ * Info is the original error code.
+ */
+ myobjv[0] = NewStringObj("panic", strlen("panic"));
+ myobjv[myobjc++] = Tcl_NewIntObj(*(int *)info);
+ break;
+ case DB_EVENT_REP_CLIENT:
+ myobjv[0] = NewStringObj("rep_client", strlen("rep_client"));
+ break;
+ case DB_EVENT_REP_MASTER:
+ myobjv[0] = NewStringObj("rep_master", strlen("rep_master"));
+ break;
+ case DB_EVENT_REP_NEWMASTER:
+ /*
+ * Info is the EID of the new master.
+ */
+ myobjv[0] = NewStringObj("newmaster", strlen("newmaster"));
+ myobjv[myobjc++] = Tcl_NewIntObj(*(int *)info);
+ break;
+ case DB_EVENT_REP_STARTUPDONE:
+ myobjv[0] = NewStringObj("startupdone", strlen("startupdone"));
+ break;
+ case DB_EVENT_WRITE_FAILED:
+ myobjv[0] =
+ NewStringObj("write_failed", strlen("write_failed"));
+ break;
+ default:
+ __db_errx(dbenv, "Tcl unknown event %lu", (u_long)event);
+ return;
+ }
+
+ for (i = 0; i < myobjc; i++)
+ Tcl_IncrRefCount(myobjv[i]);
+
+ event_o = Tcl_NewListObj(myobjc, myobjv);
+ Tcl_IncrRefCount(event_o);
+ objv[1] = event_o;
+
+ /*
+ * We really want to return the original result to the
+ * user. So, save the result obj here, and then after
+ * we've taken care of the Tcl_EvalObjv, set the result
+ * back to this original result.
+ */
+ origobj = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(origobj);
+ result = Tcl_EvalObjv(interp, TCLDB_SENDEVENT, objv, 0);
+ if (result != TCL_OK) {
+ /*
+ * XXX
+ * This probably isn't the right error behavior, but
+ * this error should only happen if the Tcl callback is
+ * somehow invalid, which is a fatal scripting bug.
+ * The event handler is a void function so we either
+ * just return or abort.
+ * For now, abort.
+ */
+ __db_errx(dbenv, "Tcl event failure");
+ abort();
+ }
+
+ Tcl_SetObjResult(interp, origobj);
+ Tcl_DecrRefCount(origobj);
+ for (i = 0; i < myobjc; i++)
+ Tcl_DecrRefCount(myobjv[i]);
+ Tcl_DecrRefCount(event_o);
+
+ return;
+}
+
#define INVALID_LSNMSG "Invalid LSN with %d parts. Should have 2.\n"
/*
@@ -631,7 +710,7 @@ _GetFlagsList(interp, flags, fnp)
* into one). If this is the case, we screwed up badly
* somehow.
*/
- DB_ASSERT(result == TCL_OK);
+ DB_ASSERT(NULL, result == TCL_OK);
}
return (newlist);
@@ -670,14 +749,14 @@ _debug_check()
* memory.
*/
/*
- * PUBLIC: int _CopyObjBytes __P((Tcl_Interp *, Tcl_Obj *obj, void **,
+ * PUBLIC: int _CopyObjBytes __P((Tcl_Interp *, Tcl_Obj *obj, void *,
* PUBLIC: u_int32_t *, int *));
*/
int
_CopyObjBytes(interp, obj, newp, sizep, freep)
Tcl_Interp *interp;
Tcl_Obj *obj;
- void **newp;
+ void *newp;
u_int32_t *sizep;
int *freep;
{
@@ -695,7 +774,7 @@ _CopyObjBytes(interp, obj, newp, sizep, freep)
*sizep = (u_int32_t)len;
if (ret == TCL_ERROR) {
Tcl_ResetResult(interp);
- *newp = tmp;
+ *(void **)newp = tmp;
return (0);
}
@@ -707,7 +786,7 @@ _CopyObjBytes(interp, obj, newp, sizep, freep)
if ((ret = __os_malloc(NULL, (size_t)len, &new)) != 0)
return (ret);
memcpy(new, tmp, (size_t)len);
- *newp = new;
+ *(void **)newp = new;
*freep = 1;
return (0);
}
diff --git a/db/tcl/tcl_lock.c b/db/tcl/tcl_lock.c
index 4a3de36bd..bc73bf81b 100644
--- a/db/tcl/tcl_lock.c
+++ b/db/tcl/tcl_lock.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_lock.c,v 11.59 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_lock.c,v 12.6 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
/*
@@ -259,10 +254,14 @@ tcl_LockStat(interp, objc, objv, envp)
MAKE_STAT_LIST("Maximum number of lockers so far", sp->st_maxnlockers);
MAKE_STAT_LIST("Current number of objects", sp->st_nobjects);
MAKE_STAT_LIST("Maximum number of objects so far", sp->st_maxnobjects);
- MAKE_STAT_LIST("Number of conflicts", sp->st_nconflicts);
MAKE_STAT_LIST("Lock requests", sp->st_nrequests);
MAKE_STAT_LIST("Lock releases", sp->st_nreleases);
- MAKE_STAT_LIST("Lock requests that would have waited", sp->st_nnowaits);
+ MAKE_STAT_LIST("Lock upgrades", sp->st_nupgrade);
+ MAKE_STAT_LIST("Lock downgrades", sp->st_ndowngrade);
+ MAKE_STAT_LIST("Number of conflicted locks for which we waited",
+ sp->st_lock_wait);
+ MAKE_STAT_LIST("Number of conflicted locks for which we did not wait",
+ sp->st_lock_nowait);
MAKE_STAT_LIST("Deadlocks detected", sp->st_ndeadlocks);
MAKE_STAT_LIST("Number of region lock waits", sp->st_region_wait);
MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
diff --git a/db/tcl/tcl_log.c b/db/tcl/tcl_log.c
index 68c678101..650f632c9 100644
--- a/db/tcl/tcl_log.c
+++ b/db/tcl/tcl_log.c
@@ -1,26 +1,20 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_log.c,v 11.61 2004/04/05 20:18:32 bostic Exp $
+ * $Id: tcl_log.c,v 12.10 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/log.h"
#include "dbinc/tcl_db.h"
-#include "dbinc/txn.h"
#ifdef CONFIG_TEST
static int tcl_LogcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_LOGC *));
@@ -382,6 +376,7 @@ tcl_LogStat(interp, objc, objv, envp)
MAKE_STAT_LIST("Log file mode", sp->st_mode);
MAKE_STAT_LIST("Log record cache size", sp->st_lg_bsize);
MAKE_STAT_LIST("Current log file size", sp->st_lg_size);
+ MAKE_STAT_LIST("Log file records written", sp->st_record);
MAKE_STAT_LIST("Mbytes written", sp->st_w_mbytes);
MAKE_STAT_LIST("Bytes written (over Mb)", sp->st_w_bytes);
MAKE_STAT_LIST("Mbytes written since checkpoint", sp->st_wc_mbytes);
@@ -390,7 +385,8 @@ tcl_LogStat(interp, objc, objv, envp)
MAKE_STAT_LIST("Times log written", sp->st_wcount);
MAKE_STAT_LIST("Times log written because cache filled up",
sp->st_wcount_fill);
- MAKE_STAT_LIST("Times log flushed", sp->st_scount);
+ MAKE_STAT_LIST("Times log read from disk", sp->st_rcount);
+ MAKE_STAT_LIST("Times log flushed to disk", sp->st_scount);
MAKE_STAT_LIST("Current log file number", sp->st_cur_file);
MAKE_STAT_LIST("Current log file offset", sp->st_cur_offset);
MAKE_STAT_LIST("On-disk log file number", sp->st_disk_file);
@@ -421,14 +417,18 @@ logc_Cmd(clientData, interp, objc, objv)
static const char *logccmds[] = {
"close",
"get",
+ "version",
NULL
};
enum logccmds {
LOGCCLOSE,
- LOGCGET
+ LOGCGET,
+ LOGCVERSION
};
DB_LOGC *logc;
DBTCL_INFO *logcip;
+ Tcl_Obj *res;
+ u_int32_t version;
int cmdindex, result, ret;
Tcl_ResetResult(interp);
@@ -477,7 +477,24 @@ logc_Cmd(clientData, interp, objc, objv)
case LOGCGET:
result = tcl_LogcGet(interp, objc, objv, logc);
break;
+ case LOGCVERSION:
+ /*
+ * No args for this. Error if there are some.
+ */
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = logc->version(logc, &version, 0);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "logc version")) == TCL_OK) {
+ res = Tcl_NewIntObj((int)version);
+ Tcl_SetObjResult(interp, res);
+ }
+ break;
}
+
return (result);
}
diff --git a/db/tcl/tcl_mp.c b/db/tcl/tcl_mp.c
index 29691a31c..ce205728a 100644
--- a/db/tcl/tcl_mp.c
+++ b/db/tcl/tcl_mp.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_mp.c,v 11.58 2004/10/07 16:48:39 bostic Exp $
+ * $Id: tcl_mp.c,v 12.7 2006/09/11 14:53:42 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
/*
@@ -160,6 +155,7 @@ tcl_Mp(interp, objc, objv, envp, envip)
static const char *mpopts[] = {
"-create",
"-mode",
+ "-multiversion",
"-nommap",
"-pagesize",
"-rdonly",
@@ -168,6 +164,7 @@ tcl_Mp(interp, objc, objv, envp, envip)
enum mpopts {
MPCREATE,
MPMODE,
+ MPMULTIVERSION,
MPNOMMAP,
MPPAGE,
MPRDONLY
@@ -203,13 +200,10 @@ tcl_Mp(interp, objc, objv, envp, envip)
case MPCREATE:
flag |= DB_CREATE;
break;
- case MPNOMMAP:
- flag |= DB_NOMMAP;
- break;
- case MPPAGE:
+ case MPMODE:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
- "?-pagesize size?");
+ "?-mode mode?");
result = TCL_ERROR;
break;
}
@@ -219,15 +213,18 @@ tcl_Mp(interp, objc, objv, envp, envip)
* set up, and we'll bail out below. If ok,
* the mode is set and we go on.
*/
- result = Tcl_GetIntFromObj(interp, objv[i++], &pgsize);
+ result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
break;
- case MPRDONLY:
- flag |= DB_RDONLY;
+ case MPMULTIVERSION:
+ flag |= DB_MULTIVERSION;
break;
- case MPMODE:
+ case MPNOMMAP:
+ flag |= DB_NOMMAP;
+ break;
+ case MPPAGE:
if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
- "?-mode mode?");
+ "?-pagesize size?");
result = TCL_ERROR;
break;
}
@@ -237,7 +234,10 @@ tcl_Mp(interp, objc, objv, envp, envip)
* set up, and we'll bail out below. If ok,
* the mode is set and we go on.
*/
- result = Tcl_GetIntFromObj(interp, objv[i++], &mode);
+ result = Tcl_GetIntFromObj(interp, objv[i++], &pgsize);
+ break;
+ case MPRDONLY:
+ flag |= DB_RDONLY;
break;
}
if (result != TCL_OK)
@@ -374,6 +374,9 @@ tcl_MpStat(interp, objc, objv, envp)
sp->st_hash_max_wait);
MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
MAKE_STAT_LIST("Number of region lock waits", sp->st_region_wait);
+ MAKE_STAT_LIST("Buffers frozen", sp->st_mvcc_frozen);
+ MAKE_STAT_LIST("Buffers thawed", sp->st_mvcc_thawed);
+ MAKE_STAT_LIST("Frozen buffers freed", sp->st_mvcc_freed);
MAKE_STAT_LIST("Page allocations", sp->st_alloc);
MAKE_STAT_LIST("Buckets examined during allocation",
sp->st_alloc_buckets);
@@ -382,6 +385,7 @@ tcl_MpStat(interp, objc, objv, envp)
MAKE_STAT_LIST("Pages examined during allocation", sp->st_alloc_pages);
MAKE_STAT_LIST("Maximum pages examined during allocation",
sp->st_alloc_max_pages);
+ MAKE_STAT_LIST("Threads waiting on buffer I/O", sp->st_io_wait);
/*
* Save global stat list as res1. The MAKE_STAT_LIST
@@ -587,24 +591,30 @@ tcl_MpGet(interp, objc, objv, mp, mpip)
{
static const char *mpget[] = {
"-create",
+ "-dirty",
"-last",
"-new",
+ "-txn",
NULL
};
enum mpget {
MPGET_CREATE,
+ MPGET_DIRTY,
MPGET_LAST,
- MPGET_NEW
+ MPGET_NEW,
+ MPGET_TXN
};
DBTCL_INFO *ip;
Tcl_Obj *res;
+ DB_TXN *txn;
db_pgno_t pgno;
u_int32_t flag;
int i, ipgno, optindex, result, ret;
- char newname[MSG_SIZE];
+ char *arg, msg[MSG_SIZE], newname[MSG_SIZE];
void *page;
+ txn = NULL;
result = TCL_OK;
memset(newname, 0, MSG_SIZE);
i = 2;
@@ -627,12 +637,30 @@ tcl_MpGet(interp, objc, objv, mp, mpip)
case MPGET_CREATE:
flag |= DB_MPOOL_CREATE;
break;
+ case MPGET_DIRTY:
+ flag |= DB_MPOOL_DIRTY;
+ break;
case MPGET_LAST:
flag |= DB_MPOOL_LAST;
break;
case MPGET_NEW:
flag |= DB_MPOOL_NEW;
break;
+ case MPGET_TXN:
+ if (i == objc) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(objv[i++], NULL);
+ txn = NAME_TO_TXN(arg);
+ if (txn == NULL) {
+ snprintf(msg, MSG_SIZE,
+ "mpool get: Invalid txn: %s\n", arg);
+ Tcl_SetResult(interp, msg, TCL_VOLATILE);
+ result = TCL_ERROR;
+ }
+ break;
}
if (result != TCL_OK)
goto error;
@@ -662,7 +690,7 @@ tcl_MpGet(interp, objc, objv, mp, mpip)
}
_debug_check();
pgno = (db_pgno_t)ipgno;
- ret = mp->get(mp, &pgno, flag, &page);
+ ret = mp->get(mp, &pgno, NULL, flag, &page);
result = _ReturnSetup(interp, ret, DB_RETOK_MPGET(ret), "mpool get");
if (result == TCL_ERROR)
_DeleteInfo(ip);
@@ -789,14 +817,10 @@ tcl_Pg(interp, objc, objv, page, mp, pgip, putop)
int putop; /* Operation */
{
static const char *pgopt[] = {
- "-clean",
- "-dirty",
"-discard",
NULL
};
enum pgopt {
- PGCLEAN,
- PGDIRTY,
PGDISCARD
};
u_int32_t flag;
@@ -811,12 +835,6 @@ tcl_Pg(interp, objc, objv, page, mp, pgip, putop)
return (IS_HELP(objv[i]));
i++;
switch ((enum pgopt)optindex) {
- case PGCLEAN:
- flag |= DB_MPOOL_CLEAN;
- break;
- case PGDIRTY:
- flag |= DB_MPOOL_DIRTY;
- break;
case PGDISCARD:
flag |= DB_MPOOL_DISCARD;
break;
diff --git a/db/tcl/tcl_rep.c b/db/tcl/tcl_rep.c
index e0e6a1a88..036171a0c 100644
--- a/db/tcl/tcl_rep.c
+++ b/db/tcl/tcl_rep.c
@@ -1,27 +1,166 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_rep.c,v 11.106 2004/10/14 18:09:00 bostic Exp $
+ * $Id: tcl_rep.c,v 12.25 2006/09/07 08:06:37 alexg Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
#ifdef CONFIG_TEST
/*
+ * tcl_RepConfig --
+ * Call DB_ENV->rep_set_config().
+ *
+ * PUBLIC: int tcl_RepConfig
+ * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+ */
+int
+tcl_RepConfig(interp, dbenv, list)
+ Tcl_Interp *interp; /* Interpreter */
+ DB_ENV *dbenv; /* Environment pointer */
+ Tcl_Obj *list; /* {which on|off} */
+{
+ static const char *confwhich[] = {
+ "bulk",
+ "delayclient",
+ "noautoinit",
+ "nowait",
+ NULL
+ };
+ enum confwhich {
+ REPCONF_BULK,
+ REPCONF_DELAYCLIENT,
+ REPCONF_NOAUTOINIT,
+ REPCONF_NOWAIT
+ };
+ static const char *confonoff[] = {
+ "off",
+ "on",
+ NULL
+ };
+ enum confonoff {
+ REPCONF_OFF,
+ REPCONF_ON
+ };
+ Tcl_Obj **myobjv, *onoff, *which;
+ int myobjc, on, optindex, result, ret;
+ u_int32_t wh;
+
+ result = Tcl_ListObjGetElements(interp, list, &myobjc, &myobjv);
+ which = myobjv[0];
+ onoff = myobjv[1];
+ if (result != TCL_OK)
+ return (result);
+ if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
+ TCL_EXACT, &optindex) != TCL_OK)
+ return (IS_HELP(which));
+
+ switch ((enum confwhich)optindex) {
+ case REPCONF_NOAUTOINIT:
+ wh = DB_REP_CONF_NOAUTOINIT;
+ break;
+ case REPCONF_BULK:
+ wh = DB_REP_CONF_BULK;
+ break;
+ case REPCONF_DELAYCLIENT:
+ wh = DB_REP_CONF_DELAYCLIENT;
+ break;
+ case REPCONF_NOWAIT:
+ wh = DB_REP_CONF_NOWAIT;
+ break;
+ default:
+ return (TCL_ERROR);
+ }
+ if (Tcl_GetIndexFromObj(interp, onoff, confonoff, "option",
+ TCL_EXACT, &optindex) != TCL_OK)
+ return (IS_HELP(onoff));
+ switch ((enum confonoff)optindex) {
+ case REPCONF_OFF:
+ on = 0;
+ break;
+ case REPCONF_ON:
+ on = 1;
+ break;
+ default:
+ return (TCL_ERROR);
+ }
+ ret = dbenv->rep_set_config(dbenv, wh, on);
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env rep_config"));
+}
+
+/*
+ * tcl_RepGetConfig --
+ * Call DB_ENV->rep_get_config().
+ *
+ * PUBLIC: int tcl_RepGetConfig
+ * PUBLIC: __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+ */
+int
+tcl_RepGetConfig(interp, dbenv, which)
+ Tcl_Interp *interp; /* Interpreter */
+ DB_ENV *dbenv; /* Environment pointer */
+ Tcl_Obj *which; /* which flag */
+{
+ static const char *confwhich[] = {
+ "bulk",
+ "delayclient",
+ "noautoinit",
+ "nowait",
+ NULL
+ };
+ enum confwhich {
+ REPGCONF_BULK,
+ REPGCONF_DELAYCLIENT,
+ REPGCONF_NOAUTOINIT,
+ REPGCONF_NOWAIT
+ };
+ Tcl_Obj *res;
+ int on, optindex, result, ret;
+ u_int32_t wh;
+
+ if (Tcl_GetIndexFromObj(interp, which, confwhich, "option",
+ TCL_EXACT, &optindex) != TCL_OK)
+ return (IS_HELP(which));
+
+ res = NULL;
+ switch ((enum confwhich)optindex) {
+ case REPGCONF_BULK:
+ wh = DB_REP_CONF_BULK;
+ break;
+ case REPGCONF_DELAYCLIENT:
+ wh = DB_REP_CONF_DELAYCLIENT;
+ break;
+ case REPGCONF_NOAUTOINIT:
+ wh = DB_REP_CONF_NOAUTOINIT;
+ break;
+ case REPGCONF_NOWAIT:
+ wh = DB_REP_CONF_NOWAIT;
+ break;
+ default:
+ return (TCL_ERROR);
+ }
+ ret = dbenv->rep_get_config(dbenv, wh, &on);
+ if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env rep_config")) == TCL_OK) {
+ res = Tcl_NewIntObj(on);
+ Tcl_SetObjResult(interp, res);
+ }
+ return (result);
+}
+#endif
+
+#ifdef CONFIG_TEST
+/*
* tcl_RepElect --
* Call DB_ENV->rep_elect().
*
@@ -53,8 +192,16 @@ tcl_RepElect(interp, objc, objv, dbenv)
return (result);
_debug_check();
- if ((ret = dbenv->rep_elect(dbenv, nsites, nvotes,
- pri, timeout, &eid, 0)) != 0)
+
+ if ((ret = dbenv->rep_set_priority(dbenv, pri)) != 0)
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env rep_elect (rep_set_priority)"));
+ if ((ret = dbenv->rep_set_timeout(dbenv, DB_REP_ELECTION_TIMEOUT,
+ timeout)) != 0)
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env rep_elect (rep_set_timeout)"));
+
+ if ((ret = dbenv->rep_elect(dbenv, nsites, nvotes, &eid, 0)) != 0)
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env rep_elect"));
@@ -93,8 +240,35 @@ tcl_RepFlush(interp, objc, objv, dbenv)
#endif
#ifdef CONFIG_TEST
/*
+ * tcl_RepSync --
+ * Call DB_ENV->rep_sync().
+ *
+ * PUBLIC: int tcl_RepSync
+ * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+ */
+int
+tcl_RepSync(interp, objc, objv, dbenv)
+ Tcl_Interp *interp;
+ int objc;
+ Tcl_Obj *CONST objv[];
+ DB_ENV *dbenv;
+{
+ int ret;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+
+ _debug_check();
+ ret = dbenv->rep_sync(dbenv, 0);
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env rep_sync"));
+}
+#endif
+#ifdef CONFIG_TEST
+/*
* tcl_RepLimit --
- * Call DB_ENV->set_rep_limit().
+ * Call DB_ENV->rep_set_limit().
*
* PUBLIC: int tcl_RepLimit
* PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
@@ -120,7 +294,7 @@ tcl_RepLimit(interp, objc, objv, dbenv)
return (result);
_debug_check();
- if ((ret = dbenv->set_rep_limit(dbenv, gbytes, bytes)) != 0)
+ if ((ret = dbenv->rep_set_limit(dbenv, gbytes, bytes)) != 0)
return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"env set_rep_limit"));
@@ -169,6 +343,71 @@ tcl_RepRequest(interp, objc, objv, dbenv)
#ifdef CONFIG_TEST
/*
+ * tcl_RepTransport --
+ * Call DB_ENV->rep_set_transport().
+ *
+ * PUBLIC: int tcl_RepTransport __P((Tcl_Interp *, int, Tcl_Obj * CONST *,
+ * PUBLIC: DB_ENV *, DBTCL_INFO *));
+ *
+ * Note that this normally can/should be achieved as an argument to
+ * berkdb env, but we need to test changing the transport function on
+ * the fly.
+ */
+int
+tcl_RepTransport(interp, objc, objv, dbenv, ip)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *dbenv;
+ DBTCL_INFO *ip;
+{
+ int intarg, result, ret;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "{id transport_func");
+ return (TCL_ERROR);
+ }
+
+ /*
+ * Store the objects containing the machine ID
+ * and the procedure name. We don't need to crack
+ * the send procedure out now, but we do convert the
+ * machine ID to an int, since rep_set_transport needs
+ * it. Even so, it'll be easier later to deal with
+ * the Tcl_Obj *, so we save that, not the int.
+ *
+ * Note that we Tcl_IncrRefCount both objects
+ * independently; Tcl is free to discard the list
+ * that they're bundled into.
+ */
+
+ /*
+ * Check that the machine ID is an int. Note that
+ * we do want to use GetIntFromObj; the machine
+ * ID is explicitly an int, not a u_int32_t.
+ */
+ if (ip->i_rep_eid != NULL)
+ Tcl_DecrRefCount(ip->i_rep_eid);
+ ip->i_rep_eid = objv[0];
+ Tcl_IncrRefCount(ip->i_rep_eid);
+ result = Tcl_GetIntFromObj(interp,
+ ip->i_rep_eid, &intarg);
+ if (result != TCL_OK)
+ return (result);
+
+ if (ip->i_rep_send != NULL)
+ Tcl_DecrRefCount(ip->i_rep_send);
+ ip->i_rep_send = objv[1];
+ Tcl_IncrRefCount(ip->i_rep_send);
+ _debug_check();
+ ret = dbenv->rep_set_transport(dbenv, intarg, tcl_rep_send);
+ return (_ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "env rep_transport"));
+}
+#endif
+
+#ifdef CONFIG_TEST
+/*
* tcl_RepStart --
* Call DB_ENV->rep_start().
*
@@ -309,6 +548,7 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv)
* {NEWMASTER #} - NEWMASTER and its ID.
* {NEWSITE 0} - NEWSITE, no other info needed.
* {STARTUPDONE 0} - STARTUPDONE, no other info needed.
+ * {IGNORE {LSN list}} - IGNORE and this msg's LSN.
* {ISPERM {LSN list}} - ISPERM and the perm LSN.
* {NOTPERM {LSN list}} - NOTPERM and this msg's LSN.
*/
@@ -328,6 +568,14 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv)
(u_char *)"HOLDELECTION", (int)strlen("HOLDELECTION"));
myobjv[1] = Tcl_NewIntObj(0);
break;
+ case DB_REP_IGNORE:
+ myobjv[0] = Tcl_NewLongObj((long)permlsn.file);
+ myobjv[1] = Tcl_NewLongObj((long)permlsn.offset);
+ lsnlist = Tcl_NewListObj(myobjc, myobjv);
+ myobjv[0] = Tcl_NewByteArrayObj(
+ (u_char *)"IGNORE", (int)strlen("IGNORE"));
+ myobjv[1] = lsnlist;
+ break;
case DB_REP_ISPERM:
myobjv[0] = Tcl_NewLongObj((long)permlsn.file);
myobjv[1] = Tcl_NewLongObj((long)permlsn.offset);
@@ -354,11 +602,6 @@ tcl_RepProcessMessage(interp, objc, objv, dbenv)
(u_char *)"NOTPERM", (int)strlen("NOTPERM"));
myobjv[1] = lsnlist;
break;
- case DB_REP_STARTUPDONE:
- myobjv[0] = Tcl_NewByteArrayObj(
- (u_char *)"STARTUPDONE", (int)strlen("STARTUPDONE"));
- myobjv[1] = Tcl_NewIntObj(0);
- break;
default:
msg = db_strerror(ret);
Tcl_AppendResult(interp, msg, NULL);
@@ -400,8 +643,8 @@ tcl_RepStat(interp, objc, objv, dbenv)
int myobjc, result, ret;
char *arg;
- result = TCL_OK;
flag = 0;
+ result = TCL_OK;
if (objc > 3) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
@@ -439,6 +682,13 @@ tcl_RepStat(interp, objc, objv, dbenv)
MAKE_STAT_LIST("Client", 1);
MAKE_STAT_LSN("Next LSN expected", &sp->st_next_lsn);
MAKE_STAT_LSN("First missed LSN", &sp->st_waiting_lsn);
+ MAKE_STAT_LIST("Bulk buffer fills", sp->st_bulk_fills);
+ MAKE_STAT_LIST("Bulk buffer overflows", sp->st_bulk_overflows);
+ MAKE_STAT_LIST("Bulk records stored", sp->st_bulk_records);
+ MAKE_STAT_LIST("Bulk buffer transfers", sp->st_bulk_transfers);
+ MAKE_STAT_LIST("Client service requests", sp->st_client_svc_req);
+ MAKE_STAT_LIST("Client service req misses", sp->st_client_svc_miss);
+ MAKE_STAT_LIST("Client rerequests", sp->st_client_rerequests);
MAKE_STAT_LIST("Duplicate master conditions", sp->st_dupmasters);
MAKE_STAT_LIST("Environment ID", sp->st_env_id);
MAKE_STAT_LIST("Environment priority", sp->st_env_priority);
@@ -480,10 +730,293 @@ tcl_RepStat(interp, objc, objv, dbenv)
MAKE_STAT_LIST("Election priority", sp->st_election_priority);
MAKE_STAT_LIST("Election tiebreaker", sp->st_election_tiebreaker);
MAKE_STAT_LIST("Election votes", sp->st_election_votes);
+ MAKE_STAT_LIST("Election seconds", sp->st_election_sec);
+ MAKE_STAT_LIST("Election usecs", sp->st_election_usec);
Tcl_SetObjResult(interp, res);
error:
__os_ufree(dbenv, sp);
return (result);
}
+
+/*
+ * tcl_RepMgr --
+ * Configure and start the Replication Manager.
+ *
+ * PUBLIC: int tcl_RepMgr
+ * PUBLIC: __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+ */
+int
+tcl_RepMgr(interp, objc, objv, dbenv)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *dbenv; /* Environment pointer */
+{
+ static const char *rmgr[] = {
+ "-ack",
+ "-local",
+ "-msgth",
+ "-nsites",
+ "-pri",
+ "-remote",
+ "-start",
+ "-timeout",
+ NULL
+ };
+ enum rmgr {
+ RMGR_ACK,
+ RMGR_LOCAL,
+ RMGR_MSGTH,
+ RMGR_NSITES,
+ RMGR_PRI,
+ RMGR_REMOTE,
+ RMGR_START,
+ RMGR_TIMEOUT
+ };
+ Tcl_Obj **myobjv;
+ long to;
+ int ack, i, myobjc, optindex, result, ret, totype;
+ u_int32_t msgth, remote_flag, start_flag, uintarg;
+ char *arg;
+
+ result = TCL_OK;
+ ack = ret = totype = 0;
+ msgth = 1;
+ remote_flag = start_flag = 0;
+
+ if (objc <= 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?args?");
+ return (TCL_ERROR);
+ }
+ /*
+ * Get the command name index from the object based on the bdbcmds
+ * defined above.
+ */
+ i = 2;
+ while (i < objc) {
+ Tcl_ResetResult(interp);
+ if (Tcl_GetIndexFromObj(interp, objv[i], rmgr, "option",
+ TCL_EXACT, &optindex) != TCL_OK) {
+ result = IS_HELP(objv[i]);
+ goto error;
+ }
+ i++;
+ switch ((enum rmgr)optindex) {
+ case RMGR_ACK:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-ack policy?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(arg, "all") == 0)
+ ack = DB_REPMGR_ACKS_ALL;
+ else if (strcmp(arg, "allpeers") == 0)
+ ack = DB_REPMGR_ACKS_ALL_PEERS;
+ else if (strcmp(arg, "none") == 0)
+ ack = DB_REPMGR_ACKS_NONE;
+ else if (strcmp(arg, "one") == 0)
+ ack = DB_REPMGR_ACKS_ONE;
+ else if (strcmp(arg, "onepeer") == 0)
+ ack = DB_REPMGR_ACKS_ONE_PEER;
+ else if (strcmp(arg, "quorum") == 0)
+ ack = DB_REPMGR_ACKS_QUORUM;
+ else {
+ Tcl_AddErrorInfo(interp,
+ "ack: illegal policy");
+ result = TCL_ERROR;
+ break;
+ }
+ _debug_check();
+ ret = dbenv->repmgr_set_ack_policy(dbenv, ack);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "ack");
+ break;
+ case RMGR_LOCAL:
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ if (myobjc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-local {host port}?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(myobjv[0], NULL);
+ if ((result = _GetUInt32(interp, myobjv[1], &uintarg))
+ != TCL_OK)
+ break;
+ _debug_check();
+ /*
+ * No flags for now.
+ */
+ ret = dbenv->repmgr_set_local_site(dbenv,
+ arg, uintarg, 0);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "repmgr_set_local_site");
+ break;
+ case RMGR_MSGTH:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(
+ interp, 2, objv, "?-msgth nth?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &msgth);
+ break;
+ case RMGR_NSITES:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-nsites num_sites?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &uintarg);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->rep_set_nsites(dbenv, uintarg);
+ }
+ break;
+ case RMGR_PRI:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-pri priority?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = _GetUInt32(interp, objv[i++], &uintarg);
+ if (result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->
+ rep_set_priority(dbenv, (int)uintarg);
+ }
+ break;
+ case RMGR_REMOTE:
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ if (myobjc != 2 && myobjc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-remote {host port [peer]}?");
+ result = TCL_ERROR;
+ break;
+ }
+ /*
+ * Get the flag first so we can reuse 'arg'.
+ */
+ if (myobjc == 3) {
+ arg = Tcl_GetStringFromObj(myobjv[2], NULL);
+ if (strcmp(arg, "peer") == 0)
+ remote_flag = DB_REPMGR_PEER;
+ else {
+ Tcl_AddErrorInfo(interp,
+ "remote: illegal flag");
+ result = TCL_ERROR;
+ break;
+ }
+ }
+ arg = Tcl_GetStringFromObj(myobjv[0], NULL);
+ if ((result = _GetUInt32(interp, myobjv[1], &uintarg))
+ != TCL_OK)
+ break;
+ _debug_check();
+ ret = dbenv->repmgr_add_remote_site(dbenv,
+ arg, uintarg, NULL, remote_flag);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "repmgr_add_remote_site");
+ break;
+ case RMGR_START:
+ if (i >= objc) {
+ Tcl_WrongNumArgs(
+ interp, 2, objv, "?-start state?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(objv[i++], NULL);
+ if (strcmp(arg, "master") == 0)
+ start_flag = DB_REP_MASTER;
+ else if (strcmp(arg, "client") == 0)
+ start_flag = DB_REP_CLIENT;
+ else if (strcmp(arg, "elect") == 0)
+ start_flag = DB_REP_ELECTION;
+ else if (strcmp(arg, "full_elect") == 0)
+ start_flag = DB_REP_FULL_ELECTION;
+ else {
+ Tcl_AddErrorInfo(
+ interp, "start: illegal state");
+ result = TCL_ERROR;
+ break;
+ }
+ /*
+ * Some config functions need to be called
+ * before repmgr_start. So finish parsing all
+ * the args and call repmgr_start at the end.
+ */
+ break;
+ case RMGR_TIMEOUT:
+ result = Tcl_ListObjGetElements(interp, objv[i],
+ &myobjc, &myobjv);
+ if (result == TCL_OK)
+ i++;
+ else
+ break;
+ if (myobjc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-timeout {type to}?");
+ result = TCL_ERROR;
+ break;
+ }
+ arg = Tcl_GetStringFromObj(myobjv[0], NULL);
+ if (strcmp(arg, "ack") == 0)
+ totype = DB_REP_ACK_TIMEOUT;
+ else if (strcmp(arg, "elect") == 0)
+ totype = DB_REP_ELECTION_TIMEOUT;
+ else if (strcmp(arg, "elect_retry") == 0)
+ totype = DB_REP_ELECTION_RETRY;
+ else if (strcmp(arg, "conn_retry") == 0)
+ totype = DB_REP_CONNECTION_RETRY;
+ else {
+ Tcl_AddErrorInfo(interp,
+ "timeout: illegal type");
+ result = TCL_ERROR;
+ break;
+ }
+ if ((result = Tcl_GetLongFromObj(
+ interp, myobjv[1], &to)) != TCL_OK)
+ break;
+ _debug_check();
+ ret = dbenv->rep_set_timeout(dbenv, totype,
+ (db_timeout_t)to);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
+ "rep_set_timeout");
+ break;
+ }
+ /*
+ * If, at any time, parsing the args we get an error,
+ * bail out and return.
+ */
+ if (result != TCL_OK)
+ goto error;
+ }
+ /*
+ * Only call repmgr_start if needed. The user may use this
+ * call just to reconfigure, change policy, etc.
+ */
+ if (start_flag != 0 && result == TCL_OK) {
+ _debug_check();
+ ret = dbenv->repmgr_start(dbenv, (int)msgth, start_flag);
+ result = _ReturnSetup(
+ interp, ret, DB_RETOK_STD(ret), "repmgr_start");
+ }
+error:
+ return (result);
+}
#endif
diff --git a/db/tcl/tcl_seq.c b/db/tcl/tcl_seq.c
index de3e4dd61..2fc43f7d6 100644
--- a/db/tcl/tcl_seq.c
+++ b/db/tcl/tcl_seq.c
@@ -1,23 +1,19 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 2004-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_seq.c,v 11.12 2004/10/25 18:02:56 bostic Exp $
+ * $Id: tcl_seq.c,v 12.6 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#ifdef HAVE_64BIT_TYPES
-#ifdef HAVE_SEQUENCE
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
#include "dbinc_auto/sequence_ext.h"
@@ -291,13 +287,11 @@ tcl_SeqGet(interp, objc, objv, seq)
DB_SEQUENCE *seq; /* Sequence pointer */
{
static const char *seqgetopts[] = {
- "-auto_commit",
"-nosync",
"-txn",
NULL
};
enum seqgetopts {
- SEQGET_AUTO_COMMIT,
SEQGET_NOSYNC,
SEQGET_TXN
};
@@ -336,9 +330,6 @@ tcl_SeqGet(interp, objc, objv, seq)
}
i++;
switch ((enum seqgetopts)optindex) {
- case SEQGET_AUTO_COMMIT:
- aflag |= DB_AUTO_COMMIT;
- break;
case SEQGET_NOSYNC:
aflag |= DB_TXN_NOSYNC;
break;
@@ -394,13 +385,11 @@ tcl_SeqRemove(interp, objc, objv, seq, ip)
DBTCL_INFO *ip; /* Info pointer */
{
static const char *seqgetopts[] = {
- "-auto_commit",
"-nosync",
"-txn",
NULL
};
enum seqgetopts {
- SEQGET_AUTO_COMMIT,
SEQGET_NOSYNC,
SEQGET_TXN
};
@@ -439,9 +428,6 @@ tcl_SeqRemove(interp, objc, objv, seq, ip)
}
i++;
switch ((enum seqgetopts)optindex) {
- case SEQGET_AUTO_COMMIT:
- aflag |= DB_AUTO_COMMIT;
- break;
case SEQGET_NOSYNC:
aflag |= DB_TXN_NOSYNC;
break;
@@ -523,4 +509,4 @@ tcl_SeqGetFlags(interp, objc, objv, seq)
return (result);
}
-#endif /* HAVE_SEQUENCE */
+#endif /* HAVE_64BIT_TYPES */
diff --git a/db/tcl/tcl_txn.c b/db/tcl/tcl_txn.c
index b819c24b7..a3712172f 100644
--- a/db/tcl/tcl_txn.c
+++ b/db/tcl/tcl_txn.c
@@ -1,23 +1,18 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_txn.c,v 11.70 2004/10/27 16:48:32 bostic Exp $
+ * $Id: tcl_txn.c,v 12.16 2006/09/11 14:53:42 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
static int tcl_TxnCommit __P((Tcl_Interp *,
@@ -142,28 +137,32 @@ tcl_Txn(interp, objc, objv, envp, envip)
{
static const char *txnopts[] = {
#ifdef CONFIG_TEST
- "-degree_2",
- "-dirty",
"-lock_timeout",
+ "-read_committed",
+ "-read_uncommitted",
"-txn_timeout",
#endif
"-nosync",
"-nowait",
"-parent",
+ "-snapshot",
"-sync",
+ "-wrnosync",
NULL
};
enum txnopts {
#ifdef CONFIG_TEST
- TXNDEGREE2,
- TXNDIRTY,
- TXN_LOCK_TIMEOUT,
- TXN_TIMEOUT,
+ TXNLOCK_TIMEOUT,
+ TXNREAD_COMMITTED,
+ TXNREAD_UNCOMMITTED,
+ TXNTIMEOUT,
#endif
TXNNOSYNC,
TXNNOWAIT,
TXNPARENT,
- TXNSYNC
+ TXNSNAPSHOT,
+ TXNSYNC,
+ TXNWRNOSYNC
};
DBTCL_INFO *ip;
DB_TXN *parent;
@@ -196,35 +195,33 @@ tcl_Txn(interp, objc, objv, envp, envip)
i++;
switch ((enum txnopts)optindex) {
#ifdef CONFIG_TEST
- case TXNDEGREE2:
- flag |= DB_DEGREE_2;
- break;
- case TXNDIRTY:
- flag |= DB_DIRTY_READ;
- break;
- case TXN_LOCK_TIMEOUT:
+ case TXNLOCK_TIMEOUT:
lk_timeflag = DB_SET_LOCK_TIMEOUT;
- goto getit;
- case TXN_TIMEOUT:
+ goto get_timeout;
+ case TXNTIMEOUT:
tx_timeflag = DB_SET_TXN_TIMEOUT;
-getit: if (i >= objc) {
+get_timeout: if (i >= objc) {
Tcl_WrongNumArgs(interp, 2, objv,
"?-txn_timestamp time?");
return (TCL_ERROR);
}
result = Tcl_GetLongFromObj(interp, objv[i++], (long *)
- ((enum txnopts)optindex == TXN_LOCK_TIMEOUT ?
+ ((enum txnopts)optindex == TXNLOCK_TIMEOUT ?
&lk_time : &tx_time));
if (result != TCL_OK)
return (TCL_ERROR);
break;
+ case TXNREAD_COMMITTED:
+ flag |= DB_READ_COMMITTED;
+ break;
+ case TXNREAD_UNCOMMITTED:
+ flag |= DB_READ_UNCOMMITTED;
+ break;
#endif
case TXNNOSYNC:
- FLAG_CHECK2(flag, DB_DIRTY_READ);
flag |= DB_TXN_NOSYNC;
break;
case TXNNOWAIT:
- FLAG_CHECK2(flag, DB_DIRTY_READ);
flag |= DB_TXN_NOWAIT;
break;
case TXNPARENT:
@@ -244,10 +241,15 @@ getit: if (i >= objc) {
return (TCL_ERROR);
}
break;
+ case TXNSNAPSHOT:
+ flag |= DB_TXN_SNAPSHOT;
+ break;
case TXNSYNC:
- FLAG_CHECK2(flag, DB_DIRTY_READ);
flag |= DB_TXN_SYNC;
break;
+ case TXNWRNOSYNC:
+ flag |= DB_TXN_WRITE_NOSYNC;
+ break;
}
}
snprintf(newname, sizeof(newname), "%s.txn%d",
@@ -304,6 +306,63 @@ getit: if (i >= objc) {
}
/*
+ * tcl_CDSGroup --
+ *
+ * PUBLIC: int tcl_CDSGroup __P((Tcl_Interp *, int,
+ * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+ */
+int
+tcl_CDSGroup(interp, objc, objv, envp, envip)
+ Tcl_Interp *interp; /* Interpreter */
+ int objc; /* How many arguments? */
+ Tcl_Obj *CONST objv[]; /* The argument objects */
+ DB_ENV *envp; /* Environment pointer */
+ DBTCL_INFO *envip; /* Info pointer */
+{
+ DBTCL_INFO *ip;
+ DB_TXN *txn;
+ Tcl_Obj *res;
+ int result, ret;
+ char newname[MSG_SIZE];
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "env cdsgroup");
+ return (TCL_ERROR);
+ }
+
+ result = TCL_OK;
+ memset(newname, 0, MSG_SIZE);
+
+ snprintf(newname, sizeof(newname), "%s.txn%d",
+ envip->i_name, envip->i_envtxnid);
+ ip = _NewInfo(interp, NULL, newname, I_TXN);
+ if (ip == NULL) {
+ Tcl_SetResult(interp, "Could not set up info",
+ TCL_STATIC);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = envp->cdsgroup_begin(envp, &txn);
+ result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "cdsgroup");
+ if (result == TCL_ERROR)
+ _DeleteInfo(ip);
+ else {
+ /*
+ * Success. Set up return. Set up new info
+ * and command widget for this txn.
+ */
+ envip->i_envtxnid++;
+ ip->i_parent = envip;
+ _SetInfoData(ip, txn);
+ (void)Tcl_CreateObjCommand(interp, newname,
+ (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)txn, NULL);
+ res = NewStringObj(newname, strlen(newname));
+ Tcl_SetObjResult(interp, res);
+ }
+ return (result);
+}
+
+/*
* tcl_TxnStat --
*
* PUBLIC: int tcl_TxnStat __P((Tcl_Interp *, int,
@@ -350,18 +409,19 @@ tcl_TxnStat(interp, objc, objv, envp)
MAKE_STAT_LSN("LSN of last checkpoint", &sp->st_last_ckp);
MAKE_STAT_LIST("Time of last checkpoint", sp->st_time_ckp);
MAKE_STAT_LIST("Last txn ID allocated", sp->st_last_txnid);
- MAKE_STAT_LIST("Max Txns", sp->st_maxtxns);
+ MAKE_STAT_LIST("Maximum txns", sp->st_maxtxns);
MAKE_STAT_LIST("Number aborted txns", sp->st_naborts);
- MAKE_STAT_LIST("Number active txns", sp->st_nactive);
- MAKE_STAT_LIST("Maximum active txns", sp->st_maxnactive);
MAKE_STAT_LIST("Number txns begun", sp->st_nbegins);
MAKE_STAT_LIST("Number committed txns", sp->st_ncommits);
+ MAKE_STAT_LIST("Number active txns", sp->st_nactive);
+ MAKE_STAT_LIST("Number of snapshot txns", sp->st_nsnapshot);
MAKE_STAT_LIST("Number restored txns", sp->st_nrestores);
+ MAKE_STAT_LIST("Maximum active txns", sp->st_maxnactive);
+ MAKE_STAT_LIST("Maximum snapshot txns", sp->st_maxnsnapshot);
MAKE_STAT_LIST("Number of region lock waits", sp->st_region_wait);
MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
for (i = 0, p = sp->st_txnarray; i < sp->st_nactive; i++, p++)
- for (ip = LIST_FIRST(&__db_infohead); ip != NULL;
- ip = LIST_NEXT(ip, entries)) {
+ LIST_FOREACH(ip, &__db_infohead, entries) {
if (ip->i_type != I_TXN)
continue;
if (ip->i_type == I_TXN &&
@@ -428,18 +488,24 @@ txn_Cmd(clientData, interp, objc, objv)
static const char *txncmds[] = {
#ifdef CONFIG_TEST
"discard",
+ "getname",
"id",
"prepare",
+ "setname",
#endif
"abort",
"commit",
+ "getname",
+ "setname",
NULL
};
enum txncmds {
#ifdef CONFIG_TEST
TXNDISCARD,
+ TXNGETNAME,
TXNID,
TXNPREPARE,
+ TXNSETNAME,
#endif
TXNABORT,
TXNCOMMIT
@@ -449,7 +515,9 @@ txn_Cmd(clientData, interp, objc, objv)
Tcl_Obj *res;
int cmdindex, result, ret;
#ifdef CONFIG_TEST
- u_int8_t *gid;
+ u_int8_t *gid, garray[DB_XIDDATASIZE];
+ int length;
+ const char *name;
#endif
Tcl_ResetResult(interp);
@@ -503,8 +571,9 @@ txn_Cmd(clientData, interp, objc, objv)
return (TCL_ERROR);
}
_debug_check();
- gid = (u_int8_t *)Tcl_GetByteArrayFromObj(objv[2], NULL);
- ret = txnp->prepare(txnp, gid);
+ gid = (u_int8_t *)Tcl_GetByteArrayFromObj(objv[2], &length);
+ memcpy(garray, gid, (size_t)length);
+ ret = txnp->prepare(txnp, garray);
/*
* !!!
* DB_TXN->prepare commits all outstanding children. But it
@@ -516,6 +585,27 @@ txn_Cmd(clientData, interp, objc, objv)
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
"txn prepare");
break;
+ case TXNGETNAME:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = txnp->get_name(txnp, &name);
+ if ((result = _ReturnSetup(
+ interp, ret, DB_RETOK_STD(ret), "txn getname")) == TCL_OK)
+ res = NewStringObj(name, strlen(name));
+ break;
+ case TXNSETNAME:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return (TCL_ERROR);
+ }
+ _debug_check();
+ ret = txnp->set_name(txnp, Tcl_GetStringFromObj(objv[2], NULL));
+ result =
+ _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "setname");
+ break;
#endif
case TXNABORT:
if (objc != 2) {
@@ -557,11 +647,13 @@ tcl_TxnCommit(interp, objc, objv, txnp, txnip)
static const char *commitopt[] = {
"-nosync",
"-sync",
+ "-wrnosync",
NULL
};
enum commitopt {
+ COMNOSYNC,
COMSYNC,
- COMNOSYNC
+ COMWRNOSYNC
};
u_int32_t flag;
int optindex, result, ret;
@@ -580,13 +672,14 @@ tcl_TxnCommit(interp, objc, objv, txnp, txnip)
return (IS_HELP(objv[2]));
switch ((enum commitopt)optindex) {
case COMSYNC:
- FLAG_CHECK(flag);
flag = DB_TXN_SYNC;
break;
case COMNOSYNC:
- FLAG_CHECK(flag);
flag = DB_TXN_NOSYNC;
break;
+ case COMWRNOSYNC:
+ flag = DB_TXN_WRITE_NOSYNC;
+ break;
}
}
diff --git a/db/tcl/tcl_util.c b/db/tcl/tcl_util.c
index 13a6d6a9d..90935f27e 100644
--- a/db/tcl/tcl_util.c
+++ b/db/tcl/tcl_util.c
@@ -1,32 +1,21 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999-2004
- * Sleepycat Software. All rights reserved.
+ * Copyright (c) 1999-2006
+ * Oracle Corporation. All rights reserved.
*
- * $Id: tcl_util.c,v 11.43 2004/06/10 17:20:57 bostic Exp $
+ * $Id: tcl_util.c,v 12.5 2006/08/24 14:46:33 bostic Exp $
*/
#include "db_config.h"
+#include "db_int.h"
#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
#include <tcl.h>
#endif
-
-#include "db_int.h"
#include "dbinc/tcl_db.h"
/*
- * Prototypes for procedures defined later in this file:
- */
-static int mutex_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-
-/*
* bdb_RandCommand --
* Implements rand* functions.
*
@@ -119,250 +108,3 @@ bdb_RandCommand(interp, objc, objv)
Tcl_SetObjResult(interp, res);
return (result);
}
-
-/*
- *
- * tcl_Mutex --
- * Opens an env mutex.
- *
- * PUBLIC: int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *,
- * PUBLIC: DBTCL_INFO *));
- */
-int
-tcl_Mutex(interp, objc, objv, envp, envip)
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
- DB_ENV *envp; /* Environment pointer */
- DBTCL_INFO *envip; /* Info pointer */
-{
- DBTCL_INFO *ip;
- Tcl_Obj *res;
- _MUTEX_DATA *md;
- int i, nitems, mode, result, ret;
- char newname[MSG_SIZE];
-
- md = NULL;
- result = TCL_OK;
- ret = 0;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "mode nitems");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &mode);
- if (result != TCL_OK)
- return (TCL_ERROR);
- result = Tcl_GetIntFromObj(interp, objv[3], &nitems);
- if (result != TCL_OK)
- return (TCL_ERROR);
-
- memset(newname, 0, MSG_SIZE);
- snprintf(newname, sizeof(newname),
- "%s.mutex%d", envip->i_name, envip->i_envmutexid);
- ip = _NewInfo(interp, NULL, newname, I_MUTEX);
- if (ip == NULL) {
- Tcl_SetResult(interp, "Could not set up info",
- TCL_STATIC);
- return (TCL_ERROR);
- }
- /*
- * Set up mutex.
- */
- /*
- * Map in the region.
- *
- * XXX
- * We don't bother doing this "right", i.e., using the shalloc
- * functions, just grab some memory knowing that it's correctly
- * aligned.
- */
- _debug_check();
- if (__os_calloc(NULL, 1, sizeof(_MUTEX_DATA), &md) != 0)
- goto posixout;
- md->env = envp;
- md->size = sizeof(_MUTEX_ENTRY) * (u_int)nitems;
-
- md->reginfo.dbenv = envp;
- md->reginfo.type = REGION_TYPE_MUTEX;
- md->reginfo.id = INVALID_REGION_ID;
- md->reginfo.flags = REGION_CREATE_OK | REGION_JOIN_OK;
- if ((ret = __db_r_attach(envp, &md->reginfo, md->size)) != 0)
- goto posixout;
- md->marray = md->reginfo.addr;
-
- /* Initialize a created region. */
- if (F_ISSET(&md->reginfo, REGION_CREATE))
- for (i = 0; i < nitems; i++) {
- md->marray[i].val = 0;
- if ((ret = __db_mutex_init_int(envp,
- &md->marray[i].m, i, 0)) != 0)
- goto posixout;
- }
- R_UNLOCK(envp, &md->reginfo);
-
- /*
- * Success. Set up return. Set up new info
- * and command widget for this mutex.
- */
- envip->i_envmutexid++;
- ip->i_parent = envip;
- _SetInfoData(ip, md);
- (void)Tcl_CreateObjCommand(interp, newname,
- (Tcl_ObjCmdProc *)mutex_Cmd, (ClientData)md, NULL);
- res = NewStringObj(newname, strlen(newname));
- Tcl_SetObjResult(interp, res);
-
- return (TCL_OK);
-
-posixout:
- if (ret > 0)
- (void)Tcl_PosixError(interp);
- result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mutex");
- _DeleteInfo(ip);
-
- if (md != NULL) {
- if (md->reginfo.addr != NULL)
- (void)__db_r_detach(md->env, &md->reginfo, 0);
- __os_free(md->env, md);
- }
- return (result);
-}
-
-/*
- * mutex_Cmd --
- * Implements the "mutex" widget.
- */
-static int
-mutex_Cmd(clientData, interp, objc, objv)
- ClientData clientData; /* Mutex handle */
- Tcl_Interp *interp; /* Interpreter */
- int objc; /* How many arguments? */
- Tcl_Obj *CONST objv[]; /* The argument objects */
-{
- static const char *mxcmds[] = {
- "close",
- "get",
- "getval",
- "release",
- "setval",
- NULL
- };
- enum mxcmds {
- MXCLOSE,
- MXGET,
- MXGETVAL,
- MXRELE,
- MXSETVAL
- };
- DB_ENV *dbenv;
- DBTCL_INFO *envip, *mpip;
- _MUTEX_DATA *mp;
- Tcl_Obj *res;
- int cmdindex, id, result, newval;
-
- Tcl_ResetResult(interp);
- mp = (_MUTEX_DATA *)clientData;
- mpip = _PtrToInfo((void *)mp);
- envip = mpip->i_parent;
- dbenv = envip->i_envp;
- result = TCL_OK;
-
- if (mp == NULL) {
- Tcl_SetResult(interp, "NULL mp pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
- if (mpip == NULL) {
- Tcl_SetResult(interp, "NULL mp info pointer", TCL_STATIC);
- return (TCL_ERROR);
- }
-
- /*
- * Get the command name index from the object based on the dbcmds
- * defined above.
- */
- if (Tcl_GetIndexFromObj(interp,
- objv[1], mxcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
- return (IS_HELP(objv[1]));
-
- res = NULL;
- switch ((enum mxcmds)cmdindex) {
- case MXCLOSE:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, NULL);
- return (TCL_ERROR);
- }
- _debug_check();
- (void)__db_r_detach(mp->env, &mp->reginfo, 0);
- res = Tcl_NewIntObj(0);
- (void)Tcl_DeleteCommand(interp, mpip->i_name);
- _DeleteInfo(mpip);
- __os_free(mp->env, mp);
- break;
- case MXRELE:
- /*
- * Check for 1 arg. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "id");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &id);
- if (result != TCL_OK)
- break;
- MUTEX_UNLOCK(dbenv, &mp->marray[id].m);
- res = Tcl_NewIntObj(0);
- break;
- case MXGET:
- /*
- * Check for 1 arg. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "id");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &id);
- if (result != TCL_OK)
- break;
- MUTEX_LOCK(dbenv, &mp->marray[id].m);
- res = Tcl_NewIntObj(0);
- break;
- case MXGETVAL:
- /*
- * Check for 1 arg. Error if different.
- */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "id");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &id);
- if (result != TCL_OK)
- break;
- res = Tcl_NewLongObj((long)mp->marray[id].val);
- break;
- case MXSETVAL:
- /*
- * Check for 2 args. Error if different.
- */
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "id val");
- return (TCL_ERROR);
- }
- result = Tcl_GetIntFromObj(interp, objv[2], &id);
- if (result != TCL_OK)
- break;
- result = Tcl_GetIntFromObj(interp, objv[3], &newval);
- if (result != TCL_OK)
- break;
- mp->marray[id].val = newval;
- res = Tcl_NewIntObj(0);
- break;
- }
- /*
- * Only set result if we have a res. Otherwise, lower
- * functions have already done so.
- */
- if (result == TCL_OK && res)
- Tcl_SetObjResult(interp, res);
- return (result);
-}