-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.zig
264 lines (248 loc) · 7.23 KB
/
test.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
const std = @import("std");
const c = @import("lmdb");
test "happy path" {
// open
try std.fs.cwd().deleteTree("test-db");
try std.fs.cwd().makePath("test-db");
const env = try ret(c.mdb_env_create, .{});
try result(c.mdb_env_set_maxdbs(env, 100));
try result(c.mdb_env_open(env, "test-db", 0, 0o600));
// put
const txn = try ret(c.mdb_txn_begin, .{ env, null, 0 });
const myDb = try ret(c.mdb_dbi_open, .{ txn, "my-db", 0x40000 });
var key = val("hello");
var value = val("world");
try result(c.mdb_put(txn, myDb, &key, &value, 0));
// get
const get_value: c.MDB_val = try ret(c.mdb_get, .{ txn, myDb, &key });
// assert
try std.testing.expectEqualStrings("world", fromVal(get_value));
}
pub fn val(bytes: []const u8) c.MDB_val {
return .{
.mv_size = bytes.len,
.mv_data = @constCast(@ptrCast(bytes.ptr)),
};
}
pub fn fromVal(value: c.MDB_val) []const u8 {
const ptr: [*c]u8 = @ptrCast(value.mv_data);
return ptr[0..value.mv_size];
}
pub fn ret(constructor: anytype, args: anytype) LmdbError!TypeToCreate(constructor) {
const Intermediate = IntermediateType(constructor);
var maybe: IntermediateType(constructor) = switch (@typeInfo(Intermediate)) {
.Optional => null,
.Int => 0,
else => undefined,
};
try result(@call(.auto, constructor, args ++ .{&maybe}));
return switch (@typeInfo(Intermediate)) {
.Optional => maybe.?,
else => maybe,
};
}
fn TypeToCreate(function: anytype) type {
const InnerType = IntermediateType(function);
return switch (@typeInfo(InnerType)) {
.Optional => |o| o.child,
else => InnerType,
};
}
fn IntermediateType(function: anytype) type {
const params = @typeInfo(@TypeOf(function)).Fn.params;
return @typeInfo(params[params.len - 1].type.?).Pointer.child;
}
pub fn result(int: isize) LmdbError!void {
const e = switch (int) {
0 => {},
-30799 => error.MDB_KEYEXIST,
-30798 => error.MDB_NOTFOUND,
-30797 => error.MDB_PAGE_NOTFOUND,
-30796 => error.MDB_CORRUPTED,
-30795 => error.MDB_PANIC,
-30794 => error.MDB_VERSION_MISMATCH,
-30793 => error.MDB_INVALID,
-30792 => error.MDB_MAP_FULL,
-30791 => error.MDB_DBS_FULL,
-30790 => error.MDB_READERS_FULL,
-30789 => error.MDB_TLS_FULL,
-30788 => error.MDB_TXN_FULL,
-30787 => error.MDB_CURSOR_FULL,
-30786 => error.MDB_PAGE_FULL,
-30785 => error.MDB_MAP_RESIZED,
-30784 => error.MDB_INCOMPATIBLE,
-30783 => error.MDB_BAD_RSLOT,
-30782 => error.MDB_BAD_TXN,
-30781 => error.MDB_BAD_VALSIZE,
-30780 => error.MDB_BAD_DBI,
-30779 => error.MDB_PROBLEM,
1 => error.EPERM,
2 => error.ENOENT,
3 => error.ESRCH,
4 => error.EINTR,
5 => error.EIO,
6 => error.ENXIO,
7 => error.E2BIG,
8 => error.ENOEXEC,
9 => error.EBADF,
10 => error.ECHILD,
11 => error.EAGAIN,
12 => error.ENOMEM,
13 => error.EACCES,
14 => error.EFAULT,
15 => error.ENOTBLK,
16 => error.EBUSY,
17 => error.EEXIST,
18 => error.EXDEV,
19 => error.ENODEV,
20 => error.ENOTDIR,
21 => error.EISDIR,
22 => error.EINVAL,
23 => error.ENFILE,
24 => error.EMFILE,
25 => error.ENOTTY,
26 => error.ETXTBSY,
27 => error.EFBIG,
28 => error.ENOSPC,
29 => error.ESPIPE,
30 => error.EROFS,
31 => error.EMLINK,
32 => error.EPIPE,
33 => error.EDOM,
34 => error.ERANGE,
else => error.UnspecifiedErrorCode,
};
return e catch |ee| {
@import("std").debug.print("{}", .{ee});
return ee;
};
}
pub const LmdbError = error{
////////////////////////////////////////////////////////
/// lmdb-specific errors
////
/// Successful result
MDB_SUCCESS,
/// key/data pair already exists
MDB_KEYEXIST,
/// key/data pair not found (EOF)
MDB_NOTFOUND,
/// Requested page not found - this usually indicates corruption
MDB_PAGE_NOTFOUND,
/// Located page was wrong type
MDB_CORRUPTED,
/// Update of meta page failed or environment had fatal error
MDB_PANIC,
/// Environment version mismatch
MDB_VERSION_MISMATCH,
/// File is not a valid LMDB file
MDB_INVALID,
/// Environment mapsize reached
MDB_MAP_FULL,
/// Environment maxdbs reached
MDB_DBS_FULL,
/// Environment maxreaders reached
MDB_READERS_FULL,
/// Too many TLS keys in use - Windows only
MDB_TLS_FULL,
/// Txn has too many dirty pages
MDB_TXN_FULL,
/// Cursor stack too deep - internal error
MDB_CURSOR_FULL,
/// Page has not enough space - internal error
MDB_PAGE_FULL,
/// Database contents grew beyond environment mapsize
MDB_MAP_RESIZED,
/// Operation and DB incompatible, or DB type changed. This can mean:
/// The operation expects an #MDB_DUPSORT / #MDB_DUPFIXED database.
/// Opening a named DB when the unnamed DB has #MDB_DUPSORT / #MDB_INTEGERKEY.
/// Accessing a data record as a database, or vice versa.
/// The database was dropped and recreated with different flags.
MDB_INCOMPATIBLE,
/// Invalid reuse of reader locktable slot
MDB_BAD_RSLOT,
/// Transaction must abort, has a child, or is invalid
MDB_BAD_TXN,
/// Unsupported size of key/DB name/data, or wrong DUPFIXED size
MDB_BAD_VALSIZE,
/// The specified DBI was changed unexpectedly
MDB_BAD_DBI,
/// Unexpected problem - txn should abort
MDB_PROBLEM,
////////////////////////////////////////////////////////
/// asm-generic errors - may be thrown by lmdb
////
/// Operation not permitted
EPERM,
/// No such file or directory
ENOENT,
/// No such process
ESRCH,
/// Interrupted system call
EINTR,
/// I/O error
EIO,
/// No such device or address
ENXIO,
/// Argument list too long
E2BIG,
/// Exec format error
ENOEXEC,
/// Bad file number
EBADF,
/// No child processes
ECHILD,
/// Try again
EAGAIN,
/// Out of memory
ENOMEM,
/// Permission denied
EACCES,
/// Bad address
EFAULT,
/// Block device required
ENOTBLK,
/// Device or resource busy
EBUSY,
/// File exists
EEXIST,
/// Cross-device link
EXDEV,
/// No such device
ENODEV,
/// Not a directory
ENOTDIR,
/// Is a directory
EISDIR,
/// Invalid argument
EINVAL,
/// File table overflow
ENFILE,
/// Too many open files
EMFILE,
/// Not a typewriter
ENOTTY,
/// Text file busy
ETXTBSY,
/// File too large
EFBIG,
/// No space left on device
ENOSPC,
/// Illegal seek
ESPIPE,
/// Read-only file system
EROFS,
/// Too many links
EMLINK,
/// Broken pipe
EPIPE,
/// Math argument out of domain of func
EDOM,
/// Math result not representable
ERANGE,
////////////////////////////////////////////////////////
/// errors interfacing with Lmdb
////
/// Got a return value that is not specified in LMDB's header files
UnspecifiedErrorCode,
};