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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bef8556fe013707e1253bff4b1e2638517fb39a5de3fb33b1c0766a17e55597
4
- data.tar.gz: 434ea5d0333c4b51851f2917a46d0f830bd080c2924812d9376e5baabdf00b30
3
+ metadata.gz: fcfc5ce25df41f83029918b757006f4f34b674f41c2c2691cc40128a7e63a46e
4
+ data.tar.gz: 9cf681ab6dc945eac9b8225717248f42cf27940a704e951aed3dbd59f151df23
5
5
  SHA512:
6
- metadata.gz: 31ec8737a301c0abdc06421291a2dc0afef6ed112c96bd403e63e64f5046178599edf13053c03ce09b937fa87f922056d7e8fdccc651052d6cb967999d36e0e2
7
- data.tar.gz: f1f78664147747397102e76c7a84ba938a28e3888bd4a52ecf46f7bb2c8a6cdbbfe3adadbe0108f63ec9885ff80cbcccc9ab5f8fb9411033448f4fba17b36fe1
6
+ metadata.gz: 888eb18fa7e8be017e950f1b8893fc9c4f3c4cc1fa616312438b23be86344cfdeb37d2cc7edc477a528292776ae45e95c0f65c8cd49cd417a4be387f1dd3a28f
7
+ data.tar.gz: 07740710e001f491d22b902d27c1e446d2bab1b93e42d41951e47fdd084b5d5f982dadc551f13764146e8725b8dda4b7a7084c2781454bac2d9f332e16fd666e
data/README.md CHANGED
@@ -1,8 +1,5 @@
1
1
  # LMDB
2
2
 
3
- [![Gittip donate button](http://img.shields.io/gittip/bevry.png)](https://www.gittip.com/min4d/ "Donate weekly to this project using Gittip")
4
- [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](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/minad/lmdb>
19
- * Bugs: <http://github.com/minad/lmdb/issues>
20
- * Tests and benchmarks: <http://travis-ci.org/minad/lmdb>
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
- 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.
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 (c) 2013 Daniel Mendler
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
@@ -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
- return rb_assoc_new(rb_str_new(key.mv_data, key.mv_size), rb_str_new(value.mv_data, value.mv_size));
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
- return Qnil;
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 coerce?
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
- return Qnil;
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);
@@ -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
- method = :set
88
- while rec = c.send(method, key)
89
- method = :next_range
90
- yield rec[1]
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
- def delete?(key, value = nil)
142
- delete key, value if has? key, value
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
@@ -1,3 +1,3 @@
1
1
  module LMDB
2
- VERSION = '0.6.4'.freeze
2
+ VERSION = '0.6.6'.freeze
3
3
  end
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', '~> 13'
25
+ s.add_development_dependency 'rake', '~> 13'
26
26
  s.add_development_dependency 'rake-compiler', '~> 1.2'
27
- s.add_development_dependency 'rspec', '~> 3'
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
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-05-06 00:00:00.000000000 Z
11
+ date: 2025-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake