Hi… I am well aware that this diff view is very suboptimal. It will be fixed when the refactored server comes along!
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;
};
};