commit
1912de2319
84
leveldb.nim
84
leveldb.nim
|
@ -11,6 +11,10 @@ type
|
|||
|
||||
LevelDbException* = object of Exception
|
||||
|
||||
const
|
||||
levelDbTrue = cuchar(1)
|
||||
levelDbFalse = cuchar(0)
|
||||
|
||||
proc checkError(errPtr: cstring) =
|
||||
if errPtr != nil:
|
||||
defer: free(errPtr)
|
||||
|
@ -29,13 +33,13 @@ proc open*(path: string): LevelDb =
|
|||
new(result, close)
|
||||
|
||||
let options = leveldb_options_create()
|
||||
leveldb_options_set_create_if_missing(options, 1.cuchar)
|
||||
leveldb_options_set_create_if_missing(options, levelDbTrue)
|
||||
defer: leveldb_options_destroy(options)
|
||||
|
||||
result.syncWriteOptions = leveldb_writeoptions_create()
|
||||
leveldb_writeoptions_set_sync(result.syncWriteOptions, cuchar(1))
|
||||
leveldb_writeoptions_set_sync(result.syncWriteOptions, levelDbTrue)
|
||||
result.asyncWriteOptions = leveldb_writeoptions_create()
|
||||
leveldb_writeoptions_set_sync(result.asyncWriteOptions, cuchar(0))
|
||||
leveldb_writeoptions_set_sync(result.asyncWriteOptions, levelDbFalse)
|
||||
result.readOptions = leveldb_readoptions_create()
|
||||
|
||||
var errPtr: cstring = nil
|
||||
|
@ -62,8 +66,80 @@ proc get*(self: LevelDb, key: string): Option[string] =
|
|||
result = some($s)
|
||||
free(s)
|
||||
|
||||
proc delete*(self: LevelDb, key: string, sync = true) =
|
||||
var errPtr: cstring = nil
|
||||
let writeOptions = if sync: self.syncWriteOptions else: self.asyncWriteOptions
|
||||
leveldb_delete(self.db, writeOptions, key, key.len, addr errPtr)
|
||||
checkError(errPtr)
|
||||
|
||||
proc getIterData(iterPtr: ptr leveldb_iterator_t): (Option[string], Option[string]) =
|
||||
var len: csize
|
||||
var str: cstring
|
||||
|
||||
str = leveldb_iter_key(iterPtr, addr len)
|
||||
if len > 0:
|
||||
result[0] = some ($str)[0..<len]
|
||||
else:
|
||||
result[0] = none string
|
||||
|
||||
str = leveldb_iter_value(iterPtr, addr len)
|
||||
if len > 0:
|
||||
result[1] = some ($str)[0..<len]
|
||||
else:
|
||||
result[1] = none string
|
||||
|
||||
iterator iter*(self: LevelDb, seek: string = "", reverse: bool = false): (
|
||||
string, string) =
|
||||
var iterPtr = leveldb_create_iterator(self.db, self.readOptions)
|
||||
defer: leveldb_iter_destroy(iterPtr)
|
||||
|
||||
if seek.len > 0:
|
||||
leveldb_iter_seek(iterPtr, seek, seek.len)
|
||||
else:
|
||||
if reverse:
|
||||
leveldb_iter_seek_to_last(iterPtr)
|
||||
else:
|
||||
leveldb_iter_seek_to_first(iterPtr)
|
||||
|
||||
while true:
|
||||
if leveldb_iter_valid(iterPtr) == levelDbFalse:
|
||||
break
|
||||
|
||||
var (key, value) = getIterData(iterPtr)
|
||||
var err: cstring = nil
|
||||
leveldb_iter_get_error(iterPtr, addr err)
|
||||
checkError(err)
|
||||
yield (key.get(), value.get())
|
||||
|
||||
if reverse:
|
||||
leveldb_iter_prev(iterPtr)
|
||||
else:
|
||||
leveldb_iter_next(iterPtr)
|
||||
|
||||
when isMainModule:
|
||||
let db = leveldb.open("test.db")
|
||||
db.put("hello", "world")
|
||||
echo db.get("one")
|
||||
echo db.get("nothing")
|
||||
echo db.get("hello")
|
||||
db.delete("hello")
|
||||
echo db.get("hello")
|
||||
|
||||
db.put("aaa", "1")
|
||||
db.put("aba", "2")
|
||||
db.put("abb", "3")
|
||||
|
||||
echo ">> iter"
|
||||
for i in db.iter:
|
||||
echo i
|
||||
|
||||
echo ">> iter reverse"
|
||||
for i in db.iter(reverse = true):
|
||||
echo i
|
||||
|
||||
echo ">> iter seek ab"
|
||||
for i in db.iter(seek = "ab"):
|
||||
echo i
|
||||
|
||||
echo ">> iter seek ab reverse"
|
||||
for i in db.iter(seek = "ab", reverse = true):
|
||||
echo i
|
||||
|
|
Loading…
Reference in New Issue