NagyZoltanPeter deb6929670
feat: introduce SDS persistency glue (#3913)
* persistency: follow nim-sds 0.3.0 snapshot persistence contract
nim-sds 0.3.0 replaced the ~14 fine-grained per-row Persistence callbacks
with a 5-proc snapshot model (saveChannelMeta / updateHistory / loadChannel
/ dropChannel / setRetrievalHint), all returning Future[Result[...]].

Rewrite waku/persistency/sds_persistency.nim accordingly:
- ChannelMeta is stored as one blob per channel; the message log as
  append/evict rows. Categories collapse from 7 to 2 (sds.meta, sds.log).
- Blob transform uses nim-sds' own codecs: snapshot_codec (schema-versioned
  protobuf) for ChannelMeta, the SDS wire codec for SdsMessage log rows. The
  generic payload_codec/BlobCodec path is retired (removed payload_codec.nim
  and test_blob_codec.nim).
- setRetrievalHint is a deliberate no-op: persisted hints are never read back
  (loadChannel/ChannelMeta carry none; hints are supplied live via the
  onRetrievalHint provider). The closure stays because the field is required.
- Fix the module import spelling (srcDir="sds" => bare module paths), which
  the previous adapter got wrong and never compiled against the locked deps.

Add tests/persistency/test_sds_persistency.nim (round-trip, empty-load,
evict, drop) replacing test_blob_codec in test_all. Full persistency suite
passes 74/74 under both refc and ORC.
* Bump to latest nim-sds and nim-brokers 3.1.1
* Update with latest nim-sds changes - removal of setRetrievalHints - not needed
2026-06-04 10:53:02 +02:00

85 lines
1.9 KiB
Nim

## Core types for the logos-delivery persistency library.
##
## The library is backend-neutral CRUD: jobs own their domain ports and
## map them onto the primitives exposed in persistency.nim. See
## persistency.nim for the public facade and brokers.nim for the
## cross-thread plumbing.
{.push raises: [].}
type
Key* = distinct seq[byte]
KeyRange* = object
start*: Key
stop*: Key ## exclusive; an empty `stop` means "no upper bound"
KvRow* = tuple[key: Key, payload: seq[byte]]
TxOpKind* = enum
txPut
txDelete
txDeletePrefix
TxOp* = object
category*: string
key*: Key
case kind*: TxOpKind
of txPut:
payload*: seq[byte]
of txDelete:
discard
of txDeletePrefix:
discard
PersistencyErrorKind* = enum
peBackend
peClosed
peInvalidArgument
peTimeout
peJobNotFound
PersistencyError* = object
kind*: PersistencyErrorKind
msg*: string
backendCode*: int
proc bytes*(k: Key): lent seq[byte] {.inline.} =
seq[byte](k)
proc len*(k: Key): int {.inline.} =
seq[byte](k).len
proc `==`*(a, b: Key): bool {.inline.} =
seq[byte](a) == seq[byte](b)
proc `<`*(a, b: Key): bool =
let ab = seq[byte](a)
let bb = seq[byte](b)
let n = min(ab.len, bb.len)
for i in 0 ..< n:
if ab[i] != bb[i]:
return ab[i] < bb[i]
return ab.len < bb.len
proc `<=`*(a, b: Key): bool {.inline.} =
a == b or a < b
proc rawKey*(b: openArray[byte]): Key =
var s = newSeq[byte](b.len)
for i, v in b:
s[i] = v
return Key(s)
proc rawKey*(b: sink seq[byte]): Key {.inline.} =
Key(b)
proc persistencyErr*(
kind: PersistencyErrorKind, msg: string, backendCode = 0
): PersistencyError {.inline.} =
PersistencyError(kind: kind, msg: msg, backendCode: backendCode)
proc `$`*(e: PersistencyError): string =
"PersistencyError(" & $e.kind & ": " & e.msg &
(if e.backendCode != 0: ", code=" & $e.backendCode else: "") & ")"