migrate_v3: split node content into content-addressed chunks

This commit is contained in:
2026-09-02 01:31:29 +00:00
parent 9bc71b8717
commit c4e731b3d0
+36
View File
@@ -15,6 +15,7 @@ import base64
import re import re
from pathlib import Path from pathlib import Path
from pagerite.chunks import chunk_key, chunk_markdown
from pagerite.data import prettify from pagerite.data import prettify
@@ -131,3 +132,38 @@ def migrate_v2(d: dict) -> None:
walk(d.get("menu") or {}) walk(d.get("menu") or {})
d.pop("version", None) d.pop("version", None)
_backfill_derivatives() _backfill_derivatives()
def migrate_v3(d: dict) -> None:
"""Content-addressed chunk storage (docs/migrate.md): split every
node's string ``content`` into block chunks stored once per content
hash in the new ``chunks`` store; the node keeps the ordered hash
list as ``chunks`` (an absent content stays absent, i.e. None = a
pure category label; "" chunks to an empty list = an empty page).
``trans``/``patches`` start empty; the translator job fills them and
maintains the ``langs`` index as translations land. ``language``,
``no_trans`` and ``langs`` need nothing — struct defaults cover them.
"""
store = d.setdefault("chunks", {})
d.setdefault("trans", {})
patches = d.setdefault("patches", {})
def walk(nodes: dict) -> None:
for node in nodes.values():
content = node.pop("content", None)
if isinstance(content, str):
hashes = []
for chunk in chunk_markdown(content):
key = chunk_key(chunk)
store.setdefault(key, chunk)
hashes.append(key)
node["chunks"] = hashes
walk(node.get("children") or {})
walk(d.get("menu") or {})
# Article paths never carry a leading slash in keys (docs/migrate.md).
# The only path-keyed store starts empty here, so this is defensive
# for databases that went through a downgrade/upgrade cycle.
for key in [k for k in patches if k.startswith("/")]:
patches[key.lstrip("/")] = patches.pop(key)