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 db *m_db;
00267 };
00268
00269
00275 class db
00276 {
00277 public:
00279 static void set_errhandler(ham_errhandler_fun f) {
00280 ham_set_errhandler(f);
00281 }
00282
00284 static void get_version(ham_u32_t *major, ham_u32_t *minor,
00285 ham_u32_t *revision) {
00286 ham_get_version(major, minor, revision);
00287 }
00288
00290 static void get_license(const char **licensee, const char **product) {
00291 ham_get_license(licensee, product);
00292 }
00293
00295 db() : m_db(0) {
00296 }
00297
00299 ~db() {
00300 close();
00301 }
00302
00309 db &operator=(const db &other) {
00310 db &rhs=(db &)other;
00311 if (this==&other)
00312 return (*this);
00313 close();
00314 m_db=rhs.m_db;
00315 rhs.m_db=0;
00316 return (*this);
00317 }
00318
00320 void create(const char *filename, ham_u32_t flags=0,
00321 ham_u32_t mode=0644, const ham_parameter_t *param=0) {
00322 ham_status_t st;
00323 if (!m_db) {
00324 st=ham_new(&m_db);
00325 if (st)
00326 throw error(st);
00327 }
00328 st=ham_create_ex(m_db, filename, flags, mode, param);
00329 if (st)
00330 throw error(st);
00331 }
00332
00334 void open(const char *filename, ham_u32_t flags=0,
00335 const ham_parameter_t *param=0) {
00336 ham_status_t st;
00337 if (!m_db) {
00338 st=ham_new(&m_db);
00339 if (st)
00340 throw error(st);
00341 }
00342 st=ham_open_ex(m_db, filename, flags, param);
00343 if (st)
00344 throw error(st);
00345 }
00346
00348 ham_status_t get_error() {
00349 if (!m_db)
00350 return (HAM_NOT_INITIALIZED);
00351 return (ham_get_error(m_db));
00352 }
00353
00355 txn begin() {
00356 ham_txn_t *h;
00357 ham_status_t st=ham_txn_begin(&h, get_handle(), 0);
00358 if (st)
00359 throw error(st);
00360 return (txn(h));
00361 }
00362
00364 void set_prefix_compare_func(ham_prefix_compare_func_t foo) {
00365 ham_status_t st=ham_set_prefix_compare_func(m_db, foo);
00366 if (st)
00367 throw error(st);
00368 }
00369
00371 void set_compare_func(ham_compare_func_t foo) {
00372 ham_status_t st=ham_set_compare_func(m_db, foo);
00373 if (st)
00374 throw error(st);
00375 }
00376
00378 void enable_compression(ham_u32_t level, ham_u32_t flags=0) {
00379 ham_status_t st=ham_enable_compression(m_db, level, flags);
00380 if (st)
00381 throw error(st);
00382 }
00383
00385 record find(txn *t, key *k, ham_u32_t flags=0) {
00386 record r;
00387 ham_status_t st=ham_find(m_db,
00388 t ? t->get_handle() : 0,
00389 k ? k->get_handle() : 0,
00390 r.get_handle(), flags);
00391 if (st)
00392 throw error(st);
00393 return (r);
00394 }
00395
00397 record find(key *k, ham_u32_t flags=0) {
00398 return (find(0, k, flags));
00399 }
00400
00402 void insert(txn *t, key *k, record *r, ham_u32_t flags=0) {
00403 ham_status_t st=ham_insert(m_db,
00404 t ? t->get_handle() : 0,
00405 k ? k->get_handle() : 0,
00406 r ? r->get_handle() : 0, flags);
00407 if (st)
00408 throw error(st);
00409 }
00410
00412 void insert(key *k, record *r, ham_u32_t flags=0) {
00413 insert(0, k, r, flags);
00414 }
00415
00417 void erase(key *k, ham_u32_t flags=0) {
00418 erase(0, k, flags);
00419 }
00420
00422 void erase(txn *t, key *k, ham_u32_t flags=0) {
00423 ham_status_t st=ham_erase(m_db,
00424 t ? t->get_handle() : 0,
00425 k ? k->get_handle() : 0, flags);
00426 if (st)
00427 throw error(st);
00428 }
00429
00431 void flush(ham_u32_t flags=0) {
00432 ham_status_t st=ham_flush(m_db, flags);
00433 if (st)
00434 throw error(st);
00435 }
00436
00438 ham_u64_t get_key_count(ham_txn_t *txn=0, ham_u32_t flags=0) {
00439 ham_u64_t count=0;
00440 ham_status_t st=ham_get_key_count(m_db, txn, flags, &count);
00441 if (st)
00442 throw error(st);
00443 return (count);
00444 }
00445
00447 void get_parameters(ham_parameter_t *param) {
00448 ham_status_t st=ham_get_parameters(m_db, param);
00449 if (st)
00450 throw error(st);
00451 }
00452
00454 void close(ham_u32_t flags=0) {
00455 if (!m_db)
00456 return;
00457 ham_status_t st=ham_close(m_db, flags);
00458 if (st)
00459 throw error(st);
00460 st=ham_delete(m_db);
00461 if (st)
00462 throw error(st);
00463 m_db=0;
00464 }
00465
00467 ham_db_t *get_handle() {
00468 return (m_db);
00469 }
00470
00471 protected:
00472 friend class env;
00473
00474
00475 db(ham_db_t *db) : m_db(db) {
00476 }
00477
00478 private:
00479 ham_db_t *m_db;
00480 };
00481
00482
00488 class cursor
00489 {
00490 public:
00492 cursor(db *db=0, txn *t=0, ham_u32_t flags=0)
00493 : m_cursor(0) {
00494 create(db, t, flags);
00495 }
00496
00498 cursor(txn *t, db *db=0, ham_u32_t flags=0)
00499 : m_cursor(0) {
00500 create(db, t, flags);
00501 }
00502
00504 ~cursor() {
00505 close();
00506 }
00507
00509 void create(db *db, txn *t=0, ham_u32_t flags=0) {
00510 if (m_cursor)
00511 close();
00512 if (db) {
00513 ham_status_t st=ham_cursor_create(db->get_handle(),
00514 t ? t->get_handle() : 0,
00515 flags, &m_cursor);
00516 if (st)
00517 throw error(st);
00518 }
00519 }
00520
00522 cursor clone() {
00523 ham_cursor_t *dest;
00524 ham_status_t st=ham_cursor_clone(m_cursor, &dest);
00525 if (st)
00526 throw error(st);
00527 return (cursor(dest));
00528 }
00529
00531 void move(key *k, record *r, ham_u32_t flags=0) {
00532 ham_status_t st=ham_cursor_move(m_cursor, k ? k->get_handle() : 0,
00533 r ? r->get_handle() : 0, flags);
00534 if (st)
00535 throw error(st);
00536 }
00537
00539 void move_first(key *k=0, record *r=0) {
00540 move(k, r, HAM_CURSOR_FIRST);
00541 }
00542
00544 void move_last(key *k=0, record *r=0) {
00545 move(k, r, HAM_CURSOR_LAST);
00546 }
00547
00549 void move_next(key *k=0, record *r=0) {
00550 move(k, r, HAM_CURSOR_NEXT);
00551 }
00552
00554 void move_previous(key *k=0, record *r=0) {
00555 move(k, r, HAM_CURSOR_PREVIOUS);
00556 }
00557
00559 void overwrite(record *r, ham_u32_t flags=0) {
00560 ham_status_t st=ham_cursor_overwrite(m_cursor,
00561 r ? r->get_handle() : 0, flags);
00562 if (st)
00563 throw error(st);
00564 }
00565
00567 void find(key *k, ham_u32_t flags=0) {
00568 ham_status_t st=ham_cursor_find(m_cursor, k->get_handle(), flags);
00569 if (st)
00570 throw error(st);
00571 }
00572
00574 void find_ex(key *k, record *r, ham_u32_t flags=0) {
00575 ham_status_t st=ham_cursor_find_ex(m_cursor, k->get_handle(),
00576 (r ? r->get_handle() : 0), flags);
00577 if (st)
00578 throw error(st);
00579 }
00580
00582 void insert(key *k, record *r, ham_u32_t flags=0) {
00583 ham_status_t st=ham_cursor_insert(m_cursor, k ? k->get_handle() : 0,
00584 r ? r->get_handle() : 0, flags);
00585 if (st)
00586 throw error(st);
00587 }
00588
00590 void erase(ham_u32_t flags=0) {
00591 ham_status_t st=ham_cursor_erase(m_cursor, flags);
00592 if (st)
00593 throw error(st);
00594 }
00595
00597 ham_u32_t get_duplicate_count(ham_u32_t flags=0) {
00598 ham_u32_t c;
00599 ham_status_t st=ham_cursor_get_duplicate_count(m_cursor, &c, flags);
00600 if (st)
00601 throw error(st);
00602 return (c);
00603 }
00604
00606 void close() {
00607 if (!m_cursor)
00608 return;
00609 ham_status_t st=ham_cursor_close(m_cursor);
00610 if (st)
00611 throw error(st);
00612 m_cursor=0;
00613 }
00614
00615 protected:
00616
00617 cursor(ham_cursor_t *c) {
00618 m_cursor=c;
00619 }
00620
00621 private:
00622 ham_cursor_t *m_cursor;
00623 };
00624
00630 class env
00631 {
00632 public:
00634 env() : m_env(0) {
00635 }
00636
00638 ~env() {
00639 close();
00640 }
00641
00643 void create(const char *filename, ham_u32_t flags=0,
00644 ham_u32_t mode=0644, const ham_parameter_t *param=0) {
00645 ham_status_t st;
00646 if (!m_env) {
00647 st=ham_env_new(&m_env);
00648 if (st)
00649 throw error(st);
00650 }
00651 st=ham_env_create_ex(m_env, filename, flags, mode, param);
00652 if (st)
00653 throw error(st);
00654 }
00655
00657 void open(const char *filename, ham_u32_t flags=0,
00658 const ham_parameter_t *param=0) {
00659 ham_status_t st;
00660 if (!m_env) {
00661 st=ham_env_new(&m_env);
00662 if (st)
00663 throw error(st);
00664 }
00665 st=ham_env_open_ex(m_env, filename, flags, param);
00666 if (st)
00667 throw error(st);
00668 }
00669
00671 db create_db(ham_u16_t name, ham_u32_t flags=0,
00672 const ham_parameter_t *param=0) {
00673 ham_status_t st;
00674 ham_db_t *dbh;
00675
00676 st=ham_new(&dbh);
00677 if (st)
00678 throw error(st);
00679 st=ham_env_create_db(m_env, dbh, name, flags, param);
00680 if (st) {
00681 ham_delete(dbh);
00682 throw error(st);
00683 }
00684
00685 return (ham::db(dbh));
00686 }
00687
00689 db open_db(ham_u16_t name, ham_u32_t flags=0,
00690 const ham_parameter_t *param=0) {
00691 ham_status_t st;
00692 ham_db_t *dbh;
00693
00694 st=ham_new(&dbh);
00695 if (st)
00696 throw error(st);
00697 st=ham_env_open_db(m_env, dbh, name, flags, param);
00698 if (st) {
00699 ham_delete(dbh);
00700 throw error(st);
00701 }
00702
00703 return (ham::db(dbh));
00704 }
00705
00707 void rename_db(ham_u16_t oldname, ham_u16_t newname, ham_u32_t flags=0) {
00708 ham_status_t st=ham_env_rename_db(m_env, oldname, newname, flags);
00709 if (st)
00710 throw error(st);
00711 }
00712
00714 void erase_db(ham_u16_t name, ham_u32_t flags=0) {
00715 ham_status_t st=ham_env_erase_db(m_env, name, flags);
00716 if (st)
00717 throw error(st);
00718 }
00719
00723 void close(void) {
00724 if (!m_env)
00725 return;
00726 ham_status_t st=ham_env_close(m_env, 0);
00727 if (st)
00728 throw error(st);
00729 st=ham_env_delete(m_env);
00730 if (st)
00731 throw error(st);
00732 m_env=0;
00733 }
00734
00736 void get_parameters(ham_parameter_t *param) {
00737 ham_status_t st=ham_env_get_parameters(m_env, param);
00738 if (st)
00739 throw error(st);
00740 }
00741
00743 void enable_encryption(ham_u8_t key[16], ham_u32_t flags=0) {
00744 ham_status_t st=ham_env_enable_encryption(m_env, key, flags);
00745 if (st)
00746 throw error(st);
00747 }
00748
00750 std::vector<ham_u16_t> get_database_names(void) {
00751 ham_size_t count=32;
00752 ham_status_t st;
00753 std::vector<ham_u16_t> v(count);
00754
00755 for(;;) {
00756 st=ham_env_get_database_names(m_env, &v[0], &count);
00757 if (!st)
00758 break;
00759 if (st && st!=HAM_LIMITS_REACHED)
00760 throw error(st);
00761 count+=16;
00762 v.resize(count);
00763 }
00764
00765 v.resize(count);
00766 return (v);
00767 }
00768
00769 private:
00770 ham_env_t *m_env;
00771 };
00772
00773 };
00774
00779 #endif // HAMSTERDB_HPP__