lmdb 0.5.3 → 0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CONTRIBUTORS +1 -0
- data/Rakefile +9 -0
- data/behaviour.org +35 -0
- data/ext/lmdb_ext/extconf.rb +1 -0
- data/ext/lmdb_ext/lmdb_ext.c +197 -93
- data/ext/lmdb_ext/lmdb_ext.h +19 -3
- data/lib/lmdb/database.rb +9 -8
- data/lib/lmdb/version.rb +1 -1
- data/lmdb.gemspec +1 -0
- data/spec/helper.rb +3 -0
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2eac165bb0261c0af6813f16df9b725b2ca2a63f4c5de98734473d9976930735
|
4
|
+
data.tar.gz: 3aa0562060e4586dd7c7a44e795adc1449f489f57634787ef5e6480abbd49a48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22cc9f78002a05aa25fba212e4d3e3e97566ed7a9bd2e0c84996297398131b5afd57da0e1510a27086ac4b1938401d1369393f9b0515bdd044856109510c6432
|
7
|
+
data.tar.gz: eea983ccb0638bed2dbcfcd3e2ea76271072ea91d259b95e392d505c26f184c351f89ae6076025b93f47bfec3e42add3ec41055e5edb67bee5bfec2e8e341a80
|
data/.gitignore
CHANGED
data/CONTRIBUTORS
CHANGED
data/Rakefile
CHANGED
@@ -7,12 +7,21 @@ PRJ = File.basename(GEMSPEC, ".gemspec")
|
|
7
7
|
require 'bundler/setup'
|
8
8
|
require 'rspec/core/rake_task'
|
9
9
|
require 'rake/extensiontask'
|
10
|
+
require 'ruby_memcheck'
|
11
|
+
require 'ruby_memcheck/rspec/rake_task'
|
12
|
+
|
13
|
+
RubyMemcheck.config(binary_name: 'lmdb_ext')
|
10
14
|
|
11
15
|
RSpec::Core::RakeTask.new :spec
|
12
16
|
Rake::ExtensionTask.new :lmdb_ext
|
13
17
|
|
18
|
+
|
14
19
|
task :default => [:compile, :spec]
|
15
20
|
|
21
|
+
namespace :spec do
|
22
|
+
RubyMemcheck::RSpec::RakeTask.new(valgrind: :compile)
|
23
|
+
end
|
24
|
+
|
16
25
|
def version
|
17
26
|
@version ||= begin
|
18
27
|
require "#{PRJ}/version"
|
data/behaviour.org
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#+STARTUP: showall hidestars
|
2
|
+
* the situtation
|
3
|
+
- lmdb has two kinds of transaction: read-write and read-only
|
4
|
+
- there are two properties associated with transactions:
|
5
|
+
- nesting
|
6
|
+
- multiplicity
|
7
|
+
- *read-write* transactions can nest, but there can only be one stack of read-write transactions per *database*, that is, amongst /all/ threads and all processes attached to the persitent storage.
|
8
|
+
- *read-only* transactions /cannot/ nest (because it's not meaningful for a read-only transaction to nest), but there can be a read-only transaction per thread (and of course multiple threads per process).
|
9
|
+
- (i can't remember if you can have a thread with a read-write *and* read-only transaction going but we can probably assume not)
|
10
|
+
- so therefore we need a way to distinguish between read-write and read-only as well as identify the thread /across processes/ that has the one read-write transaction open.
|
11
|
+
* undocumented behaviour
|
12
|
+
** ~mdb_txn_begin~
|
13
|
+
- if the environment is read-only and the transaction is read-write, returns ~EACCES~
|
14
|
+
- if there is a parent transaction and the current transaction's flags are ~MDB_RDONLY~ or ~MDB_WRITEMAP~ (?) or ~TXN_BLOCKED~
|
15
|
+
- if the *parent's* transaction is ~MDB_TXN_RDONLY~ (which is the same as ~MDB_RDONLY~), return ~EINVAL~
|
16
|
+
- that's saying "read-only transactions can't be nested"
|
17
|
+
- otherwise, return ~MDB_BAD_TXN~
|
18
|
+
- this is saying "read-only transactions can't be children of read-write parents"
|
19
|
+
- otherwise a few boring scenarios where the function may return ~ENOMEM~
|
20
|
+
- otherwise check ~mdb_cursor_shadow~ or ~mdb_txn_renew0~
|
21
|
+
- XXX does ~mdb_txn_begin~ block when waiting for the read-write??
|
22
|
+
* desired behaviour
|
23
|
+
** ruby interface
|
24
|
+
- when the ruby programmer opens a read-only transaction within a read-only transaction, this should be a noop
|
25
|
+
- don't push any stack, don't allocate any resources, just do nothing
|
26
|
+
- when the ruby programmer opens a read-only transaction within a read-/write/ transaction, this should raise an exception
|
27
|
+
- in practice there's no harm except that this is more about communicating the right thing to the ruby programmer
|
28
|
+
- do we warn?
|
29
|
+
- problem: there's no way to know (via the lmdb api) if another process has a read-write transaction open
|
30
|
+
- poll?
|
31
|
+
- actually no it probably doesn't matter (the mdb api blocks anyway?)
|
32
|
+
- /actually/ actually, the cursed-ass goto pseudo-loop containing the ~CALL_WITHOUT_GVL~ deals with that
|
33
|
+
** internal implementation
|
34
|
+
- a successfully-created read-write transaction has to set ~rw_txn_thread~ to the current thread (unless it is a sub-transaction in which case noop)
|
35
|
+
- when a read-write transaction is committed or aborted, ~rw_txn_thread~ has to be set back to null (unless the transaction has a parent)
|
data/ext/lmdb_ext/extconf.rb
CHANGED
data/ext/lmdb_ext/lmdb_ext.c
CHANGED
@@ -26,6 +26,7 @@ static void check(int code) {
|
|
26
26
|
|
27
27
|
const char* err = mdb_strerror(code);
|
28
28
|
const char* sep = strchr(err, ':');
|
29
|
+
// increment the offset by two in case there is a colon (plus space)
|
29
30
|
if (sep)
|
30
31
|
err = sep + 2;
|
31
32
|
|
@@ -37,7 +38,7 @@ static void check(int code) {
|
|
37
38
|
}
|
38
39
|
|
39
40
|
static void transaction_free(Transaction* transaction) {
|
40
|
-
if (transaction->txn) {
|
41
|
+
if (transaction->txn && !NIL_P(transaction->txn)) {
|
41
42
|
//int id = (int)mdb_txn_id(transaction->txn);
|
42
43
|
//rb_warn(sprintf("Memory leak: Garbage collecting active transaction %d", id));
|
43
44
|
rb_warn("Memory leak: Garbage collecting active transaction");
|
@@ -49,6 +50,7 @@ static void transaction_free(Transaction* transaction) {
|
|
49
50
|
|
50
51
|
static void transaction_mark(Transaction* transaction) {
|
51
52
|
rb_gc_mark(transaction->parent);
|
53
|
+
rb_gc_mark(transaction->child);
|
52
54
|
rb_gc_mark(transaction->env);
|
53
55
|
rb_gc_mark(transaction->cursors);
|
54
56
|
}
|
@@ -130,55 +132,79 @@ static VALUE transaction_env(VALUE self) {
|
|
130
132
|
* @return [false,true] whether the transaction is read-only.
|
131
133
|
*/
|
132
134
|
static VALUE transaction_is_readonly(VALUE self) {
|
133
|
-
|
134
|
-
|
135
|
-
|
135
|
+
TRANSACTION(self, transaction);
|
136
|
+
//MDB_txn* txn = transaction->txn;
|
137
|
+
return (transaction->flags & MDB_RDONLY) ? Qtrue : Qfalse;
|
136
138
|
}
|
137
139
|
|
138
140
|
|
139
141
|
static void transaction_finish(VALUE self, int commit) {
|
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
|
-
|
142
|
+
TRANSACTION(self, transaction);
|
143
|
+
|
144
|
+
if (!transaction->txn)
|
145
|
+
rb_raise(cError, "Transaction is already terminated");
|
146
|
+
|
147
|
+
if (transaction->thread != rb_thread_current())
|
148
|
+
rb_raise(cError, "The thread closing the transaction "
|
149
|
+
"is not the one that opened it");
|
150
|
+
|
151
|
+
// ensure the transaction being closed is the active one
|
152
|
+
VALUE p = environment_active_txn(transaction->env);
|
153
|
+
while (!NIL_P(p) && p != self) {
|
154
|
+
TRANSACTION(p, txn);
|
155
|
+
p = txn->parent;
|
156
|
+
}
|
157
|
+
// bail out if the transaction `self` is not the active one
|
158
|
+
if (p != self)
|
159
|
+
rb_raise(cError, "Transaction is not active");
|
160
|
+
|
161
|
+
// now eliminate the cursors
|
162
|
+
long i;
|
163
|
+
for (i=0; i<RARRAY_LEN(transaction->cursors); i++) {
|
164
|
+
VALUE cursor = RARRAY_AREF(transaction->cursors, i);
|
165
|
+
cursor_close(cursor);
|
166
|
+
}
|
167
|
+
rb_ary_clear(transaction->cursors);
|
168
|
+
|
169
|
+
// now actually finish the internal transaction
|
170
|
+
int ret = 0;
|
171
|
+
if (commit)
|
172
|
+
ret = mdb_txn_commit(transaction->txn);
|
173
|
+
else
|
174
|
+
mdb_txn_abort(transaction->txn);
|
175
|
+
|
176
|
+
// eliminate child transactions
|
177
|
+
if (transaction->child) {
|
178
|
+
p = self; // again this is a VALUE
|
179
|
+
Transaction* txn = transaction; // and this is the struct
|
180
|
+
|
181
|
+
// descend into deepest child transaction
|
182
|
+
do {
|
183
|
+
p = txn->child;
|
184
|
+
// this is TRANSACTION minus the declaration
|
185
|
+
Data_Get_Struct(txn->child, Transaction, txn);
|
186
|
+
} while (txn->child);
|
187
|
+
|
188
|
+
// now we ascend back up
|
172
189
|
while (p != self) {
|
173
|
-
|
174
|
-
|
175
|
-
|
190
|
+
TRANSACTION(p, txn);
|
191
|
+
txn->txn = 0;
|
192
|
+
p = txn->parent;
|
176
193
|
}
|
177
|
-
|
194
|
+
}
|
195
|
+
transaction->txn = 0;
|
178
196
|
|
179
|
-
|
197
|
+
// no more active read-write transaction; unset the registry
|
198
|
+
if (!(transaction->flags & MDB_RDONLY) && !transaction->parent) {
|
199
|
+
ENVIRONMENT(transaction->env, env);
|
200
|
+
env->rw_txn_thread = NULL;
|
201
|
+
}
|
180
202
|
|
181
|
-
|
203
|
+
// now set the active transaction to the parent, if there is one
|
204
|
+
environment_set_active_txn(transaction->env, transaction->thread,
|
205
|
+
transaction->parent);
|
206
|
+
|
207
|
+
check(ret);
|
182
208
|
}
|
183
209
|
|
184
210
|
// Ruby 1.8.7 compatibility
|
@@ -219,65 +245,143 @@ static void stop_txn_begin(void *arg)
|
|
219
245
|
txn_args->stop = 1;
|
220
246
|
}
|
221
247
|
|
248
|
+
/**
|
249
|
+
* This is the code that opens transactions. Read-write transactions
|
250
|
+
* have to be called outside the GVL because they will block without
|
251
|
+
*
|
252
|
+
*
|
253
|
+
* Here is the basic problem with LMDB transactions:
|
254
|
+
*
|
255
|
+
* - There can only be one read-write transaction per LMDB
|
256
|
+
* ENVIRONMENT, not process, not thread.
|
257
|
+
*
|
258
|
+
* - Read-write transactions can nest.
|
259
|
+
*
|
260
|
+
* - There can only be one active transaction per thread.
|
261
|
+
*
|
262
|
+
* - Every thread can have an active read-ONLY transaction, but only one.
|
263
|
+
*
|
264
|
+
* - This is because read-only transactions canNOT nest (it is
|
265
|
+
* meaningless to have a nested read-only transaction)
|
266
|
+
*
|
267
|
+
* - Furthermore it is an error to open a read-only transaction under
|
268
|
+
* a read-write transaction.
|
269
|
+
*
|
270
|
+
* - Same goes for opening a read-write transaction in the same thread
|
271
|
+
* as an active read-only transaction.
|
272
|
+
*
|
273
|
+
* Nevertheless, the downstream Ruby user may not be able to
|
274
|
+
* completely control calls to env.transaction (e.g. if they are
|
275
|
+
* wrapping a transaction around a proc or lambda that happens to
|
276
|
+
* contain its own transaction), plus every call in LMDB needs to be
|
277
|
+
* implicitly wrapped in a transaction anyway.
|
278
|
+
*
|
279
|
+
* What this means is that we will, first, have to keep explicit track
|
280
|
+
* of the read-write transaction, if one exists. Second, we will have
|
281
|
+
* to simulate nesting for read-only transactions, so the behaviour in
|
282
|
+
* Ruby is the same as a read-write transaction.
|
283
|
+
*
|
284
|
+
*/
|
285
|
+
|
222
286
|
static VALUE with_transaction(VALUE venv, VALUE(*fn)(VALUE), VALUE arg, int flags) {
|
223
|
-
|
287
|
+
ENVIRONMENT(venv, environment);
|
224
288
|
|
225
|
-
|
226
|
-
|
289
|
+
MDB_txn* txn;
|
290
|
+
TxnArgs txn_args;
|
227
291
|
|
228
|
-
|
229
|
-
|
292
|
+
VALUE thread = rb_thread_current();
|
293
|
+
VALUE vparent = environment_active_txn(venv);
|
230
294
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
txn_args.htxn = &txn;
|
235
|
-
txn_args.result = 0;
|
236
|
-
txn_args.stop = 0;
|
295
|
+
Transaction* tparent = NULL;
|
296
|
+
if (vparent && !NIL_P(vparent))
|
297
|
+
Data_Get_Struct(vparent, Transaction, tparent);
|
237
298
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
299
|
+
// rb_warn("fart lol");
|
300
|
+
|
301
|
+
// XXX note this is a cursed goto loop that could almost certainly
|
302
|
+
// be rewritten as a do-while
|
303
|
+
retry:
|
304
|
+
txn = NULL;
|
305
|
+
|
306
|
+
txn_args.env = environment->env;
|
307
|
+
txn_args.parent = active_txn(venv);
|
308
|
+
txn_args.flags = flags;
|
309
|
+
txn_args.htxn = &txn;
|
310
|
+
txn_args.result = 0;
|
311
|
+
txn_args.stop = 0;
|
312
|
+
|
313
|
+
if (flags & MDB_RDONLY) {
|
314
|
+
if (tparent && tparent->flags & MDB_RDONLY)
|
315
|
+
// this is a no-op: put the same actual transaction in a
|
316
|
+
// different wrapper struct
|
317
|
+
txn = txn_args.parent;
|
318
|
+
else
|
319
|
+
// this will return an error if the parent transaction is
|
320
|
+
// read-write, so we don't need to handle the case explicitly
|
321
|
+
call_txn_begin(&txn_args);
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
if (tparent) {
|
325
|
+
// first we have to determine if we're on the same thread
|
326
|
+
// as the parent, which in turn must be the same as the
|
327
|
+
// environment's registry for which thread has the
|
328
|
+
// read-write transaction
|
329
|
+
if (thread != tparent->thread ||
|
330
|
+
thread != environment->rw_txn_thread)
|
331
|
+
rb_raise(cError,
|
332
|
+
"Attempt to nest transaction on a different thread");
|
255
333
|
}
|
256
334
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
VALUE ret = rb_protect(fn, NIL_P(arg) ? vtxn : arg, &exception);
|
271
|
-
|
272
|
-
if (exception) {
|
273
|
-
//rb_warn("lol got exception");
|
274
|
-
if (vtxn == environment_active_txn(venv))
|
275
|
-
transaction_abort(vtxn);
|
276
|
-
rb_jump_tag(exception);
|
335
|
+
CALL_WITHOUT_GVL(call_txn_begin, &txn_args, stop_txn_begin, &txn_args);
|
336
|
+
|
337
|
+
if (txn_args.stop || !txn) {
|
338
|
+
// !txn is when rb_thread_call_without_gvl2
|
339
|
+
// returns before calling txn_begin
|
340
|
+
if (txn) {
|
341
|
+
mdb_txn_abort(txn);
|
342
|
+
txn_args.result = 0;
|
343
|
+
}
|
344
|
+
|
345
|
+
//rb_warn("got here lol");
|
346
|
+
rb_thread_check_ints();
|
347
|
+
goto retry; // in what cases do we get here?
|
277
348
|
}
|
349
|
+
|
350
|
+
// set the thread
|
351
|
+
environment->rw_txn_thread = thread;
|
352
|
+
}
|
353
|
+
|
354
|
+
// this will raise unless result is zero
|
355
|
+
check(txn_args.result);
|
356
|
+
|
357
|
+
Transaction* transaction;
|
358
|
+
VALUE vtxn = Data_Make_Struct(cTransaction, Transaction, transaction_mark,
|
359
|
+
transaction_free, transaction);
|
360
|
+
transaction->parent = vparent;
|
361
|
+
transaction->env = venv;
|
362
|
+
transaction->txn = txn;
|
363
|
+
transaction->flags = flags;
|
364
|
+
transaction->thread = rb_thread_current();
|
365
|
+
transaction->cursors = rb_ary_new();
|
366
|
+
|
367
|
+
// set the parent's child to self
|
368
|
+
if (tparent) tparent->child = vtxn;
|
369
|
+
|
370
|
+
environment_set_active_txn(venv, transaction->thread, vtxn);
|
371
|
+
|
372
|
+
// now we run the function in the transaction
|
373
|
+
int exception;
|
374
|
+
VALUE ret = rb_protect(fn, NIL_P(arg) ? vtxn : arg, &exception);
|
375
|
+
|
376
|
+
if (exception) {
|
377
|
+
// rb_warn("lol got exception");
|
278
378
|
if (vtxn == environment_active_txn(venv))
|
279
|
-
|
280
|
-
|
379
|
+
transaction_abort(vtxn);
|
380
|
+
rb_jump_tag(exception);
|
381
|
+
}
|
382
|
+
if (vtxn == environment_active_txn(venv))
|
383
|
+
transaction_commit(vtxn);
|
384
|
+
return ret;
|
281
385
|
}
|
282
386
|
|
283
387
|
static void environment_check(Environment* environment) {
|
@@ -674,7 +778,7 @@ static MDB_txn* active_txn(VALUE self) {
|
|
674
778
|
return 0;
|
675
779
|
TRANSACTION(vtxn, transaction);
|
676
780
|
if (!transaction->txn)
|
677
|
-
rb_raise(cError, "Transaction is terminated");
|
781
|
+
rb_raise(cError, "Transaction is already terminated");
|
678
782
|
if (transaction->thread != rb_thread_current())
|
679
783
|
rb_raise(cError, "Wrong thread");
|
680
784
|
return transaction->txn;
|
data/ext/lmdb_ext/lmdb_ext.h
CHANGED
@@ -47,19 +47,35 @@
|
|
47
47
|
Data_Get_Struct(var, Cursor, var_cur); \
|
48
48
|
cursor_check(var_cur)
|
49
49
|
|
50
|
+
/*
|
51
|
+
hey yo if you can convince hyc to add a function like
|
52
|
+
mdb_txn_get_flags or even mdb_txn_is_rdonly, you could probably get
|
53
|
+
rid of these wrapper structs and a lot of complexity, cause that is
|
54
|
+
literally the only reason why they're needed
|
55
|
+
|
56
|
+
actually no we would also need to know when a txn has a child and
|
57
|
+
there is also no mdb_txn_get_child or whatever
|
58
|
+
*/
|
59
|
+
|
50
60
|
typedef struct {
|
51
61
|
VALUE env;
|
52
|
-
VALUE parent;
|
62
|
+
VALUE parent; // ignored for ro threads
|
63
|
+
VALUE child; // ditto
|
53
64
|
VALUE thread;
|
54
65
|
VALUE cursors;
|
55
66
|
MDB_txn* txn;
|
56
67
|
unsigned int flags;
|
57
68
|
} Transaction;
|
58
69
|
|
70
|
+
// we have an extra field `rw_txn_thread` here that acts as the
|
71
|
+
// registry for the single read-write transaction. if it's populated,
|
72
|
+
// that's the one
|
73
|
+
|
59
74
|
typedef struct {
|
60
75
|
MDB_env* env;
|
61
|
-
VALUE thread_txn_hash;
|
62
|
-
VALUE txn_thread_hash;
|
76
|
+
VALUE thread_txn_hash; /* transaction -> thread */
|
77
|
+
VALUE txn_thread_hash; /* thread -> transaction */
|
78
|
+
VALUE rw_txn_thread; /* the thread with the rw transaction */
|
63
79
|
} Environment;
|
64
80
|
|
65
81
|
typedef struct {
|
data/lib/lmdb/database.rb
CHANGED
@@ -11,8 +11,8 @@ module LMDB
|
|
11
11
|
# puts "at #{key}: #{value}"
|
12
12
|
# end
|
13
13
|
def each
|
14
|
-
|
15
|
-
env.transaction do
|
14
|
+
maybe_txn true do
|
15
|
+
# env.transaction do
|
16
16
|
cursor do |c|
|
17
17
|
while i = c.next
|
18
18
|
yield(i)
|
@@ -56,8 +56,8 @@ module LMDB
|
|
56
56
|
# @return [Enumerator] in lieu of a block.
|
57
57
|
def each_key(&block)
|
58
58
|
return enum_for :each_key unless block_given?
|
59
|
-
|
60
|
-
env.transaction do
|
59
|
+
maybe_txn true do
|
60
|
+
#env.transaction do
|
61
61
|
cursor do |c|
|
62
62
|
while (rec = c.next true)
|
63
63
|
yield rec.first
|
@@ -81,8 +81,8 @@ module LMDB
|
|
81
81
|
return
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
|
-
env.transaction do
|
84
|
+
maybe_txn true do
|
85
|
+
# env.transaction do
|
86
86
|
cursor do |c|
|
87
87
|
method = :set
|
88
88
|
while rec = c.send(method, key)
|
@@ -124,8 +124,9 @@ module LMDB
|
|
124
124
|
|
125
125
|
ret = false
|
126
126
|
# read-only txn was having trouble being nested inside a read-write
|
127
|
-
|
128
|
-
env.transaction do
|
127
|
+
maybe_txn true do
|
128
|
+
# env.transaction true do
|
129
|
+
# env.transaction do
|
129
130
|
cursor { |c| ret = !!c.set(key, value) }
|
130
131
|
end
|
131
132
|
ret
|
data/lib/lmdb/version.rb
CHANGED
data/lmdb.gemspec
CHANGED
data/spec/helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lmdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Mendler
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ruby_memcheck
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
55
69
|
description: lmdb is a Ruby binding to OpenLDAP Lightning MDB.
|
56
70
|
email: mail@daniel-mendler.de
|
57
71
|
executables: []
|
@@ -66,6 +80,7 @@ files:
|
|
66
80
|
- Gemfile
|
67
81
|
- README.md
|
68
82
|
- Rakefile
|
83
|
+
- behaviour.org
|
69
84
|
- ext/lmdb_ext/cursor_delete_flags.h
|
70
85
|
- ext/lmdb_ext/cursor_put_flags.h
|
71
86
|
- ext/lmdb_ext/dbi_flags.h
|
@@ -95,7 +110,7 @@ homepage: https://github.com/minad/lmdb
|
|
95
110
|
licenses:
|
96
111
|
- MIT
|
97
112
|
metadata: {}
|
98
|
-
post_install_message:
|
113
|
+
post_install_message:
|
99
114
|
rdoc_options: []
|
100
115
|
require_paths:
|
101
116
|
- lib
|
@@ -110,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
125
|
- !ruby/object:Gem::Version
|
111
126
|
version: '0'
|
112
127
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
-
signing_key:
|
128
|
+
rubygems_version: 3.3.11
|
129
|
+
signing_key:
|
115
130
|
specification_version: 4
|
116
131
|
summary: Ruby bindings to Lightning MDB
|
117
132
|
test_files:
|