1 /** 2 Copyright: Copyright (c) 2017-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module lmdb; 7 8 template checked(alias func) 9 { 10 import std.traits; 11 debug auto checked(string file = __FILE__, int line = __LINE__)(auto ref Parameters!func args) 12 { 13 int rc = func(args); 14 checkCode(rc, file, line); 15 return rc; 16 } else 17 alias checked = func; 18 } 19 20 void checkCode(int code, string file = __FILE__, int line = __LINE__) @nogc 21 { 22 if (code != MDB_SUCCESS && code != MDB_NOTFOUND) 23 { 24 //errorf("%s@%s: MDB error: %s", file, line, mdb_strerror(code).fromStringz); 25 import core.stdc.stdio; 26 printf("%s@%d: MDB error: %s", file.ptr, line, mdb_strerror(code)); 27 assert(false); 28 } 29 } 30 31 extern(C): 32 nothrow: 33 @nogc: 34 35 static int mdb_cmp_long(const MDB_val *a, const MDB_val *b) 36 { 37 immutable ulong a0 = (cast(ulong*)a.ptr)[0]; 38 immutable ulong a1 = (cast(ulong*)a.ptr)[1]; 39 immutable ulong b0 = (cast(ulong*)b.ptr)[0]; 40 immutable ulong b1 = (cast(ulong*)b.ptr)[1]; 41 42 if (a1 == b1) 43 { 44 if (a0 == b0) 45 return 0; 46 else 47 return (a0 < b0) ? -1 : 1; 48 } 49 else 50 { 51 return (a1 < b1) ? -1 : 1; 52 } 53 } 54 55 alias mdb_mode_t = uint; 56 struct mdb_filehandle_ts {} 57 alias mdb_filehandle_t = mdb_filehandle_ts*; 58 59 struct MDB_env {} 60 struct MDB_txn {} 61 alias MDB_dbi = uint; 62 struct MDB_cursor {} 63 64 alias MDB_val = ubyte[]; 65 66 enum { 67 MDB_FIXEDMAP = 0x01, 68 MDB_NOSUBDIR = 0x4000, 69 MDB_NOSYNC = 0x10000, 70 MDB_RDONLY = 0x20000, 71 MDB_NOMETASYNC = 0x40000, 72 MDB_WRITEMAP = 0x80000, 73 MDB_MAPASYNC = 0x100000, 74 MDB_NOTLS = 0x200000, 75 MDB_NOLOCK = 0x400000, 76 MDB_NORDAHEAD = 0x800000, 77 MDB_NOMEMINIT = 0x1000000 78 } 79 80 enum { 81 MDB_REVERSEKEY = 0x02, 82 MDB_DUPSORT = 0x04, 83 MDB_INTEGERKEY = 0x08, 84 MDB_DUPFIXED = 0x10, 85 MDB_INTEGERDUP = 0x20, 86 MDB_REVERSEDUP = 0x40, 87 MDB_CREATE = 0x40000 88 } 89 90 enum { 91 MDB_NOOVERWRITE = 0x10, 92 MDB_NODUPDATA = 0x20, 93 MDB_RESERVE = 0x10000, 94 MDB_APPEND = 0x20000, 95 MDB_APPENDDUP = 0x40000, 96 MDB_MULTIPLE = 0x80000 97 } 98 99 enum /*MDB_cursor_op*/ { 100 MDB_FIRST, 101 MDB_FIRST_DUP, 102 MDB_GET_BOTH, 103 MDB_GET_BOTH_RANGE, 104 MDB_GET_CURRENT, 105 MDB_GET_MULTIPLE, 106 MDB_LAST, 107 MDB_LAST_DUP, 108 MDB_NEXT, 109 MDB_NEXT_DUP, 110 MDB_NEXT_MULTIPLE, 111 MDB_NEXT_NODUP, 112 MDB_PREV, 113 MDB_PREV_DUP, 114 MDB_PREV_NODUP, 115 MDB_SET, 116 MDB_SET_KEY, 117 MDB_SET_RANGE, 118 } 119 120 enum { 121 MDB_SUCCESS = 0, 122 MDB_KEYEXIST = (-30799), 123 MDB_NOTFOUND = (-30798), 124 MDB_PAGE_NOTFOUND = (-30797), 125 MDB_CORRUPTED = (-30796), 126 MDB_PANIC = (-30795), 127 MDB_VERSION_MISMATCH = (-30794), 128 MDB_INVALID = (-30793), 129 MDB_MAP_FULL = (-30792), 130 MDB_DBS_FULL = (-30791), 131 MDB_READERS_FULL = (-30790), 132 MDB_TLS_FULL = (-30789), 133 MDB_TXN_FULL = (-30788), 134 MDB_CURSOR_FULL = (-30787), 135 MDB_PAGE_FULL = (-30786), 136 MDB_MAP_RESIZED = (-30785), 137 MDB_INCOMPATIBLE = (-30784), 138 MDB_BAD_RSLOT = (-30783), 139 MDB_BAD_TXN = (-30782), 140 MDB_BAD_VALSIZE = (-30781), 141 MDB_BAD_DBI = (-30780), 142 MDB_LAST_ERRCODE = MDB_BAD_DBI 143 } 144 145 struct MDB_stat { 146 uint ms_psize; 147 uint ms_depth; 148 size_t ms_branch_pages; 149 size_t ms_leaf_pages; 150 size_t ms_overflow_pages; 151 size_t ms_entries; 152 } 153 154 struct MDB_envinfo { 155 void* me_mapaddr; 156 size_t me_mapsize; 157 size_t me_last_pgno; 158 size_t me_last_txnid; 159 uint me_maxreaders; 160 uint me_numreaders; 161 } 162 163 const(char)* mdb_version (int* major, int* minor, int* patch); 164 const(char)* mdb_strerror (int err); 165 166 int mdb_env_create (MDB_env** env); 167 int mdb_env_open (MDB_env* env, const(char)* path, uint flags, mdb_mode_t mode); 168 int mdb_env_copy (MDB_env* env, const(char)* path); 169 int mdb_env_copyfd (MDB_env* env, mdb_filehandle_t fd); 170 int mdb_env_stat (MDB_env* env, MDB_stat* stat); 171 int mdb_env_info (MDB_env* env, MDB_envinfo* stat); 172 int mdb_env_sync (MDB_env* env, int force); 173 void mdb_env_close (MDB_env* env); 174 int mdb_env_set_flags (MDB_env* env, uint flags, int onoff); 175 int mdb_env_get_flags (MDB_env* env, uint* flags); 176 int mdb_env_get_path (MDB_env* env, const(char)** path); 177 int mdb_env_get_fd (MDB_env* env, mdb_filehandle_t* fd); 178 int mdb_env_set_mapsize (MDB_env* env, size_t size); 179 int mdb_env_set_maxreaders (MDB_env* env, uint readers); 180 int mdb_env_get_maxreaders (MDB_env* env, uint* readers); 181 int mdb_env_set_maxdbs (MDB_env* env, MDB_dbi dbs); 182 int mdb_env_get_maxkeysize (MDB_env* env); 183 int mdb_env_set_userctx (MDB_env* env, void* ctx); 184 void* mdb_env_get_userctx (MDB_env* env); 185 int mdb_env_set_assert (MDB_env* env, void function (MDB_env* env, const(char)* msg) func); 186 187 int mdb_txn_begin (MDB_env* env, MDB_txn* parent, uint flags, MDB_txn** txn); 188 MDB_env* mdb_txn_env (MDB_txn* txn); 189 size_t mdb_txn_id (MDB_txn* txn); 190 int mdb_txn_commit (MDB_txn* txn); 191 void mdb_txn_abort (MDB_txn* txn); 192 void mdb_txn_reset (MDB_txn* txn); 193 int mdb_txn_renew (MDB_txn* txn); 194 195 int mdb_dbi_open (MDB_txn* txn, const(char)* name, uint flags, MDB_dbi* dbi); 196 int mdb_stat (MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat); 197 int mdb_dbi_flags (MDB_txn* txn, MDB_dbi dbi, uint* flags); 198 void mdb_dbi_close (MDB_env* env, MDB_dbi dbi); 199 int mdb_drop (MDB_txn* txn, MDB_dbi dbi, int del); 200 int mdb_set_compare (MDB_txn* txn, MDB_dbi dbi, int function (const MDB_val* a, const MDB_val* b) cmp); 201 int mdb_set_dupsort (MDB_txn* txn, MDB_dbi dbi, int function (MDB_val* a, MDB_val* b) cmp); 202 int mdb_set_relfunc (MDB_txn* txn, MDB_dbi dbi, void function (MDB_val* item, void* oldptr, void* newptr, void* relctx) rel); 203 int mdb_set_relctx (MDB_txn* txn, MDB_dbi dbi, void* ctx); 204 int mdb_get (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data); 205 int mdb_put (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data, uint flags); 206 int mdb_del (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data); 207 int mdb_cursor_open (MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor); 208 void mdb_cursor_close (MDB_cursor* cursor); 209 int mdb_cursor_renew (MDB_txn* txn, MDB_cursor* cursor); 210 MDB_txn* mdb_cursor_txn (MDB_cursor* cursor); 211 MDB_dbi mdb_cursor_dbi (MDB_cursor* cursor); 212 int mdb_cursor_get (MDB_cursor* cursor, MDB_val* key, MDB_val* data, /*MDB_cursor_op*/uint op); 213 int mdb_cursor_put (MDB_cursor* cursor, MDB_val* key, MDB_val* data, uint flags); 214 int mdb_cursor_del (MDB_cursor* cursor, uint flags); 215 int mdb_cursor_count (MDB_cursor* cursor, size_t* countp); 216 int mdb_cmp (MDB_txn* txn, MDB_dbi dbi, MDB_val* a, MDB_val* b); 217 int mdb_dcmp (MDB_txn* txn, MDB_dbi dbi, MDB_val* a, MDB_val* b); 218 int mdb_reader_list (MDB_env* env, int function (const(char)* msg, void* ctx) func, void* ctx); 219 int mdb_reader_check (MDB_env* env, int* dead);