add delete and iter procedures
This commit is contained in:
parent
15895a2dba
commit
62b30097b6
88
leveldb.nim
88
leveldb.nim
|
@ -11,6 +11,10 @@ type
|
||||||
|
|
||||||
LevelDbException* = object of Exception
|
LevelDbException* = object of Exception
|
||||||
|
|
||||||
|
const
|
||||||
|
levelDbTrue = cuchar(1)
|
||||||
|
levelDbFalse = cuchar(0)
|
||||||
|
|
||||||
proc checkError(errPtr: cstring) =
|
proc checkError(errPtr: cstring) =
|
||||||
if errPtr != nil:
|
if errPtr != nil:
|
||||||
defer: free(errPtr)
|
defer: free(errPtr)
|
||||||
|
@ -18,7 +22,7 @@ proc checkError(errPtr: cstring) =
|
||||||
|
|
||||||
proc close*(self: LevelDb) =
|
proc close*(self: LevelDb) =
|
||||||
if self.db == nil:
|
if self.db == nil:
|
||||||
return
|
return
|
||||||
leveldb_close(self.db)
|
leveldb_close(self.db)
|
||||||
leveldb_writeoptions_destroy(self.syncWriteOptions)
|
leveldb_writeoptions_destroy(self.syncWriteOptions)
|
||||||
leveldb_writeoptions_destroy(self.asyncWriteOptions)
|
leveldb_writeoptions_destroy(self.asyncWriteOptions)
|
||||||
|
@ -29,20 +33,20 @@ proc open*(path: string): LevelDb =
|
||||||
new(result, close)
|
new(result, close)
|
||||||
|
|
||||||
let options = leveldb_options_create()
|
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)
|
defer: leveldb_options_destroy(options)
|
||||||
|
|
||||||
result.syncWriteOptions = leveldb_writeoptions_create()
|
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()
|
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()
|
result.readOptions = leveldb_readoptions_create()
|
||||||
|
|
||||||
var errPtr: cstring = nil
|
var errPtr: cstring = nil
|
||||||
result.db = leveldb_open(options, path, addr errPtr)
|
result.db = leveldb_open(options, path, addr errPtr)
|
||||||
checkError(errPtr)
|
checkError(errPtr)
|
||||||
|
|
||||||
proc put*(self: LevelDb, key: string, value: string, sync=true) =
|
proc put*(self: LevelDb, key: string, value: string, sync = true) =
|
||||||
assert self.db != nil
|
assert self.db != nil
|
||||||
var errPtr: cstring = nil
|
var errPtr: cstring = nil
|
||||||
let writeOptions = if sync: self.syncWriteOptions else: self.asyncWriteOptions
|
let writeOptions = if sync: self.syncWriteOptions else: self.asyncWriteOptions
|
||||||
|
@ -62,8 +66,80 @@ proc get*(self: LevelDb, key: string): Option[string] =
|
||||||
result = some($s)
|
result = some($s)
|
||||||
free(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:
|
when isMainModule:
|
||||||
let db = leveldb.open("test.db")
|
let db = leveldb.open("test.db")
|
||||||
db.put("hello", "world")
|
db.put("hello", "world")
|
||||||
echo db.get("one")
|
echo db.get("nothing")
|
||||||
echo db.get("hello")
|
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