Lindenii Project Forge
Support nomem
use fmt; use io; use lmdb_ffi = lmdb::ffi; use lmdb; use strings; use types; use types::c; use os; export fn main() void = { if (len(os::args) != 3) { fmt::fprintln(os::stderr, "need two arguments (db dir, key)")!; return; }; match (real()) { case void => void; case let e: lmdb::error => fmt::fprintln(os::stderr, lmdb::strerror(e))!; case let e: io::error => fmt::fprintln(os::stderr, io::strerror(e))!;
case nomem => fmt::fprintln(os::stderr, "OOM")!;
}; };
export fn real() (void | lmdb::error | io::error) = {
export fn real() (void | lmdb::error | io::error | nomem) = {
const key = lmdb::val{ mv_size = len(strings::toutf8(os::args[2])), mv_data = c::unterminatedstr(os::args[2]): *opaque, }; let env = lmdb::env_create()?; lmdb::env_open(env, os::args[1], 0, 0o644)?; let txn = lmdb::txn_begin(env, 0)?; let dbi = lmdb::dbi_open(txn, null, lmdb_ffi::CREATE)?; let val = lmdb::get(dbi, &key)?; let data = lmdb::val_u8s(&val); io::write(os::stdout, data)?; lmdb::txn_abort(txn)?; };
use fmt; use io; use lmdb; use lmdb_ffi = lmdb::ffi; use strings; use types; use types::c; use os; export fn main() void = { if (len(os::args) != 3) { fmt::fprintln(os::stderr, "need two arguments (db dir, key)")!; return; }; match (real()) { case void => void; case let e: lmdb::error => fmt::fprintln(os::stderr, lmdb::strerror(e))!; case let e: io::error => fmt::fprintln(os::stderr, io::strerror(e))!;
case nomem => fmt::fprintln(os::stderr, "OOM")!;
}; };
export fn real() (void | lmdb::error | io::error) = {
export fn real() (void | lmdb::error | io::error | nomem) = {
const key = lmdb::val { mv_size = len(strings::toutf8(os::args[2])), mv_data = c::unterminatedstr(os::args[2]): *opaque, };
let v = io::drain(os::stdin)!; defer free(v); const val = lmdb::u8s_val(v); let env = lmdb::env_create()?; lmdb::env_open(env, os::args[1], 0, 0o644)?; let txn = lmdb::txn_begin(env, 0)?; let dbi = lmdb::dbi_open(txn, null, lmdb_ffi::CREATE)?; let val = lmdb::put(dbi, &key, &val, 0)?; lmdb::txn_commit(txn)?; };
use lmdb::ffi; use types::c; // An individual LMDB database, i.e. one key-value store. // // They are only valid for the lifetime of their parent transaction. export type dbi = struct { txn: *ffi::txn, dbi: ffi::dbi, }; // Opens a database from a transaction.
export fn dbi_open(txn: *txn, name: nullable *str, flags: uint) (dbi | error) = {
export fn dbi_open(txn: *txn, name: nullable *str, flags: uint) (dbi | error | nomem) = {
const n: nullable *c::char = match (name) {
case *str => yield c::fromstr(*(name as *str));
case *str => yield c::fromstr(*(name as *str))?;
case null => yield null; }; defer free(n); let d: ffi::dbi = 0; const rc = ffi::dbi_open(txn: *ffi::txn, n, flags, &d): error; switch (rc) { case 0 => return dbi { txn = txn: *ffi::txn, dbi = d, }; case => return rc; }; }; // Get a value from the database. The returned value is only valid for the // lifetime of the transaction associated with the dbi. export fn get(dbi: dbi, key: *val) (val | error) = { let data = ffi::val { mv_size = 0, mv_data = null, }; const rc = ffi::get(dbi.txn, dbi.dbi, key: *ffi::val, &data): error; switch (rc) { case 0 => return data: val; case => return rc; }; }; // Put a value into the database. export fn put(dbi: dbi, key: *val, data: *val, flags: uint) (void | error) = { const rc = ffi::put(dbi.txn, dbi.dbi, key: *ffi::val, data: *ffi::val, flags): error; switch (rc) { case 0 => return void; case => return rc; }; };
use lmdb::ffi; use types::c; // Opaque structure for a database environment. // // A DB environment supports multiple databases, all residing in the same // shared-memory map. export type env = ffi::env; // Creates an [[env]]. The caller must free it with [[env_close]]. export fn env_create() (*env | error) = { let e: nullable *ffi::env = null; const rc = ffi::env_create(&e): error; switch (rc) { case 0 => return e: *env; case => return rc; }; }; // Closes an [[env]]. export fn env_close(env: *env) void = { ffi::env_close(env: *ffi::env); }; // Associates an [[env]] with a on-disk environment.
export fn env_open(env: *env, path: str, flag: uint, mode: u32) (void | error) = { const p = c::fromstr(path);
export fn env_open(env: *env, path: str, flag: uint, mode: u32) (void | error | nomem) = { const p = c::fromstr(path)?;
defer free(p); const rc = ffi::env_open(env: *ffi::env, p, flag, mode): error; return switch (rc) { case 0 => yield; case => yield rc; }; };