From d76f1df350737b0276e6eba321924b84e20967db Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Tue, 4 Jun 2024 12:49:56 +0300 Subject: [PATCH] sqlite-actor: convert to gatekeeper protocol --- README.md | 49 +++++++++++++++++++++++++++---------------- sbom.json | 4 ++++ src/schema/config.nim | 17 +++++++-------- src/sqlite_actor.nim | 23 +++++++++++++------- 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 53be6f5..3602bd2 100644 --- a/README.md +++ b/README.md @@ -414,30 +414,43 @@ It can be used to feed the environment variables of a nested child of the Syndic ## SQLite -Readonly access to SQLite databases. Asserts rows as records in response to SQL query assertions. Dynamic updates are not implemented. - -Can be disabled by passing `--define:withSqlite=no` to the Nim compiler. +Readonly access to SQLite databases. +Asserts rows as records in response to SQL query assertions. +Dynamic updates are not implemented. ``` # Configuration example -> - -let ?sqlspace = dataspace - -? ?cap> [ - $cap -] +let ?sqliteStep = let ?tuplespace = dataspace - -$sqlspace - -$tuplespace ? [?id ?name] [ - $log ! }> +$tuplespace ? ?row [ + $log ! ] + +let ?resolver = dataspace +$resolver [ + ? [ + $log ! + ] + ? [ + $log ! + $sqlspace ? [ + $log ! + ] + $sqlspace + ] +] + +> +$config ? ?cap> [ + $cap +] + + ``` ## syndump diff --git a/sbom.json b/sbom.json index 2dedd9d..917db74 100644 --- a/sbom.json +++ b/sbom.json @@ -69,6 +69,10 @@ "name": "nim:bin:syndump", "value": "syndump" }, + { + "name": "nim:bin:sqlite-actor", + "value": "sqlite_actor" + }, { "name": "nim:srcDir", "value": "src" diff --git a/src/schema/config.nim b/src/schema/config.nim index 50583c9..4e78e10 100644 --- a/src/schema/config.nim +++ b/src/schema/config.nim @@ -40,6 +40,12 @@ type Base64DecoderArguments* {.preservesRecord: "base64-decoder".} = object `field0`*: Base64DecoderArgumentsField0 + SqliteStepField0* {.preservesDictionary.} = object + `database`*: string + + SqliteStep* {.preservesRecord: "sqlite".} = object + `field0`*: SqliteStepField0 + XsltArgumentsField0* {.preservesDictionary.} = object `dataspace`* {.preservesEmbedded.}: EmbeddedRef @@ -71,13 +77,6 @@ type FileSystemUsageArguments* {.preservesRecord: "file-system-usage".} = object `field0`*: FileSystemUsageArgumentsField0 - SqliteArgumentsField0* {.preservesDictionary.} = object - `database`*: string - `dataspace`* {.preservesEmbedded.}: EmbeddedRef - - SqliteArguments* {.preservesRecord: "sqlite".} = object - `field0`*: SqliteArgumentsField0 - PostgreStepField0* {.preservesDictionary.} = object `connection`*: seq[PostgreConnectionParameter] @@ -126,12 +125,12 @@ type proc `$`*(x: WebsocketArguments | HttpClientArguments | JsonTranslatorArguments | SocketAddress | Base64DecoderArguments | + SqliteStep | XsltArguments | HttpDriverArguments | JsonSocketTranslatorStep | WebhooksArguments | FileSystemUsageArguments | - SqliteArguments | PostgreStep | TcpAddress | CacheArguments | @@ -147,12 +146,12 @@ proc encode*(x: WebsocketArguments | HttpClientArguments | JsonTranslatorArguments | SocketAddress | Base64DecoderArguments | + SqliteStep | XsltArguments | HttpDriverArguments | JsonSocketTranslatorStep | WebhooksArguments | FileSystemUsageArguments | - SqliteArguments | PostgreStep | TcpAddress | CacheArguments | diff --git a/src/sqlite_actor.nim b/src/sqlite_actor.nim index f5a8c7b..e5644b3 100644 --- a/src/sqlite_actor.nim +++ b/src/sqlite_actor.nim @@ -1,8 +1,10 @@ # SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense -import preserves, syndicate -import ./schema/[config, sql] +import + pkg/preserves, + pkg/syndicate, pkg/syndicate/protocols/[gatekeeper, sturdy], + ./schema/[config, sql] # Avoid Sqlite3 from the standard library because it is # only held together by wishful thinking and dlload. @@ -107,19 +109,24 @@ proc renderSql(tokens: openarray[Value]): string = else: return "" -proc spawnSqliteActor*(turn: Turn; root: Cap): Actor {.discardable.} = - spawn("sqlite-actor", turn) do (turn: Turn): - during(turn, root, ?:SqliteArguments) do (path: string, ds: Cap): +proc spawnSqliteActor*(turn: Turn; relay: Cap): Actor {.discardable.} = + result = spawnActor(turn, "sqlite") do (turn: Turn): + let pat = Resolve?:{ 0: SqliteStep.grabTypeFlat, 1: grab() } + during(turn, relay, pat) do (path: string, observer: Cap): linkActor(turn, path) do (turn: Turn): let facet = turn.facet stderr.writeLine("opening SQLite database ", path) var db: Sqlite3 if open_v2(path, addr db, SQLITE_OPEN_READONLY, nil) != SQLITE_OK: - assertError(facet, ds, db, path) + discard publish(turn, observer, + Rejected(detail: toPreserves($errmsg(db)))) else: turn.onStop do (turn: Turn): close(db) stderr.writeLine("closed SQLite database ", path) + let ds = turn.newDataspace() + discard publish(turn, observer, + ResolvedAccepted(responderSession: ds)) during(turn, ds, ?:Query) do (statement: seq[Value], target: Cap): var stmt: Stmt @@ -145,5 +152,5 @@ proc spawnSqliteActor*(turn: Turn; root: Cap): Actor {.discardable.} = when isMainModule: import syndicate/relays runActor("main") do (turn: Turn): - resolveEnvironment(turn) do (turn: Turn; ds: Cap): - spawnSqliteActor(turn, ds) + resolveEnvironment(turn) do (turn: Turn; relay: Cap): + spawnSqliteActor(turn, relay)