tcl_log.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:13k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: tcl_log.c,v 11.21 2000/11/30 00:58:45 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <tcl.h>
  16. #endif
  17. #include "db_int.h"
  18. #include "tcl_db.h"
  19. /*
  20.  * tcl_LogArchive --
  21.  *
  22.  * PUBLIC: int tcl_LogArchive __P((Tcl_Interp *, int,
  23.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  24.  */
  25. int
  26. tcl_LogArchive(interp, objc, objv, envp)
  27. Tcl_Interp *interp; /* Interpreter */
  28. int objc; /* How many arguments? */
  29. Tcl_Obj *CONST objv[]; /* The argument objects */
  30. DB_ENV *envp; /* Environment pointer */
  31. {
  32. static char *archopts[] = {
  33. "-arch_abs", "-arch_data", "-arch_log",
  34. NULL
  35. };
  36. enum archopts {
  37. ARCH_ABS, ARCH_DATA, ARCH_LOG
  38. };
  39. Tcl_Obj *fileobj, *res;
  40. u_int32_t flag;
  41. int i, optindex, result, ret;
  42. char **file, **list;
  43. result = TCL_OK;
  44. flag = 0;
  45. /*
  46.  * Get the flag index from the object based on the options
  47.  * defined above.
  48.  */
  49. i = 2;
  50. while (i < objc) {
  51. if (Tcl_GetIndexFromObj(interp, objv[i],
  52.     archopts, "option", TCL_EXACT, &optindex) != TCL_OK)
  53. return (IS_HELP(objv[i]));
  54. i++;
  55. switch ((enum archopts)optindex) {
  56. case ARCH_ABS:
  57. flag |= DB_ARCH_ABS;
  58. break;
  59. case ARCH_DATA:
  60. flag |= DB_ARCH_DATA;
  61. break;
  62. case ARCH_LOG:
  63. flag |= DB_ARCH_LOG;
  64. break;
  65. }
  66. }
  67. _debug_check();
  68. list = NULL;
  69. ret = log_archive(envp, &list, flag, NULL);
  70. result = _ReturnSetup(interp, ret, "log archive");
  71. if (result == TCL_OK) {
  72. res = Tcl_NewListObj(0, NULL);
  73. for (file = list; file != NULL && *file != NULL; file++) {
  74. fileobj = Tcl_NewStringObj(*file, strlen(*file));
  75. result = Tcl_ListObjAppendElement(interp, res, fileobj);
  76. if (result != TCL_OK)
  77. break;
  78. }
  79. Tcl_SetObjResult(interp, res);
  80. }
  81. if (list != NULL)
  82. __os_free(list, 0);
  83. return (result);
  84. }
  85. /*
  86.  * tcl_LogCompare --
  87.  *
  88.  * PUBLIC: int tcl_LogCompare __P((Tcl_Interp *, int,
  89.  * PUBLIC:    Tcl_Obj * CONST*));
  90.  */
  91. int
  92. tcl_LogCompare(interp, objc, objv)
  93. Tcl_Interp *interp; /* Interpreter */
  94. int objc; /* How many arguments? */
  95. Tcl_Obj *CONST objv[]; /* The argument objects */
  96. {
  97. DB_LSN lsn0, lsn1;
  98. Tcl_Obj *res;
  99. int result, ret;
  100. result = TCL_OK;
  101. /*
  102.  * No flags, must be 4 args.
  103.  */
  104. if (objc != 4) {
  105. Tcl_WrongNumArgs(interp, 2, objv, "lsn1 lsn2");
  106. return (TCL_ERROR);
  107. }
  108. result = _GetLsn(interp, objv[2], &lsn0);
  109. if (result == TCL_ERROR)
  110. return (result);
  111. result = _GetLsn(interp, objv[3], &lsn1);
  112. if (result == TCL_ERROR)
  113. return (result);
  114. _debug_check();
  115. ret = log_compare(&lsn0, &lsn1);
  116. res = Tcl_NewIntObj(ret);
  117. Tcl_SetObjResult(interp, res);
  118. return (result);
  119. }
  120. /*
  121.  * tcl_LogFile --
  122.  *
  123.  * PUBLIC: int tcl_LogFile __P((Tcl_Interp *, int,
  124.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  125.  */
  126. int
  127. tcl_LogFile(interp, objc, objv, envp)
  128. Tcl_Interp *interp; /* Interpreter */
  129. int objc; /* How many arguments? */
  130. Tcl_Obj *CONST objv[]; /* The argument objects */
  131. DB_ENV *envp; /* Environment pointer */
  132. {
  133. DB_LSN lsn;
  134. Tcl_Obj *res;
  135. size_t len;
  136. int result, ret;
  137. char *name;
  138. result = TCL_OK;
  139. /*
  140.  * No flags, must be 3 args.
  141.  */
  142. if (objc != 3) {
  143. Tcl_WrongNumArgs(interp, 2, objv, "lsn");
  144. return (TCL_ERROR);
  145. }
  146. result = _GetLsn(interp, objv[2], &lsn);
  147. if (result == TCL_ERROR)
  148. return (result);
  149. len = MSG_SIZE;
  150. ret = ENOMEM;
  151. name = NULL;
  152. while (ret == ENOMEM) {
  153. if (name != NULL)
  154. __os_free(name, len/2);
  155. ret = __os_malloc(envp, len, NULL, &name);
  156. if (ret != 0) {
  157. Tcl_SetResult(interp, db_strerror(ret), TCL_STATIC);
  158. break;
  159. }
  160. _debug_check();
  161. ret = log_file(envp, &lsn, name, len);
  162. len *= 2;
  163. }
  164. result = _ReturnSetup(interp, ret, "log_file");
  165. if (ret == 0) {
  166. res = Tcl_NewStringObj(name, strlen(name));
  167. Tcl_SetObjResult(interp, res);
  168. }
  169. if (name != NULL)
  170. __os_free(name, len/2);
  171. return (result);
  172. }
  173. /*
  174.  * tcl_LogFlush --
  175.  *
  176.  * PUBLIC: int tcl_LogFlush __P((Tcl_Interp *, int,
  177.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  178.  */
  179. int
  180. tcl_LogFlush(interp, objc, objv, envp)
  181. Tcl_Interp *interp; /* Interpreter */
  182. int objc; /* How many arguments? */
  183. Tcl_Obj *CONST objv[]; /* The argument objects */
  184. DB_ENV *envp; /* Environment pointer */
  185. {
  186. DB_LSN lsn, *lsnp;
  187. int result, ret;
  188. result = TCL_OK;
  189. /*
  190.  * No flags, must be 2 or 3 args.
  191.  */
  192. if (objc > 3) {
  193. Tcl_WrongNumArgs(interp, 2, objv, "?lsn?");
  194. return (TCL_ERROR);
  195. }
  196. if (objc == 3) {
  197. lsnp = &lsn;
  198. result = _GetLsn(interp, objv[2], &lsn);
  199. if (result == TCL_ERROR)
  200. return (result);
  201. } else
  202. lsnp = NULL;
  203. _debug_check();
  204. ret = log_flush(envp, lsnp);
  205. result = _ReturnSetup(interp, ret, "log_flush");
  206. return (result);
  207. }
  208. /*
  209.  * tcl_LogGet --
  210.  *
  211.  * PUBLIC: int tcl_LogGet __P((Tcl_Interp *, int,
  212.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  213.  */
  214. int
  215. tcl_LogGet(interp, objc, objv, envp)
  216. Tcl_Interp *interp; /* Interpreter */
  217. int objc; /* How many arguments? */
  218. Tcl_Obj *CONST objv[]; /* The argument objects */
  219. DB_ENV *envp; /* Environment pointer */
  220. {
  221. static char *loggetopts[] = {
  222. "-checkpoint", "-current", "-first",
  223. "-last", "-next", "-prev",
  224. "-set",
  225. NULL
  226. };
  227. enum loggetopts {
  228. LOGGET_CKP, LOGGET_CUR, LOGGET_FIRST,
  229. LOGGET_LAST, LOGGET_NEXT, LOGGET_PREV,
  230. LOGGET_SET
  231. };
  232. DB_LSN lsn;
  233. DBT data;
  234. Tcl_Obj *dataobj, *lsnlist, *myobjv[2], *res;
  235. u_int32_t flag;
  236. int i, myobjc, optindex, result, ret;
  237. result = TCL_OK;
  238. flag = 0;
  239. if (objc < 3) {
  240. Tcl_WrongNumArgs(interp, 2, objv, "?-args? lsn");
  241. return (TCL_ERROR);
  242. }
  243. /*
  244.  * Get the command name index from the object based on the options
  245.  * defined above.
  246.  */
  247. i = 2;
  248. while (i < objc) {
  249. if (Tcl_GetIndexFromObj(interp, objv[i],
  250.     loggetopts, "option", TCL_EXACT, &optindex) != TCL_OK)
  251. return (IS_HELP(objv[i]));
  252. i++;
  253. switch ((enum loggetopts)optindex) {
  254. case LOGGET_CKP:
  255. FLAG_CHECK(flag);
  256. flag |= DB_CHECKPOINT;
  257. break;
  258. case LOGGET_CUR:
  259. FLAG_CHECK(flag);
  260. flag |= DB_CURRENT;
  261. break;
  262. case LOGGET_FIRST:
  263. FLAG_CHECK(flag);
  264. flag |= DB_FIRST;
  265. break;
  266. case LOGGET_LAST:
  267. FLAG_CHECK(flag);
  268. flag |= DB_LAST;
  269. break;
  270. case LOGGET_NEXT:
  271. FLAG_CHECK(flag);
  272. flag |= DB_NEXT;
  273. break;
  274. case LOGGET_PREV:
  275. FLAG_CHECK(flag);
  276. flag |= DB_PREV;
  277. break;
  278. case LOGGET_SET:
  279. FLAG_CHECK(flag);
  280. flag |= DB_SET;
  281. if (i == objc) {
  282. Tcl_WrongNumArgs(interp, 2, objv, "?-set lsn?");
  283. result = TCL_ERROR;
  284. break;
  285. }
  286. result = _GetLsn(interp, objv[i++], &lsn);
  287. break;
  288. }
  289. }
  290. if (result == TCL_ERROR)
  291. return (result);
  292. memset(&data, 0, sizeof(data));
  293. data.flags |= DB_DBT_MALLOC;
  294. _debug_check();
  295. ret = log_get(envp, &lsn, &data, flag);
  296. res = Tcl_NewListObj(0, NULL);
  297. result = _ReturnSetup(interp, ret, "log_get");
  298. if (ret == 0) {
  299. /*
  300.  * Success.  Set up return list as {LSN data} where LSN
  301.  * is a sublist {file offset}.
  302.  */
  303. myobjc = 2;
  304. myobjv[0] = Tcl_NewIntObj(lsn.file);
  305. myobjv[1] = Tcl_NewIntObj(lsn.offset);
  306. lsnlist = Tcl_NewListObj(myobjc, myobjv);
  307. if (lsnlist == NULL) {
  308. if (data.data != NULL)
  309. __os_free(data.data, data.size);
  310. return (TCL_ERROR);
  311. }
  312. result = Tcl_ListObjAppendElement(interp, res, lsnlist);
  313. dataobj = Tcl_NewStringObj(data.data, data.size);
  314. result = Tcl_ListObjAppendElement(interp, res, dataobj);
  315. }
  316. if (data.data != NULL)
  317. __os_free(data.data, data.size);
  318. if (result == TCL_OK)
  319. Tcl_SetObjResult(interp, res);
  320. return (result);
  321. }
  322. /*
  323.  * tcl_LogPut --
  324.  *
  325.  * PUBLIC: int tcl_LogPut __P((Tcl_Interp *, int,
  326.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  327.  */
  328. int
  329. tcl_LogPut(interp, objc, objv, envp)
  330. Tcl_Interp *interp; /* Interpreter */
  331. int objc; /* How many arguments? */
  332. Tcl_Obj *CONST objv[]; /* The argument objects */
  333. DB_ENV *envp; /* Environment pointer */
  334. {
  335. static char *logputopts[] = {
  336. "-checkpoint", "-curlsn", "-flush",
  337. NULL
  338. };
  339. enum logputopts {
  340. LOGPUT_CKP, LOGPUT_CUR, LOGPUT_FLUSH
  341. };
  342. DB_LSN lsn;
  343. DBT data;
  344. Tcl_Obj *intobj, *res;
  345. u_int32_t flag;
  346. int itmp, optindex, result, ret;
  347. result = TCL_OK;
  348. flag = 0;
  349. if (objc < 3) {
  350. Tcl_WrongNumArgs(interp, 2, objv, "?-args? record");
  351. return (TCL_ERROR);
  352. }
  353. /*
  354.  * Data/record must be the last arg.
  355.  */
  356. memset(&data, 0, sizeof(data));
  357. data.data = Tcl_GetByteArrayFromObj(objv[objc-1], &itmp);
  358. data.size = itmp;
  359. /*
  360.  * Get the command name index from the object based on the options
  361.  * defined above.
  362.  */
  363. if (objc == 4) {
  364. if (Tcl_GetIndexFromObj(interp, objv[2],
  365.     logputopts, "option", TCL_EXACT, &optindex) != TCL_OK) {
  366. return (IS_HELP(objv[2]));
  367. }
  368. switch ((enum logputopts)optindex) {
  369. case LOGPUT_CKP:
  370. flag = DB_CHECKPOINT;
  371. break;
  372. case LOGPUT_CUR:
  373. flag = DB_CURLSN;
  374. break;
  375. case LOGPUT_FLUSH:
  376. flag = DB_FLUSH;
  377. break;
  378. }
  379. }
  380. if (result == TCL_ERROR)
  381. return (result);
  382. _debug_check();
  383. ret = log_put(envp, &lsn, &data, flag);
  384. result = _ReturnSetup(interp, ret, "log_put");
  385. if (result == TCL_ERROR)
  386. return (result);
  387. res = Tcl_NewListObj(0, NULL);
  388. intobj = Tcl_NewIntObj(lsn.file);
  389. result = Tcl_ListObjAppendElement(interp, res, intobj);
  390. intobj = Tcl_NewIntObj(lsn.offset);
  391. result = Tcl_ListObjAppendElement(interp, res, intobj);
  392. Tcl_SetObjResult(interp, res);
  393. return (result);
  394. }
  395. /*
  396.  * tcl_LogRegister --
  397.  *
  398.  * PUBLIC: int tcl_LogRegister __P((Tcl_Interp *, int,
  399.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  400.  */
  401. int
  402. tcl_LogRegister(interp, objc, objv, envp)
  403. Tcl_Interp *interp; /* Interpreter */
  404. int objc; /* How many arguments? */
  405. Tcl_Obj *CONST objv[]; /* The argument objects */
  406. DB_ENV *envp; /* Environment pointer */
  407. {
  408. DB *dbp;
  409. Tcl_Obj *res;
  410. int result, ret;
  411. char *arg, msg[MSG_SIZE];
  412. result = TCL_OK;
  413. if (objc != 4) {
  414. Tcl_WrongNumArgs(interp, 2, objv, "db filename");
  415. return (TCL_ERROR);
  416. }
  417. /*
  418.  * First comes the DB.
  419.  */
  420. arg = Tcl_GetStringFromObj(objv[2], NULL);
  421. dbp = NAME_TO_DB(arg);
  422. if (dbp == NULL) {
  423. snprintf(msg, MSG_SIZE,
  424.     "LogRegister: Invalid db: %sn", arg);
  425. Tcl_SetResult(interp, msg, TCL_VOLATILE);
  426. return (TCL_ERROR);
  427. }
  428. /*
  429.  * Next is the filename.
  430.  */
  431. arg = Tcl_GetStringFromObj(objv[3], NULL);
  432. _debug_check();
  433. ret = log_register(envp, dbp, arg);
  434. result = _ReturnSetup(interp, ret, "log_register");
  435. if (result == TCL_OK) {
  436. res = Tcl_NewIntObj((int)dbp->log_fileid);
  437. Tcl_SetObjResult(interp, res);
  438. }
  439. return (result);
  440. }
  441. /*
  442.  * tcl_LogStat --
  443.  *
  444.  * PUBLIC: int tcl_LogStat __P((Tcl_Interp *, int,
  445.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  446.  */
  447. int
  448. tcl_LogStat(interp, objc, objv, envp)
  449. Tcl_Interp *interp; /* Interpreter */
  450. int objc; /* How many arguments? */
  451. Tcl_Obj *CONST objv[]; /* The argument objects */
  452. DB_ENV *envp; /* Environment pointer */
  453. {
  454. DB_LOG_STAT *sp;
  455. Tcl_Obj *res;
  456. int result, ret;
  457. result = TCL_OK;
  458. /*
  459.  * No args for this.  Error if there are some.
  460.  */
  461. if (objc != 2) {
  462. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  463. return (TCL_ERROR);
  464. }
  465. _debug_check();
  466. ret = log_stat(envp, &sp, NULL);
  467. result = _ReturnSetup(interp, ret, "log stat");
  468. if (result == TCL_ERROR)
  469. return (result);
  470. /*
  471.  * Have our stats, now construct the name value
  472.  * list pairs and free up the memory.
  473.  */
  474. res = Tcl_NewObj();
  475. /*
  476.  * MAKE_STAT_LIST assumes 'res' and 'error' label.
  477.  */
  478. MAKE_STAT_LIST("Magic", sp->st_magic);
  479. MAKE_STAT_LIST("Log file Version", sp->st_version);
  480. MAKE_STAT_LIST("Region size", sp->st_regsize);
  481. MAKE_STAT_LIST("Log file mode", sp->st_mode);
  482. MAKE_STAT_LIST("Log record cache size", sp->st_lg_bsize);
  483. MAKE_STAT_LIST("Maximum log file size", sp->st_lg_max);
  484. MAKE_STAT_LIST("Mbytes written", sp->st_w_mbytes);
  485. MAKE_STAT_LIST("Bytes written (over Mb)", sp->st_w_bytes);
  486. MAKE_STAT_LIST("Mbytes written since checkpoint", sp->st_wc_mbytes);
  487. MAKE_STAT_LIST("Bytes written (over Mb) since checkpoint",
  488.     sp->st_wc_bytes);
  489. MAKE_STAT_LIST("Times log written", sp->st_wcount);
  490. MAKE_STAT_LIST("Times log written because cache filled up",
  491.     sp->st_wcount_fill);
  492. MAKE_STAT_LIST("Times log flushed", sp->st_scount);
  493. MAKE_STAT_LIST("Current log file number", sp->st_cur_file);
  494. MAKE_STAT_LIST("Current log file offset", sp->st_cur_offset);
  495. MAKE_STAT_LIST("Number of region lock waits", sp->st_region_wait);
  496. MAKE_STAT_LIST("Number of region lock nowaits", sp->st_region_nowait);
  497. Tcl_SetObjResult(interp, res);
  498. error:
  499. __os_free(sp, sizeof(*sp));
  500. return (result);
  501. }
  502. /*
  503.  * tcl_LogUnregister --
  504.  *
  505.  * PUBLIC: int tcl_LogUnregister __P((Tcl_Interp *, int,
  506.  * PUBLIC:    Tcl_Obj * CONST*, DB_ENV *));
  507.  */
  508. int
  509. tcl_LogUnregister(interp, objc, objv, envp)
  510. Tcl_Interp *interp; /* Interpreter */
  511. int objc; /* How many arguments? */
  512. Tcl_Obj *CONST objv[]; /* The argument objects */
  513. DB_ENV *envp; /* Environment pointer */
  514. {
  515. DB *dbp;
  516. char *arg, msg[MSG_SIZE];
  517. int result, ret;
  518. result = TCL_OK;
  519. /*
  520.  * 1 arg for this.  Error if more or less.
  521.  */
  522. if (objc != 3) {
  523. Tcl_WrongNumArgs(interp, 2, objv, NULL);
  524. return (TCL_ERROR);
  525. }
  526. arg = Tcl_GetStringFromObj(objv[2], NULL);
  527. dbp = NAME_TO_DB(arg);
  528. if (dbp == NULL) {
  529. snprintf(msg, MSG_SIZE,
  530.     "log_unregister: Invalid db identifier: %sn", arg);
  531. Tcl_SetResult(interp, msg, TCL_VOLATILE);
  532. return (TCL_ERROR);
  533. }
  534. _debug_check();
  535. ret = log_unregister(envp, dbp);
  536. result = _ReturnSetup(interp, ret, "log_unregister");
  537. return (result);
  538. }