M src/tkrzw.nim => src/tkrzw.nim +58 -34
@@ 16,34 16,40 @@ type
ooNoWait = 1 shl 2,
ooNoLock = 1 shl 3
- HashDBM* {.
+ HashDBMObj* {.
header: "tkrzw_dbm_hash.h",
importcpp: "tkrzw::HashDBM", byref.} = object
+ HashDBM* = ref HashDBMObj
## File database manager implementation based on hash table.
- TreeDBM* {.
+ TreeDBMObj {.
header: "tkrzw_dbm_tree.h",
importcpp: "tkrzw::TreeDBM", byref.} = object
+ TreeDBM* = ref TreeDBMObj
## File database manager implementation based on B+ tree.
- SkipDBM* {.
+ SkipDBMObj {.
header: "tkrzw_dbm_skip.h",
importcpp: "tkrzw::SkipDBM", byref.} = object
+ SkipDBM* = ref SkipDBMObj
## File database manager implementation based on skip list.
- TinyDBM* {.
+ TinyDBMObj {.
header: "tkrzw_dbm_tiny.h",
importcpp: "tkrzw::TinyDBM", byref.} = object
+ TinyDBM* = ref TinyDBMObj
## TinyDBM : On-memory database manager implementation based on hash table.
- BabyDBM* {.
+ BabyDBMObj {.
header: "tkrzw_dbm_baby.h",
importcpp: "tkrzw::BabyDBM", byref.} = object
+ BabyDBM* = ref BabyDBMObj
## On-memory database manager implementation based on B+ tree.
- CacheDBM* {.
+ CacheDBMObj {.
header: "tkrzw_dbm_cache.h",
importcpp: "tkrzw::CacheDBM", byref.} = object
+ CacheDBM* = ref CacheDBMObj
## On-memory database manager implementation with LRU deletion.
FileDBM = HashDBM | TreeDBM | SkipDBM
@@ 66,36 72,52 @@ proc GetKey(iter: Iterator): cstring {.importcpp: "#->GetKey().c_str()".}
proc GetValue(iter: Iterator): cstring {.importcpp: "#->GetValue().c_str()".}
template importDBM(T: untyped): untyped =
- proc Close(dbm: T) {.importcpp: "#.Close()".}
- proc GetSimple(dbm: T; key, default: cstring): cstring {.
- importcpp: "#.GetSimple(@).c_str()".}
- proc Set(dbm: T; key, value: cstring; overwrite: bool) {.importcpp: "#.Set(@)".}
- proc MakeIterator(dbm: T): Iterator {.importcpp: "#.MakeIterator()".}
- proc Synchronize(dbm: T; hard: bool): Status {.importcpp: "#.Synchronize(@)".}
- proc Rebuild(dbm: T): Status {.importcpp: "#.Rebuild()".}
- proc ShouldBeRebuilt(dbm: T; toBe: ptr bool): Status {.importcpp: "#.ShouldBeRebuilt()".}
- proc IsOpen(dbm: T): bool {.importcpp: "#.IsOpen()".}
- proc IsWritable(dbm: T): bool {.importcpp: "#.IsWritable()".}
- proc IsHealthy(dbm: T): bool {.importcpp: "#.IsHealthy()".}
- proc IsOrdered(dbm: T): bool {.importcpp: "#.IsOrdered()".}
-
-template importFileDBM(T: untyped): untyped =
+ proc `=destroy`(obj: var `T Obj`) {.importcpp: "#.~" & $T & "()".}
proc Open(dbm: T; path: cstring; writeable: bool; options: int32) {.
- importcpp: "#.Open(@)".}
- importDBM(T)
-
-importFileDBM(HashDBM)
-importFileDBM(TreeDBM)
-importFileDBM(SkipDBM)
+ importcpp: "#->Open(@)".}
+ proc Close(dbm: T) {.importcpp: "#->Close()".}
+ proc GetSimple(dbm: T; key, default: cstring): cstring {.
+ importcpp: "#->GetSimple(@).c_str()".}
+ proc Set(dbm: T; key, value: cstring; overwrite: bool) {.
+ importcpp: "#->Set(@)".}
+ proc MakeIterator(dbm: T): Iterator {.importcpp: "#->MakeIterator()".}
+ proc Synchronize(dbm: T; hard: bool): Status {.
+ importcpp: "#->Synchronize(@)".}
+ proc Rebuild(dbm: T): Status {.importcpp: "#->Rebuild()".}
+ proc ShouldBeRebuilt(dbm: T; toBe: ptr bool): Status {.
+ importcpp: "#->ShouldBeRebuilt()".}
+ proc IsOpen(dbm: T): bool {.importcpp: "#->IsOpen()".}
+ proc IsWritable(dbm: T): bool {.importcpp: "#->IsWritable()".}
+ proc IsHealthy(dbm: T): bool {.importcpp: "#->IsHealthy()".}
+ proc IsOrdered(dbm: T): bool {.importcpp: "#->IsOrdered()".}
+
+importDBM(HashDBM)
+importDBM(TreeDBM)
+importDBM(SkipDBM)
importDBM(TinyDBM)
importDBM(BabyDBM)
importDBM(CacheDBM)
-proc open*(dbm: FileDBM; path: string; rw: RW; options: set[OpenOption] = {}) =
- ## Opens a database file.
- var opt: int32
- for o in options.items: opt.inc o.int32
- dbm.Open(path, rw == writeable, opt)
+proc construct[T](): T =
+ new(result)
+ {.emit: "new ((void*)result) tkrzw::" & $T & "();".}
+
+template declareNewFile(T: untyped): untyped =
+ proc `new T`*(path: string; rw: RW; options: set[OpenOption] = {}): T =
+ var opts: int32
+ for o in options.items: opts.inc o.int32
+ result = construct[T]()
+ result.Open(path, rw == writeable, opts)
+
+template declareNewMem(T: untyped): untyped =
+ proc `new T`*(): T = construct[T]()
+
+declareNewFile(HashDBM)
+declareNewFile(TreeDBM)
+declareNewFile(SkipDBM)
+declareNewMem(TinyDBM)
+declareNewMem(BabyDBM)
+declareNewMem(CacheDBM)
proc close*(dbm: DBM) =
## Closes the database file.
@@ 146,7 168,8 @@ proc rebuild*(dbm) =
proc rebuild*(dbm: TinyDBM; numBuckets = -1) =
## Rebuilds the entire database.
## When `numBuckets` is calculated implicitly when -1.
- proc RebuildAdvanced(dbm: TinyDBM; nb: int64): Status {.importcpp: "#.RebuildAdvanced(@)".}
+ proc RebuildAdvanced(dbm: TinyDBM; nb: int64): Status {.
+ importcpp: "#->RebuildAdvanced(@)".}
check dbm.RebuildAdvanced(numBuckets)
proc rebuild*(dbm: CacheDBM; capRecNum = -1; capMemSize = -1) =
@@ 154,13 177,14 @@ proc rebuild*(dbm: CacheDBM; capRecNum = -1; capMemSize = -1) =
## * `capRecNum` is the maximum number of records.
## * `capMemSize` is the total memory size to use
## When `numBuckets` is calculated implicitly when -1.
- proc RebuildAdvanced(dbm: CacheDBM; crn, cms: int64): Status {.importcpp: "#.RebuildAdvanced(@)".}
+ proc RebuildAdvanced(dbm: CacheDBM; crn, cms: int64): Status {.
+ importcpp: "#->RebuildAdvanced(@)".}
check dbm.RebuildAdvanced(capRecNum, capMemSize)
proc isOpen*(dbm): bool = dbm.IsOpen()
## Checks whether the database is open.
-proc isWritable*(dbm): bool = dbm .IsWritable()
+proc isWritable*(dbm): bool = dbm.IsWritable()
## Checks whether the database is writable.
proc isHealthy*(dbm): bool = dbm.IsHealthy()
M tests/config.nims => tests/config.nims +1 -1
@@ 1,1 1,1 @@
-switch("path", "$projectDir/../src")>
\ No newline at end of file
+switch("path", "$projectDir/../src")
M tests/test_tkrzw.nim => tests/test_tkrzw.nim +13 -11
@@ 2,18 2,20 @@ import std/[os, unittest]
import tkrzw
-template testEx1(T: untyped; isFile: static[bool]): untyped =
+template testEx1(newProc: untyped; isFile: static[bool]): untyped =
test "ex1":
const path = "casket.test"
- var dbm: T
- when isFIle:
- dbm.open(path, writeable, {ooTruncate})
+ when isFile:
+ var dbm = newProc(path, writeable, {ooTruncate})
+ # newHashDBM(…), etc
+ else:
+ var dbm = newProc()
dbm["foo"] = "hop"
dbm["bar"] = "step"
dbm["baz"] = "jump"
- dbm.synchronize(hard=false)
+ dbm.synchronize(hard = false)
check dbm["foo"] == "hop"
check dbm["bar"] == "step"
@@ 32,19 34,19 @@ template testEx1(T: untyped; isFile: static[bool]): untyped =
removeFile(path)
suite "HashDBM":
- testEx1(HashDBM, true)
+ testEx1(newHashDBM, true)
suite "TreeDBM":
- testEx1(TreeDBM, true)
+ testEx1(newTreeDBM, true)
suite "SkipDBM":
- testEx1(SkipDBM, true)
+ testEx1(newSkipDBM, true)
suite "TinyDBM":
- testEx1(TinyDBM, false)
+ testEx1(newTinyDBM, false)
suite "BabyDBM":
- testEx1(BabyDBM, false)
+ testEx1(newBabyDBM, false)
suite "CacheDBM":
- testEx1(CacheDBM, false)
+ testEx1(newCacheDBM, false)