aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sisudoc/ocda
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2026-09-08 08:28:24 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2026-09-09 17:56:14 -0400
commit9af1dda9b03f745aa2b7700419574e2e3e59fde2 (patch)
tree62ebe97f85a6bac96aeede065c9137c087296c84 /src/sisudoc/ocda
parenta reader for the ocda db, and its round trip (diff)
ocda db: built from the .ssp, (tethered)
The ocda database is now built from the .ssp itself: the writer's lines are emitted, read straight back by ssp_in, and the objects that come out populate the database. Anything the .ssp does not carry, the database will not have either, by construction (rather than by test). [instead of as previously through a second walk over the in-memory abstraction] - spineAbstractionTxt is split: sspDocumentLines(doc) returns the whole .ssp as lines, and the file writer emits them. Output neutral, the reference test confirms. - spineAbstractionDb takes the abstraction as an argument rather than taking doc.abstraction. - sspRoundTripAbstraction(doc) in ssp_in is the join: lines out, lines in, abstraction returned. Both call sites in spine.d use it. - the header blocks and the image blobs still come from doc_matters (as: the .ssp does not carry image bytes). All (35) markup sample sourced databases built through the .ssp have byte identical SQL dumps to the one built directly before the change. That comparison also found one reader inaccuracy, which the .ssp round trip could not see because the writer omits the field either way: an absent identifier was restored as the ocn in every case, but for an object with no ocn it was empty ("a"~N identifiers are always written). Fixed; the two artefacts checking each other is what caught it. (assisted by Claude-Code)
Diffstat (limited to 'src/sisudoc/ocda')
-rw-r--r--src/sisudoc/ocda/abstraction/ssp.d11
-rw-r--r--src/sisudoc/ocda/abstraction/ssp_in.d19
2 files changed, 27 insertions, 3 deletions
diff --git a/src/sisudoc/ocda/abstraction/ssp.d b/src/sisudoc/ocda/abstraction/ssp.d
index 6aa55c2..3e80956 100644
--- a/src/sisudoc/ocda/abstraction/ssp.d
+++ b/src/sisudoc/ocda/abstraction/ssp.d
@@ -414,7 +414,11 @@ template spineAbstractionTxt() {
import std.string;
import std.array;
mixin sspObjectRecord;
- void spineAbstractionTxt(D)(D doc) {
+ /+ ↓ the whole .ssp for a document, as lines. the file writer below emits
+ these, and the abstraction db is built by reading them back, so the
+ database cannot carry anything the .ssp does not
+ +/
+ string[] sspDocumentLines(D)(D doc) {
auto doc_abstraction = doc.abstraction;
auto doc_matters = doc.matters;
string[] output;
@@ -556,6 +560,11 @@ template spineAbstractionTxt() {
output ~= "}";
output ~= "";
}
+ return output;
+ }
+ void spineAbstractionTxt(D)(D doc) {
+ auto doc_matters = doc.matters;
+ string[] output = sspDocumentLines(doc);
/+ ↓ write to file +/
/+ path: <output_path>/<language>/abstraction/<doc_uid_out>.ssp +/
string out_root = (doc_matters.output_path.length > 0)
diff --git a/src/sisudoc/ocda/abstraction/ssp_in.d b/src/sisudoc/ocda/abstraction/ssp_in.d
index f0fb963..220bfe3 100644
--- a/src/sisudoc/ocda/abstraction/ssp_in.d
+++ b/src/sisudoc/ocda/abstraction/ssp_in.d
@@ -198,11 +198,16 @@ template spineAbstractionRead() {
obj.metainfo.identifier = _tail[_sp + 1 .. $];
} else {
obj.metainfo.heading_lev_markup = _levOfMarkedUp(_tail);
- obj.metainfo.identifier = obj.metainfo.ocn.to!string;
+ /+ ↓ omitted means it equals the ocn, and for an object with no ocn
+ it was empty: "a"~N identifiers are always written
+ +/
+ obj.metainfo.identifier = (obj.metainfo.ocn != 0)
+ ? obj.metainfo.ocn.to!string : "";
}
} else {
obj.metainfo.is_a = _rest;
- obj.metainfo.identifier = obj.metainfo.ocn.to!string;
+ obj.metainfo.identifier = (obj.metainfo.ocn != 0)
+ ? obj.metainfo.ocn.to!string : "";
}
obj.metainfo.is_of_section = section;
continue;
@@ -327,6 +332,16 @@ template spineAbstractionRead() {
}
return doc;
}
+ /+ ↓ the abstraction as it survives a trip through the .ssp text: emitted
+ as lines by the writer, read straight back. what a consumer built
+ from this cannot see, the .ssp does not carry, which is what makes a
+ second artefact built from it unable to drift
+ +/
+ auto sspRoundTripAbstraction(D)(D doc) {
+ import sisudoc.ocda.abstraction.ssp;
+ mixin spineAbstractionTxt;
+ return sspRead(sspDocumentLines(doc)).abstraction;
+ }
SSPdocument sspReadFile(string file_path) {
string[] _lines;
try {