engine/migrations/v1_to_v2.py: option sub_category->sub_categories[]; sub-category name slugify (whitespace/grammar chars->_, reserved suffixed, de-duped) cascaded to options + tag_groups; instance category_filter list->boolean-expr string + exclude_null flag; nested @{uuid:a,b,null} refs->@{uuid:a or b!null}. Idempotent. Two entry points share one core: envelope migrate_v1_to_v2 (import/export, registered in _CHAIN) + per-row migrate_module/bundle_v1_to_v2 (lazy/bulk DB path).
Register _CHAIN[1] + bump engine CURRENT_SCHEMA_VERSION 1->2. New SQL migration 016 marches stale DB rows 1->2 at boot via run_bulk_lazy + the per-row migrators (014's documented bump pattern). TS mirror (migrations.ts) + client CURRENT bump follow next (no cross-language version assertion couples them). Update version/entity-count assertions in payload-migration, migration-runner, and export-build tests.
49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""Migration 016 auto-migrates stale v1 rows to v2 on boot (bulk lazy)."""
|
|
import json
|
|
import sqlite3
|
|
|
|
import pytest
|
|
|
|
from engine.db.migrations import current_version, migrate
|
|
|
|
|
|
@pytest.fixture
|
|
def db() -> sqlite3.Connection:
|
|
conn = sqlite3.connect(":memory:")
|
|
conn.row_factory = sqlite3.Row
|
|
migrate(conn) # full chain, incl. 016 (no-op on the empty DB)
|
|
return conn
|
|
|
|
|
|
def _insert_v1_wildcard(conn: sqlite3.Connection, payload: dict) -> None:
|
|
conn.execute(
|
|
"INSERT INTO modules(id, type, name, description, category_id, tags, "
|
|
"is_favorite, payload, version, created_at, updated_at, schema_version, "
|
|
"original_payload_json, tolerant_drift_status) "
|
|
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
|
("w1", "wildcard", "n", "", None, "[]", 0, json.dumps(payload),
|
|
1, "now", "now", 1, None, "none"),
|
|
)
|
|
conn.commit()
|
|
|
|
|
|
def test_016_discovered_and_runs_clean(db: sqlite3.Connection) -> None:
|
|
assert current_version(db) >= 16
|
|
|
|
|
|
def test_016_bulk_migrates_v1_wildcard_row(db: sqlite3.Connection) -> None:
|
|
_insert_v1_wildcard(db, {"sub_categories": ["warm tones"], "options": [
|
|
{"id": "o", "value": "x", "weight": 1, "sub_category": "warm tones"}]})
|
|
# Rewind the migration ledger so migrate() re-runs 016 against the row.
|
|
db.execute("DELETE FROM migrations WHERE version >= 16")
|
|
db.commit()
|
|
migrate(db)
|
|
row = db.execute(
|
|
"SELECT payload, schema_version FROM modules WHERE id='w1'"
|
|
).fetchone()
|
|
p = json.loads(row["payload"])
|
|
assert row["schema_version"] == 2
|
|
assert p["sub_categories"] == ["warm_tones"]
|
|
assert p["options"][0]["sub_categories"] == ["warm_tones"]
|
|
assert "sub_category" not in p["options"][0]
|