Qwiratry *::DatabaseStorage::Location::JSON
NAME
Qwiratry *::DatabaseStorage::Location::JSON — JSON document ↔ rows
AUTHOR
Tim Nelson - https://github.com/wayland
Ships with the Qwiratry::Format::JSON distribution (not core). Thin
subclass of core Qwiratry::DatabaseStorage::Location::Tree that defaults
:format('JSON') and advertises today's root/identity/object-key projection
as §8 Format defaults (plan DatabaseStorage-Location-Tree §8 / Q4 / Q14).
Document shape (omit-args defaults):
Parse: JSON array of objects → one row per object; a single object → one-row table (table root = document parse root).
Render/flush: rows → a JSON array of objects (empty table →
[]).
Override :table-selector / :row-selector / :field-projection /
:transformer / :path-transformer on useTable (or the constructor)
for nested tables. Default :path-transformer is core
associative-path-transformer (plan §10.3 / §16.4.3).
use Qwiratry::TaOP;
use Qwiratry::Mold::Slang;
use Qwiratry::DatabaseStorage::Location::JSON; # or rely on Database load-library
my $db = Database.new(
storage-type => 'Location::JSON',
location => './data',
);
my $t = $db.useTable(name => 'people', action => 'can-create');
$t.add-row({ name => 'Ada', age => 36 });
$t.storage-object.flush; # Tree sync is explicit (plan Q20)
# → ./data/people.json
# Nested table under a key (override §8 defaults; keep sibling structure).
# Merge mold sees $*CONTEXT<rows> (plan Q18); topic is the document.
clear-collected-molds();
transformer MergePeople {
mold TOP
when { True }
do {
my %out = $_ ~~ Associative ?? %($_) !! %();
%out<people> = [@($*CONTEXT<rows> // []).map({ %($_) })];
%out
}
}
# my $roster = $db.useTable(
# name => 'roster',
# action => 'use',
# row-selector => sub (Mu $doc) { slip(($doc<people> // []).list) },
# transformer => MergePeople.new,
# );
See also t/03-location-json.rakutest and the core Qwiratry plan
docs/rakudoc/Developing/DatabaseStorage-Location-Tree.md.