hamsterdb Embedded Database  2.1.7
hamsterdb.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2014 Christoph Rupp (chris@crupp.de).
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
31 #ifndef HAM_HAMSTERDB_HPP__
32 #define HAM_HAMSTERDB_HPP__
33 
34 #include <ham/hamsterdb.h>
35 #include <ham/hamsterdb_int.h>
36 #include <cstring>
37 #include <vector>
38 
39 #if defined(_MSC_VER) && defined(_DEBUG) && !defined(_CRTDBG_MAP_ALLOC)
40 # define _CRTDBG_MAP_ALLOC
41 # include <crtdbg.h>
42 #endif
43 
52 namespace hamsterdb {
53 
54 class txn;
55 class db;
56 class env;
57 
63 class error {
64  public:
67  : m_errno(st) {
68  };
69 
72  return (m_errno);
73  }
74 
76  const char *get_string() const {
77  return (ham_strerror(m_errno));
78  }
79 
80 private:
82 };
83 
89 class key {
90  public:
92  key(void *data = 0, ham_u16_t size = 0, ham_u32_t flags = 0) {
93  memset(&m_key, 0, sizeof(m_key));
94  m_key.data = data;
95  m_key.size = size;
96  m_key.flags = flags;
97  if (m_key.size != size) // check for overflow
98  throw error(HAM_INV_KEYSIZE);
99  }
100 
102  key(const key &other)
103  : m_key(other.m_key) {
104  }
105 
107  key &operator=(const key &other) {
108  if (&other != this)
109  m_key = other.m_key;
110  return (*this);
111  }
112 
114  void *get_data() const {
115  return (m_key.data);
116  }
117 
119  void set_data(void *data) {
120  m_key.data = data;
121  }
122 
124  ham_u16_t get_size() const {
125  return (m_key.size);
126  }
127 
129  void set_size(ham_u16_t size) {
130  m_key.size = size;
131  }
132 
134  template <class T>
135  void set(T &t) {
136  set_data(&t);
137  set_size(sizeof(t));
138  }
139 
142  return (m_key.flags);
143  }
144 
146  void set_flags(ham_u32_t flags) {
147  m_key.flags = flags;
148  }
149 
152  return (&m_key);
153  }
154 
158  }
159 
160 private:
162 };
163 
169 class record {
170  public:
172  record(void *data = 0, ham_u32_t size = 0, ham_u32_t flags = 0) {
173  memset(&m_rec, 0, sizeof(m_rec));
174  m_rec.data = data;
175  m_rec.size = size;
176  m_rec.flags = flags;
177  }
178 
180  record(const record &other)
181  : m_rec(other.m_rec) {
182  }
183 
185  record &operator=(const record &other) {
186  m_rec = other.m_rec;
187  return (*this);
188  }
189 
191  void *get_data() const {
192  return (m_rec.data);
193  }
194 
196  void set_data(void *data) {
197  m_rec.data = data;
198  }
199 
201  ham_u32_t get_size() const {
202  return (m_rec.size);
203  }
204 
206  void set_size(ham_u32_t size) {
207  m_rec.size = size;
208  }
209 
212  return (m_rec.flags);
213  }
214 
216  void set_flags(ham_u32_t flags) {
217  m_rec.flags = flags;
218  }
219 
222  return (&m_rec);
223  }
224 
225  protected:
227 };
228 
229 
235 class txn {
236  public:
238  txn(ham_txn_t *t = 0)
239  : m_txn(t) {
240  }
241 
243  void abort() {
245  if (st)
246  throw error(st);
247  }
248 
250  void commit() {
252  if (st)
253  throw error(st);
254  }
255 
256  std::string get_name() {
257  const char *p = ham_txn_get_name(m_txn);
258  return (p ? p : "");
259  }
260 
263  return (m_txn);
264  }
265 
266  protected:
268 };
269 
270 
276 class db {
277  public:
281  }
282 
284  static void get_version(ham_u32_t *major, ham_u32_t *minor,
285  ham_u32_t *revision) {
286  ham_get_version(major, minor, revision);
287  }
288 
290  static void get_license(const char **licensee, const char **product) {
291  ham_get_license(licensee, product);
292  }
293 
295  db()
296  : m_db(0) {
297  }
298 
300  ~db() {
301  close();
302  }
303 
310  db &operator=(const db &other) {
311  db &rhs = (db &)other;
312  if (this == &other)
313  return (*this);
314  close();
315  m_db = rhs.m_db;
316  rhs.m_db = 0;
317  return (*this);
318  }
319 
322  return (ham_db_get_error(m_db));
323  }
324 
328  if (st)
329  throw error(st);
330  }
331 
333  record find(txn *t, key *k, ham_u32_t flags = 0) {
334  record r;
336  t ? t->get_handle() : 0,
337  k ? k->get_handle() : 0,
338  r.get_handle(), flags);
339  if (st)
340  throw error(st);
341  return (r);
342  }
343 
345  record &find(txn *t, key *k, record *r, ham_u32_t flags = 0) {
347  t ? t->get_handle() : 0,
348  k ? k->get_handle() : 0,
349  r->get_handle(), flags);
350  if (st)
351  throw error(st);
352  return (*r);
353  }
354 
356  record find(key *k, ham_u32_t flags = 0) {
357  return (find(0, k, flags));
358  }
359 
361  void insert(txn *t, key *k, record *r, ham_u32_t flags = 0) {
363  t ? t->get_handle() : 0,
364  k ? k->get_handle() : 0,
365  r ? r->get_handle() : 0, flags);
366  if (st)
367  throw error(st);
368  }
369 
371  void insert(key *k, record *r, ham_u32_t flags=0) {
372  insert(0, k, r, flags);
373  }
374 
376  void erase(key *k, ham_u32_t flags = 0) {
377  erase(0, k, flags);
378  }
379 
381  void erase(txn *t, key *k, ham_u32_t flags = 0) {
383  t ? t->get_handle() : 0,
384  k ? k->get_handle() : 0, flags);
385  if (st)
386  throw error(st);
387  }
388 
391  ham_u64_t count = 0;
392  ham_status_t st = ham_db_get_key_count(m_db, txn, flags, &count);
393  if (st)
394  throw error(st);
395  return (count);
396  }
397 
401  if (st)
402  throw error(st);
403  }
404 
406  void close(ham_u32_t flags = 0) {
407  if (!m_db)
408  return;
409  // disable auto-cleanup; all objects will be destroyed when
410  // going out of scope
411  flags &= ~HAM_AUTO_CLEANUP;
412  ham_status_t st = ham_db_close(m_db, flags);
413  if (st)
414  throw error(st);
415  m_db = 0;
416  }
417 
420  return (m_db);
421  }
422 
423 protected:
424  friend class env;
425 
426  /* Copy Constructor. Is protected and should not be used. */
428  : m_db(db) {
429  }
430 
431  private:
433 };
434 
435 
441 class cursor {
442  public:
444  cursor(db *db = 0, txn *t = 0, ham_u32_t flags = 0)
445  : m_cursor(0) {
446  create(db, t, flags);
447  }
448 
450  cursor(txn *t, db *db = 0, ham_u32_t flags = 0)
451  : m_cursor(0) {
452  create(db, t, flags);
453  }
454 
457  close();
458  }
459 
461  void create(db *db, txn *t = 0, ham_u32_t flags = 0) {
462  if (m_cursor)
463  close();
464  if (db) {
466  t ? t->get_handle() : 0, flags);
467  if (st)
468  throw error(st);
469  }
470  }
471 
474  ham_cursor_t *dest;
476  if (st)
477  throw error(st);
478  return (cursor(dest));
479  }
480 
482  void move(key *k, record *r, ham_u32_t flags = 0) {
483  ham_status_t st = ham_cursor_move(m_cursor, k ? k->get_handle() : 0,
484  r ? r->get_handle() : 0, flags);
485  if (st)
486  throw error(st);
487  }
488 
490  void move_first(key *k = 0, record *r = 0) {
491  move(k, r, HAM_CURSOR_FIRST);
492  }
493 
495  void move_last(key *k = 0, record *r = 0) {
496  move(k, r, HAM_CURSOR_LAST);
497  }
498 
500  void move_next(key *k = 0, record *r = 0) {
501  move(k, r, HAM_CURSOR_NEXT);
502  }
503 
505  void move_previous(key *k = 0, record *r = 0) {
506  move(k, r, HAM_CURSOR_PREVIOUS);
507  }
508 
510  void overwrite(record *r, ham_u32_t flags = 0) {
512  r ? r->get_handle() : 0, flags);
513  if (st)
514  throw error(st);
515  }
516 
518  void find(key *k, record *r = 0, ham_u32_t flags = 0) {
520  (r ? r->get_handle() : 0), flags);
521  if (st)
522  throw error(st);
523  }
524 
526  void insert(key *k, record *r, ham_u32_t flags = 0) {
528  r ? r->get_handle() : 0, flags);
529  if (st)
530  throw error(st);
531  }
532 
534  void erase(ham_u32_t flags = 0) {
536  if (st)
537  throw error(st);
538  }
539 
542  ham_u32_t c;
544  if (st)
545  throw error(st);
546  return (c);
547  }
548 
551  ham_u64_t s;
553  if (st)
554  throw error(st);
555  return (s);
556  }
557 
559  void close() {
560  if (!m_cursor)
561  return;
563  if (st)
564  throw error(st);
565  m_cursor = 0;
566  }
567 
568  protected:
569  /* Copy Constructor. Is protected and should not be used. */
571  m_cursor = c;
572  }
573 
574  private:
576 };
577 
583 class env {
584  public:
586  env()
587  : m_env(0) {
588  }
589 
591  ~env() {
592  close();
593  }
594 
596  void create(const char *filename, ham_u32_t flags = 0,
597  ham_u32_t mode = 0644, const ham_parameter_t *param = 0) {
598  ham_status_t st = ham_env_create(&m_env, filename, flags, mode, param);
599  if (st)
600  throw error(st);
601  }
602 
604  void open(const char *filename, ham_u32_t flags = 0,
605  const ham_parameter_t *param = 0) {
606  ham_status_t st = ham_env_open(&m_env, filename, flags, param);
607  if (st)
608  throw error(st);
609  }
610 
612  void flush(ham_u32_t flags = 0) {
613  ham_status_t st = ham_env_flush(m_env, flags);
614  if (st)
615  throw error(st);
616  }
617 
619  db create_db(ham_u16_t name, ham_u32_t flags = 0,
620  const ham_parameter_t *param = 0) {
621  ham_db_t *dbh;
622 
623  ham_status_t st = ham_env_create_db(m_env, &dbh, name, flags, param);
624  if (st)
625  throw error(st);
626 
627  return (hamsterdb::db(dbh));
628  }
629 
631  db open_db(ham_u16_t name, ham_u32_t flags = 0,
632  const ham_parameter_t *param = 0) {
633  ham_db_t *dbh;
634 
635  ham_status_t st = ham_env_open_db(m_env, &dbh, name, flags, param);
636  if (st)
637  throw error(st);
638 
639  return (hamsterdb::db(dbh));
640  }
641 
643  void rename_db(ham_u16_t oldname, ham_u16_t newname, ham_u32_t flags = 0) {
644  ham_status_t st = ham_env_rename_db(m_env, oldname, newname, flags);
645  if (st)
646  throw error(st);
647  }
648 
650  void erase_db(ham_u16_t name, ham_u32_t flags = 0) {
651  ham_status_t st = ham_env_erase_db(m_env, name, flags);
652  if (st)
653  throw error(st);
654  }
655 
657  txn begin(const char *name = 0) {
658  ham_txn_t *h;
659  ham_status_t st = ham_txn_begin(&h, m_env, name, 0, 0);
660  if (st)
661  throw error(st);
662  return (txn(h));
663  }
664 
665 
667  void close(ham_u32_t flags = 0) {
668  if (!m_env)
669  return;
670  // disable auto-cleanup; all objects will be destroyed when
671  // going out of scope
672  flags &= ~HAM_AUTO_CLEANUP;
673  ham_status_t st = ham_env_close(m_env, flags);
674  if (st)
675  throw error(st);
676  m_env = 0;
677  }
678 
682  if (st)
683  throw error(st);
684  }
685 
687  std::vector<ham_u16_t> get_database_names() {
688  ham_u32_t count = 32;
689  ham_status_t st;
690  std::vector<ham_u16_t> v(count);
691 
692  for (;;) {
693  st = ham_env_get_database_names(m_env, &v[0], &count);
694  if (!st)
695  break;
696  if (st && st!=HAM_LIMITS_REACHED)
697  throw error(st);
698  count += 16;
699  v.resize(count);
700  }
701 
702  v.resize(count);
703  return (v);
704  }
705 
706  private:
708 };
709 
710 } // namespace hamsterdb
711 
716 #endif // HAMSTERDB_HPP__