lmdb 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGES +4 -0
- data/CONTRIBUTORS +3 -0
- data/README.md +15 -8
- data/ext/lmdb_ext/extconf.rb +1 -0
- data/ext/lmdb_ext/lmdb_ext.c +582 -2
- data/lib/lmdb/database.rb +23 -0
- data/lib/lmdb/version.rb +1 -1
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92f31229585bce51aaa1f94fab800c5f98488869
|
4
|
+
data.tar.gz: e57e72dac8a031aeb3163c917252160b2c3c21c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7fe9fba9eae7efe4c0a15387906dd006e7f1f9659b8df9b8d7459386e9ea833df4b32e3df8d131d060299d6e948212d26dca9cb2b593d3f9106d55530b4c1b8
|
7
|
+
data.tar.gz: fc1108b3f94451fd44b29b9f37a30d0cd6641c8c5193552751f970ed46b67f91da32a7da3b044d4443371e515d781b537f6cc2df975169ea1beb6e50bc338514
|
data/.gitignore
CHANGED
data/CHANGES
CHANGED
data/CONTRIBUTORS
CHANGED
@@ -1,3 +1,6 @@
|
|
1
1
|
Daniel Mendler <mail@daniel-mendler.de>
|
2
2
|
Dimitrij Denissenko <dimitrij.denissenko@blacksquaremedia.com>
|
3
3
|
Evgeniy Dolzhenko <evgeniy.dolzhenko@blacksquaremedia.com>
|
4
|
+
Julien Ammous <schmurfy@gmail.com>
|
5
|
+
Nathaniel Pierce <nwpierce@gmail.com>
|
6
|
+
Richard Golding <golding@chrysaetos.org>
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
Ruby bindings for the amazing OpenLDAP's Lightning Memory-Mapped Database (LMDB)
|
7
7
|
http://symas.com/mdb/
|
8
8
|
|
9
|
-
|
9
|
+
## Installation
|
10
10
|
|
11
11
|
Install via rubygems:
|
12
12
|
|
@@ -14,9 +14,18 @@ Install via rubygems:
|
|
14
14
|
gem install lmdb
|
15
15
|
```
|
16
16
|
|
17
|
-
|
17
|
+
## Links
|
18
18
|
|
19
|
-
|
19
|
+
* Source: <http://github.com/minad/lmdb>
|
20
|
+
* Bugs: <http://github.com/minad/lmdb/issues>
|
21
|
+
* Tests and benchmarks: <http://travis-ci.org/minad/lmdb>
|
22
|
+
* API documentation:
|
23
|
+
* Latest Gem: <http://rubydoc.info/gems/lmdb/frames>
|
24
|
+
* GitHub master: <http://rubydoc.info/github/minad/lmdb/master/frames>
|
25
|
+
|
26
|
+
## API
|
27
|
+
|
28
|
+
```ruby
|
20
29
|
require 'lmdb'
|
21
30
|
|
22
31
|
env = LMDB.new(path)
|
@@ -32,13 +41,11 @@ env.transaction do
|
|
32
41
|
end
|
33
42
|
|
34
43
|
env.close
|
35
|
-
|
44
|
+
```
|
36
45
|
|
37
|
-
|
38
|
-
to LMDB databases please consider using [Moneta](https://github.com/minad/moneta).
|
39
|
-
The Moneta gem provides an LMDB adapter which uses this gem.
|
46
|
+
If you want to have a simpler interface to LMDB databases please consider using [Moneta](https://github.com/minad/moneta). The Moneta gem provides an LMDB adapter which uses this gem.
|
40
47
|
|
41
|
-
|
48
|
+
## Licence (MIT)
|
42
49
|
|
43
50
|
```
|
44
51
|
Copyright (c) 2013 Daniel Mendler
|
data/ext/lmdb_ext/extconf.rb
CHANGED
@@ -5,6 +5,7 @@ $CFLAGS = '-std=c99 -Wall -g'
|
|
5
5
|
# Embed lmdb if we cannot find it
|
6
6
|
if enable_config("bundled-lmdb", false) || !(find_header('lmdb.h') && have_library('lmdb', 'mdb_env_create'))
|
7
7
|
$INCFLAGS << " -I$(srcdir)/liblmdb"
|
8
|
+
$VPATH ||= []
|
8
9
|
$VPATH << "$(srcdir)/liblmdb"
|
9
10
|
$srcs = Dir.glob("#{$srcdir}/{,liblmdb/}*.c").map {|n| File.basename(n) }
|
10
11
|
end
|
data/ext/lmdb_ext/lmdb_ext.c
CHANGED
@@ -29,11 +29,58 @@ static void transaction_mark(Transaction* transaction) {
|
|
29
29
|
rb_gc_mark(transaction->env);
|
30
30
|
}
|
31
31
|
|
32
|
+
/**
|
33
|
+
* Commit a transaction in process. Any subtransactions of this
|
34
|
+
* transaction will be committed as well.
|
35
|
+
*
|
36
|
+
* One does not normally need to call commit explicitly; a
|
37
|
+
* commit is performed automatically when the block supplied to
|
38
|
+
* {Environment#transaction} exits normally.
|
39
|
+
*
|
40
|
+
* @note After committing a transaction, no further database operations
|
41
|
+
* should be done in the block. Any cursors created in the context
|
42
|
+
* of the transaction will no longer be valid.
|
43
|
+
*
|
44
|
+
* @example Single transaction
|
45
|
+
* env.transaction do |txn|
|
46
|
+
* # ... modify the databases ...
|
47
|
+
* txn.commit
|
48
|
+
* end
|
49
|
+
*
|
50
|
+
* @example Child transactions
|
51
|
+
* env.transaction do |txn1|
|
52
|
+
* env.transaction.do |txn2|
|
53
|
+
* txn1.commit # txn1 and txn2 are both committed
|
54
|
+
* end
|
55
|
+
* end
|
56
|
+
*/
|
32
57
|
static VALUE transaction_commit(VALUE self) {
|
33
58
|
transaction_finish(self, 1);
|
34
59
|
return Qnil;
|
35
60
|
}
|
36
61
|
|
62
|
+
/**
|
63
|
+
* Abort a transaction in process. Any subtransactions of this
|
64
|
+
* transaction will be aborted as well.
|
65
|
+
*
|
66
|
+
* @note After aborting a transaction, no further database operations
|
67
|
+
* should be done in the block. Any cursors created in the context
|
68
|
+
* of the transaction will no longer be valid.
|
69
|
+
*
|
70
|
+
* @example Single transaction
|
71
|
+
* env.transaction do |txn|
|
72
|
+
* # ... modify the databases ...
|
73
|
+
* txn.abort
|
74
|
+
* # modifications are rolled back
|
75
|
+
* end
|
76
|
+
*
|
77
|
+
* @example Child transactions
|
78
|
+
* env.transaction do |txn1|
|
79
|
+
* env.transaction.do |txn2|
|
80
|
+
* txn1.abort # txn1 and txn2 are both aborted
|
81
|
+
* end
|
82
|
+
* end
|
83
|
+
*/
|
37
84
|
static VALUE transaction_abort(VALUE self) {
|
38
85
|
transaction_finish(self, 0);
|
39
86
|
return Qnil;
|
@@ -140,6 +187,15 @@ static void environment_mark(Environment* environment) {
|
|
140
187
|
rb_gc_mark(environment->txn_thread_hash);
|
141
188
|
}
|
142
189
|
|
190
|
+
/**
|
191
|
+
* @overload close
|
192
|
+
* Close an environment, completing all IOs and cleaning up database
|
193
|
+
* state if needed.
|
194
|
+
* @example
|
195
|
+
* env = LMDB.new('abc')
|
196
|
+
* # ...various operations on the environment...
|
197
|
+
* env.close
|
198
|
+
*/
|
143
199
|
static VALUE environment_close(VALUE self) {
|
144
200
|
ENVIRONMENT(self, environment);
|
145
201
|
mdb_env_close(environment->env);
|
@@ -162,6 +218,17 @@ static VALUE stat2hash(const MDB_stat* stat) {
|
|
162
218
|
return ret;
|
163
219
|
}
|
164
220
|
|
221
|
+
/**
|
222
|
+
* @overload stat
|
223
|
+
* Return useful statistics about an environment.
|
224
|
+
* @return [Hash] the statistics
|
225
|
+
* * +:psize+ Size of a database page
|
226
|
+
* * +:depth+ Depth (height) of the B-tree
|
227
|
+
* * +:branch_pages+ Number of internal (non-leaf) pages
|
228
|
+
* * +:leaf_pages+ Number of leaf pages
|
229
|
+
* * +:overflow_pages+ Number of overflow pages
|
230
|
+
* * +:entries+ Number of data items
|
231
|
+
*/
|
165
232
|
static VALUE environment_stat(VALUE self) {
|
166
233
|
ENVIRONMENT(self, environment);
|
167
234
|
MDB_stat stat;
|
@@ -169,6 +236,17 @@ static VALUE environment_stat(VALUE self) {
|
|
169
236
|
return stat2hash(&stat);
|
170
237
|
}
|
171
238
|
|
239
|
+
/**
|
240
|
+
* @overload info
|
241
|
+
* Return useful information about an environment.
|
242
|
+
* @return [Hash]
|
243
|
+
* * +:mapaddr+ The memory address at which the database is mapped, if fixed
|
244
|
+
* * +:mapsize+ The size of the data memory map
|
245
|
+
* * +:last_pgno+ ID of the last used page
|
246
|
+
* * +:last_txnid+ ID of the last committed transaction
|
247
|
+
* * +:maxreaders+ Max reader slots in the environment
|
248
|
+
* * +:numreaders+ Max readers slots in the environment
|
249
|
+
*/
|
172
250
|
static VALUE environment_info(VALUE self) {
|
173
251
|
MDB_envinfo info;
|
174
252
|
|
@@ -189,12 +267,37 @@ static VALUE environment_info(VALUE self) {
|
|
189
267
|
return ret;
|
190
268
|
}
|
191
269
|
|
270
|
+
/**
|
271
|
+
* @overload copy(path)
|
272
|
+
* Create a copy (snapshot) of an environment. The copy can be used
|
273
|
+
* as a backup. The copy internally uses a read-only transaction to
|
274
|
+
* ensure that the copied data is serialized with respect to database
|
275
|
+
* updates.
|
276
|
+
* @param [String] path The directory in which the copy will
|
277
|
+
* reside. This directory must already exist and be writable but
|
278
|
+
* must otherwise be empty.
|
279
|
+
* @return nil
|
280
|
+
* @raise [Error] when there is an error creating the copy.
|
281
|
+
*/
|
192
282
|
static VALUE environment_copy(VALUE self, VALUE path) {
|
193
283
|
ENVIRONMENT(self, environment);
|
194
284
|
check(mdb_env_copy(environment->env, StringValueCStr(path)));
|
195
285
|
return Qnil;
|
196
286
|
}
|
197
287
|
|
288
|
+
/**
|
289
|
+
* @overload sync(force)
|
290
|
+
* Flush the data buffers to disk.
|
291
|
+
*
|
292
|
+
* Data is always written to disk when {Transaction#commit} is called, but
|
293
|
+
* the operating system may keep it buffered. MDB always flushes the
|
294
|
+
* OS buffers upon commit as well, unless the environment was opened
|
295
|
+
* with +:nosync+ or in part +:nometasync+.
|
296
|
+
* @param [Boolean] force If true, force a synchronous
|
297
|
+
* flush. Otherwise if the environment has the +:nosync+ flag set
|
298
|
+
* the flushes will be omitted, and with +:mapasync+ they will be
|
299
|
+
* asynchronous.
|
300
|
+
*/
|
198
301
|
static VALUE environment_sync(int argc, VALUE *argv, VALUE self) {
|
199
302
|
ENVIRONMENT(self, environment);
|
200
303
|
|
@@ -229,6 +332,40 @@ static int environment_options(VALUE key, VALUE value, EnvironmentOptions* optio
|
|
229
332
|
return 0;
|
230
333
|
}
|
231
334
|
|
335
|
+
/**
|
336
|
+
* @overload new(path, opts)
|
337
|
+
* Open an LMDB database environment.
|
338
|
+
* The database environment is the root object for all operations on
|
339
|
+
* a collection of databases. It has to be opened first, before
|
340
|
+
* individual databases can be opened or created in the environment.
|
341
|
+
* The database should be closed when it is no longer needed.
|
342
|
+
*
|
343
|
+
* The options hash on this method includes all the flags listed in
|
344
|
+
* {Environment#flags} as well as the options documented here.
|
345
|
+
* @return [Environment]
|
346
|
+
* @param [String] path the path to the files containing the database
|
347
|
+
* @param [Hash] opts options for the database environment
|
348
|
+
* @option opts [Number] :mode The Posix permissions to set on created files.
|
349
|
+
* @option opts [Number] :maxreaders The maximum number of concurrent threads
|
350
|
+
* that can be executing transactions at once. Default is 126.
|
351
|
+
* @option opts [Number] :maxdbs The maximum number of named databases in the
|
352
|
+
* environment. Not needed if only one database is being used.
|
353
|
+
* @option opts [Number] :mapsize The size of the memory map to be allocated
|
354
|
+
* for this environment, in bytes. The memory map size is the
|
355
|
+
* maximum total size of the database. The size should be a
|
356
|
+
* multiple of the OS page size. The default size is about
|
357
|
+
* 10MiB.
|
358
|
+
* @yield [env] The block to be executed with the environment. The environment is closed afterwards.
|
359
|
+
* @yieldparam env [Environment] The environment
|
360
|
+
* @see #close
|
361
|
+
* @see Environment#flags
|
362
|
+
* @example Open environment and pass options
|
363
|
+
* env = LMDB.new "dbdir", :maxdbs => 30, :mapasync => true, :writemap => true
|
364
|
+
* @example Pass environment to block
|
365
|
+
* LMDB.new "dbdir" do |env|
|
366
|
+
* # ...
|
367
|
+
* end
|
368
|
+
*/
|
232
369
|
static VALUE environment_new(int argc, VALUE *argv, VALUE klass) {
|
233
370
|
VALUE path, option_hash;
|
234
371
|
rb_scan_args(argc, argv, "1:", &path, &option_hash);
|
@@ -266,6 +403,23 @@ static VALUE environment_new(int argc, VALUE *argv, VALUE klass) {
|
|
266
403
|
return venv;
|
267
404
|
}
|
268
405
|
|
406
|
+
/**
|
407
|
+
* @overload flags
|
408
|
+
* Return the flags that are set in this environment.
|
409
|
+
* @return [Array] Array of flag symbols
|
410
|
+
* The environment flags are:
|
411
|
+
* * +:fixedmap+ Use a fixed address for the mmap region.
|
412
|
+
* * +:nosubdir+ By default, MDB creates its environment in a directory whose pathname is given in +path+, and creates its data and lock files under that directory. With this option, path is used as-is for the database main data file. The database lock file is the path with "-lock" appended.
|
413
|
+
* * +:nosync+ Don't flush system buffers to disk when committing a transaction. This optimization means a system crash can corrupt the database or lose the last transactions if buffers are not yet flushed to disk. The risk is governed by how often the system flushes dirty buffers to disk and how often {Environment#sync} is called. However, if the filesystem preserves write order and the +:writemap+ flag is not used, transactions exhibit ACI (atomicity, consistency, isolation) properties and only lose D (durability). That is, database integrity is maintained, but a system crash may undo the final transactions. Note that +:nosync + :writemap+ leaves the system with no hint for when to write transactions to disk, unless {Environment#sync} is called. +:mapasync + :writemap+ may be preferable.
|
414
|
+
* * +:rdonly+ Open the environment in read-only mode. No write operations will be allowed. MDB will still modify the lock file - except on read-only filesystems, where MDB does not use locks.
|
415
|
+
* * +:nometasync+ Flush system buffers to disk only once per transaction, omit the metadata flush. Defer that until the system flushes files to disk, or next non-MDB_RDONLY commit or {Environment#sync}. This optimization maintains database integrity, but a system crash may undo the last committed transaction. That is, it preserves the ACI (atomicity, consistency, isolation) but not D (durability) database property.
|
416
|
+
* * +:writemap+ Use a writeable memory map unless +:rdonly+ is set. This is faster and uses fewer mallocs, but loses protection from application bugs like wild pointer writes and other bad updates into the database. Incompatible with nested transactions.
|
417
|
+
* * +:mapasync+ When using +:writemap+, use asynchronous flushes to disk. As with +:nosync+, a system crash can then corrupt the database or lose the last transactions. Calling {Environment#sync} ensures on-disk database integrity until next commit.
|
418
|
+
* * +:notls+ Don't use thread-local storage.
|
419
|
+
* @example
|
420
|
+
* env = LMDB.new "abc", :writemap => true, :nometasync => true
|
421
|
+
* env.flags #=> [:writemap, :nometasync]
|
422
|
+
*/
|
269
423
|
static VALUE environment_flags(VALUE self) {
|
270
424
|
unsigned int flags;
|
271
425
|
ENVIRONMENT(self, environment);
|
@@ -279,6 +433,11 @@ static VALUE environment_flags(VALUE self) {
|
|
279
433
|
return ret;
|
280
434
|
}
|
281
435
|
|
436
|
+
/**
|
437
|
+
* @overload path
|
438
|
+
* Return the path to the database environment files
|
439
|
+
* @return [String] the path that was used to open the environment.
|
440
|
+
*/
|
282
441
|
static VALUE environment_path(VALUE self) {
|
283
442
|
const char* path;
|
284
443
|
ENVIRONMENT(self, environment);
|
@@ -303,16 +462,45 @@ static VALUE environment_change_flags(int argc, VALUE* argv, VALUE self, int set
|
|
303
462
|
return Qnil;
|
304
463
|
}
|
305
464
|
|
465
|
+
/**
|
466
|
+
* @overload set_flags(flags)
|
467
|
+
* Set one or more flags in the environment. The available flags are defined in {Environment#flags}.
|
468
|
+
* @see Environment#flags
|
469
|
+
* @param [Array] flags Array of flag names (symbols) to set
|
470
|
+
* @return nil
|
471
|
+
* @raise [Error] if an invalid flag name is specified
|
472
|
+
* @example
|
473
|
+
* env.set_flags :nosync, :writemap
|
474
|
+
*/
|
306
475
|
static VALUE environment_set_flags(int argc, VALUE* argv, VALUE self) {
|
307
476
|
environment_change_flags(argc, argv, self, 1);
|
308
477
|
return Qnil;
|
309
478
|
}
|
310
479
|
|
480
|
+
/**
|
481
|
+
* @overload clear_flags(flags)
|
482
|
+
* Clear one or more flags in the environment. The available flags are defined in {Environment#flags}.
|
483
|
+
* @see Environment#flags
|
484
|
+
* @param [Array] flags Array of flag names (symbols) to clear
|
485
|
+
* @return nil
|
486
|
+
* @raise [Error] if an invalid flag name is specified
|
487
|
+
* @example
|
488
|
+
* env.clear_flags :nosync, :writemap
|
489
|
+
*/
|
311
490
|
static VALUE environment_clear_flags(int argc, VALUE* argv, VALUE self) {
|
312
491
|
environment_change_flags(argc, argv, self, 0);
|
313
492
|
return Qnil;
|
314
493
|
}
|
315
494
|
|
495
|
+
/**
|
496
|
+
* @overload active_txn
|
497
|
+
* @return [Transaction] the current active transaction on this thread in the environment.
|
498
|
+
* @example
|
499
|
+
* env.transaction do |t|
|
500
|
+
* active = env.active_txn
|
501
|
+
* # active should equal t
|
502
|
+
* end
|
503
|
+
*/
|
316
504
|
static VALUE environment_active_txn(VALUE self) {
|
317
505
|
ENVIRONMENT(self, environment);
|
318
506
|
return rb_hash_aref(environment->thread_txn_hash, rb_thread_current());
|
@@ -353,6 +541,34 @@ static MDB_txn* need_txn(VALUE self) {
|
|
353
541
|
return txn;
|
354
542
|
}
|
355
543
|
|
544
|
+
/**
|
545
|
+
* @overload transaction(readonly)
|
546
|
+
* Begin a transaction. Takes a block to run the body of the
|
547
|
+
* transaction. A transaction commits when it exits the block successfully.
|
548
|
+
* A transaction aborts when it raises an exception or calls
|
549
|
+
* {Transaction#abort}.
|
550
|
+
* @param [Boolean] readonly This transaction will not perform any
|
551
|
+
* write operations
|
552
|
+
* @note Transactions can be nested.
|
553
|
+
* @yield [txn] The block to be executed with the body of the transaction.
|
554
|
+
* @yieldparam txn [Transaction] An optional transaction argument
|
555
|
+
* @example
|
556
|
+
* db = env.database "mydata"
|
557
|
+
* env.transaction do |txn1|
|
558
|
+
* db['a'] = 1
|
559
|
+
* env.transaction do |txn2|
|
560
|
+
* # txn2 is nested in txn1
|
561
|
+
* db['a'] = 2
|
562
|
+
* db['a'] #=> 2
|
563
|
+
* txn2.abort
|
564
|
+
* end
|
565
|
+
* db['a'] #=> 1
|
566
|
+
* env.transaction do
|
567
|
+
* db['a'] = 3
|
568
|
+
* end
|
569
|
+
* end
|
570
|
+
* db['a'] #=> 3
|
571
|
+
*/
|
356
572
|
static VALUE environment_transaction(int argc, VALUE *argv, VALUE self) {
|
357
573
|
rb_need_block();
|
358
574
|
|
@@ -373,6 +589,43 @@ static void database_mark(Database* database) {
|
|
373
589
|
#undef METHOD
|
374
590
|
#undef FILE
|
375
591
|
|
592
|
+
/**
|
593
|
+
* @overload database(name, options)
|
594
|
+
* Opens a database within the environment.
|
595
|
+
*
|
596
|
+
* Note that a database is opened or created within a transaction. If
|
597
|
+
* the open creates a new database, the database is not available for
|
598
|
+
* other operations in other transactions until the transaction that
|
599
|
+
* is creating the database commits. If the transaction creating the
|
600
|
+
* database aborts, the database is not created.
|
601
|
+
* @return [Database] newly-opened database
|
602
|
+
* @raise [Error] if there is an error opening the database
|
603
|
+
* @param [String] name Optional name for the database to be opened.
|
604
|
+
* @param [Hash] options Options for the database.
|
605
|
+
* @option options [Boolean] :reversekey Keys are strings to be
|
606
|
+
* compared in reverse order, from the end of the strings to the
|
607
|
+
* beginning. By default, Keys are treated as strings and
|
608
|
+
* compared from beginning to end.
|
609
|
+
* @option options [Boolean] :dupsort Duplicate keys may be used in
|
610
|
+
* the database. (Or, from another perspective, keys may have
|
611
|
+
* multiple data items, stored in sorted order.) By default keys
|
612
|
+
* must be unique and may have only a single data item.
|
613
|
+
* @option options [Boolean] :integerkey Keys are binary integers in
|
614
|
+
* native byte order.
|
615
|
+
* @option options [Boolean] :dupfixed This flag may only be used in
|
616
|
+
* combination with +:dupsort+. This option tells the library
|
617
|
+
* that the data items for this database are all the same size,
|
618
|
+
* which allows further optimizations in storage and retrieval.
|
619
|
+
* @option options [Boolean] :integerdup This option specifies that
|
620
|
+
* duplicate data items are also integers, and should be sorted
|
621
|
+
* as such.
|
622
|
+
* @option options [Boolean] :reversedup This option specifies that
|
623
|
+
* duplicate data items should be compared as strings in reverse
|
624
|
+
* order.
|
625
|
+
* @option options [Boolean] :create Create the named database if it
|
626
|
+
* doesn't exist. This option is not allowed in a read-only
|
627
|
+
* transaction or a read-only environment.
|
628
|
+
*/
|
376
629
|
static VALUE environment_database(int argc, VALUE *argv, VALUE self) {
|
377
630
|
ENVIRONMENT(self, environment);
|
378
631
|
if (!active_txn(self))
|
@@ -396,6 +649,17 @@ static VALUE environment_database(int argc, VALUE *argv, VALUE self) {
|
|
396
649
|
return vdb;
|
397
650
|
}
|
398
651
|
|
652
|
+
/**
|
653
|
+
* @overload stat
|
654
|
+
* Return useful statistics about a database.
|
655
|
+
* @return [Hash] the statistics
|
656
|
+
* * +:psize+ Size of a database page
|
657
|
+
* * +:depth+ Depth (height) of the B-tree
|
658
|
+
* * +:branch_pages+ Number of internal (non-leaf) pages
|
659
|
+
* * +:leaf_pages+ Number of leaf pages
|
660
|
+
* * +:overflow_pages+ Number of overflow pages
|
661
|
+
* * +:entries+ Number of data items
|
662
|
+
*/
|
399
663
|
static VALUE database_stat(VALUE self) {
|
400
664
|
DATABASE(self, database);
|
401
665
|
if (!active_txn(database->env))
|
@@ -406,6 +670,12 @@ static VALUE database_stat(VALUE self) {
|
|
406
670
|
return stat2hash(&stat);
|
407
671
|
}
|
408
672
|
|
673
|
+
/**
|
674
|
+
* @overload drop
|
675
|
+
* Remove a database from the environment.
|
676
|
+
* @return nil
|
677
|
+
* @note The drop happens transactionally.
|
678
|
+
*/
|
409
679
|
static VALUE database_drop(VALUE self) {
|
410
680
|
DATABASE(self, database);
|
411
681
|
if (!active_txn(database->env))
|
@@ -414,6 +684,12 @@ static VALUE database_drop(VALUE self) {
|
|
414
684
|
return Qnil;
|
415
685
|
}
|
416
686
|
|
687
|
+
/**
|
688
|
+
* @overload clear
|
689
|
+
* Empty out the database
|
690
|
+
* @return nil
|
691
|
+
* @note The clear happens transactionally.
|
692
|
+
*/
|
417
693
|
static VALUE database_clear(VALUE self) {
|
418
694
|
DATABASE(self, database);
|
419
695
|
if (!active_txn(database->env))
|
@@ -422,6 +698,15 @@ static VALUE database_clear(VALUE self) {
|
|
422
698
|
return Qnil;
|
423
699
|
}
|
424
700
|
|
701
|
+
/**
|
702
|
+
* @overload get(key)
|
703
|
+
* Retrieves one value associated with this key.
|
704
|
+
* This function retrieves key/data pairs from the database. If the
|
705
|
+
* database supports duplicate keys (+:dupsort+) then the first data
|
706
|
+
* item for the key will be returned. Retrieval of other items
|
707
|
+
* requires the use of {#cursor}.
|
708
|
+
* @param key The key of the record to retrieve.
|
709
|
+
*/
|
425
710
|
static VALUE database_get(VALUE self, VALUE vkey) {
|
426
711
|
DATABASE(self, database);
|
427
712
|
if (!active_txn(database->env))
|
@@ -445,6 +730,33 @@ static VALUE database_get(VALUE self, VALUE vkey) {
|
|
445
730
|
#undef METHOD
|
446
731
|
#undef FILE
|
447
732
|
|
733
|
+
/**
|
734
|
+
* @overload put(key, value, options)
|
735
|
+
* Stores items into a database.
|
736
|
+
* This function stores key/value pairs in the database. The default
|
737
|
+
* behavior is to enter the new key/value pair, replacing any
|
738
|
+
* previously existing key if duplicates are disallowed, or adding a
|
739
|
+
* duplicate data item if duplicates are allowed (+:dupsort+).
|
740
|
+
* @param key The key of the record to set
|
741
|
+
* @param value The value to insert for this key
|
742
|
+
* @option options [Boolean] :nodupdata Enter the new key/value
|
743
|
+
* pair only if it does not already appear in the database. This
|
744
|
+
* flag may only be specified if the database was opened with
|
745
|
+
* +:dupsort+. The function will raise an {Error} if the
|
746
|
+
* key/data pair already appears in the database.
|
747
|
+
* @option options [Boolean] :nooverwrite Enter the new key/value
|
748
|
+
* pair only if the key does not already appear in the
|
749
|
+
* database. The function will raise an {Error] if the key
|
750
|
+
* already appears in the database, even if the database
|
751
|
+
* supports duplicates (+:dupsort+).
|
752
|
+
* @option options [Boolean] :append Append the given key/data pair
|
753
|
+
* to the end of the database. No key comparisons are
|
754
|
+
* performed. This option allows fast bulk loading when keys are
|
755
|
+
* already known to be in the correct order. Loading unsorted
|
756
|
+
* keys with this flag will cause data corruption.
|
757
|
+
* @option options [Boolean] :appenddup As above, but for sorted dup
|
758
|
+
* data.
|
759
|
+
*/
|
448
760
|
static VALUE database_put(int argc, VALUE *argv, VALUE self) {
|
449
761
|
DATABASE(self, database);
|
450
762
|
if (!active_txn(database->env))
|
@@ -470,6 +782,21 @@ static VALUE database_put(int argc, VALUE *argv, VALUE self) {
|
|
470
782
|
return Qnil;
|
471
783
|
}
|
472
784
|
|
785
|
+
/**
|
786
|
+
* @overload delete(key, value=nil)
|
787
|
+
*
|
788
|
+
* Deletes records from the database. This function removes
|
789
|
+
* key/data pairs from the database. If the database does not support
|
790
|
+
* sorted duplicate data items (+:dupsort+) the value parameter is
|
791
|
+
* ignored. If the database supports sorted duplicates and the value
|
792
|
+
* parameter is +nil+, all of the duplicate data items for the key will
|
793
|
+
* be deleted. Otherwise, if the data parameter is non-nil only the
|
794
|
+
* matching data item will be deleted.
|
795
|
+
*
|
796
|
+
* @param key The key of the record to delete.
|
797
|
+
* @param value The optional value of the record to delete.
|
798
|
+
* @raise [Error] if the specified key/value pair is not in the database.
|
799
|
+
*/
|
473
800
|
static VALUE database_delete(int argc, VALUE *argv, VALUE self) {
|
474
801
|
DATABASE(self, database);
|
475
802
|
if (!active_txn(database->env))
|
@@ -515,6 +842,10 @@ static void cursor_mark(Cursor* cursor) {
|
|
515
842
|
rb_gc_mark(cursor->db);
|
516
843
|
}
|
517
844
|
|
845
|
+
/**
|
846
|
+
* @overload close
|
847
|
+
* Close a cursor. The cursor must not be used again after this call.
|
848
|
+
*/
|
518
849
|
static VALUE cursor_close(VALUE self) {
|
519
850
|
CURSOR(self, cursor);
|
520
851
|
mdb_cursor_close(cursor->cur);
|
@@ -522,6 +853,20 @@ static VALUE cursor_close(VALUE self) {
|
|
522
853
|
return Qnil;
|
523
854
|
}
|
524
855
|
|
856
|
+
/**
|
857
|
+
* @overload cursor
|
858
|
+
* Create a cursor to iterate through a database.
|
859
|
+
*
|
860
|
+
* @see Cursor
|
861
|
+
* @yield [cursor] A block to be executed with the cursor
|
862
|
+
* @yieldparam cursor [Cursor] The cursor to be used to iterate
|
863
|
+
* @example
|
864
|
+
* db = env.database "abc"
|
865
|
+
* db.cursor do |c|
|
866
|
+
* key, value = c.next
|
867
|
+
* puts "#{key}: #{value}"
|
868
|
+
* end
|
869
|
+
*/
|
525
870
|
static VALUE database_cursor(VALUE self) {
|
526
871
|
DATABASE(self, database);
|
527
872
|
if (!active_txn(database->env))
|
@@ -549,6 +894,13 @@ static VALUE database_cursor(VALUE self) {
|
|
549
894
|
return vcur;
|
550
895
|
}
|
551
896
|
|
897
|
+
/**
|
898
|
+
* @overload first
|
899
|
+
* Position the cursor to the first record in the database, and
|
900
|
+
* return its value.
|
901
|
+
* @return [Array,nil] The [key, value] pair for the first record, or
|
902
|
+
* nil if no record
|
903
|
+
*/
|
552
904
|
static VALUE cursor_first(VALUE self) {
|
553
905
|
CURSOR(self, cursor);
|
554
906
|
MDB_val key, value;
|
@@ -557,6 +909,13 @@ static VALUE cursor_first(VALUE self) {
|
|
557
909
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
558
910
|
}
|
559
911
|
|
912
|
+
/**
|
913
|
+
* @overload last
|
914
|
+
* Position the cursor to the last record in the database, and
|
915
|
+
* return its value.
|
916
|
+
* @return [Array,nil] The [key, value] pair for the last record, or
|
917
|
+
* nil if no record.
|
918
|
+
*/
|
560
919
|
static VALUE cursor_last(VALUE self) {
|
561
920
|
CURSOR(self, cursor);
|
562
921
|
MDB_val key, value;
|
@@ -565,6 +924,13 @@ static VALUE cursor_last(VALUE self) {
|
|
565
924
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
566
925
|
}
|
567
926
|
|
927
|
+
/**
|
928
|
+
* @overload prev
|
929
|
+
* Position the cursor to the previous record in the database, and
|
930
|
+
* return its value.
|
931
|
+
* @return [Array,nil] The [key, value] pair for the previous record, or
|
932
|
+
* nil if no previous record.
|
933
|
+
*/
|
568
934
|
static VALUE cursor_prev(VALUE self) {
|
569
935
|
CURSOR(self, cursor);
|
570
936
|
MDB_val key, value;
|
@@ -576,6 +942,13 @@ static VALUE cursor_prev(VALUE self) {
|
|
576
942
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
577
943
|
}
|
578
944
|
|
945
|
+
/**
|
946
|
+
* @overload next
|
947
|
+
* Position the cursor to the next record in the database, and
|
948
|
+
* return its value.
|
949
|
+
* @return [Array,nil] The [key, value] pair for the next record, or
|
950
|
+
* nil if no next record.
|
951
|
+
*/
|
579
952
|
static VALUE cursor_next(VALUE self) {
|
580
953
|
CURSOR(self, cursor);
|
581
954
|
MDB_val key, value;
|
@@ -587,6 +960,12 @@ static VALUE cursor_next(VALUE self) {
|
|
587
960
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
588
961
|
}
|
589
962
|
|
963
|
+
/**
|
964
|
+
* @overload set(key)
|
965
|
+
* Set the cursor to a specified key
|
966
|
+
* @param key The key to which the cursor should be positioned
|
967
|
+
* @return [Array] The [key, value] pair to which the cursor now points.
|
968
|
+
*/
|
590
969
|
static VALUE cursor_set(VALUE self, VALUE vkey) {
|
591
970
|
CURSOR(self, cursor);
|
592
971
|
MDB_val key, value;
|
@@ -598,6 +977,12 @@ static VALUE cursor_set(VALUE self, VALUE vkey) {
|
|
598
977
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
599
978
|
}
|
600
979
|
|
980
|
+
/**
|
981
|
+
* @overload set_range(key)
|
982
|
+
* Set the cursor at the first key greater than or equal to a specified key.
|
983
|
+
* @param key The key to which the cursor should be positioned
|
984
|
+
* @return [Array] The [key, value] pair to which the cursor now points.
|
985
|
+
*/
|
601
986
|
static VALUE cursor_set_range(VALUE self, VALUE vkey) {
|
602
987
|
CURSOR(self, cursor);
|
603
988
|
MDB_val key, value;
|
@@ -609,6 +994,12 @@ static VALUE cursor_set_range(VALUE self, VALUE vkey) {
|
|
609
994
|
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
|
610
995
|
}
|
611
996
|
|
997
|
+
/**
|
998
|
+
* @overload get
|
999
|
+
* Return the value of the record to which the cursor points.
|
1000
|
+
* @return [Array] The [key, value] pair for the current record.
|
1001
|
+
*/
|
1002
|
+
|
612
1003
|
static VALUE cursor_get(VALUE self) {
|
613
1004
|
CURSOR(self, cursor);
|
614
1005
|
|
@@ -626,6 +1017,37 @@ static VALUE cursor_get(VALUE self) {
|
|
626
1017
|
#undef METHOD
|
627
1018
|
#undef FILE
|
628
1019
|
|
1020
|
+
/**
|
1021
|
+
* @overload put(key, value, options)
|
1022
|
+
* Store by cursor. This function stores key/data pairs into the
|
1023
|
+
* database. If the function fails for any reason, the state of
|
1024
|
+
* the cursor will be unchanged. If the function succeeds and an
|
1025
|
+
* item is inserted into the database, the cursor is always
|
1026
|
+
* positioned to refer to the newly inserted item.
|
1027
|
+
* @return nil
|
1028
|
+
* @param key The key of the record to set
|
1029
|
+
* @param value The value to insert for this key
|
1030
|
+
* @option options [Boolean] :current Overwrite the data of the
|
1031
|
+
* key/data pair to which the cursor refers with the specified
|
1032
|
+
* data item. The +key+ parameter is ignored.
|
1033
|
+
* @option options [Boolean] :nodupdata Enter the new key/value
|
1034
|
+
* pair only if it does not already appear in the database. This
|
1035
|
+
* flag may only be specified if the database was opened with
|
1036
|
+
* +:dupsort+. The function will raise an {Error} if the
|
1037
|
+
* key/data pair already appears in the database.
|
1038
|
+
* @option options [Boolean] :nooverwrite Enter the new key/value
|
1039
|
+
* pair only if the key does not already appear in the
|
1040
|
+
* database. The function will raise an {Error] if the key
|
1041
|
+
* already appears in the database, even if the database
|
1042
|
+
* supports duplicates (+:dupsort+).
|
1043
|
+
* @option options [Boolean] :append Append the given key/data pair
|
1044
|
+
* to the end of the database. No key comparisons are
|
1045
|
+
* performed. This option allows fast bulk loading when keys are
|
1046
|
+
* already known to be in the correct order. Loading unsorted
|
1047
|
+
* keys with this flag will cause data corruption.
|
1048
|
+
* @option options [Boolean] :appenddup As above, but for sorted dup
|
1049
|
+
* data.
|
1050
|
+
*/
|
629
1051
|
static VALUE cursor_put(int argc, VALUE* argv, VALUE self) {
|
630
1052
|
CURSOR(self, cursor);
|
631
1053
|
|
@@ -655,6 +1077,14 @@ static VALUE cursor_put(int argc, VALUE* argv, VALUE self) {
|
|
655
1077
|
#undef METHOD
|
656
1078
|
#undef FILE
|
657
1079
|
|
1080
|
+
/**
|
1081
|
+
* @overload delete(options)
|
1082
|
+
* Delete current key/data pair.
|
1083
|
+
* This function deletes the key/data pair to which the cursor refers.
|
1084
|
+
* @option options [Boolean] :nodupdata Delete all of the data
|
1085
|
+
* items for the current key. This flag may only be specified
|
1086
|
+
* if the database was opened with +:dupsort+.
|
1087
|
+
*/
|
658
1088
|
static VALUE cursor_delete(int argc, VALUE *argv, VALUE self) {
|
659
1089
|
CURSOR(self, cursor);
|
660
1090
|
|
@@ -669,6 +1099,13 @@ static VALUE cursor_delete(int argc, VALUE *argv, VALUE self) {
|
|
669
1099
|
return Qnil;
|
670
1100
|
}
|
671
1101
|
|
1102
|
+
/**
|
1103
|
+
* @overload count
|
1104
|
+
* Return count of duplicates for current key. This call is only
|
1105
|
+
* valid on databases that support sorted duplicate data items
|
1106
|
+
* +:dupsort+.
|
1107
|
+
* @return [Number] count of duplicates
|
1108
|
+
*/
|
672
1109
|
static VALUE cursor_count(VALUE self) {
|
673
1110
|
CURSOR(self, cursor);
|
674
1111
|
size_t count;
|
@@ -679,6 +1116,12 @@ static VALUE cursor_count(VALUE self) {
|
|
679
1116
|
void Init_lmdb_ext() {
|
680
1117
|
VALUE mLMDB;
|
681
1118
|
|
1119
|
+
/**
|
1120
|
+
* Document-module: LMDB
|
1121
|
+
*
|
1122
|
+
* The LMDB module presents a Ruby API to the OpenLDAP Lightning Memory-mapped Database (LMDB).
|
1123
|
+
* @see http://symas.com/mdb/
|
1124
|
+
*/
|
682
1125
|
mLMDB = rb_define_module("LMDB");
|
683
1126
|
rb_define_const(mLMDB, "LIB_VERSION", rb_str_new2(MDB_VERSION_STRING));
|
684
1127
|
rb_define_singleton_method(mLMDB, "new", environment_new, -1);
|
@@ -689,11 +1132,40 @@ void Init_lmdb_ext() {
|
|
689
1132
|
VERSION_CONST(PATCH)
|
690
1133
|
#undef VERSION_CONST
|
691
1134
|
|
1135
|
+
/**
|
1136
|
+
* Document-class: LMDB::Error
|
1137
|
+
*
|
1138
|
+
* A general class of exceptions raised within the LMDB gem.
|
1139
|
+
*/
|
692
1140
|
cError = rb_define_class_under(mLMDB, "Error", rb_eRuntimeError);
|
693
1141
|
#define ERROR(name) cError_##name = rb_define_class_under(cError, #name, cError);
|
694
1142
|
#include "errors.h"
|
695
1143
|
#undef ERROR
|
696
1144
|
|
1145
|
+
/**
|
1146
|
+
* Document-class: LMDB::Environment
|
1147
|
+
*
|
1148
|
+
* The Environment is the root object for all LMDB operations.
|
1149
|
+
*
|
1150
|
+
* An LMDB "environment" is a collection of one or more "databases"
|
1151
|
+
* (key-value tables), along with transactions to modify those
|
1152
|
+
* databases and cursors to iterate through them.
|
1153
|
+
*
|
1154
|
+
* An environment -- and its collection of databases -- is normally
|
1155
|
+
* stored in a directory. That directory will contain two files:
|
1156
|
+
* * +data.mdb+: all the records in all the databases in the environment
|
1157
|
+
* * +lock.mdb+: state of transactions that may be going on in the environment.
|
1158
|
+
*
|
1159
|
+
* An environment can contain multiple databases. Each of the
|
1160
|
+
* databases has a string name ("mydatabase", "db.3.1982"). You use
|
1161
|
+
* the database name to open the database within the environment.
|
1162
|
+
*
|
1163
|
+
* @example The normal pattern for using LMDB in Ruby
|
1164
|
+
* env = LMDB.new "databasedir"
|
1165
|
+
* db = env.database "databasename"
|
1166
|
+
* # ... do things to the database ...
|
1167
|
+
* env.close
|
1168
|
+
*/
|
697
1169
|
cEnvironment = rb_define_class_under(mLMDB, "Environment", rb_cObject);
|
698
1170
|
rb_define_singleton_method(cEnvironment, "new", environment_new, -1);
|
699
1171
|
rb_define_method(cEnvironment, "database", environment_database, -1);
|
@@ -709,6 +1181,31 @@ void Init_lmdb_ext() {
|
|
709
1181
|
rb_define_method(cEnvironment, "path", environment_path, 0);
|
710
1182
|
rb_define_method(cEnvironment, "transaction", environment_transaction, -1);
|
711
1183
|
|
1184
|
+
/**
|
1185
|
+
* Document-class: LMDB::Database
|
1186
|
+
*
|
1187
|
+
* An LMDB Database is a table of key-value pairs. It is stored as
|
1188
|
+
* part of the {Environment}.
|
1189
|
+
*
|
1190
|
+
* By default, each key in a Database maps to one value. However, a
|
1191
|
+
* Database can be configured at creation to allow duplicate keys, in
|
1192
|
+
* which case one key will map to multiple values.
|
1193
|
+
*
|
1194
|
+
* A Database stores the keys in a sorted order. The order can also
|
1195
|
+
* be set with options when the database is created.
|
1196
|
+
*
|
1197
|
+
* The basic operations on a database are to {#put}, {#get}, and
|
1198
|
+
* {#delete} records. One can also iterate through the records in a
|
1199
|
+
* database using a {Cursor}.
|
1200
|
+
*
|
1201
|
+
* @example Typical usage
|
1202
|
+
* env = LMDB.new "databasedir"
|
1203
|
+
* db = env.database "databasename"
|
1204
|
+
* db.put "key1", "value1"
|
1205
|
+
* db.put "key2", "value2"
|
1206
|
+
* db.get "key1" #=> "value1"
|
1207
|
+
* env.close
|
1208
|
+
*/
|
712
1209
|
cDatabase = rb_define_class_under(mLMDB, "Database", rb_cObject);
|
713
1210
|
rb_undef_method(rb_singleton_class(cDatabase), "new");
|
714
1211
|
rb_define_method(cDatabase, "stat", database_stat, 0);
|
@@ -719,11 +1216,94 @@ void Init_lmdb_ext() {
|
|
719
1216
|
rb_define_method(cDatabase, "delete", database_delete, -1);
|
720
1217
|
rb_define_method(cDatabase, "cursor", database_cursor, 0);
|
721
1218
|
|
1219
|
+
/**
|
1220
|
+
* Document-class: LMDB::Transaction
|
1221
|
+
*
|
1222
|
+
* The LMDB environment supports transactional reads and updates. By
|
1223
|
+
* default, these provide the standard ACID (atomicity, consistency,
|
1224
|
+
* isolation, durability) behaviors.
|
1225
|
+
*
|
1226
|
+
* Transactions can be committed or aborted. When a transaction is
|
1227
|
+
* committed, all its effects take effect in the database atomically.
|
1228
|
+
* When a transaction is aborted, none of its effects take effect.
|
1229
|
+
*
|
1230
|
+
* Transactions span the entire environment. All the updates made in
|
1231
|
+
* the course of an update transaction -- writing records across all
|
1232
|
+
* databases, creating databases, and destroying databases -- are
|
1233
|
+
* either completed atomically or rolled back.
|
1234
|
+
*
|
1235
|
+
* Transactions can be nested. A child transaction can be started
|
1236
|
+
* within a parent transaction. The child transaction can commit or
|
1237
|
+
* abort, at which point the effects of the child become visible to
|
1238
|
+
* the parent transaction or not. If the parent aborts, all of the
|
1239
|
+
* changes performed in the context of the parent -- including the
|
1240
|
+
* changes from a committed child transaction -- are rolled back.
|
1241
|
+
*
|
1242
|
+
* To create a transaction, call {Environment#transaction} and supply
|
1243
|
+
* a block for the code to execute in that transaction.
|
1244
|
+
*
|
1245
|
+
* @example Typical usage
|
1246
|
+
* env = LMDB.new "databasedir"
|
1247
|
+
* db1 = env.database "database1"
|
1248
|
+
* env.transaction do |parent|
|
1249
|
+
* db2 = env.database "database2", :create => true
|
1250
|
+
* #=> creates a new database, but it isn't
|
1251
|
+
* #=> yet committed to storage
|
1252
|
+
* db1['x'] #=> nil
|
1253
|
+
* env.transaction do |child1|
|
1254
|
+
* db2['a'] = 'b'
|
1255
|
+
* db1['x'] = 'y'
|
1256
|
+
* end
|
1257
|
+
* #=> first child transaction commits
|
1258
|
+
* #=> changes are visible within the parent transaction
|
1259
|
+
* #=> but are not yet permanent
|
1260
|
+
* db1['x'] #=> 'y'
|
1261
|
+
* db2['a'] #=> 'a'
|
1262
|
+
* env.transaction do |child2|
|
1263
|
+
* db2['a'] = 'def'
|
1264
|
+
* db1['x'] = 'ghi'
|
1265
|
+
* child2.abort
|
1266
|
+
* #=> second child transaction aborts and rolls
|
1267
|
+
* #=> back its changes
|
1268
|
+
* end
|
1269
|
+
* db1['x'] #=> 'y'
|
1270
|
+
* db2['a'] #=> 'a'
|
1271
|
+
* end
|
1272
|
+
* #=> parent transaction commits and writes database2
|
1273
|
+
* #=> and the updates from transaction child1 to
|
1274
|
+
* #=> storage.
|
1275
|
+
*/
|
722
1276
|
cTransaction = rb_define_class_under(mLMDB, "Transaction", rb_cObject);
|
723
1277
|
rb_undef_method(rb_singleton_class(cTransaction), "new");
|
724
1278
|
rb_define_method(cTransaction, "commit", transaction_commit, 0);
|
725
1279
|
rb_define_method(cTransaction, "abort", transaction_abort, 0);
|
726
1280
|
|
1281
|
+
/**
|
1282
|
+
* Document-class: LMDB::Cursor
|
1283
|
+
*
|
1284
|
+
* A Cursor points to records in a database, and is used to iterate
|
1285
|
+
* through the records in the database.
|
1286
|
+
*
|
1287
|
+
* Cursors are created in the context of a transaction, and should
|
1288
|
+
* only be used as long as that transaction is active. In other words,
|
1289
|
+
* after you {Transaction#commit} or {Transaction#abort} a transaction,
|
1290
|
+
* the cursors created while that transaction was active are no longer
|
1291
|
+
* usable.
|
1292
|
+
*
|
1293
|
+
* To create a cursor, call {Database#cursor} and pass it a block for
|
1294
|
+
* that should be performed using the cursor.
|
1295
|
+
*
|
1296
|
+
* @example Typical usage
|
1297
|
+
* env = LMDB.new "databasedir"
|
1298
|
+
* db = env.database "databasename"
|
1299
|
+
* db.cursor do |cursor|
|
1300
|
+
* rl = cursor.last #=> content of the last record
|
1301
|
+
* r1 = cursor.first #=> content of the first record
|
1302
|
+
* r2 = cursor.next #=> content of the second record
|
1303
|
+
* cursor.put "x", "y", current: true
|
1304
|
+
* #=> replaces the second record with a new value "y"
|
1305
|
+
* end
|
1306
|
+
*/
|
727
1307
|
cCursor = rb_define_class_under(mLMDB, "Cursor", rb_cObject);
|
728
1308
|
rb_undef_method(rb_singleton_class(cCursor), "new");
|
729
1309
|
rb_define_method(cCursor, "close", cursor_close, 0);
|
@@ -734,7 +1314,7 @@ void Init_lmdb_ext() {
|
|
734
1314
|
rb_define_method(cCursor, "prev", cursor_prev, 0);
|
735
1315
|
rb_define_method(cCursor, "set", cursor_set, 1);
|
736
1316
|
rb_define_method(cCursor, "set_range", cursor_set_range, 1);
|
737
|
-
rb_define_method(cCursor, "put", cursor_put,
|
1317
|
+
rb_define_method(cCursor, "put", cursor_put, -1);
|
738
1318
|
rb_define_method(cCursor, "count", cursor_count, 0);
|
739
|
-
rb_define_method(cCursor, "delete", cursor_delete,
|
1319
|
+
rb_define_method(cCursor, "delete", cursor_delete, -1);
|
740
1320
|
}
|
data/lib/lmdb/database.rb
CHANGED
@@ -2,6 +2,14 @@ module LMDB
|
|
2
2
|
class Database
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
+
# Iterate through the records in a database
|
6
|
+
# @yield [i] Gives a record [key, value] to the block
|
7
|
+
# @yieldparam [Array] i The key, value pair for each record
|
8
|
+
# @example
|
9
|
+
# db.each do |record|
|
10
|
+
# key, value = record
|
11
|
+
# puts "at #{key}: #{value}"
|
12
|
+
# end
|
5
13
|
def each
|
6
14
|
cursor do |c|
|
7
15
|
while i = c.next
|
@@ -10,15 +18,30 @@ module LMDB
|
|
10
18
|
end
|
11
19
|
end
|
12
20
|
|
21
|
+
# Retrieve the value of a record from a database
|
22
|
+
# @param key the record key to retrieve
|
23
|
+
# @return value of the record for that key, or nil if there is
|
24
|
+
# no record with that key
|
25
|
+
# @see #get(key)
|
13
26
|
def [](key)
|
14
27
|
get(key)
|
15
28
|
end
|
16
29
|
|
30
|
+
# Set (write or update) a record in a database.
|
31
|
+
# @param key key for the record
|
32
|
+
# @param value the value of the record
|
33
|
+
# @return returns the value of the record
|
34
|
+
# @see #put(key, value)
|
35
|
+
# @example
|
36
|
+
# db['a'] = 'b' #=> 'b'
|
37
|
+
# db['b'] = 1234 #=> 1234
|
38
|
+
# db['a'] #=> 'b'
|
17
39
|
def []=(key, value)
|
18
40
|
put(key, value)
|
19
41
|
value
|
20
42
|
end
|
21
43
|
|
44
|
+
# @return the number of records in this database
|
22
45
|
def size
|
23
46
|
stat[:entries]
|
24
47
|
end
|
data/lib/lmdb/version.rb
CHANGED
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lmdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Mendler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake-compiler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - <=
|
31
|
+
- - "<="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.8.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - <=
|
38
|
+
- - "<="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.8.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
description: lmdb is a Ruby binding to OpenLDAP Lightning MDB.
|
@@ -59,8 +59,8 @@ extensions:
|
|
59
59
|
- ext/lmdb_ext/extconf.rb
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- .travis.yml
|
62
|
+
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
64
64
|
- CHANGES
|
65
65
|
- CONTRIBUTORS
|
66
66
|
- Gemfile
|
@@ -101,17 +101,17 @@ require_paths:
|
|
101
101
|
- lib
|
102
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
103
103
|
requirements:
|
104
|
-
- -
|
104
|
+
- - ">="
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '0'
|
107
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
113
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.0
|
114
|
+
rubygems_version: 2.2.0
|
115
115
|
signing_key:
|
116
116
|
specification_version: 4
|
117
117
|
summary: Ruby bindings to Lightning MDB
|