Class: LMDB::Database
- Inherits:
-
Object
- Object
- LMDB::Database
- Includes:
- Enumerable
- Defined in:
- ext/lmdb_ext/lmdb_ext.c,
lib/lmdb/database.rb,
ext/lmdb_ext/lmdb_ext.c
Overview
An LMDB Database is a table of key-value pairs. It is stored as part of the Environment.
By default, each key in a Database maps to one value. However, a Database can be configured at creation to allow duplicate keys, in which case one key will map to multiple values.
A Database stores the keys in a sorted order. The order can also be set with options when the database is created.
The basic operations on a database are to #put, #get, and #delete records. One can also iterate through the records in a database using a Cursor.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Retrieve the value of a record from a database.
-
#[]=(key, value) ⇒ Object
Set (write or update) a record in a database.
-
#cardinality(key) ⇒ Integer
Return the cardinality (number of duplicates) of a given key.
-
#clear ⇒ Object
Empty out the database.
-
#cursor {|cursor| ... } ⇒ Object
Create a cursor to iterate through a database.
-
#delete(key, value = nil) ⇒ Object
Deletes records from the database.
-
#delete?(key, value = nil) ⇒ void
Delete the key (and optional value pair) if it exists; do not complain about missing keys.
-
#drop ⇒ Object
Remove a database from the environment.
-
#dupfixed? ⇒ true, false
Returns whether the database is in
:dupfixedmode. -
#dupsort? ⇒ true, false
Returns whether the database is in
:dupsortmode. -
#each {|i| ... } ⇒ Object
Iterate through the records in a database.
-
#each_key(&block) ⇒ Enumerator
Iterate over each key in the database, skipping over duplicate records.
-
#each_value(key, &block) ⇒ Enumerator
Iterate over the duplicate values of a given key, using an implicit cursor.
-
#empty? ⇒ Boolean
Whether the database is empty.
- #env ⇒ Environment
-
#flags ⇒ Hash
Return the flags used to open the database.
-
#get(key) ⇒ Object
Retrieves one value associated with this key.
-
#has?(key, value = nil) ⇒ Boolean
Test if the database has a given key (or, if opened in
:dupsort, value). -
#keys ⇒ Array
Get the keys as an array.
-
#put(key, value, options) ⇒ Object
Stores items into a database.
-
#put?(key, value = nil, **options) ⇒ void
Conditionally put a value into the database.
-
#size ⇒ Object
Return how many records there are in this database.
-
#stat ⇒ Hash
Return useful statistics about a database.
Instance Method Details
#[](key) ⇒ Object
Retrieve the value of a record from a database
29 30 31 |
# File 'lib/lmdb/database.rb', line 29 def [](key) get(key) end |
#[]=(key, value) ⇒ Object
Set (write or update) a record in a database.
42 43 44 45 |
# File 'lib/lmdb/database.rb', line 42 def []=(key, value) put key, value value end |
#cardinality(key) ⇒ Integer
Return the cardinality (number of duplicates) of a given key. Works whether :dupsort is set or not.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/lmdb/database.rb', line 100 def cardinality(key) ret = 0 maybe_txn true do # env.transaction do if get key if dupsort? cursor do |c| c.set key ret = c.count end else ret = 1 end end end ret end |
#clear ⇒ Object
1071 1072 1073 1074 1075 1076 1077 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1071
static VALUE database_clear(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self, "clear", 0, 0, 0);
check(mdb_drop(need_txn(database->env), database->dbi, 0));
return Qnil;
}
|
#cursor {|cursor| ... } ⇒ Object
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1257
static VALUE database_cursor(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env)) {
if (!rb_block_given_p()) {
rb_raise(cError, "Must call with block or active transaction.");
}
return call_with_transaction(database->env, self, "cursor", 0, 0, 0);
}
MDB_cursor* cur;
check(mdb_cursor_open(need_txn(database->env), database->dbi, &cur));
Cursor* cursor;
VALUE vcur = Data_Make_Struct(cCursor, Cursor, cursor_mark, cursor_free, cursor);
cursor->cur = cur;
cursor->db = self;
if (rb_block_given_p()) {
int exception;
VALUE ret = rb_protect(rb_yield, vcur, &exception);
if (exception) {
cursor_close(vcur);
rb_jump_tag(exception);
}
cursor_close(vcur);
return ret;
}
else {
VALUE vtxn = environment_active_txn(database->env);
if (NIL_P(vtxn)) {
rb_fatal("Internal error: transaction finished unexpectedly.");
}
else {
TRANSACTION(vtxn, txn);
rb_ary_push(txn->cursors, vcur);
}
}
return vcur;
}
|
#delete(key, value = nil) ⇒ Object
Deletes records from the database. This function removes key/data pairs from the database. If the database does not support sorted duplicate data items (:dupsort) the value parameter is ignored. If the database supports sorted duplicates and the value parameter is nil, all of the duplicate data items for the key will be deleted. Otherwise, if the data parameter is non-nil only the matching data item will be deleted.
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1184
static VALUE database_delete(int argc, VALUE *argv, VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self, "delete", argc, argv, 0);
VALUE vkey, vval;
rb_scan_args(argc, argv, "11", &vkey, &vval);
vkey = StringValue(vkey);
MDB_val key;
key.mv_size = RSTRING_LEN(vkey);
key.mv_data = RSTRING_PTR(vkey);
if (NIL_P(vval)) {
check(mdb_del(need_txn(database->env), database->dbi, &key, 0));
} else {
vval = StringValue(vval);
MDB_val value;
value.mv_size = RSTRING_LEN(vval);
value.mv_data = RSTRING_PTR(vval);
check(mdb_del(need_txn(database->env), database->dbi, &key, &value));
}
return Qnil;
}
|
#delete?(key, value = nil) ⇒ void
This method returns an undefined value.
Delete the key (and optional value pair) if it exists; do not complain about missing keys.
165 166 167 168 169 170 171 |
# File 'lib/lmdb/database.rb', line 165 def delete?(key, value = nil) begin delete key, value rescue LMDB::Error::NOTFOUND nil end end |
#drop ⇒ Object
1057 1058 1059 1060 1061 1062 1063 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1057
static VALUE database_drop(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self, "drop", 0, 0, 0);
check(mdb_drop(need_txn(database->env), database->dbi, 1));
return Qnil;
}
|
#dupfixed? ⇒ true, false
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1040
static VALUE database_is_dupfixed(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self,
"dupfixed?", 0, 0, MDB_RDONLY);
unsigned int flags;
check(mdb_dbi_flags(need_txn(database->env), database->dbi, &flags));
return (flags & MDB_DUPFIXED) == 0 ? Qfalse : Qtrue;
}
|
#dupsort? ⇒ true, false
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1024
static VALUE database_is_dupsort(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self,
"dupsort?", 0, 0, MDB_RDONLY);
unsigned int flags;
check(mdb_dbi_flags(need_txn(database->env), database->dbi, &flags));
return (flags & MDB_DUPSORT) == 0 ? Qfalse : Qtrue;
}
|
#each {|i| ... } ⇒ Object
Iterate through the records in a database
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/lmdb/database.rb', line 13 def each maybe_txn true do # env.transaction do cursor do |c| while i = c.next yield(i) end end end end |
#each_key(&block) ⇒ Enumerator
Iterate over each key in the database, skipping over duplicate records.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/lmdb/database.rb', line 57 def each_key(&block) return enum_for :each_key unless block_given? maybe_txn true do #env.transaction do cursor do |c| while (rec = c.next true) yield rec.first end end end end |
#each_value(key, &block) ⇒ Enumerator
Iterate over the duplicate values of a given key, using an implicit cursor. Works whether :dupsort is set or not.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/lmdb/database.rb', line 75 def each_value(key, &block) return enum_for :each_value, key unless block_given? value = get(key) or return unless dupsort? yield value return end maybe_txn true do # env.transaction do cursor do |c| rec = c.set key while rec yield rec.last rec = c.next_range key end end end end |
#empty? ⇒ Boolean
Returns whether the database is empty.
182 183 184 |
# File 'lib/lmdb/database.rb', line 182 def empty? stat[:entries] == 0 end |
#env ⇒ Environment
1302 1303 1304 1305 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1302
static VALUE database_env(VALUE self) {
DATABASE(self, database);
return database->env;
}
|
#flags ⇒ Hash
1007 1008 1009 1010 1011 1012 1013 1014 1015 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1007
static VALUE database_get_flags(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env,
self, "flags", 0, 0, MDB_RDONLY);
unsigned int flags;
check(mdb_dbi_flags(need_txn(database->env), database->dbi, &flags));
return flags2hash(flags);
}
|
#get(key) ⇒ Object
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1088
static VALUE database_get(VALUE self, VALUE vkey) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self, "get", 1, &vkey, MDB_RDONLY);
vkey = StringValue(vkey);
MDB_val key, value;
key.mv_size = RSTRING_LEN(vkey);
key.mv_data = RSTRING_PTR(vkey);
int ret = mdb_get(need_txn(database->env), database->dbi, &key, &value);
if (ret == MDB_NOTFOUND)
return Qnil;
check(ret);
return rb_str_new(value.mv_data, value.mv_size);
}
|
#has?(key, value = nil) ⇒ Boolean
Test if the database has a given key (or, if opened in :dupsort, value)
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/lmdb/database.rb', line 120 def has?(key, value = nil) v = get(key) or return false return true if value.nil? or value.to_s == v return false unless dupsort? # warn "checking dupsort value `#{value.inspect}` (#{value.class})" ret = false # read-only txn was having trouble being nested inside a read-write maybe_txn true do # env.transaction true do # env.transaction do cursor { |c| ret = !!c.set(key, value) } end ret end |
#keys ⇒ Array
Get the keys as an array.
49 50 51 |
# File 'lib/lmdb/database.rb', line 49 def keys each_key.to_a end |
#put(key, value, options) ⇒ Object
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 1138
static VALUE database_put(int argc, VALUE *argv, VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env, self, "put", argc, argv, 0);
VALUE vkey, vval, option_hash = Qnil;
#ifdef RB_SCAN_ARGS_KEYWORDS
rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS,
argc, argv, "20:", &vkey, &vval, &option_hash);
#else
rb_scan_args(argc, argv, "20:", &vkey, &vval, &option_hash);
#endif
int flags = 0;
if (!NIL_P(option_hash))
rb_hash_foreach(option_hash, (int (*)(ANYARGS))database_put_flags,
(VALUE)&flags);
vkey = StringValue(vkey);
vval = StringValue(vval);
MDB_val key, value;
key.mv_size = RSTRING_LEN(vkey);
key.mv_data = RSTRING_PTR(vkey);
value.mv_size = RSTRING_LEN(vval);
value.mv_data = RSTRING_PTR(vval);
check(mdb_put(need_txn(database->env), database->dbi, &key, &value, flags));
return Qnil;
}
|
#put?(key, value = nil, **options) ⇒ void
This method returns an undefined value.
Conditionally put a value into the database.
147 148 149 150 151 152 153 154 |
# File 'lib/lmdb/database.rb', line 147 def put?(key, value = nil, **) flags = { (dupsort? ? :nodupdata : :nooverwrite) => true } begin put key, value, **.merge(flags) rescue LMDB::Error::KEYEXIST nil end end |
#size ⇒ Object
Return how many records there are in this database.
176 177 178 |
# File 'lib/lmdb/database.rb', line 176 def size stat[:entries] end |
#stat ⇒ Hash
991 992 993 994 995 996 997 998 999 1000 |
# File 'ext/lmdb_ext/lmdb_ext.c', line 991
static VALUE database_stat(VALUE self) {
DATABASE(self, database);
if (!active_txn(database->env))
return call_with_transaction(database->env,
self, "stat", 0, 0, MDB_RDONLY);
MDB_stat stat;
check(mdb_stat(need_txn(database->env), database->dbi, &stat));
return stat2hash(&stat);
}
|