hamsterdb.hpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005-2010 Christoph Rupp (chris@crupp.de).
00003  *
00004  * This program is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License as published by the
00006  * Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * See files COPYING.* for License information.
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  * forward declarations
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) // check for overflow
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         /* TODO -- [i_a] copy key data; same for record; depends on USER_ALLOC flags, etc. */
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     /* Copy Constructor. Is protected and should not be used. */
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     /* Copy Constructor. Is protected and should not be used. */
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 }; // namespace ham
00774 
00779 #endif // HAMSTERDB_HPP__

Generated on Wed Apr 14 20:37:55 2010 for hamsterdb Embedded Database by  doxygen 1.6.1