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);