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

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: cxx_table.cpp,v 11.35 2001/01/11 18:19:49 bostic Exp $";
  10. #endif /* not lint */
  11. #include <errno.h>
  12. #include <string.h>
  13. #include "db_cxx.h"
  14. #include "cxx_int.h"
  15. #include "db_int.h"
  16. #include "db_page.h"
  17. #include "db_ext.h"
  18. #include "common_ext.h"
  19. ////////////////////////////////////////////////////////////////////////
  20. //                                                                    //
  21. //                            Db                                      //
  22. //                                                                    //
  23. ////////////////////////////////////////////////////////////////////////
  24. // A truism for the DbEnv object is that there is a valid
  25. // DB_ENV handle from the constructor until close().
  26. // After the close, the DB handle is invalid and
  27. // no operations are permitted on the Db (other than
  28. // destructor).  Leaving the Db handle open and not
  29. // doing a close is generally considered an error.
  30. //
  31. // We used to allow Db objects to be closed and reopened.
  32. // This implied always keeping a valid DB object, and
  33. // coordinating the open objects between Db/DbEnv turned
  34. // out to be overly complicated.  Now we do not allow this.
  35. Db::Db(DbEnv *env, u_int32_t flags)
  36. : imp_(0)
  37. , env_(env)
  38. , construct_error_(0)
  39. , flags_(0)
  40. , construct_flags_(flags)
  41. {
  42. if (env_ == 0)
  43. flags_ |= DB_CXX_PRIVATE_ENV;
  44. initialize();
  45. }
  46. // Note: if the user has not closed, we call _destroy_check
  47. // to warn against this non-safe programming practice.
  48. // We can't close, because the environment may already
  49. // be closed/destroyed.
  50. //
  51. Db::~Db()
  52. {
  53. DB *db;
  54. db = unwrap(this);
  55. if (db != NULL) {
  56. DbEnv::_destroy_check("Db", 0);
  57. cleanup();
  58. }
  59. }
  60. // private method to initialize during constructor.
  61. // initialize must create a backing DB object,
  62. // and if that creates a new DB_ENV, it must be tied to a new DbEnv.
  63. // If there is an error, construct_error_ is set; this is examined
  64. // during open.
  65. //
  66. int Db::initialize()
  67. {
  68. u_int32_t cxx_flags;
  69. DB *db;
  70. int err;
  71. DB_ENV *cenv = unwrap(env_);
  72. cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS;
  73. // Create a new underlying DB object.
  74. // We rely on the fact that if a NULL DB_ENV* is given,
  75. // one is allocated by DB.
  76. //
  77. if ((err = db_create(&db, cenv,
  78.      construct_flags_ & ~cxx_flags)) != 0) {
  79. construct_error_ = err;
  80. return (err);
  81. }
  82. // Associate the DB with this object
  83. imp_ = wrap(db);
  84. db->cj_internal = this;
  85. // Create a new DbEnv from a DB_ENV* if it was created locally.
  86. // It is deleted in Db::close().
  87. //
  88. if ((flags_ & DB_CXX_PRIVATE_ENV) != 0)
  89. env_ = new DbEnv(db->dbenv, cxx_flags);
  90. return (0);
  91. }
  92. // private method to cleanup after destructor or during close.
  93. // If the environment was created by this Db object, we optionally
  94. // delete it, or return it so the caller can delete it after
  95. // last use.
  96. //
  97. void Db::cleanup()
  98. {
  99. DB *db = unwrap(this);
  100. if (db != NULL) {
  101. // extra safety
  102. db->cj_internal = 0;
  103. imp_ = 0;
  104. // we must dispose of the DbEnv object if
  105. // we created it.  This will be the case
  106. // if a NULL DbEnv was passed into the constructor.
  107. // The underlying DB_ENV object will be inaccessible
  108. // after the close, so we must clean it up now.
  109. //
  110. if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) {
  111. env_->cleanup();
  112. delete env_;
  113. env_ = 0;
  114. }
  115. }
  116. construct_error_ = 0;
  117. }
  118. // Return a tristate value corresponding to whether we should
  119. // throw exceptions on errors:
  120. //   ON_ERROR_RETURN
  121. //   ON_ERROR_THROW
  122. //   ON_ERROR_UNKNOWN
  123. //
  124. int Db::error_policy()
  125. {
  126. if (env_ != NULL)
  127. return (env_->error_policy());
  128. else {
  129. // If the env_ is null, that means that the user
  130. // did not attach an environment, so the correct error
  131. // policy can be deduced from constructor flags
  132. // for this Db.
  133. //
  134. if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) {
  135. return (ON_ERROR_RETURN);
  136. }
  137. else {
  138. return (ON_ERROR_THROW);
  139. }
  140. }
  141. }
  142. int Db::close(u_int32_t flags)
  143. {
  144. DB *db = unwrap(this);
  145. int err;
  146. // after a DB->close (no matter if success or failure),
  147. // the underlying DB object must not be accessed,
  148. // so we clean up in advance.
  149. //
  150. cleanup();
  151. // It's safe to throw an error after the close,
  152. // since our error mechanism does not peer into
  153. // the DB* structures.
  154. //
  155. if ((err = db->close(db, flags)) != 0 && err != DB_INCOMPLETE)
  156. DB_ERROR("Db::close", err, error_policy());
  157. return (err);
  158. }
  159. int Db::cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags)
  160. {
  161. DB *db = unwrap(this);
  162. DBC *dbc = 0;
  163. int err;
  164. if ((err = db->cursor(db, unwrap(txnid), &dbc, flags)) != 0) {
  165. DB_ERROR("Db::cursor", err, error_policy());
  166. return (err);
  167. }
  168. // The following cast implies that Dbc can be no larger than DBC
  169. *cursorp = (Dbc*)dbc;
  170. return (0);
  171. }
  172. int Db::del(DbTxn *txnid, Dbt *key, u_int32_t flags)
  173. {
  174. DB *db = unwrap(this);
  175. int err;
  176. if ((err = db->del(db, unwrap(txnid), key, flags)) != 0) {
  177. // DB_NOTFOUND is a "normal" return, so should not be
  178. // thrown as an error
  179. //
  180. if (err != DB_NOTFOUND) {
  181. DB_ERROR("Db::del", err, error_policy());
  182. return (err);
  183. }
  184. }
  185. return (err);
  186. }
  187. void Db::err(int error, const char *format, ...)
  188. {
  189. va_list args;
  190. DB *db = unwrap(this);
  191. va_start(args, format);
  192. __db_real_err(db->dbenv, error, 1, 1, format, args);
  193. va_end(args);
  194. }
  195. void Db::errx(const char *format, ...)
  196. {
  197. va_list args;
  198. DB *db = unwrap(this);
  199. va_start(args, format);
  200. __db_real_err(db->dbenv, 0, 0, 1, format, args);
  201. va_end(args);
  202. }
  203. int Db::fd(int *fdp)
  204. {
  205. DB *db = unwrap(this);
  206. int err;
  207. if ((err = db->fd(db, fdp)) != 0) {
  208. DB_ERROR("Db::fd", err, error_policy());
  209. return (err);
  210. }
  211. return (0);
  212. }
  213. // This is a 'glue' function declared as extern "C" so it will
  214. // be compatible with picky compilers that do not allow mixing
  215. // of function pointers to 'C' functions with function pointers
  216. // to C++ functions.
  217. //
  218. extern "C"
  219. void _db_feedback_intercept_c(DB *db, int opcode, int pct)
  220. {
  221. Db::_feedback_intercept(db, opcode, pct);
  222. }
  223. //static
  224. void Db::_feedback_intercept(DB *db, int opcode, int pct)
  225. {
  226. if (db == 0) {
  227. DB_ERROR("Db::feedback_callback", EINVAL, ON_ERROR_UNKNOWN);
  228. return;
  229. }
  230. Db *cxxdb = (Db *)db->cj_internal;
  231. if (cxxdb == 0) {
  232. DB_ERROR("Db::feedback_callback", EINVAL, ON_ERROR_UNKNOWN);
  233. return;
  234. }
  235. if (cxxdb->feedback_callback_ == 0) {
  236. DB_ERROR("Db::feedback_callback", EINVAL, cxxdb->error_policy());
  237. return;
  238. }
  239. (*cxxdb->feedback_callback_)(cxxdb, opcode, pct);
  240. }
  241. int Db::set_feedback(void (*arg)(Db *, int, int))
  242. {
  243. DB *db = unwrap(this);
  244. feedback_callback_ = arg;
  245. return ((*(db->set_feedback))(db, _db_feedback_intercept_c));
  246. }
  247. // This is a 'glue' function declared as extern "C" so it will
  248. // be compatible with picky compilers that do not allow mixing
  249. // of function pointers to 'C' functions with function pointers
  250. // to C++ functions.
  251. //
  252. extern "C"
  253. int _db_append_recno_intercept_c(DB *db, DBT *data, db_recno_t recno)
  254. {
  255. return (Db::_append_recno_intercept(db, data, recno));
  256. }
  257. //static
  258. int Db::_append_recno_intercept(DB *db, DBT *data, db_recno_t recno)
  259. {
  260. int err;
  261. if (db == 0) {
  262. DB_ERROR("Db::append_recno_callback", EINVAL, ON_ERROR_UNKNOWN);
  263. return (EINVAL);
  264. }
  265. Db *cxxdb = (Db *)db->cj_internal;
  266. if (cxxdb == 0) {
  267. DB_ERROR("Db::append_recno_callback", EINVAL, ON_ERROR_UNKNOWN);
  268. return (EINVAL);
  269. }
  270. if (cxxdb->append_recno_callback_ == 0) {
  271. DB_ERROR("Db::append_recno_callback", EINVAL, cxxdb->error_policy());
  272. return (EINVAL);
  273. }
  274. // making these copies is slow but portable.
  275. // Another alternative is to cast the DBT* manufactured
  276. // by the C layer to a Dbt*.  It 'should be' safe since
  277. // Dbt is a thin shell over DBT, adding no extra data,
  278. // but is nonportable, and could lead to errors if anything
  279. // were added to the Dbt class.
  280. //
  281. Dbt cxxdbt;
  282. memcpy((DBT *)&cxxdbt, data, sizeof(DBT));
  283. err = (*cxxdb->append_recno_callback_)(cxxdb, &cxxdbt, recno);
  284. memcpy(data, (DBT *)&cxxdbt, sizeof(DBT));
  285. return (err);
  286. }
  287. int Db::set_append_recno(int (*arg)(Db *, Dbt *, db_recno_t))
  288. {
  289. DB *db = unwrap(this);
  290. append_recno_callback_ = arg;
  291. return ((*(db->set_append_recno))(db, _db_append_recno_intercept_c));
  292. }
  293. int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags)
  294. {
  295. DB *db = unwrap(this);
  296. int err;
  297. if ((err = db->get(db, unwrap(txnid), key, value, flags)) != 0) {
  298. // DB_NOTFOUND and DB_KEYEMPTY are "normal" returns,
  299. // so should not be thrown as an error
  300. //
  301. if (err != DB_NOTFOUND && err != DB_KEYEMPTY) {
  302. DB_ERROR("Db::get", err, error_policy());
  303. return (err);
  304. }
  305. }
  306. return (err);
  307. }
  308. int Db::get_byteswapped() const
  309. {
  310. DB *db = (DB *)unwrapConst(this);
  311. return (db->get_byteswapped(db));
  312. }
  313. DBTYPE Db::get_type() const
  314. {
  315. DB *db = (DB *)unwrapConst(this);
  316. return ((DBTYPE)db->get_type(db));
  317. }
  318. int Db::join(Dbc **curslist, Dbc **cursorp, u_int32_t flags)
  319. {
  320. // Dbc is a "compatible" subclass of DBC -
  321. // that is, no virtual functions or even extra data members,
  322. // so this cast, although technically non-portable,
  323. // "should" always be okay.
  324. //
  325. DBC **list = (DBC **)(curslist);
  326. DB *db = unwrap(this);
  327. DBC *dbc = 0;
  328. int err;
  329. if ((err = db->join(db, list, &dbc, flags)) != 0) {
  330. DB_ERROR("Db::join_cursor", err, error_policy());
  331. return (err);
  332. }
  333. *cursorp = (Dbc*)dbc;
  334. return (0);
  335. }
  336. int Db::key_range(DbTxn *txnid, Dbt *key,
  337.   DB_KEY_RANGE *results, u_int32_t flags)
  338. {
  339. DB *db = unwrap(this);
  340. int err;
  341. if ((err = db->key_range(db, unwrap(txnid), key,
  342.  results, flags)) != 0) {
  343. DB_ERROR("Db::key_range", err, error_policy());
  344. return (err);
  345. }
  346. return (0);
  347. }
  348. // If an error occurred during the constructor, report it now.
  349. // Otherwise, call the underlying DB->open method.
  350. //
  351. int Db::open(const char *file, const char *database,
  352.      DBTYPE type, u_int32_t flags, int mode)
  353. {
  354. int err;
  355. DB *db = unwrap(this);
  356. if ((err = construct_error_) != 0)
  357. DB_ERROR("Db::open", construct_error_, error_policy());
  358. else if ((err = db->open(db, file, database, type, flags, mode)) != 0)
  359. DB_ERROR("Db::open", err, error_policy());
  360. return (err);
  361. }
  362. int Db::put(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags)
  363. {
  364. int err;
  365. DB *db = unwrap(this);
  366. if ((err = db->put(db, unwrap(txnid), key, value, flags)) != 0) {
  367. // DB_KEYEXIST is a "normal" return, so should not be
  368. // thrown as an error
  369. //
  370. if (err != DB_KEYEXIST) {
  371. DB_ERROR("Db::put", err, error_policy());
  372. return (err);
  373. }
  374. }
  375. return (err);
  376. }
  377. int Db::rename(const char *file, const char *database,
  378.        const char *newname, u_int32_t flags)
  379. {
  380. int err = 0;
  381. DB *db = unwrap(this);
  382. if (!db) {
  383. DB_ERROR("Db::rename", EINVAL, error_policy());
  384. return (EINVAL);
  385. }
  386. // after a DB->rename (no matter if success or failure),
  387. // the underlying DB object must not be accessed,
  388. // so we clean up in advance.
  389. //
  390. cleanup();
  391. if ((err = db->rename(db, file, database, newname, flags)) != 0) {
  392. DB_ERROR("Db::rename", err, error_policy());
  393. return (err);
  394. }
  395. return (0);
  396. }
  397. int Db::remove(const char *file, const char *database, u_int32_t flags)
  398. {
  399. int err = 0;
  400. DB *db = unwrap(this);
  401. if (!db) {
  402. DB_ERROR("Db::remove", EINVAL, error_policy());
  403. return (EINVAL);
  404. }
  405. // after a DB->remove (no matter if success or failure),
  406. // the underlying DB object must not be accessed,
  407. // so we clean up in advance.
  408. //
  409. cleanup();
  410. if ((err = db->remove(db, file, database, flags)) != 0)
  411. DB_ERROR("Db::remove", err, error_policy());
  412. return (err);
  413. }
  414. int Db::stat(void *sp, db_malloc_fcn_type db_malloc_fcn, u_int32_t flags)
  415. {
  416. int err;
  417. DB *db = unwrap(this);
  418. if (!db) {
  419. DB_ERROR("Db::stat", EINVAL, error_policy());
  420. return (EINVAL);
  421. }
  422. if ((err = db->stat(db, sp, db_malloc_fcn, flags)) != 0) {
  423. DB_ERROR("Db::stat", err, error_policy());
  424. return (err);
  425. }
  426. return (0);
  427. }
  428. int Db::sync(u_int32_t flags)
  429. {
  430. int err;
  431. DB *db = unwrap(this);
  432. if (!db) {
  433. DB_ERROR("Db::sync", EINVAL, error_policy());
  434. return (EINVAL);
  435. }
  436. if ((err = db->sync(db, flags)) != 0 && err != DB_INCOMPLETE) {
  437. DB_ERROR("Db::sync", err, error_policy());
  438. return (err);
  439. }
  440. return (err);
  441. }
  442. int Db::upgrade(const char *name, u_int32_t flags)
  443. {
  444. int err;
  445. DB *db = unwrap(this);
  446. if (!db) {
  447. DB_ERROR("Db::upgrade", EINVAL, error_policy());
  448. return (EINVAL);
  449. }
  450. if ((err = db->upgrade(db, name, flags)) != 0) {
  451. DB_ERROR("Db::upgrade", err, error_policy());
  452. return (err);
  453. }
  454. return (0);
  455. }
  456. static int _verify_callback_cxx(void *handle, const void *str_arg)
  457. {
  458. char *str;
  459. ostream *out;
  460. str = (char *)str_arg;
  461. out = (ostream *)handle;
  462. (*out) << str;
  463. if (out->fail())
  464. return (EIO);
  465. return (0);
  466. }
  467. // This is a 'glue' function declared as extern "C" so it will
  468. // be compatible with picky compilers that do not allow mixing
  469. // of function pointers to 'C' functions with function pointers
  470. // to C++ functions.
  471. //
  472. extern "C"
  473. int _verify_callback_c(void *handle, const void *str_arg)
  474. {
  475. return (_verify_callback_cxx(handle, str_arg));
  476. }
  477. int Db::verify(const char *name, const char *subdb,
  478.        ostream *ostr, u_int32_t flags)
  479. {
  480. int err;
  481. DB *db = unwrap(this);
  482. if (!db) {
  483. DB_ERROR("Db::verify", EINVAL, error_policy());
  484. return (EINVAL);
  485. }
  486. if ((err = __db_verify_internal(db, name, subdb, ostr,
  487. _verify_callback_c, flags)) != 0) {
  488. DB_ERROR("Db::verify", err, error_policy());
  489. return (err);
  490. }
  491. return (0);
  492. }
  493. // This is a variant of the DB_WO_ACCESS macro to define a simple set_
  494. // method calling the underlying C method, but unlike a simple
  495. // set method, it may return an error or raise an exception.
  496. // Note this macro expects that input _argspec is an argument
  497. // list element (e.g. "char *arg") defined in terms of "arg".
  498. //
  499. #define DB_DB_ACCESS(_name, _argspec)                          
  500. int Db::set_##_name(_argspec)                                  
  501. {                                                              
  502. int ret;                                               
  503. DB *db = unwrap(this);                                 
  504.        
  505. if ((ret = (*(db->set_##_name))(db, arg)) != 0) {      
  506. DB_ERROR("Db::set_" # _name, ret, error_policy()); 
  507. }                                                      
  508. return (ret);                                          
  509. }
  510. #define DB_DB_ACCESS_NORET(_name, _argspec)                    
  511.        
  512. void Db::set_##_name(_argspec)                                 
  513. {                                                              
  514. DB *db = unwrap(this);                                 
  515.        
  516. (*(db->set_##_name))(db, arg);                         
  517. return;                                                
  518. }
  519. DB_DB_ACCESS(bt_compare, bt_compare_fcn_type arg)
  520. DB_DB_ACCESS(bt_maxkey, u_int32_t arg)
  521. DB_DB_ACCESS(bt_minkey, u_int32_t arg)
  522. DB_DB_ACCESS(bt_prefix, bt_prefix_fcn_type arg)
  523. DB_DB_ACCESS(dup_compare, dup_compare_fcn_type arg)
  524. DB_DB_ACCESS_NORET(errfile, FILE *arg)
  525. DB_DB_ACCESS_NORET(errpfx, const char *arg)
  526. DB_DB_ACCESS(flags, u_int32_t arg)
  527. DB_DB_ACCESS(h_ffactor, u_int32_t arg)
  528. DB_DB_ACCESS(h_hash, h_hash_fcn_type arg)
  529. DB_DB_ACCESS(h_nelem, u_int32_t arg)
  530. DB_DB_ACCESS(lorder, int arg)
  531. DB_DB_ACCESS(malloc, db_malloc_fcn_type arg)
  532. DB_DB_ACCESS(pagesize, u_int32_t arg)
  533. DB_DB_ACCESS(realloc, db_realloc_fcn_type arg)
  534. DB_DB_ACCESS(re_delim, int arg)
  535. DB_DB_ACCESS(re_len, u_int32_t arg)
  536. DB_DB_ACCESS(re_pad, int arg)
  537. DB_DB_ACCESS(re_source, char *arg)
  538. DB_DB_ACCESS(q_extentsize, u_int32_t arg)
  539. // Here are the set methods that don't fit the above mold.
  540. //
  541. void Db::set_errcall(void (*arg)(const char *, char *))
  542. {
  543. env_->set_errcall(arg);
  544. }
  545. int Db::set_cachesize(u_int32_t gbytes, u_int32_t bytes, int ncache)
  546. {
  547. int ret;
  548. DB *db = unwrap(this);
  549. if ((ret = (*(db->set_cachesize))(db, gbytes, bytes, ncache)) != 0) {
  550. DB_ERROR("Db::set_cachesize", ret, error_policy());
  551. }
  552. return (ret);
  553. }
  554. int Db::set_paniccall(void (*callback)(DbEnv *, int))
  555. {
  556. return (env_->set_paniccall(callback));
  557. }
  558. void Db::set_error_stream(ostream *error_stream)
  559. {
  560. env_->set_error_stream(error_stream);
  561. }
  562. ////////////////////////////////////////////////////////////////////////
  563. //                                                                    //
  564. //                            Dbc                                     //
  565. //                                                                    //
  566. ////////////////////////////////////////////////////////////////////////
  567. // It's private, and should never be called, but VC4.0 needs it resolved
  568. //
  569. Dbc::~Dbc()
  570. {
  571. }
  572. int Dbc::close()
  573. {
  574. DBC *cursor = this;
  575. int err;
  576. if ((err = cursor->c_close(cursor)) != 0) {
  577. DB_ERROR("Db::close", err, ON_ERROR_UNKNOWN);
  578. return (err);
  579. }
  580. return (0);
  581. }
  582. int Dbc::count(db_recno_t *countp, u_int32_t flags_arg)
  583. {
  584. DBC *cursor = this;
  585. int err;
  586. if ((err = cursor->c_count(cursor, countp, flags_arg)) != 0) {
  587. DB_ERROR("Db::count", err, ON_ERROR_UNKNOWN);
  588. return (err);
  589. }
  590. return (0);
  591. }
  592. int Dbc::del(u_int32_t flags_arg)
  593. {
  594. DBC *cursor = this;
  595. int err;
  596. if ((err = cursor->c_del(cursor, flags_arg)) != 0) {
  597. // DB_KEYEMPTY is a "normal" return, so should not be
  598. // thrown as an error
  599. //
  600. if (err != DB_KEYEMPTY) {
  601. DB_ERROR("Db::del", err, ON_ERROR_UNKNOWN);
  602. return (err);
  603. }
  604. }
  605. return (err);
  606. }
  607. int Dbc::dup(Dbc** cursorp, u_int32_t flags_arg)
  608. {
  609. DBC *cursor = this;
  610. DBC *new_cursor = 0;
  611. int err;
  612. if ((err = cursor->c_dup(cursor, &new_cursor, flags_arg)) != 0) {
  613. DB_ERROR("Db::dup", err, ON_ERROR_UNKNOWN);
  614. return (err);
  615. }
  616. // The following cast implies that Dbc can be no larger than DBC
  617. *cursorp = (Dbc*)new_cursor;
  618. return (0);
  619. }
  620. int Dbc::get(Dbt* key, Dbt *data, u_int32_t flags_arg)
  621. {
  622. DBC *cursor = this;
  623. int err;
  624. if ((err = cursor->c_get(cursor, key, data, flags_arg)) != 0) {
  625. // DB_NOTFOUND and DB_KEYEMPTY are "normal" returns,
  626. // so should not be thrown as an error
  627. //
  628. if (err != DB_NOTFOUND && err != DB_KEYEMPTY) {
  629. DB_ERROR("Db::get", err, ON_ERROR_UNKNOWN);
  630. return (err);
  631. }
  632. }
  633. return (err);
  634. }
  635. int Dbc::put(Dbt* key, Dbt *data, u_int32_t flags_arg)
  636. {
  637. DBC *cursor = this;
  638. int err;
  639. if ((err = cursor->c_put(cursor, key, data, flags_arg)) != 0) {
  640. // DB_KEYEXIST is a "normal" return, so should not be
  641. // thrown as an error
  642. //
  643. if (err != DB_KEYEXIST) {
  644. DB_ERROR("Db::put", err, ON_ERROR_UNKNOWN);
  645. return (err);
  646. }
  647. }
  648. return (err);
  649. }
  650. ////////////////////////////////////////////////////////////////////////
  651. //                                                                    //
  652. //                            Dbt                                 //
  653. //                                                                    //
  654. ////////////////////////////////////////////////////////////////////////
  655. Dbt::Dbt()
  656. {
  657. DBT *dbt = this;
  658. memset(dbt, 0, sizeof(DBT));
  659. }
  660. Dbt::Dbt(void *data_arg, size_t size_arg)
  661. {
  662. DBT *dbt = this;
  663. memset(dbt, 0, sizeof(DBT));
  664. set_data(data_arg);
  665. set_size(size_arg);
  666. }
  667. Dbt::~Dbt()
  668. {
  669. }
  670. Dbt::Dbt(const Dbt &that)
  671. {
  672. const DBT *from = &that;
  673. DBT *to = this;
  674. memcpy(to, from, sizeof(DBT));
  675. }
  676. Dbt &Dbt::operator = (const Dbt &that)
  677. {
  678. if (this != &that) {
  679. const DBT *from = &that;
  680. DBT *to = this;
  681. memcpy(to, from, sizeof(DBT));
  682. }
  683. return (*this);
  684. }
  685. DB_RW_ACCESS(Dbt, void *, data, data)
  686. DB_RW_ACCESS(Dbt, u_int32_t, size, size)
  687. DB_RW_ACCESS(Dbt, u_int32_t, ulen, ulen)
  688. DB_RW_ACCESS(Dbt, u_int32_t, dlen, dlen)
  689. DB_RW_ACCESS(Dbt, u_int32_t, doff, doff)
  690. DB_RW_ACCESS(Dbt, u_int32_t, flags, flags)