Skip to content

Instantly share code, notes, and snippets.

@asterite
Last active November 26, 2016 21:56
Show Gist options
  • Save asterite/3898c87ae8cf1525d3c6c3037f17e796 to your computer and use it in GitHub Desktop.
Save asterite/3898c87ae8cf1525d3c6c3037f17e796 to your computer and use it in GitHub Desktop.
@[Link("lmdb")]
lib LibLMDB
alias Int = LibC::Int
alias UInt = LibC::UInt
alias Char = LibC::Char
alias SizeT = LibC::SizeT
type Env = Void*
type Txn = Void*
type Cursor = Void*
alias Dbi = UInt
alias Mode = Int
struct Val
size : SizeT
data : Void*
end
enum CursorOp
FIRST
FIRST_DUP
GET_BOTH
GET_BOTH_RANGE
GET_CURRENT
GET_MULTIPLE
LAST
LAST_DUP
NEXT
NEXT_DUP
NEXT_MULTIPLE
NEXT_NODUP
PREV
PREV_DUP
PREV_NODUP
SET
SET_KEY
SET_RANGE
end
fun mdb_env_create(Env*) : Int
fun mdb_env_open(env : Env, path : Char*, flags : UInt, mode : Mode) : Int
fun mdb_txn_begin(env : Env, parent : Txn, flags : UInt, txn : Txn*) : Int
fun mdb_open = mdb_dbi_open(txn : Txn, name : Char*, flags : UInt, dbi : Dbi*) : Int
fun mdb_put(txn : Txn, dbi : Dbi, key : Val*, data : Val*, flags : UInt) : Int
fun mdb_txn_commit(txn : Txn) : Int
fun mdb_cursor_open(txn : Txn, dbi : Dbi, cursor : Cursor*) : Int
fun mdb_cursor_get(cursor : Cursor, key : Val*, data : Val*, op : CursorOp) : Int
end
macro check(op)
%err = LibLMDB.mdb_{{op}}
if %err != 0
raise "Method failed: #{ {{op.stringify}} }"
end
end
Dir.mkdir_p("./testdb")
check env_create(out env)
check env_open(env, "./testdb", 0, 0o664)
check txn_begin(env, nil, 0, out txn)
check open(txn, nil, 0, out dbi)
def with_val(value)
yield LibLMDB::Val.new(size: value.bytesize, data: value.to_unsafe)
end
def with_val(value : Int32)
with_generic_val(value) { |x| yield x }
end
def with_val(value : Float64)
with_generic_val(value) { |x| yield x }
end
def with_generic_val(value : T)
yield LibLMDB::Val.new(size: sizeof(T), data: pointerof(value).as(Void*))
end
def put(txn, dbi, key, value)
with_val(key) do |okey|
with_val(value) do |ovalue|
check put(txn, dbi, pointerof(okey), pointerof(ovalue), 0)
end
end
end
put txn, dbi, "String", "bar"
put txn, dbi, "Int32", 2
put txn, dbi, "Float64", 1.5
check txn_commit(txn)
check txn_begin(env, nil, 0x20000, pointerof(txn))
check cursor_open(txn, dbi, out cursor)
while LibLMDB.mdb_cursor_get(cursor, out okey, out odata, LibLMDB::CursorOp::NEXT) == 0
the_key = String.new(okey.data.as(UInt8*), okey.size)
print the_key
print ": "
case the_key
when "String"
p String.new(odata.data.as(UInt8*), odata.size)
when "Int32"
p odata.data.as(Int32*).value
when "Float64"
p odata.data.as(Float64*).value
else
puts "(other)"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment