Merge pull request #1 from xyb/iter

add delete and iter procedures
This commit is contained in:
Michał Zieliński 2019-11-06 17:09:52 +01:00 committed by GitHub
commit 1912de2319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 82 additions and 6 deletions

View File

@ -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