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@%s: 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 void mdb_load_libs(); 56 57 alias mdb_mode_t = uint; 58 struct mdb_filehandle_ts {} 59 alias mdb_filehandle_t = mdb_filehandle_ts*; 60 61 struct MDB_env {} 62 struct MDB_txn {} 63 alias MDB_dbi = uint; 64 struct MDB_cursor {} 65 66 alias MDB_val = ubyte[]; 67 68 enum { 69 MDB_FIXEDMAP = 0x01, 70 MDB_NOSUBDIR = 0x4000, 71 MDB_NOSYNC = 0x10000, 72 MDB_RDONLY = 0x20000, 73 MDB_NOMETASYNC = 0x40000, 74 MDB_WRITEMAP = 0x80000, 75 MDB_MAPASYNC = 0x100000, 76 MDB_NOTLS = 0x200000, 77 MDB_NOLOCK = 0x400000, 78 MDB_NORDAHEAD = 0x800000, 79 MDB_NOMEMINIT = 0x1000000 80 } 81 82 enum { 83 MDB_REVERSEKEY = 0x02, 84 MDB_DUPSORT = 0x04, 85 MDB_INTEGERKEY = 0x08, 86 MDB_DUPFIXED = 0x10, 87 MDB_INTEGERDUP = 0x20, 88 MDB_REVERSEDUP = 0x40, 89 MDB_CREATE = 0x40000 90 } 91 92 enum { 93 MDB_NOOVERWRITE = 0x10, 94 MDB_NODUPDATA = 0x20, 95 MDB_RESERVE = 0x10000, 96 MDB_APPEND = 0x20000, 97 MDB_APPENDDUP = 0x40000, 98 MDB_MULTIPLE = 0x80000 99 } 100 101 enum /*MDB_cursor_op*/ { 102 MDB_FIRST, 103 MDB_FIRST_DUP, 104 MDB_GET_BOTH, 105 MDB_GET_BOTH_RANGE, 106 MDB_GET_CURRENT, 107 MDB_GET_MULTIPLE, 108 MDB_LAST, 109 MDB_LAST_DUP, 110 MDB_NEXT, 111 MDB_NEXT_DUP, 112 MDB_NEXT_MULTIPLE, 113 MDB_NEXT_NODUP, 114 MDB_PREV, 115 MDB_PREV_DUP, 116 MDB_PREV_NODUP, 117 MDB_SET, 118 MDB_SET_KEY, 119 MDB_SET_RANGE, 120 } 121 122 enum { 123 MDB_SUCCESS = 0, 124 MDB_KEYEXIST = (-30799), 125 MDB_NOTFOUND = (-30798), 126 MDB_PAGE_NOTFOUND = (-30797), 127 MDB_CORRUPTED = (-30796), 128 MDB_PANIC = (-30795), 129 MDB_VERSION_MISMATCH = (-30794), 130 MDB_INVALID = (-30793), 131 MDB_MAP_FULL = (-30792), 132 MDB_DBS_FULL = (-30791), 133 MDB_READERS_FULL = (-30790), 134 MDB_TLS_FULL = (-30789), 135 MDB_TXN_FULL = (-30788), 136 MDB_CURSOR_FULL = (-30787), 137 MDB_PAGE_FULL = (-30786), 138 MDB_MAP_RESIZED = (-30785), 139 MDB_INCOMPATIBLE = (-30784), 140 MDB_BAD_RSLOT = (-30783), 141 MDB_BAD_TXN = (-30782), 142 MDB_BAD_VALSIZE = (-30781), 143 MDB_BAD_DBI = (-30780), 144 MDB_LAST_ERRCODE = MDB_BAD_DBI 145 } 146 147 struct MDB_stat { 148 uint ms_psize; 149 uint ms_depth; 150 size_t ms_branch_pages; 151 size_t ms_leaf_pages; 152 size_t ms_overflow_pages; 153 size_t ms_entries; 154 } 155 156 struct MDB_envinfo { 157 void* me_mapaddr; 158 size_t me_mapsize; 159 size_t me_last_pgno; 160 size_t me_last_txnid; 161 uint me_maxreaders; 162 uint me_numreaders; 163 } 164 165 const(char)* mdb_version (int* major, int* minor, int* patch); 166 const(char)* mdb_strerror (int err); 167 168 int mdb_env_create (MDB_env** env); 169 int mdb_env_open (MDB_env* env, const(char)* path, uint flags, mdb_mode_t mode); 170 int mdb_env_copy (MDB_env* env, const(char)* path); 171 int mdb_env_copyfd (MDB_env* env, mdb_filehandle_t fd); 172 int mdb_env_stat (MDB_env* env, MDB_stat* stat); 173 int mdb_env_info (MDB_env* env, MDB_envinfo* stat); 174 int mdb_env_sync (MDB_env* env, int force); 175 void mdb_env_close (MDB_env* env); 176 int mdb_env_set_flags (MDB_env* env, uint flags, int onoff); 177 int mdb_env_get_flags (MDB_env* env, uint* flags); 178 int mdb_env_get_path (MDB_env* env, const(char)** path); 179 int mdb_env_get_fd (MDB_env* env, mdb_filehandle_t* fd); 180 int mdb_env_set_mapsize (MDB_env* env, size_t size); 181 int mdb_env_set_maxreaders (MDB_env* env, uint readers); 182 int mdb_env_get_maxreaders (MDB_env* env, uint* readers); 183 int mdb_env_set_maxdbs (MDB_env* env, MDB_dbi dbs); 184 int mdb_env_get_maxkeysize (MDB_env* env); 185 int mdb_env_set_userctx (MDB_env* env, void* ctx); 186 void* mdb_env_get_userctx (MDB_env* env); 187 int mdb_env_set_assert (MDB_env* env, void function (MDB_env* env, const(char)* msg) func); 188 189 int mdb_txn_begin (MDB_env* env, MDB_txn* parent, uint flags, MDB_txn** txn); 190 MDB_env* mdb_txn_env (MDB_txn* txn); 191 size_t mdb_txn_id (MDB_txn* txn); 192 int mdb_txn_commit (MDB_txn* txn); 193 void mdb_txn_abort (MDB_txn* txn); 194 void mdb_txn_reset (MDB_txn* txn); 195 int mdb_txn_renew (MDB_txn* txn); 196 197 int mdb_dbi_open (MDB_txn* txn, const(char)* name, uint flags, MDB_dbi* dbi); 198 int mdb_stat (MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat); 199 int mdb_dbi_flags (MDB_txn* txn, MDB_dbi dbi, uint* flags); 200 void mdb_dbi_close (MDB_env* env, MDB_dbi dbi); 201 int mdb_drop (MDB_txn* txn, MDB_dbi dbi, int del); 202 int mdb_set_compare (MDB_txn* txn, MDB_dbi dbi, int function (const MDB_val* a, const MDB_val* b) cmp); 203 int mdb_set_dupsort (MDB_txn* txn, MDB_dbi dbi, int function (MDB_val* a, MDB_val* b) cmp); 204 int mdb_set_relfunc (MDB_txn* txn, MDB_dbi dbi, void function (MDB_val* item, void* oldptr, void* newptr, void* relctx) rel); 205 int mdb_set_relctx (MDB_txn* txn, MDB_dbi dbi, void* ctx); 206 int mdb_get (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data); 207 int mdb_put (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data, uint flags); 208 int mdb_del (MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data); 209 int mdb_cursor_open (MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor); 210 void mdb_cursor_close (MDB_cursor* cursor); 211 int mdb_cursor_renew (MDB_txn* txn, MDB_cursor* cursor); 212 MDB_txn* mdb_cursor_txn (MDB_cursor* cursor); 213 MDB_dbi mdb_cursor_dbi (MDB_cursor* cursor); 214 int mdb_cursor_get (MDB_cursor* cursor, MDB_val* key, MDB_val* data, /*MDB_cursor_op*/uint op); 215 int mdb_cursor_put (MDB_cursor* cursor, MDB_val* key, MDB_val* data, uint flags); 216 int mdb_cursor_del (MDB_cursor* cursor, uint flags); 217 int mdb_cursor_count (MDB_cursor* cursor, size_t* countp); 218 int mdb_cmp (MDB_txn* txn, MDB_dbi dbi, MDB_val* a, MDB_val* b); 219 int mdb_dcmp (MDB_txn* txn, MDB_dbi dbi, MDB_val* a, MDB_val* b); 220 int mdb_reader_list (MDB_env* env, int function (const(char)* msg, void* ctx) func, void* ctx); 221 int mdb_reader_check (MDB_env* env, int* dead);