2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 1999-2002
5
* Sleepycat Software. All rights reserved.
11
static const char revid[] = "$Id$";
14
#ifndef NO_SYSTEM_INCLUDES
15
#include <sys/types.h>
23
#include "dbinc/log.h"
24
#include "dbinc/tcl_db.h"
25
#include "dbinc/txn.h"
28
static int tcl_LogcGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_LOGC *));
33
* PUBLIC: int tcl_LogArchive __P((Tcl_Interp *, int,
34
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
37
tcl_LogArchive(interp, objc, objv, envp)
38
Tcl_Interp *interp; /* Interpreter */
39
int objc; /* How many arguments? */
40
Tcl_Obj *CONST objv[]; /* The argument objects */
41
DB_ENV *envp; /* Environment pointer */
43
static char *archopts[] = {
44
"-arch_abs", "-arch_data", "-arch_log",
48
ARCH_ABS, ARCH_DATA, ARCH_LOG
50
Tcl_Obj *fileobj, *res;
52
int i, optindex, result, ret;
58
* Get the flag index from the object based on the options
63
if (Tcl_GetIndexFromObj(interp, objv[i],
64
archopts, "option", TCL_EXACT, &optindex) != TCL_OK)
65
return (IS_HELP(objv[i]));
67
switch ((enum archopts)optindex) {
81
ret = envp->log_archive(envp, &list, flag);
82
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log archive");
83
if (result == TCL_OK) {
84
res = Tcl_NewListObj(0, NULL);
85
for (file = list; file != NULL && *file != NULL; file++) {
86
fileobj = Tcl_NewStringObj(*file, strlen(*file));
87
result = Tcl_ListObjAppendElement(interp, res, fileobj);
91
Tcl_SetObjResult(interp, res);
94
__os_ufree(envp, list);
101
* PUBLIC: int tcl_LogCompare __P((Tcl_Interp *, int,
102
* PUBLIC: Tcl_Obj * CONST*));
105
tcl_LogCompare(interp, objc, objv)
106
Tcl_Interp *interp; /* Interpreter */
107
int objc; /* How many arguments? */
108
Tcl_Obj *CONST objv[]; /* The argument objects */
116
* No flags, must be 4 args.
119
Tcl_WrongNumArgs(interp, 2, objv, "lsn1 lsn2");
123
result = _GetLsn(interp, objv[2], &lsn0);
124
if (result == TCL_ERROR)
126
result = _GetLsn(interp, objv[3], &lsn1);
127
if (result == TCL_ERROR)
131
ret = log_compare(&lsn0, &lsn1);
132
res = Tcl_NewIntObj(ret);
133
Tcl_SetObjResult(interp, res);
140
* PUBLIC: int tcl_LogFile __P((Tcl_Interp *, int,
141
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
144
tcl_LogFile(interp, objc, objv, envp)
145
Tcl_Interp *interp; /* Interpreter */
146
int objc; /* How many arguments? */
147
Tcl_Obj *CONST objv[]; /* The argument objects */
148
DB_ENV *envp; /* Environment pointer */
158
* No flags, must be 3 args.
161
Tcl_WrongNumArgs(interp, 2, objv, "lsn");
165
result = _GetLsn(interp, objv[2], &lsn);
166
if (result == TCL_ERROR)
172
while (ret == ENOMEM) {
174
__os_free(envp, name);
175
ret = __os_malloc(envp, len, &name);
177
Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
181
ret = envp->log_file(envp, &lsn, name, len);
184
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_file");
186
res = Tcl_NewStringObj(name, strlen(name));
187
Tcl_SetObjResult(interp, res);
191
__os_free(envp, name);
199
* PUBLIC: int tcl_LogFlush __P((Tcl_Interp *, int,
200
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
203
tcl_LogFlush(interp, objc, objv, envp)
204
Tcl_Interp *interp; /* Interpreter */
205
int objc; /* How many arguments? */
206
Tcl_Obj *CONST objv[]; /* The argument objects */
207
DB_ENV *envp; /* Environment pointer */
214
* No flags, must be 2 or 3 args.
217
Tcl_WrongNumArgs(interp, 2, objv, "?lsn?");
223
result = _GetLsn(interp, objv[2], &lsn);
224
if (result == TCL_ERROR)
230
ret = envp->log_flush(envp, lsnp);
231
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_flush");
238
* PUBLIC: int tcl_LogGet __P((Tcl_Interp *, int,
239
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
242
tcl_LogGet(interp, objc, objv, envp)
243
Tcl_Interp *interp; /* Interpreter */
244
int objc; /* How many arguments? */
245
Tcl_Obj *CONST objv[]; /* The argument objects */
246
DB_ENV *envp; /* Environment pointer */
249
COMPQUIET(objv, NULL);
251
COMPQUIET(envp, NULL);
253
Tcl_SetResult(interp, "FAIL: log_get deprecated\n", TCL_STATIC);
260
* PUBLIC: int tcl_LogPut __P((Tcl_Interp *, int,
261
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
264
tcl_LogPut(interp, objc, objv, envp)
265
Tcl_Interp *interp; /* Interpreter */
266
int objc; /* How many arguments? */
267
Tcl_Obj *CONST objv[]; /* The argument objects */
268
DB_ENV *envp; /* Environment pointer */
270
static char *logputopts[] = {
279
Tcl_Obj *intobj, *res;
282
int freedata, optindex, result, ret;
288
Tcl_WrongNumArgs(interp, 2, objv, "?-args? record");
293
* Data/record must be the last arg.
295
memset(&data, 0, sizeof(data));
296
ret = _CopyObjBytes(interp, objv[objc-1], &dtmp,
297
&data.size, &freedata);
299
result = _ReturnSetup(interp, ret,
300
DB_RETOK_STD(ret), "log put");
306
* Get the command name index from the object based on the options
310
if (Tcl_GetIndexFromObj(interp, objv[2],
311
logputopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
312
return (IS_HELP(objv[2]));
314
switch ((enum logputopts)optindex) {
321
if (result == TCL_ERROR)
325
ret = envp->log_put(envp, &lsn, &data, flag);
326
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log_put");
327
if (result == TCL_ERROR)
329
res = Tcl_NewListObj(0, NULL);
330
intobj = Tcl_NewLongObj((long)lsn.file);
331
result = Tcl_ListObjAppendElement(interp, res, intobj);
332
intobj = Tcl_NewLongObj((long)lsn.offset);
333
result = Tcl_ListObjAppendElement(interp, res, intobj);
334
Tcl_SetObjResult(interp, res);
336
(void)__os_free(NULL, dtmp);
342
* PUBLIC: int tcl_LogStat __P((Tcl_Interp *, int,
343
* PUBLIC: Tcl_Obj * CONST*, DB_ENV *));
346
tcl_LogStat(interp, objc, objv, envp)
347
Tcl_Interp *interp; /* Interpreter */
348
int objc; /* How many arguments? */
349
Tcl_Obj *CONST objv[]; /* The argument objects */
350
DB_ENV *envp; /* Environment pointer */
358
* No args for this. Error if there are some.
361
Tcl_WrongNumArgs(interp, 2, objv, NULL);
365
ret = envp->log_stat(envp, &sp, 0);
366
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "log stat");
367
if (result == TCL_ERROR)
371
* Have our stats, now construct the name value
372
* list pairs and free up the memory.
376
* MAKE_STAT_LIST assumes 'res' and 'error' label.
378
MAKE_STAT_LIST("Magic", sp->st_magic);
379
MAKE_STAT_LIST("Log file Version", sp->st_version);
380
MAKE_STAT_LIST("Region size", sp->st_regsize);
381
MAKE_STAT_LIST("Log file mode", sp->st_mode);
382
MAKE_STAT_LIST("Log record cache size", sp->st_lg_bsize);
383
MAKE_STAT_LIST("Current log file size", sp->st_lg_size);
384
MAKE_STAT_LIST("Mbytes written", sp->st_w_mbytes);
385
MAKE_STAT_LIST("Bytes written (over Mb)", sp->st_w_bytes);
386
MAKE_STAT_LIST("Mbytes written since checkpoint", sp->st_wc_mbytes);
387
MAKE_STAT_LIST("Bytes written (over Mb) since checkpoint",
389
MAKE_STAT_LIST("Times log written", sp->st_wcount);
390
MAKE_STAT_LIST("Times log written because cache filled up",
392
MAKE_STAT_LIST("Times log flushed", sp->st_scount);
393
MAKE_STAT_LIST("Current log file number", sp->st_cur_file);
394
MAKE_STAT_LIST("Current log file offset", sp->st_cur_offset);
395
MAKE_STAT_LIST("On-disk log file number", sp->st_disk_file);
396
MAKE_STAT_LIST("On-disk log file offset", sp->st_disk_offset);
397
MAKE_STAT_LIST("Max commits in a log flush", sp->st_maxcommitperflush);
398
MAKE_STAT_LIST("Min commits in a log flush", sp->st_mincommitperflush);
399
MAKE_STAT_LIST("Number of region lock waits", sp->st_region_wait);
400
MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
401
Tcl_SetObjResult(interp, res);
409
* Implements the log cursor command.
411
* PUBLIC: int logc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
414
logc_Cmd(clientData, interp, objc, objv)
415
ClientData clientData; /* Cursor handle */
416
Tcl_Interp *interp; /* Interpreter */
417
int objc; /* How many arguments? */
418
Tcl_Obj *CONST objv[]; /* The argument objects */
420
static char *logccmds[] = {
431
int cmdindex, result, ret;
433
Tcl_ResetResult(interp);
434
logc = (DB_LOGC *)clientData;
435
logcip = _PtrToInfo((void *)logc);
439
Tcl_WrongNumArgs(interp, 1, objv, "command cmdargs");
443
Tcl_SetResult(interp, "NULL logc pointer", TCL_STATIC);
446
if (logcip == NULL) {
447
Tcl_SetResult(interp, "NULL logc info pointer", TCL_STATIC);
452
* Get the command name index from the object based on the berkdbcmds
455
if (Tcl_GetIndexFromObj(interp, objv[1], logccmds, "command",
456
TCL_EXACT, &cmdindex) != TCL_OK)
457
return (IS_HELP(objv[1]));
458
switch ((enum logccmds)cmdindex) {
461
* No args for this. Error if there are some.
464
Tcl_WrongNumArgs(interp, 2, objv, NULL);
468
ret = logc->close(logc, 0);
469
result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret),
471
if (result == TCL_OK) {
472
(void)Tcl_DeleteCommand(interp, logcip->i_name);
477
result = tcl_LogcGet(interp, objc, objv, logc);
484
tcl_LogcGet(interp, objc, objv, logc)
487
Tcl_Obj * CONST *objv;
490
static char *logcgetopts[] = {
509
Tcl_Obj *dataobj, *lsnlist, *myobjv[2], *res;
511
int i, myobjc, optindex, result, ret;
518
Tcl_WrongNumArgs(interp, 2, objv, "?-args? lsn");
523
* Get the command name index from the object based on the options
528
if (Tcl_GetIndexFromObj(interp, objv[i],
529
logcgetopts, "option", TCL_EXACT, &optindex) != TCL_OK)
530
return (IS_HELP(objv[i]));
532
switch ((enum logcgetopts)optindex) {
533
case LOGCGET_CURRENT:
557
Tcl_WrongNumArgs(interp, 2, objv, "?-set lsn?");
561
result = _GetLsn(interp, objv[i++], &lsn);
566
if (result == TCL_ERROR)
569
memset(&data, 0, sizeof(data));
572
ret = logc->get(logc, &lsn, &data, flag);
574
res = Tcl_NewListObj(0, NULL);
580
* Success. Set up return list as {LSN data} where LSN
581
* is a sublist {file offset}.
584
myobjv[0] = Tcl_NewLongObj((long)lsn.file);
585
myobjv[1] = Tcl_NewLongObj((long)lsn.offset);
586
lsnlist = Tcl_NewListObj(myobjc, myobjv);
590
result = Tcl_ListObjAppendElement(interp, res, lsnlist);
591
dataobj = Tcl_NewStringObj(data.data, data.size);
592
if (dataobj == NULL) {
595
result = Tcl_ListObjAppendElement(interp, res, dataobj);
597
result = _ReturnSetup(interp, ret, DB_RETOK_LGGET(ret),
600
Tcl_SetObjResult(interp, res);
603
memerr: if (res != NULL)
604
Tcl_DecrRefCount(res);
605
Tcl_SetResult(interp, "allocation failed", TCL_STATIC);