00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00026 #ifndef HAM_HAMSTERDB_HPP__
00027 #define HAM_HAMSTERDB_HPP__
00028
00029 #include <ham/hamsterdb.h>
00030 #include <ham/hamsterdb_int.h>
00031 #include <cstring>
00032 #include <vector>
00033
00034 #if defined(_MSC_VER) && defined(_DEBUG) && !defined(_CRTDBG_MAP_ALLOC) && !defined(UNDER_CE)
00035 #define _CRTDBG_MAP_ALLOC
00036 #include <crtdbg.h>
00037 #endif
00038
00047 namespace ham {
00048
00049
00050
00051
00052 class txn;
00053 class db;
00054 class env;
00055
00061 class error {
00062 public:
00064 error(ham_status_t st) : m_errno(st) {
00065 };
00066
00068 ham_status_t get_errno() const {
00069 return (m_errno);
00070 }
00071
00073 const char *get_string() const {
00074 return (ham_strerror(m_errno));
00075 }
00076
00077 private:
00078 ham_status_t m_errno;
00079 };
00080
00086 class key {
00087 public:
00089 key(void *data=0, ham_size_t size=0, ham_u32_t flags=0) {
00090 memset(&m_key, 0, sizeof(m_key));
00091 m_key.data=data;
00092 m_key.size=(ham_u16_t)size;
00093 m_key.flags=flags;
00094 if (m_key.size != size)
00095 throw error(HAM_INV_KEYSIZE);
00096 }
00097
00099 key(const key &other) : m_key(other.m_key) {
00100 }
00101
00103 key &operator=(const key &other)
00104 {
00105
00106 if (&other != this)
00107 {
00108 m_key=other.m_key;
00109 }
00110 return (*this);
00111 }
00112
00114 void *get_data() const {
00115 return (m_key.data);
00116 }
00117
00119 void set_data(void *data) {
00120 m_key.data=data;
00121 }
00122
00124 ham_size_t get_size() const {
00125 return (m_key.size);
00126 }
00127
00129 void set_size(ham_size_t size) {
00130 m_key.size=(ham_u16_t)size;
00131 if (m_key.size != size)
00132 throw error(HAM_INV_KEYSIZE);
00133 }
00134
00136 template <class T>
00137 void set(T &t) {
00138 set_data(&t);
00139 set_size(sizeof(t));
00140 }
00141
00143 ham_u32_t get_flags() const {
00144 return (m_key.flags);
00145 }
00146
00148 void set_flags(ham_u32_t flags) {
00149 m_key.flags=flags;
00150 }
00151
00153 ham_key_t *get_handle() {
00154 return (&m_key);
00155 }
00156
00158 int get_approximate_match_type() {
00159 return (ham_key_get_approximate_match_type(&m_key));
00160 }
00161
00162
00163 private:
00164 ham_key_t m_key;
00165 };
00166
00172 class record {
00173 public:
00175 record(void *data=0, ham_size_t size=0, ham_u32_t flags=0) {
00176 memset(&m_rec, 0, sizeof(m_rec));
00177 m_rec.data=data;
00178 m_rec.size=size;
00179 m_rec.flags=flags;
00180 }
00181
00183 record(const record &other) : m_rec(other.m_rec) {
00184 }
00185
00187 record &operator=(const record &other) {
00188 m_rec=other.m_rec;
00189 return (*this);
00190 }
00191
00193 void *get_data() const {
00194 return (m_rec.data);
00195 }
00196
00198 void set_data(void *data) {
00199 m_rec.data=data;
00200 }
00201
00203 ham_size_t get_size() const {
00204 return (m_rec.size);
00205 }
00206
00208 void set_size(ham_size_t size) {
00209 m_rec.size=size;
00210 }
00211
00213 ham_u32_t get_flags() const {
00214 return (m_rec.flags);
00215 }
00216
00218 void set_flags(ham_u32_t flags) {
00219 m_rec.flags=flags;
00220 }
00221
00223 ham_record_t *get_handle() {
00224 return (&m_rec);
00225 }
00226
00227 protected:
00228 ham_record_t m_rec;
00229 };
00230
00231
00237 class txn {
00238 public:
00240 txn(ham_txn_t *t=0) : m_txn(t) {
00241 }
00242
00244 void abort() {
00245 ham_status_t st;
00246 st=ham_txn_abort(m_txn, 0);
00247 if (st)
00248 throw error(st);
00249 }
00250
00252 void commit() {
00253 ham_status_t st;
00254 st=ham_txn_commit(m_txn, 0);
00255 if (st)
00256 throw error(st);
00257 }
00258
00260 ham_txn_t *get_handle() {
00261 return (m_txn);
00262 }
00263
00264 protected:
00265 ham_txn_t *m_txn;
00266 };
00267
00268
00274 class db
00275 {
00276 public:
00278 static void set_errhandler(ham_errhandler_fun f) {
00279 ham_set_errhandler(f);
00280 }
00281
00283 static void get_version(ham_u32_t *major, ham_u32_t *minor,
00284 ham_u32_t *revision) {
00285 ham_get_version(major, minor, revision);
00286 }
00287
00289 static void get_license(const char **licensee, const char **product) {
00290 ham_get_license(licensee, product);
00291 }
00292
00294 db() : m_db(0) {
00295 }
00296
00298 ~db() {
00299 close();
00300 }
00301
00308 db &operator=(const db &other) {
00309 db &rhs=(db &)other;
00310 if (this==&other)
00311 return (*this);
00312 close();
00313 m_db=rhs.m_db;
00314 rhs.m_db=0;
00315 return (*this);
00316 }
00317
00319 void create(const char *filename, ham_u32_t flags=0,
00320 ham_u32_t mode=0644, const ham_parameter_t *param=0) {
00321 ham_status_t st;
00322 if (!m_db) {
00323 st=ham_new(&m_db);
00324 if (st)
00325 throw error(st);
00326 }
00327 st=ham_create_ex(m_db, filename, flags, mode, param);
00328 if (st)
00329 throw error(st);
00330 }
00331
00333 void open(const char *filename, ham_u32_t flags=0,
00334 const ham_parameter_t *param=0) {
00335 ham_status_t st;
00336 if (!m_db) {
00337 st=ham_new(&m_db);
00338 if (st)
00339 throw error(st);
00340 }
00341 st=ham_open_ex(m_db, filename, flags, param);
00342 if (st)
00343 throw error(st);
00344 }
00345
00347 ham_status_t get_error() {
00348 if (!m_db)
00349 return (HAM_NOT_INITIALIZED);
00350 return (ham_get_error(m_db));
00351 }
00352
00354 txn begin() {
00355 ham_txn_t *h;
00356 ham_status_t st=ham_txn_begin(&h, get_handle(), 0);
00357 if (st)
00358 throw error(st);
00359 return (txn(h));
00360 }
00361
00363 void set_prefix_compare_func(ham_prefix_compare_func_t foo) {
00364 ham_status_t st=ham_set_prefix_compare_func(m_db, foo);
00365 if (st)
00366 throw error(st);
00367 }
00368
00370 void set_compare_func(ham_compare_func_t foo) {
00371 ham_status_t st=ham_set_compare_func(m_db, foo);
00372 if (st)
00373 throw error(st);
00374 }
00375
00377 void enable_compression(ham_u32_t level, ham_u32_t flags=0) {
00378 ham_status_t st=ham_enable_compression(m_db, level, flags);
00379 if (st)
00380 throw error(st);
00381 }
00382
00384 record find(txn *t, key *k, ham_u32_t flags=0) {
00385 record r;
00386 ham_status_t st=ham_find(m_db,
00387 t ? t->get_handle() : 0,
00388 k ? k->get_handle() : 0,
00389 r.get_handle(), flags);
00390 if (st)
00391 throw error(st);
00392 return (r);
00393 }
00394
00396 record find(key *k, ham_u32_t flags=0) {
00397 return (find(0, k, flags));
00398 }
00399
00401 void insert(txn *t, key *k, record *r, ham_u32_t flags=0) {
00402 ham_status_t st=ham_insert(m_db,
00403 t ? t->get_handle() : 0,
00404 k ? k->get_handle() : 0,
00405 r ? r->get_handle() : 0, flags);
00406 if (st)
00407 throw error(st);
00408 }
00409
00411 void insert(key *k, record *r, ham_u32_t flags=0) {
00412 insert(0, k, r, flags);
00413 }
00414
00416 void erase(key *k, ham_u32_t flags=0) {
00417 erase(0, k, flags);
00418 }
00419
00421 void erase(txn *t, key *k, ham_u32_t flags=0) {
00422 ham_status_t st=ham_erase(m_db,
00423 t ? t->get_handle() : 0,
00424 k ? k->get_handle() : 0, flags);
00425 if (st)
00426 throw error(st);
00427 }
00428
00430 void flush(ham_u32_t flags=0) {
00431 ham_status_t st=ham_flush(m_db, flags);
00432 if (st)
00433 throw error(st);
00434 }
00435
00437 ham_u64_t get_key_count(ham_txn_t *txn=0, ham_u32_t flags=0) {
00438 ham_u64_t count=0;
00439 ham_status_t st=ham_get_key_count(m_db, txn, flags, &count);
00440 if (st)
00441 throw error(st);
00442 return (count);
00443 }
00444
00446 void get_parameters(ham_parameter_t *param) {
00447 ham_status_t st=ham_get_parameters(m_db, param);
00448 if (st)
00449 throw error(st);
00450 }
00451
00453 void close(ham_u32_t flags=0) {
00454 if (!m_db)
00455 return;
00456 ham_status_t st=ham_close(m_db, flags);
00457 if (st)
00458 throw error(st);
00459 st=ham_delete(m_db);
00460 if (st)
00461 throw error(st);
00462 m_db=0;
00463 }
00464
00466 ham_db_t *get_handle() {
00467 return (m_db);
00468 }
00469
00470 protected:
00471 friend class env;
00472
00473
00474 db(ham_db_t *db) : m_db(db) {
00475 }
00476
00477 private:
00478 ham_db_t *m_db;
00479 };
00480
00481
00487 class cursor
00488 {
00489 public:
00491 cursor(db *db=0, txn *t=0, ham_u32_t flags=0)
00492 : m_cursor(0) {
00493 create(db, t, flags);
00494 }
00495
00497 cursor(txn *t, db *db=0, ham_u32_t flags=0)
00498 : m_cursor(0) {
00499 create(db, t, flags);
00500 }
00501
00503 ~cursor() {
00504 close();
00505 }
00506
00508 void create(db *db, txn *t=0, ham_u32_t flags=0) {
00509 if (m_cursor)
00510 close();
00511 if (db) {
00512 ham_status_t st=ham_cursor_create(db->get_handle(),
00513 t ? t->get_handle() : 0,
00514 flags, &m_cursor);
00515 if (st)
00516 throw error(st);
00517 }
00518 }
00519
00521 cursor clone() {
00522 ham_cursor_t *dest;
00523 ham_status_t st=ham_cursor_clone(m_cursor, &dest);
00524 if (st)
00525 throw error(st);
00526 return (cursor(dest));
00527 }
00528
00530 void move(key *k, record *r, ham_u32_t flags=0) {
00531 ham_status_t st=ham_cursor_move(m_cursor, k ? k->get_handle() : 0,
00532 r ? r->get_handle() : 0, flags);
00533 if (st)
00534 throw error(st);
00535 }
00536
00538 void move_first(key *k=0, record *r=0) {
00539 move(k, r, HAM_CURSOR_FIRST);
00540 }
00541
00543 void move_last(key *k=0, record *r=0) {
00544 move(k, r, HAM_CURSOR_LAST);
00545 }
00546
00548 void move_next(key *k=0, record *r=0) {
00549 move(k, r, HAM_CURSOR_NEXT);
00550 }
00551
00553 void move_previous(key *k=0, record *r=0) {
00554 move(k, r, HAM_CURSOR_PREVIOUS);
00555 }
00556
00558 void overwrite(record *r, ham_u32_t flags=0) {
00559 ham_status_t st=ham_cursor_overwrite(m_cursor,
00560 r ? r->get_handle() : 0, flags);
00561 if (st)
00562 throw error(st);
00563 }
00564
00566 void find(key *k, ham_u32_t flags=0) {
00567 ham_status_t st=ham_cursor_find(m_cursor, k->get_handle(), flags);
00568 if (st)
00569 throw error(st);
00570 }
00571
00573 void find_ex(key *k, record *r, ham_u32_t flags=0) {
00574 ham_status_t st=ham_cursor_find_ex(m_cursor, k->get_handle(),
00575 (r ? r->get_handle() : 0), flags);
00576 if (st)
00577 throw error(st);
00578 }
00579
00581 void insert(key *k, record *r, ham_u32_t flags=0) {
00582 ham_status_t st=ham_cursor_insert(m_cursor, k ? k->get_handle() : 0,
00583 r ? r->get_handle() : 0, flags);
00584 if (st)
00585 throw error(st);
00586 }
00587
00589 void erase(ham_u32_t flags=0) {
00590 ham_status_t st=ham_cursor_erase(m_cursor, flags);
00591 if (st)
00592 throw error(st);
00593 }
00594
00596 ham_u32_t get_duplicate_count(ham_u32_t flags=0) {
00597 ham_u32_t c;
00598 ham_status_t st=ham_cursor_get_duplicate_count(m_cursor, &c, flags);
00599 if (st)
00600 throw error(st);
00601 return (c);
00602 }
00603
00605 void close() {
00606 if (!m_cursor)
00607 return;
00608 ham_status_t st=ham_cursor_close(m_cursor);
00609 if (st)
00610 throw error(st);
00611 m_cursor=0;
00612 }
00613
00614 protected:
00615
00616 cursor(ham_cursor_t *c) {
00617 m_cursor=c;
00618 }
00619
00620 private:
00621 ham_cursor_t *m_cursor;
00622 };
00623
00629 class env
00630 {
00631 public:
00633 env() : m_env(0) {
00634 }
00635
00637 ~env() {
00638 close();
00639 }
00640
00642 void create(const char *filename, ham_u32_t flags=0,
00643 ham_u32_t mode=0644, const ham_parameter_t *param=0) {
00644 ham_status_t st;
00645 if (!m_env) {
00646 st=ham_env_new(&m_env);
00647 if (st)
00648 throw error(st);
00649 }
00650 st=ham_env_create_ex(m_env, filename, flags, mode, param);
00651 if (st)
00652 throw error(st);
00653 }
00654
00656 void open(const char *filename, ham_u32_t flags=0,
00657 const ham_parameter_t *param=0) {
00658 ham_status_t st;
00659 if (!m_env) {
00660 st=ham_env_new(&m_env);
00661 if (st)
00662 throw error(st);
00663 }
00664 st=ham_env_open_ex(m_env, filename, flags, param);
00665 if (st)
00666 throw error(st);
00667 }
00668
00670 db create_db(ham_u16_t name, ham_u32_t flags=0,
00671 const ham_parameter_t *param=0) {
00672 ham_status_t st;
00673 ham_db_t *dbh;
00674
00675 st=ham_new(&dbh);
00676 if (st)
00677 throw error(st);
00678 st=ham_env_create_db(m_env, dbh, name, flags, param);
00679 if (st) {
00680 ham_delete(dbh);
00681 throw error(st);
00682 }
00683
00684 return (ham::db(dbh));
00685 }
00686
00688 db open_db(ham_u16_t name, ham_u32_t flags=0,
00689 const ham_parameter_t *param=0) {
00690 ham_status_t st;
00691 ham_db_t *dbh;
00692
00693 st=ham_new(&dbh);
00694 if (st)
00695 throw error(st);
00696 st=ham_env_open_db(m_env, dbh, name, flags, param);
00697 if (st) {
00698 ham_delete(dbh);
00699 throw error(st);
00700 }
00701
00702 return (ham::db(dbh));
00703 }
00704
00706 void rename_db(ham_u16_t oldname, ham_u16_t newname, ham_u32_t flags=0) {
00707 ham_status_t st=ham_env_rename_db(m_env, oldname, newname, flags);
00708 if (st)
00709 throw error(st);
00710 }
00711
00713 void erase_db(ham_u16_t name, ham_u32_t flags=0) {
00714 ham_status_t st=ham_env_erase_db(m_env, name, flags);
00715 if (st)
00716 throw error(st);
00717 }
00718
00722 void close(void) {
00723 if (!m_env)
00724 return;
00725 ham_status_t st=ham_env_close(m_env, 0);
00726 if (st)
00727 throw error(st);
00728 st=ham_env_delete(m_env);
00729 if (st)
00730 throw error(st);
00731 m_env=0;
00732 }
00733
00735 void get_parameters(ham_parameter_t *param) {
00736 ham_status_t st=ham_env_get_parameters(m_env, param);
00737 if (st)
00738 throw error(st);
00739 }
00740
00742 void enable_encryption(ham_u8_t key[16], ham_u32_t flags=0) {
00743 ham_status_t st=ham_env_enable_encryption(m_env, key, flags);
00744 if (st)
00745 throw error(st);
00746 }
00747
00749 std::vector<ham_u16_t> get_database_names(void) {
00750 ham_size_t count=32;
00751 ham_status_t st;
00752 std::vector<ham_u16_t> v(count);
00753
00754 for(;;) {
00755 st=ham_env_get_database_names(m_env, &v[0], &count);
00756 if (!st)
00757 break;
00758 if (st && st!=HAM_LIMITS_REACHED)
00759 throw error(st);
00760 count+=16;
00761 v.resize(count);
00762 }
00763
00764 v.resize(count);
00765 return (v);
00766 }
00767
00768 private:
00769 ham_env_t *m_env;
00770 };
00771
00772 };
00773
00778 #endif // HAMSTERDB_HPP__