00001
00025 #ifndef HAM_HAMSTERDB_HPP__
00026 #define HAM_HAMSTERDB_HPP__
00027
00028 #include <ham/hamsterdb_int.h>
00029 #include <cstring>
00030 #include <vector>
00031
00040 namespace ham {
00041
00042
00043
00044
00045 class txn;
00046 class db;
00047 class env;
00048
00054 class error {
00055 public:
00057 error(ham_status_t st) : m_errno(st) {
00058 };
00059
00061 ham_status_t get_errno() const {
00062 return (m_errno);
00063 }
00064
00066 const char *get_string() const {
00067 return (ham_strerror(m_errno));
00068 }
00069
00070 private:
00071 ham_status_t m_errno;
00072 };
00073
00079 class key {
00080 public:
00082 key(void *data=0, ham_size_t size=0, ham_u32_t flags=0) {
00083 memset(&m_key, 0, sizeof(m_key));
00084 m_key.data=data;
00085 m_key.size=size;
00086 m_key.flags=flags;
00087 }
00088
00090 key(const key &other) : m_key(other.m_key) {
00091 }
00092
00094 key &operator=(const key &other) {
00095 m_key=other.m_key;
00096 return (*this);
00097 }
00098
00100 void *get_data() const {
00101 return (m_key.data);
00102 }
00103
00105 void set_data(void *data) {
00106 m_key.data=data;
00107 }
00108
00110 ham_size_t get_size() const {
00111 return (m_key.size);
00112 }
00113
00115 void set_size(ham_size_t size) {
00116 m_key.size=size;
00117 }
00118
00120 ham_u32_t get_flags() const {
00121 return (m_key.flags);
00122 }
00123
00125 void set_flags(ham_u32_t flags) {
00126 m_key.flags=flags;
00127 }
00128
00130 ham_key_t *get_handle() {
00131 return (&m_key);
00132 }
00133
00134 private:
00135 ham_key_t m_key;
00136 };
00137
00143 class record {
00144 public:
00146 record(void *data=0, ham_size_t size=0, ham_u32_t flags=0) {
00147 memset(&m_rec, 0, sizeof(m_rec));
00148 m_rec.data=data;
00149 m_rec.size=size;
00150 m_rec.flags=flags;
00151 }
00152
00154 record(const record &other) : m_rec(other.m_rec) {
00155 }
00156
00158 record &operator=(const record &other) {
00159 m_rec=other.m_rec;
00160 return (*this);
00161 }
00162
00164 void *get_data() const {
00165 return (m_rec.data);
00166 }
00167
00169 void set_data(void *data) {
00170 m_rec.data=data;
00171 }
00172
00174 ham_size_t get_size() const {
00175 return (m_rec.size);
00176 }
00177
00179 void set_size(ham_size_t size) {
00180 m_rec.size=size;
00181 }
00182
00184 ham_u32_t get_flags() const {
00185 return (m_rec.flags);
00186 }
00187
00189 void set_flags(ham_u32_t flags) {
00190 m_rec.flags=flags;
00191 }
00192
00194 ham_record_t *get_handle() {
00195 return (&m_rec);
00196 }
00197
00198 protected:
00199 ham_record_t m_rec;
00200 };
00201
00202
00208 class txn {
00209 public:
00211 txn(ham_txn_t *t=0) : m_txn(t) {
00212 }
00213
00215 void abort() {
00216 ham_status_t st;
00217 st=ham_txn_abort(m_txn, 0);
00218 if (st)
00219 throw error(st);
00220 }
00221
00223 void commit() {
00224 ham_status_t st;
00225 st=ham_txn_commit(m_txn, 0);
00226 if (st)
00227 throw error(st);
00228 }
00229
00231 ham_txn_t *get_handle() {
00232 return (m_txn);
00233 }
00234
00235 protected:
00236 ham_txn_t *m_txn;
00237 db *m_db;
00238 };
00239
00240
00246 class db
00247 {
00248 public:
00250 static void set_errhandler(ham_errhandler_fun f) {
00251 ham_set_errhandler(f);
00252 }
00253
00255 static void get_version(ham_u32_t *major, ham_u32_t *minor,
00256 ham_u32_t *revision) {
00257 ham_get_version(major, minor, revision);
00258 }
00259
00261 static void get_license(const char **licensee, const char **product) {
00262 ham_get_license(licensee, product);
00263 }
00264
00266 db() : m_db(0) {
00267 }
00268
00270 ~db() {
00271 close();
00272 }
00273
00280 db &operator=(const db &other) {
00281 db &rhs=(db &)other;
00282 if (this==&other)
00283 return (*this);
00284 close();
00285 m_db=rhs.m_db;
00286 rhs.m_db=0;
00287 return (*this);
00288 }
00289
00291 void create(const char *filename, ham_u32_t flags=0,
00292 ham_u32_t mode=0644, ham_parameter_t *param=0) {
00293 ham_status_t st;
00294 if (!m_db) {
00295 st=ham_new(&m_db);
00296 if (st)
00297 throw error(st);
00298 }
00299 if ((st=ham_create_ex(m_db, filename, flags, mode, param)))
00300 throw error(st);
00301 }
00302
00304 void open(const char *filename, ham_u32_t flags=0,
00305 ham_parameter_t *param=0) {
00306 ham_status_t st;
00307 if (!m_db) {
00308 st=ham_new(&m_db);
00309 if (st)
00310 throw error(st);
00311 }
00312 if ((st=ham_open_ex(m_db, filename, flags, param)))
00313 throw error(st);
00314 }
00315
00317 ham_status_t get_error() {
00318 return (ham_get_error(m_db));
00319 }
00320
00322 txn begin() {
00323 ham_txn_t *h;
00324 ham_status_t st=ham_txn_begin(&h, get_handle(), 0);
00325 if (st)
00326 throw error(st);
00327 return (txn(h));
00328 }
00329
00331 void set_prefix_compare_func(ham_prefix_compare_func_t foo) {
00332 ham_status_t st=ham_set_prefix_compare_func(m_db, foo);
00333 if (st)
00334 throw error(st);
00335 }
00336
00338 void set_compare_func(ham_compare_func_t foo) {
00339 ham_status_t st=ham_set_compare_func(m_db, foo);
00340 if (st)
00341 throw error(st);
00342 }
00343
00345 void enable_compression(ham_u32_t level, ham_u32_t flags=0) {
00346 ham_status_t st=ham_enable_compression(m_db, level, flags);
00347 if (st)
00348 throw error(st);
00349 }
00350
00352 record find(txn *t, key *k, ham_u32_t flags=0) {
00353 record r;
00354 ham_status_t st=ham_find(m_db,
00355 t ? t->get_handle() : 0,
00356 k ? k->get_handle() : 0,
00357 r.get_handle(), flags);
00358 if (st)
00359 throw error(st);
00360 return (r);
00361 }
00362
00364 record find(key *k, ham_u32_t flags=0) {
00365 return (find(0, k, flags));
00366 }
00367
00369 void insert(txn *t, key *k, record *r, ham_u32_t flags=0) {
00370 ham_status_t st=ham_insert(m_db,
00371 t ? t->get_handle() : 0,
00372 k ? k->get_handle() : 0,
00373 r ? r->get_handle() : 0, flags);
00374 if (st)
00375 throw error(st);
00376 }
00377
00379 void insert(key *k, record *r, ham_u32_t flags=0) {
00380 insert(0, k, r, flags);
00381 }
00382
00384 void erase(key *k, ham_u32_t flags=0) {
00385 erase(0, k, flags);
00386 }
00387
00389 void erase(txn *t, key *k, ham_u32_t flags=0) {
00390 ham_status_t st=ham_erase(m_db,
00391 t ? t->get_handle() : 0,
00392 k ? k->get_handle() : 0, flags);
00393 if (st)
00394 throw error(st);
00395 }
00396
00398 void flush(ham_u32_t flags=0) {
00399 ham_status_t st=ham_flush(m_db, flags);
00400 if (st)
00401 throw error(st);
00402 }
00403
00405 void close(ham_u32_t flags=0) {
00406 if (!m_db)
00407 return;
00408 ham_status_t st=ham_close(m_db, flags);
00409 if (st)
00410 throw error(st);
00411 st=ham_delete(m_db);
00412 if (st)
00413 throw error(st);
00414 m_db=0;
00415 }
00416
00418 ham_db_t *get_handle() {
00419 return (m_db);
00420 }
00421
00422 protected:
00423 friend class env;
00424
00425
00426 db(ham_db_t *db) : m_db(db) {
00427 }
00428
00429 private:
00430 ham_db_t *m_db;
00431 };
00432
00433
00439 class cursor
00440 {
00441 public:
00443 cursor(db *db=0, txn *t=0, ham_u32_t flags=0)
00444 : m_cursor(0) {
00445 create(db, t, flags);
00446 }
00447
00449 cursor(txn *t, db *db=0, ham_u32_t flags=0)
00450 : m_cursor(0) {
00451 create(db, t, flags);
00452 }
00453
00455 ~cursor() {
00456 close();
00457 }
00458
00460 void create(db *db, txn *t=0, ham_u32_t flags=0) {
00461 if (m_cursor)
00462 close();
00463 if (db) {
00464 ham_status_t st=ham_cursor_create(db->get_handle(),
00465 t ? t->get_handle() : 0,
00466 flags, &m_cursor);
00467 if (st)
00468 throw error(st);
00469 }
00470 }
00471
00473 cursor clone() {
00474 ham_cursor_t *dest;
00475 ham_status_t st=ham_cursor_clone(m_cursor, &dest);
00476 if (st)
00477 throw error(st);
00478 return (cursor(dest));
00479 }
00480
00482 void move(key *k, record *r, ham_u32_t flags=0) {
00483 ham_status_t st=ham_cursor_move(m_cursor, k ? k->get_handle() : 0,
00484 r ? r->get_handle() : 0, flags);
00485 if (st)
00486 throw error(st);
00487 }
00488
00490 void move_first(key *k=0, record *r=0) {
00491 move(k, r, HAM_CURSOR_FIRST);
00492 }
00493
00495 void move_last(key *k=0, record *r=0) {
00496 move(k, r, HAM_CURSOR_LAST);
00497 }
00498
00500 void move_next(key *k=0, record *r=0) {
00501 move(k, r, HAM_CURSOR_NEXT);
00502 }
00503
00505 void move_previous(key *k=0, record *r=0) {
00506 move(k, r, HAM_CURSOR_PREVIOUS);
00507 }
00508
00510 void overwrite(record *r, ham_u32_t flags=0) {
00511 ham_status_t st=ham_cursor_overwrite(m_cursor,
00512 r ? r->get_handle() : 0, flags);
00513 if (st)
00514 throw error(st);
00515 }
00516
00518 void find(key *k, ham_u32_t flags=0) {
00519 ham_status_t st=ham_cursor_find(m_cursor, k->get_handle(), flags);
00520 if (st)
00521 throw error(st);
00522 }
00523
00525 void insert(key *k, record *r, ham_u32_t flags=0) {
00526 ham_status_t st=ham_cursor_insert(m_cursor, k ? k->get_handle() : 0,
00527 r ? r->get_handle() : 0, flags);
00528 if (st)
00529 throw error(st);
00530 }
00531
00533 void erase(ham_u32_t flags=0) {
00534 ham_status_t st=ham_cursor_erase(m_cursor, flags);
00535 if (st)
00536 throw error(st);
00537 }
00538
00540 ham_u32_t get_duplicate_count(ham_u32_t flags=0) {
00541 ham_u32_t c;
00542 ham_status_t st=ham_cursor_get_duplicate_count(m_cursor, &c, flags);
00543 if (st)
00544 throw error(st);
00545 return (c);
00546 }
00547
00549 void close() {
00550 if (!m_cursor)
00551 return;
00552 ham_status_t st=ham_cursor_close(m_cursor);
00553 if (st)
00554 throw error(st);
00555 m_cursor=0;
00556 }
00557
00558 protected:
00559
00560 cursor(ham_cursor_t *c) {
00561 m_cursor=c;
00562 }
00563
00564 private:
00565 ham_cursor_t *m_cursor;
00566 };
00567
00573 class env
00574 {
00575 public:
00577 env() : m_env(0) {
00578 }
00579
00581 ~env() {
00582 close();
00583 }
00584
00586 void create(const char *filename, ham_u32_t flags=0,
00587 ham_u32_t mode=0644, ham_parameter_t *param=0) {
00588 ham_status_t st;
00589 if (!m_env) {
00590 st=ham_env_new(&m_env);
00591 if (st)
00592 throw error(st);
00593 }
00594 if ((st=ham_env_create_ex(m_env, filename, flags, mode, param)))
00595 throw error(st);
00596 }
00597
00599 void open(const char *filename, ham_u32_t flags=0,
00600 ham_parameter_t *param=0) {
00601 ham_status_t st;
00602 if (!m_env) {
00603 st=ham_env_new(&m_env);
00604 if (st)
00605 throw error(st);
00606 }
00607 if ((st=ham_env_open_ex(m_env, filename, flags, param)))
00608 throw error(st);
00609 }
00610
00612 db create_db(ham_u16_t name, ham_u32_t flags=0, ham_parameter_t *param=0) {
00613 ham_status_t st;
00614 ham_db_t *dbh;
00615
00616 st=ham_new(&dbh);
00617 if (st)
00618 throw error(st);
00619 st=ham_env_create_db(m_env, dbh, name, flags, param);
00620 if (st) {
00621 ham_delete(dbh);
00622 throw error(st);
00623 }
00624
00625 return (ham::db(dbh));
00626 }
00627
00629 db open_db(ham_u16_t name, ham_u32_t flags=0, ham_parameter_t *param=0) {
00630 ham_status_t st;
00631 ham_db_t *dbh;
00632
00633 st=ham_new(&dbh);
00634 if (st)
00635 throw error(st);
00636 st=ham_env_open_db(m_env, dbh, name, flags, param);
00637 if (st) {
00638 ham_delete(dbh);
00639 throw error(st);
00640 }
00641
00642 return (ham::db(dbh));
00643 }
00644
00646 void rename_db(ham_u16_t oldname, ham_u16_t newname, ham_u32_t flags=0) {
00647 ham_status_t st=ham_env_rename_db(m_env, oldname, newname, flags);
00648 if (st)
00649 throw error(st);
00650 }
00651
00653 void erase_db(ham_u16_t name, ham_u32_t flags=0) {
00654 ham_status_t st=ham_env_erase_db(m_env, name, flags);
00655 if (st)
00656 throw error(st);
00657 }
00658
00662 void close(void) {
00663 if (!m_env)
00664 return;
00665 ham_status_t st=ham_env_close(m_env, 0);
00666 if (st)
00667 throw error(st);
00668 st=ham_env_delete(m_env);
00669 if (st)
00670 throw error(st);
00671 m_env=0;
00672 }
00673
00675 void enable_encryption(ham_u8_t key[16], ham_u32_t flags=0) {
00676 ham_status_t st=ham_env_enable_encryption(m_env, key, flags);
00677 if (st)
00678 throw error(st);
00679 }
00680
00682 std::vector<ham_u16_t> get_database_names(void) {
00683 ham_size_t count=32;
00684 ham_status_t st;
00685 std::vector<ham_u16_t> v(count);
00686
00687 do {
00688 st=ham_env_get_database_names(m_env, &v[0], &count);
00689 if (!st)
00690 break;
00691 if (st && st!=HAM_LIMITS_REACHED)
00692 throw error(st);
00693 count+=16;
00694 v.resize(count);
00695 } while (1);
00696
00697 v.resize(count);
00698 return (v);
00699 }
00700
00701 private:
00702 ham_env_t *m_env;
00703 };
00704
00705 };
00706
00711 #endif // HAMSTERDB_HPP__