lmdb 0.6.4 → 0.6.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/README.md +9 -11
- data/ext/lmdb_ext/lmdb_ext.c +54 -4
- data/ext/lmdb_ext/lmdb_ext.h +1 -0
- data/lib/lmdb/database.rb +42 -8
- data/lib/lmdb/version.rb +1 -1
- data/lmdb.gemspec +2 -2
- data/spec/lmdb_spec.rb +23 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fcfc5ce25df41f83029918b757006f4f34b674f41c2c2691cc40128a7e63a46e
|
|
4
|
+
data.tar.gz: 9cf681ab6dc945eac9b8225717248f42cf27940a704e951aed3dbd59f151df23
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 888eb18fa7e8be017e950f1b8893fc9c4f3c4cc1fa616312438b23be86344cfdeb37d2cc7edc477a528292776ae45e95c0f65c8cd49cd417a4be387f1dd3a28f
|
|
7
|
+
data.tar.gz: 07740710e001f491d22b902d27c1e446d2bab1b93e42d41951e47fdd084b5d5f982dadc551f13764146e8725b8dda4b7a7084c2781454bac2d9f332e16fd666e
|
data/README.md
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# LMDB
|
|
2
2
|
|
|
3
|
-
[](https://www.gittip.com/min4d/ "Donate weekly to this project using Gittip")
|
|
4
|
-
[](https://flattr.com/submit/auto?user_id=min4d&url=https://github.com/minad/lmdb&title=LMDB&language=&tags=github&category=software)
|
|
5
|
-
|
|
6
3
|
Ruby bindings for the amazing [OpenLDAP's Lightning Memory-Mapped Database (LMDB)](https://www.symas.com/lmdb/).
|
|
7
4
|
|
|
8
5
|
## Installation
|
|
@@ -15,12 +12,9 @@ gem install lmdb
|
|
|
15
12
|
|
|
16
13
|
## Links
|
|
17
14
|
|
|
18
|
-
* Source: <http://github.com/
|
|
19
|
-
* Bugs: <http://github.com/
|
|
20
|
-
*
|
|
21
|
-
* API documentation:
|
|
22
|
-
* Latest Gem: <http://rubydoc.info/gems/lmdb/frames>
|
|
23
|
-
* GitHub master: <http://rubydoc.info/github/minad/lmdb/master/frames>
|
|
15
|
+
* Source: <http://github.com/doriantaylor/rb-lmdb>
|
|
16
|
+
* Bugs: <http://github.com/doriantaylor/rb-lmdb/issues>
|
|
17
|
+
* API documentation: <http://rubydoc.info/gems/lmdb/>
|
|
24
18
|
|
|
25
19
|
## API
|
|
26
20
|
|
|
@@ -42,12 +36,16 @@ end
|
|
|
42
36
|
env.close
|
|
43
37
|
```
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
## Moneta
|
|
40
|
+
|
|
41
|
+
If you want to have a simpler interface to LMDB databases please
|
|
42
|
+
consider using [Moneta](https://github.com/minad/moneta). The Moneta
|
|
43
|
+
gem provides an LMDB adapter which uses this gem.
|
|
46
44
|
|
|
47
45
|
## License (MIT)
|
|
48
46
|
|
|
49
47
|
```
|
|
50
|
-
Copyright
|
|
48
|
+
Copyright ©2013 Daniel Mendler (later changes ©2025 Dorian Taylor)
|
|
51
49
|
|
|
52
50
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
53
51
|
a copy of this software and associated documentation files (the
|
data/ext/lmdb_ext/lmdb_ext.c
CHANGED
|
@@ -910,6 +910,53 @@ static VALUE environment_database(int argc, VALUE *argv, VALUE self) {
|
|
|
910
910
|
return vdb;
|
|
911
911
|
}
|
|
912
912
|
|
|
913
|
+
/**
|
|
914
|
+
* @overload databases()
|
|
915
|
+
* Returns a list of the names of all databases in the environment, or
|
|
916
|
+
* an empty list if there are no named databases but only the defaut database.
|
|
917
|
+
*
|
|
918
|
+
* @return [Array] The names of all databases in the environment.
|
|
919
|
+
* @raise [Error] If there is an error opening the main database.
|
|
920
|
+
*/
|
|
921
|
+
static VALUE environment_databases(VALUE self) {
|
|
922
|
+
ENVIRONMENT(self, environment);
|
|
923
|
+
if (!active_txn(self))
|
|
924
|
+
return call_with_transaction(self, self, "databases", 0, 0, MDB_RDONLY);
|
|
925
|
+
|
|
926
|
+
MDB_dbi dbi;
|
|
927
|
+
MDB_cursor *cursor;
|
|
928
|
+
MDB_txn *txn = need_txn(self);
|
|
929
|
+
MDB_val key;
|
|
930
|
+
|
|
931
|
+
check(mdb_dbi_open(txn, NULL, 0, &dbi));
|
|
932
|
+
check(mdb_cursor_open(txn, dbi, &cursor));
|
|
933
|
+
|
|
934
|
+
VALUE ret = rb_ary_new();
|
|
935
|
+
while (mdb_cursor_get(cursor, &key, NULL, MDB_NEXT_NODUP) == MDB_SUCCESS) {
|
|
936
|
+
char *intern_db_name;
|
|
937
|
+
MDB_dbi db;
|
|
938
|
+
VALUE db_name;
|
|
939
|
+
|
|
940
|
+
if (memchr(key.mv_data, '\0', key.mv_size))
|
|
941
|
+
continue;
|
|
942
|
+
|
|
943
|
+
intern_db_name = malloc(key.mv_size + 1);
|
|
944
|
+
memcpy(intern_db_name, key.mv_data, key.mv_size);
|
|
945
|
+
intern_db_name[key.mv_size] = '\0';
|
|
946
|
+
|
|
947
|
+
if (mdb_dbi_open(txn, intern_db_name, 0, &db) == MDB_SUCCESS) {
|
|
948
|
+
mdb_dbi_close(environment->env, db);
|
|
949
|
+
db_name = rb_str_new(key.mv_data, key.mv_size);
|
|
950
|
+
rb_ary_push(ret, db_name);
|
|
951
|
+
}
|
|
952
|
+
free(intern_db_name);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
mdb_cursor_close(cursor);
|
|
956
|
+
|
|
957
|
+
return ret;
|
|
958
|
+
}
|
|
959
|
+
|
|
913
960
|
/**
|
|
914
961
|
* @overload stat
|
|
915
962
|
* Return useful statistics about a database.
|
|
@@ -1337,9 +1384,10 @@ static VALUE cursor_next_range(VALUE self, VALUE upper_bound_key) {
|
|
|
1337
1384
|
MDB_dbi dbi = mdb_cursor_dbi(cursor->cur);
|
|
1338
1385
|
|
|
1339
1386
|
if (mdb_cmp(txn, dbi, &key, &ub_key) <= 0) {
|
|
1340
|
-
|
|
1387
|
+
return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size),
|
|
1388
|
+
rb_str_new(value.mv_data, value.mv_size));
|
|
1341
1389
|
} else {
|
|
1342
|
-
|
|
1390
|
+
return Qnil;
|
|
1343
1391
|
}
|
|
1344
1392
|
}
|
|
1345
1393
|
|
|
@@ -1363,7 +1411,8 @@ static VALUE cursor_next_range(VALUE self, VALUE upper_bound_key) {
|
|
|
1363
1411
|
/*
|
|
1364
1412
|
XXX TODO: this was a nasty segfault: the key (and any
|
|
1365
1413
|
non-nil value) should be asserted to be strings, but then
|
|
1366
|
-
if the database is `integerkeys` then perhaps we should
|
|
1414
|
+
if the database is `integerkeys` then perhaps we should
|
|
1415
|
+
coerce?
|
|
1367
1416
|
*/
|
|
1368
1417
|
|
|
1369
1418
|
if (TYPE(vkey) != T_STRING)
|
|
@@ -1384,7 +1433,7 @@ static VALUE cursor_next_range(VALUE self, VALUE upper_bound_key) {
|
|
|
1384
1433
|
ret = mdb_cursor_get(cursor->cur, &key, &value, op);
|
|
1385
1434
|
|
|
1386
1435
|
if (!NIL_P(vval) && ret == MDB_NOTFOUND)
|
|
1387
|
-
|
|
1436
|
+
return Qnil;
|
|
1388
1437
|
|
|
1389
1438
|
check(ret);
|
|
1390
1439
|
|
|
@@ -1615,6 +1664,7 @@ void Init_lmdb_ext() {
|
|
|
1615
1664
|
rb_undef_alloc_func(cEnvironment);
|
|
1616
1665
|
rb_define_singleton_method(cEnvironment, "new", environment_new, -1);
|
|
1617
1666
|
rb_define_method(cEnvironment, "database", environment_database, -1);
|
|
1667
|
+
rb_define_method(cEnvironment, "databases", environment_databases, 0);
|
|
1618
1668
|
rb_define_method(cEnvironment, "active_txn", environment_active_txn, 0);
|
|
1619
1669
|
rb_define_method(cEnvironment, "close", environment_close, 0);
|
|
1620
1670
|
rb_define_method(cEnvironment, "stat", environment_stat, 0);
|
data/ext/lmdb_ext/lmdb_ext.h
CHANGED
|
@@ -156,6 +156,7 @@ static VALUE environment_clear_flags(int argc, VALUE* argv, VALUE self);
|
|
|
156
156
|
static VALUE environment_close(VALUE self);
|
|
157
157
|
static VALUE environment_copy(VALUE self, VALUE path);
|
|
158
158
|
static VALUE environment_database(int argc, VALUE *argv, VALUE self);
|
|
159
|
+
static VALUE environment_databases(VALUE self);
|
|
159
160
|
static VALUE environment_flags(VALUE self);
|
|
160
161
|
static void environment_free(Environment *environment);
|
|
161
162
|
static VALUE environment_info(VALUE self);
|
data/lib/lmdb/database.rb
CHANGED
|
@@ -84,10 +84,10 @@ module LMDB
|
|
|
84
84
|
maybe_txn true do
|
|
85
85
|
# env.transaction do
|
|
86
86
|
cursor do |c|
|
|
87
|
-
|
|
88
|
-
while rec
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
rec = c.set key
|
|
88
|
+
while rec
|
|
89
|
+
yield rec.last
|
|
90
|
+
rec = c.next_range key
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -134,19 +134,53 @@ module LMDB
|
|
|
134
134
|
ret
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
+
# Conditionally put a value into the database.
|
|
138
|
+
#
|
|
139
|
+
# @param key [String] The key of the record
|
|
140
|
+
# @param value [String] the (optional) value
|
|
141
|
+
# @param options [Hash] options
|
|
142
|
+
#
|
|
143
|
+
# @see #put
|
|
144
|
+
#
|
|
145
|
+
# @return [void]
|
|
146
|
+
def put?(key, value = nil, **options)
|
|
147
|
+
begin
|
|
148
|
+
put key, value, **options
|
|
149
|
+
rescue LMDB::Error::KEYEXIST
|
|
150
|
+
nil
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
137
154
|
# Delete the key (and optional value pair) if it exists; do not
|
|
138
155
|
# complain about missing keys.
|
|
139
|
-
# @param key [#to_s] The key
|
|
140
|
-
# @param value [#to_s] The optional value
|
|
141
|
-
|
|
142
|
-
|
|
156
|
+
# @param key [#to_s] The key of the record
|
|
157
|
+
# @param value [#to_s] The optional value
|
|
158
|
+
#
|
|
159
|
+
# @see #delete
|
|
160
|
+
#
|
|
161
|
+
# @return [void]
|
|
162
|
+
#
|
|
163
|
+
def delete?(key, value = nil, **options)
|
|
164
|
+
begin
|
|
165
|
+
delete key, value, **options
|
|
166
|
+
rescue LMDB::Error::NOTFOUND
|
|
167
|
+
nil
|
|
168
|
+
end
|
|
143
169
|
end
|
|
144
170
|
|
|
171
|
+
# Return how many records there are in this database.
|
|
172
|
+
#
|
|
145
173
|
# @return the number of records in this database
|
|
146
174
|
def size
|
|
147
175
|
stat[:entries]
|
|
148
176
|
end
|
|
149
177
|
|
|
178
|
+
#
|
|
179
|
+
# @return whether the database is empty
|
|
180
|
+
def empty?
|
|
181
|
+
stat[:entries] == 0
|
|
182
|
+
end
|
|
183
|
+
|
|
150
184
|
private
|
|
151
185
|
|
|
152
186
|
# having trouble with read-only transactions embedded in
|
data/lib/lmdb/version.rb
CHANGED
data/lmdb.gemspec
CHANGED
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
|
|
23
23
|
s.required_ruby_version = '>= 2.7'
|
|
24
24
|
|
|
25
|
-
s.add_development_dependency 'rake',
|
|
25
|
+
s.add_development_dependency 'rake', '~> 13'
|
|
26
26
|
s.add_development_dependency 'rake-compiler', '~> 1.2'
|
|
27
|
-
s.add_development_dependency 'rspec',
|
|
27
|
+
s.add_development_dependency 'rspec', '~> 3'
|
|
28
28
|
s.add_development_dependency 'ruby_memcheck', '~> 3'
|
|
29
29
|
end
|
data/spec/lmdb_spec.rb
CHANGED
|
@@ -100,6 +100,27 @@ describe LMDB do
|
|
|
100
100
|
subject.flags.should_not include(:nosync)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
describe 'databases' do
|
|
104
|
+
it 'returns empty list when there are no named databases' do
|
|
105
|
+
subject.databases.should == []
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'returns list of named databases' do
|
|
109
|
+
db1 = subject.database 'db1', create: true
|
|
110
|
+
db2 = subject.database 'db2', create: true
|
|
111
|
+
subject.databases.should == ['db1', 'db2']
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'returns list of named databases when there are non-database kes in the main db' do
|
|
115
|
+
main = subject.database
|
|
116
|
+
main['key'] = 'value'
|
|
117
|
+
subject.database 'db1', create: true
|
|
118
|
+
subject.database 'db2', create: true
|
|
119
|
+
|
|
120
|
+
subject.databases.should == ['db1', 'db2']
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
103
124
|
describe LMDB::Transaction do
|
|
104
125
|
subject { env }
|
|
105
126
|
|
|
@@ -371,6 +392,8 @@ describe LMDB do
|
|
|
371
392
|
c.set('key1', 'value3').should == nil
|
|
372
393
|
end
|
|
373
394
|
|
|
395
|
+
dupdb.put?('key1', 'value1', nodupdata: true).should be_nil
|
|
396
|
+
|
|
374
397
|
# this is basically an extended test of `cursor.set key, val`
|
|
375
398
|
dupdb.has?('key1', 'value1').should == true
|
|
376
399
|
dupdb.has?('key1', 'value2').should == true
|
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.6.
|
|
4
|
+
version: 0.6.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Mendler
|
|
8
8
|
- Dorian Taylor
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|