diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-21 11:42:42 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-22 14:54:32 -0400 |
| commit | 3f87aa600b5080135557d846ee1ba7daef9d3155 (patch) | |
| tree | fed92ba22b9baa0b8f3acfbb1eda46f5f5fa5d67 /src/sisudoc/ocda | |
| parent | ocda db: one <doc>.ocda.db holding every language (diff) | |
ocda.db: read a document language of a database
A database now holds every language of its document, so reading one
means naming a language. Three small pieces:
- spineDbLanguages says what languages a file holds. Its own template
rather than part of the reader (asking a file what it holds does not
instantiate the object setter and the markup regexes with it).
- abstractionLoad and spineDocFromArtefact take a language and pass it
to dbReadFile, which resolves it to a doc_id, takes that language
document where there is one, and lists the languages and stops where
there is a choice.
- spineArtefactLanguages turns an artefact into the documents to build:
one for a .ssp, and for a database the languages it holds filtered by
--lang. The artefact loop then has a language loop inside it, so a
single .ocda.db argument builds every language, as the pod it came
from would.
--db-round-trip takes --lang for the same reason, and ocda-db looses
--parallel (would cause a race).
(assisted by Claude-Code)
Diffstat (limited to 'src/sisudoc/ocda')
| -rw-r--r-- | src/sisudoc/ocda/abstraction/db_in.d | 30 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/doc_from_artefact.d | 31 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/load.d | 10 |
3 files changed, 67 insertions, 4 deletions
diff --git a/src/sisudoc/ocda/abstraction/db_in.d b/src/sisudoc/ocda/abstraction/db_in.d index a8a216c..5535870 100644 --- a/src/sisudoc/ocda/abstraction/db_in.d +++ b/src/sisudoc/ocda/abstraction/db_in.d @@ -60,6 +60,36 @@ module sisudoc.ocda.abstraction.db_in; writer's own record definition, and require the result to equal the .ssp written from the same document. +/ +/+ ↓ the languages a database holds, in the order they were written. + a caller that wants every language of a document has to be told what + they are, and this is the only place that knows: the file is named for + the document and says nothing about its languages. + . + an unreadable or unexpected file gives an empty list rather than an + exception, and the caller then treats the artefact as it would any other + it could not read. + . + its own template, and not part of spineAbstractionDbRead: asking a file + what languages it holds should not instantiate the whole reader, which + brings the object setter and the markup regexes with it. ++/ +template spineDbLanguages() { + @trusted string[] spineDbLanguages(string db_file) { + import std.file : exists; + import d2sqlite3; + string[] _out; + if (!db_file.exists) { return _out; } + try { + auto db = Database(db_file, SQLITE_OPEN_READONLY); + foreach (row; db.execute("SELECT lang FROM documents ORDER BY id")) { + _out ~= row["lang"].as!string; + } + } catch (Exception ex) { + return string[].init; + } + return _out; + } +} template spineAbstractionDbRead() { import std.conv : to; import std.file; diff --git a/src/sisudoc/ocda/abstraction/doc_from_artefact.d b/src/sisudoc/ocda/abstraction/doc_from_artefact.d index 7cbc73a..fa620f8 100644 --- a/src/sisudoc/ocda/abstraction/doc_from_artefact.d +++ b/src/sisudoc/ocda/abstraction/doc_from_artefact.d @@ -74,6 +74,34 @@ module sisudoc.ocda.abstraction.doc_from_artefact; so a pod cannot be rebuilt from one, and the empty list is the truthful answer rather than a gap. +/ +/+ ↓ which languages of an artefact there are to build, and in what order. + a .ssp is one language and answers [""], meaning "the one it holds". + a .ocda.db holds every language of its document, so each one named in it + is a document to build, filtered by --lang where that was given. --lang + naming a language the database does not hold leaves an empty list, and + the caller says so rather than silently building nothing. + . + Its own template rather than a function inside spineDocFromArtefact: + that one is eponymous, so nothing beside the function of the same name + can be reached from outside it. The listing itself is db_in's + spineDbLanguages, which is separate from the reader for the same reason: + asking what languages a file holds should not instantiate the reader. ++/ +template spineArtefactLanguages() { + string[] spineArtefactLanguages(string _artefact, string[] _langs_wanted) { + import std.algorithm : endsWith; + import sisudoc.ocda.abstraction.db_in : spineDbLanguages; + if (!_artefact.endsWith(".db")) { return [""]; } + string[] _held = spineDbLanguages!()(_artefact); + if (_held.length == 0) { return [""]; } // let the read report why + if (_langs_wanted.length == 0 || _langs_wanted[0] == "all") { return _held; } + string[] _out; + foreach (_l; _held) { + foreach (_w; _langs_wanted) { if (_l == _w) { _out ~= _l; break; } } + } + return _out; + } +} template spineDocFromArtefact() { import std.algorithm : endsWith; import std.array; @@ -332,8 +360,9 @@ template spineDocFromArtefact() { O _opt_action, E _env, ConfComposite _site_conf, + string _lang = "", ) { - auto _loaded = abstractionLoad(_artefact); + auto _loaded = abstractionLoad(_artefact, _lang); auto _ssp = _loaded.doc; auto _pths = artefactPaths(_artefact, _ssp); /+ ↓ the images. diff --git a/src/sisudoc/ocda/abstraction/load.d b/src/sisudoc/ocda/abstraction/load.d index 2072aae..ae6c673 100644 --- a/src/sisudoc/ocda/abstraction/load.d +++ b/src/sisudoc/ocda/abstraction/load.d @@ -139,13 +139,17 @@ template spineAbstractionLoad() { } /+ ↓ load what can be loaded from the path alone. - .ssp and .ocda.db come back filled. the three source forms come back with loaded = false and a note saying where they are handled, because reading them needs the manifest, environment and configuration that spine.d builds, not a file path. + . + _lang names which language of a .ocda.db to take, a database holding + every language of its document. With none named it takes the only one + there is, and where there is a choice it says so rather than choosing. + A .ssp is one language by construction and ignores it. +/ - LoadedAbstraction abstractionLoad(string _path) { + LoadedAbstraction abstractionLoad(string _path, string _lang = "") { LoadedAbstraction _out; _out.path = _path; _out.source = abstractionSourceOf(_path); @@ -160,7 +164,7 @@ template spineAbstractionLoad() { if (!_out.loaded) { _out.note = "no object sections found"; } break; case AbstractionSource.ocda_db: - _out.doc = dbReadFile(_path); + _out.doc = dbReadFile(_path, _lang); _out.loaded = (_out.doc.section_order.length > 0); if (!_out.loaded) { _out.note = "no object sections found"; } break; |
