[node] custom iterator/query for SQLiteStore's `method listBlocks`
This commit is contained in:
parent
2ecf750959
commit
eebcf7e7b2
|
@ -19,6 +19,7 @@ import pkg/datastore/sqlite_datastore
|
||||||
import pkg/libp2p
|
import pkg/libp2p
|
||||||
import pkg/questionable
|
import pkg/questionable
|
||||||
import pkg/questionable/results
|
import pkg/questionable/results
|
||||||
|
import pkg/sqlite3_abi
|
||||||
|
|
||||||
import ./blockstore
|
import ./blockstore
|
||||||
import ./cachestore
|
import ./cachestore
|
||||||
|
@ -29,14 +30,20 @@ logScope:
|
||||||
topics = "codex sqlitestore"
|
topics = "codex sqlitestore"
|
||||||
|
|
||||||
type
|
type
|
||||||
|
ListBlocksQueryResponse = string
|
||||||
|
|
||||||
|
ListBlocksQueryStmt = SQLiteStmt[(string), void]
|
||||||
|
|
||||||
SQLiteStore* = ref object of BlockStore
|
SQLiteStore* = ref object of BlockStore
|
||||||
cache: BlockStore
|
cache: BlockStore
|
||||||
datastore: SQLiteDatastore
|
datastore: SQLiteDatastore
|
||||||
|
|
||||||
const
|
const
|
||||||
allBlocks = when (let keyRes = Key.init("*"); true):
|
listBlocksQueryStmtStr = """
|
||||||
if keyRes.isOk: Query.init(keyRes.get)
|
SELECT """ & idColName & """ FROM """ & tableName & """;
|
||||||
else: raise (ref Defect)(msg: keyRes.error.msg)
|
"""
|
||||||
|
|
||||||
|
listBlocksQueryStmtIdCol = 0
|
||||||
|
|
||||||
proc new*(
|
proc new*(
|
||||||
T: type SQLiteStore,
|
T: type SQLiteStore,
|
||||||
|
@ -195,6 +202,31 @@ method hasBlock*(
|
||||||
|
|
||||||
return await self.datastore.contains(blkKey)
|
return await self.datastore.contains(blkKey)
|
||||||
|
|
||||||
|
iterator listBlocksQuery(self: SQLiteStore): ListBlocksQueryResponse =
|
||||||
|
without listBlocksQueryStmt =? ListBlocksQueryStmt.prepare(self.datastore.env,
|
||||||
|
listBlocksQueryStmtStr), error:
|
||||||
|
|
||||||
|
raise (ref Defect)(msg: error.msg)
|
||||||
|
|
||||||
|
let
|
||||||
|
s = RawStmtPtr(listBlocksQueryStmt)
|
||||||
|
|
||||||
|
defer:
|
||||||
|
discard sqlite3_reset(s)
|
||||||
|
s.dispose
|
||||||
|
|
||||||
|
while true:
|
||||||
|
let
|
||||||
|
v = sqlite3_step(s)
|
||||||
|
|
||||||
|
case v
|
||||||
|
of SQLITE_ROW:
|
||||||
|
yield $sqlite3_column_text_not_null(s, listBlocksQueryStmtIdCol)
|
||||||
|
of SQLITE_DONE:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise (ref Defect)(msg: $sqlite3_errstr(v))
|
||||||
|
|
||||||
method listBlocks*(
|
method listBlocks*(
|
||||||
self: SQLiteStore,
|
self: SQLiteStore,
|
||||||
onBlock: OnBlock): Future[?!void] {.async.} =
|
onBlock: OnBlock): Future[?!void] {.async.} =
|
||||||
|
@ -202,15 +234,16 @@ method listBlocks*(
|
||||||
## This is an intensive operation
|
## This is an intensive operation
|
||||||
##
|
##
|
||||||
|
|
||||||
for kd in self.datastore.query(allBlocks):
|
for id in self.listBlocksQuery():
|
||||||
let
|
let
|
||||||
(key, _) = await kd
|
# keys stored in id column of SQLiteDatastore are serialized Key
|
||||||
cidRes = Cid.init(key.name)
|
# instances that start with "/", so drop the first character
|
||||||
|
cidRes = Cid.init(id[1..^1])
|
||||||
|
|
||||||
if cidRes.isOk:
|
if cidRes.isOk:
|
||||||
await onBlock(cidRes.get)
|
await onBlock(cidRes.get)
|
||||||
else:
|
else:
|
||||||
trace "Unable to construct CID from key", key = key.id, error = $cidRes.error
|
trace "Unable to construct CID from key", key = id, error = $cidRes.error
|
||||||
|
|
||||||
return success()
|
return success()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue