aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2022-12-06 02:51:22 -0600
committerthe lemons <citrons@mondecitronne.com>2022-12-06 02:51:22 -0600
commit2731d37fe4f62b1ce9bfd7da09d1636082526fc2 (patch)
treea565906cb973deb5e82c41c534b38d2729cc30da
parent442acbe4ea0769d81d39c93572b859fb145b17f4 (diff)
add lmdb.next and pairs(db)
-rw-r--r--README.md16
-rw-r--r--lmdb.c43
2 files changed, 56 insertions, 3 deletions
diff --git a/README.md b/README.md
index dd0fdef..b63c4e3 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,9 @@ create a new environment handle and open the database at the `path`. returns the
### `lmdb.version()`
returns the LMDB version as `major, minor, patch`.
+### `lmdb.next(db, key)`
+returns the next key-value pair after `key` in the database handle `db`, or the first key-value pair if `key` is `nil`. keys are ordered lexicographically. unlike `next`, this function does not work for traversal if, during traversal, keys are set to `nil`. (TODO: fix this somehow)
+
### `env:txn_begin(write_enabled)`
create a new transaction in the environment. if `write_enabled` is true, then the transaction may make modifications to the database. returns the transaction handle (`txn`) on success.
@@ -32,9 +35,7 @@ flush buffers to disk. if `force` is `true`, a synchronous flush is performed ev
close the environment.
### `txn:open(name, create)`
-open a database in the environment. if multiple databases are to be used in the environment, `name` is the name of the database to open. otherwise, it should not be supplied. if `create` is true, the database is created if it does not exist. returns a database handle on success.
-
-the database handle behaves as a table that may be indexed with string keys and contains string values, read from the database. any changes made will be saved to the database when the transaction is committed.
+open a database in the environment. if multiple databases are to be used in the environment, `name` is the name of the database to open. otherwise, it should not be supplied. if `create` is true, the database is created if it does not exist. returns a database handle (`db`) on success.
### `txn:drop(name)`
delete the database `name` from the environment. (or clear the database, if `name` is not supplied)
@@ -47,3 +48,12 @@ commit all operations of the transaction into the database.
### `txn:txn_begin()`
create a nested transaction in the parent transaction.
+
+### `db[key]`
+read the value of `key` from the database.
+
+### `db[key] = value`
+write `value` as the value of `key` into the database.
+
+### `pairs(db)`
+returns `lmdb.next, db, nil`.
diff --git a/lmdb.c b/lmdb.c
index 7e562c0..d85ce4f 100644
--- a/lmdb.c
+++ b/lmdb.c
@@ -276,6 +276,47 @@ static int db_put(lua_State *L) {
return 0;
}
+static int db_next(lua_State *L) {
+ lua_settop(L, 2);
+ MDB_dbi dbi = *(MDB_dbi *) luaL_checkudata(L, 1, "lmdb.db");
+ check_env(L, 1);
+ luaL_argcheck(
+ L, lua_isnil(L, 2) || lua_isstring(L, 2), 2, "expected string or nil");
+
+ lua_getuservalue(L, 1);
+ struct handle *tud = lua_touserdata(L, -1);
+ MDB_cursor *curs;
+ asserr(mdb_cursor_open(tud->obj, dbi, &curs));
+
+ MDB_val key;
+ MDB_val data;
+ int result;
+ if (!lua_isnil(L, 2)) {
+ key = toval(L, 2);
+ asserr(mdb_cursor_get(curs, &key, &data, MDB_SET));
+ result = mdb_cursor_get(curs, &key, &data, MDB_NEXT);
+ } else
+ result = mdb_cursor_get(curs, &key, &data, MDB_FIRST);
+ if (result == MDB_NOTFOUND) {
+ lua_pushnil(L);
+ return 1;
+ } else asserr(result);
+
+ fromval(L, key);
+ fromval(L, data);
+ mdb_cursor_close(curs);
+ return 2;
+}
+
+static int db_pairs(lua_State *L) {
+ lua_settop(L, 1);
+ luaL_checkudata(L, 1, "lmdb.db");
+ lua_pushcfunction(L, db_next);
+ lua_pushvalue(L, 1);
+ lua_pushnil(L);
+ return 3;
+}
+
static int db_drop(lua_State *L) {
lua_settop(L, 2);
struct handle *ud = luaL_checkudata(L, 1, "lmdb.txn");
@@ -294,6 +335,7 @@ static int db_drop(lua_State *L) {
static const struct luaL_Reg lmdb[] = {
{"open", env_open},
{"version", version},
+ {"next", db_next},
{NULL, NULL},
};
@@ -322,6 +364,7 @@ static const struct luaL_Reg lmdb_txn[] = {
static const struct luaL_Reg lmdb_db[] = {
{"__index", db_get},
{"__newindex", db_put},
+ {"__pairs", db_pairs},
{NULL, NULL},
};