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

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. /*
  8.  * Copyright (c) 1990, 1993
  9.  * Margo Seltzer.  All rights reserved.
  10.  */
  11. /*
  12.  * Copyright (c) 1990, 1993
  13.  * The Regents of the University of California.  All rights reserved.
  14.  *
  15.  * This code is derived from software contributed to Berkeley by
  16.  * Margo Seltzer.
  17.  *
  18.  * Redistribution and use in source and binary forms, with or without
  19.  * modification, are permitted provided that the following conditions
  20.  * are met:
  21.  * 1. Redistributions of source code must retain the above copyright
  22.  *    notice, this list of conditions and the following disclaimer.
  23.  * 2. Redistributions in binary form must reproduce the above copyright
  24.  *    notice, this list of conditions and the following disclaimer in the
  25.  *    documentation and/or other materials provided with the distribution.
  26.  * 3. Neither the name of the University nor the names of its contributors
  27.  *    may be used to endorse or promote products derived from this software
  28.  *    without specific prior written permission.
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  31.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  34.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40.  * SUCH DAMAGE.
  41.  */
  42. #include "db_config.h"
  43. #ifndef lint
  44. static const char revid[] = "$Id: dbm.c,v 11.7 2000/11/30 00:58:35 ubell Exp $";
  45. #endif /* not lint */
  46. #ifndef NO_SYSTEM_INCLUDES
  47. #include <sys/types.h>
  48. #include <fcntl.h>
  49. #include <string.h>
  50. #endif
  51. #define DB_DBM_HSEARCH 1
  52. #include "db_int.h"
  53. /*
  54.  *
  55.  * This package provides dbm and ndbm compatible interfaces to DB.
  56.  *
  57.  * The DBM routines, which call the NDBM routines.
  58.  */
  59. static DBM *__cur_db;
  60. static void __db_no_open __P((void));
  61. int
  62. __db_dbm_init(file)
  63. char *file;
  64. {
  65. if (__cur_db != NULL)
  66. (void)dbm_close(__cur_db);
  67. if ((__cur_db =
  68.     dbm_open(file, O_CREAT | O_RDWR, __db_omode("rw----"))) != NULL)
  69. return (0);
  70. if ((__cur_db = dbm_open(file, O_RDONLY, 0)) != NULL)
  71. return (0);
  72. return (-1);
  73. }
  74. int
  75. __db_dbm_close()
  76. {
  77. if (__cur_db != NULL) {
  78. dbm_close(__cur_db);
  79. __cur_db = NULL;
  80. }
  81. return (0);
  82. }
  83. datum
  84. __db_dbm_fetch(key)
  85. datum key;
  86. {
  87. datum item;
  88. if (__cur_db == NULL) {
  89. __db_no_open();
  90. item.dptr = 0;
  91. return (item);
  92. }
  93. return (dbm_fetch(__cur_db, key));
  94. }
  95. datum
  96. __db_dbm_firstkey()
  97. {
  98. datum item;
  99. if (__cur_db == NULL) {
  100. __db_no_open();
  101. item.dptr = 0;
  102. return (item);
  103. }
  104. return (dbm_firstkey(__cur_db));
  105. }
  106. datum
  107. __db_dbm_nextkey(key)
  108. datum key;
  109. {
  110. datum item;
  111. COMPQUIET(key.dsize, 0);
  112. if (__cur_db == NULL) {
  113. __db_no_open();
  114. item.dptr = 0;
  115. return (item);
  116. }
  117. return (dbm_nextkey(__cur_db));
  118. }
  119. int
  120. __db_dbm_delete(key)
  121. datum key;
  122. {
  123. if (__cur_db == NULL) {
  124. __db_no_open();
  125. return (-1);
  126. }
  127. return (dbm_delete(__cur_db, key));
  128. }
  129. int
  130. __db_dbm_store(key, dat)
  131. datum key, dat;
  132. {
  133. if (__cur_db == NULL) {
  134. __db_no_open();
  135. return (-1);
  136. }
  137. return (dbm_store(__cur_db, key, dat, DBM_REPLACE));
  138. }
  139. static void
  140. __db_no_open()
  141. {
  142. (void)fprintf(stderr, "dbm: no open database.n");
  143. }
  144. /*
  145.  * This package provides dbm and ndbm compatible interfaces to DB.
  146.  *
  147.  * The NDBM routines, which call the DB routines.
  148.  */
  149. /*
  150.  * Returns:
  151.  * *DBM on success
  152.  *  NULL on failure
  153.  */
  154. DBM *
  155. __db_ndbm_open(file, oflags, mode)
  156. const char *file;
  157. int oflags, mode;
  158. {
  159. DB *dbp;
  160. DBC *dbc;
  161. int ret;
  162. char path[MAXPATHLEN];
  163. /*
  164.  * !!!
  165.  * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and
  166.  * the latter isn't standard, and we're manipulating strings handed
  167.  * us by the application.
  168.  */
  169. if (strlen(file) + strlen(DBM_SUFFIX) + 1 > sizeof(path)) {
  170. __os_set_errno(ENAMETOOLONG);
  171. return (NULL);
  172. }
  173. (void)strcpy(path, file);
  174. (void)strcat(path, DBM_SUFFIX);
  175. if ((ret = db_create(&dbp, NULL, 0)) != 0) {
  176. __os_set_errno(ret);
  177. return (NULL);
  178. }
  179. /*
  180.  * !!!
  181.  * The historic ndbm library corrected for opening O_WRONLY.
  182.  */
  183. if (oflags & O_WRONLY) {
  184. oflags &= ~O_WRONLY;
  185. oflags |= O_RDWR;
  186. }
  187. if ((ret = dbp->set_pagesize(dbp, 4096)) != 0 ||
  188.     (ret = dbp->set_h_ffactor(dbp, 40)) != 0 ||
  189.     (ret = dbp->set_h_nelem(dbp, 1)) != 0 ||
  190.     (ret = dbp->open(dbp,
  191.     path, NULL, DB_HASH, __db_oflags(oflags), mode)) != 0) {
  192. __os_set_errno(ret);
  193. return (NULL);
  194. }
  195. if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) {
  196. (void)dbp->close(dbp, 0);
  197. __os_set_errno(ret);
  198. return (NULL);
  199. }
  200. return ((DBM *)dbc);
  201. }
  202. /*
  203.  * Returns:
  204.  * Nothing.
  205.  */
  206. void
  207. __db_ndbm_close(dbm)
  208. DBM *dbm;
  209. {
  210. DBC *dbc;
  211. dbc = (DBC *)dbm;
  212. (void)dbc->dbp->close(dbc->dbp, 0);
  213. }
  214. /*
  215.  * Returns:
  216.  * DATUM on success
  217.  * NULL on failure
  218.  */
  219. datum
  220. __db_ndbm_fetch(dbm, key)
  221. DBM *dbm;
  222. datum key;
  223. {
  224. DBC *dbc;
  225. DBT _key, _data;
  226. datum data;
  227. int ret;
  228. dbc = (DBC *)dbm;
  229. memset(&_key, 0, sizeof(DBT));
  230. memset(&_data, 0, sizeof(DBT));
  231. _key.size = key.dsize;
  232. _key.data = key.dptr;
  233. /*
  234.  * Note that we can't simply use the dbc we have to do a c_get/SET,
  235.  * because that cursor is the one used for sequential iteration and
  236.  * it has to remain stable in the face of intervening gets and puts.
  237.  */
  238. if ((ret = dbc->dbp->get(dbc->dbp, NULL, &_key, &_data, 0)) == 0) {
  239. data.dptr = _data.data;
  240. data.dsize = _data.size;
  241. } else {
  242. data.dptr = NULL;
  243. data.dsize = 0;
  244. if (ret == DB_NOTFOUND)
  245. __os_set_errno(ENOENT);
  246. else {
  247. __os_set_errno(ret);
  248. F_SET(dbc->dbp, DB_DBM_ERROR);
  249. }
  250. }
  251. return (data);
  252. }
  253. /*
  254.  * Returns:
  255.  * DATUM on success
  256.  * NULL on failure
  257.  */
  258. datum
  259. __db_ndbm_firstkey(dbm)
  260. DBM *dbm;
  261. {
  262. DBC *dbc;
  263. DBT _key, _data;
  264. datum key;
  265. int ret;
  266. dbc = (DBC *)dbm;
  267. memset(&_key, 0, sizeof(DBT));
  268. memset(&_data, 0, sizeof(DBT));
  269. if ((ret = dbc->c_get(dbc, &_key, &_data, DB_FIRST)) == 0) {
  270. key.dptr = _key.data;
  271. key.dsize = _key.size;
  272. } else {
  273. key.dptr = NULL;
  274. key.dsize = 0;
  275. if (ret == DB_NOTFOUND)
  276. __os_set_errno(ENOENT);
  277. else {
  278. __os_set_errno(ret);
  279. F_SET(dbc->dbp, DB_DBM_ERROR);
  280. }
  281. }
  282. return (key);
  283. }
  284. /*
  285.  * Returns:
  286.  * DATUM on success
  287.  * NULL on failure
  288.  */
  289. datum
  290. __db_ndbm_nextkey(dbm)
  291. DBM *dbm;
  292. {
  293. DBC *dbc;
  294. DBT _key, _data;
  295. datum key;
  296. int ret;
  297. dbc = (DBC *)dbm;
  298. memset(&_key, 0, sizeof(DBT));
  299. memset(&_data, 0, sizeof(DBT));
  300. if ((ret = dbc->c_get(dbc, &_key, &_data, DB_NEXT)) == 0) {
  301. key.dptr = _key.data;
  302. key.dsize = _key.size;
  303. } else {
  304. key.dptr = NULL;
  305. key.dsize = 0;
  306. if (ret == DB_NOTFOUND)
  307. __os_set_errno(ENOENT);
  308. else {
  309. __os_set_errno(ret);
  310. F_SET(dbc->dbp, DB_DBM_ERROR);
  311. }
  312. }
  313. return (key);
  314. }
  315. /*
  316.  * Returns:
  317.  *  0 on success
  318.  * <0 failure
  319.  */
  320. int
  321. __db_ndbm_delete(dbm, key)
  322. DBM *dbm;
  323. datum key;
  324. {
  325. DBC *dbc;
  326. DBT _key;
  327. int ret;
  328. dbc = (DBC *)dbm;
  329. memset(&_key, 0, sizeof(DBT));
  330. _key.data = key.dptr;
  331. _key.size = key.dsize;
  332. if ((ret = dbc->dbp->del(dbc->dbp, NULL, &_key, 0)) == 0)
  333. return (0);
  334. if (ret == DB_NOTFOUND)
  335. __os_set_errno(ENOENT);
  336. else {
  337. __os_set_errno(ret);
  338. F_SET(dbc->dbp, DB_DBM_ERROR);
  339. }
  340. return (-1);
  341. }
  342. /*
  343.  * Returns:
  344.  *  0 on success
  345.  * <0 failure
  346.  *  1 if DBM_INSERT and entry exists
  347.  */
  348. int
  349. __db_ndbm_store(dbm, key, data, flags)
  350. DBM *dbm;
  351. datum key, data;
  352. int flags;
  353. {
  354. DBC *dbc;
  355. DBT _key, _data;
  356. int ret;
  357. dbc = (DBC *)dbm;
  358. memset(&_key, 0, sizeof(DBT));
  359. _key.data = key.dptr;
  360. _key.size = key.dsize;
  361. memset(&_data, 0, sizeof(DBT));
  362. _data.data = data.dptr;
  363. _data.size = data.dsize;
  364. if ((ret = dbc->dbp->put(dbc->dbp, NULL,
  365.     &_key, &_data, flags == DBM_INSERT ? DB_NOOVERWRITE : 0)) == 0)
  366. return (0);
  367. if (ret == DB_KEYEXIST)
  368. return (1);
  369. __os_set_errno(ret);
  370. F_SET(dbc->dbp, DB_DBM_ERROR);
  371. return (-1);
  372. }
  373. int
  374. __db_ndbm_error(dbm)
  375. DBM *dbm;
  376. {
  377. DBC *dbc;
  378. dbc = (DBC *)dbm;
  379. return (F_ISSET(dbc->dbp, DB_DBM_ERROR));
  380. }
  381. int
  382. __db_ndbm_clearerr(dbm)
  383. DBM *dbm;
  384. {
  385. DBC *dbc;
  386. dbc = (DBC *)dbm;
  387. F_CLR(dbc->dbp, DB_DBM_ERROR);
  388. return (0);
  389. }
  390. /*
  391.  * Returns:
  392.  * 1 if read-only
  393.  * 0 if not read-only
  394.  */
  395. int
  396. __db_ndbm_rdonly(dbm)
  397. DBM *dbm;
  398. {
  399. DBC *dbc;
  400. dbc = (DBC *)dbm;
  401. return (F_ISSET(dbc->dbp, DB_AM_RDONLY) ? 1 : 0);
  402. }
  403. /*
  404.  * XXX
  405.  * We only have a single file descriptor that we can return, not two.  Return
  406.  * the same one for both files.  Hopefully, the user is using it for locking
  407.  * and picked one to use at random.
  408.  */
  409. int
  410. __db_ndbm_dirfno(dbm)
  411. DBM *dbm;
  412. {
  413. return (dbm_pagfno(dbm));
  414. }
  415. int
  416. __db_ndbm_pagfno(dbm)
  417. DBM *dbm;
  418. {
  419. DBC *dbc;
  420. int fd;
  421. dbc = (DBC *)dbm;
  422. (void)dbc->dbp->fd(dbc->dbp, &fd);
  423. return (fd);
  424. }