2929from __future__ import annotations
3030
3131import os
32- import re
3332import sqlite3
3433import tempfile
3534from pathlib import Path
3635from typing import Any , List , Optional , Union
3736
38- __all__ = ["DucSQL" ]
39-
40-
41- _MIGRATION_RE = re .compile (r"^(\d+)_to_(\d+)$" )
37+ import ducpy_native
4238
43-
44- def _find_schema_dir () -> Optional [Path ]:
45- env_path = os .environ .get ("DUC_SCHEMA_DIR" )
46- if env_path :
47- candidate = Path (env_path )
48- if (candidate / "duc.sql" ).exists ():
49- return candidate
50-
51- current = Path (__file__ ).resolve ()
52- for parent in current .parents :
53- candidate = parent / "schema"
54- if (candidate / "duc.sql" ).exists ():
55- return candidate
56- return None
39+ __all__ = ["DucSQL" ]
5740
5841
5942def _get_current_schema_version () -> int :
60- """Read the target user_version from duc.sql — mirrors Rust's CURRENT_VERSION."""
61- schema_dir = _find_schema_dir ()
62- if schema_dir is None :
63- return 0
64- duc_sql = (schema_dir / "duc.sql" ).read_text (encoding = "utf-8" )
65- m = re .search (r"PRAGMA\s+user_version\s*=\s*(\d+)" , duc_sql , re .IGNORECASE )
66- return int (m .group (1 )) if m else 0
43+ """Current schema version integer (e.g. 3000000) — from the Rust crate."""
44+ return ducpy_native .get_schema_version_int ()
6745
6846
6947def _read_migrations () -> list [tuple [int , int , str ]]:
70- """Load all migration SQL files from schema/migrations/, sorted by from_version."""
71- schema_dir = _find_schema_dir ()
72- if schema_dir is None :
73- return []
74- migrations_dir = schema_dir / "migrations"
75- if not migrations_dir .exists ():
76- return []
77- result : list [tuple [int , int , str ]] = []
78- for path in sorted (migrations_dir .glob ("*.sql" )):
79- m = _MIGRATION_RE .match (path .stem )
80- if m :
81- result .append ((int (m .group (1 )), int (m .group (2 )), path .read_text (encoding = "utf-8" )))
82- result .sort (key = lambda x : x [0 ])
83- return result
48+ """All migrations as (from_version, to_version, sql) — from the Rust crate."""
49+ raw = ducpy_native .get_migrations ()
50+ # get_migrations returns list of tuples with i64 values
51+ return [(int (f ), int (t ), sql ) for f , t , sql in raw ]
8452
8553
8654def _apply_migrations (conn : sqlite3 .Connection ) -> None :
8755 """Walk the migration chain until user_version reaches the current schema version.
8856
89- Mirrors the migration logic in Rust's ``bootstrap.rs``:
90- reads ``schema/migrations/{from}_to_{to}.sql`` files in order and executes
91- them until ``PRAGMA user_version`` matches the version declared in ``duc.sql``.
92- Safe to call on already-current or brand-new databases.
57+ Mirrors the migration logic in Rust's ``bootstrap.rs``. Safe to call on
58+ already-current or brand-new databases.
9359 """
9460 user_version : int = conn .execute ("PRAGMA user_version" ).fetchone ()[0 ]
9561 if user_version == 0 :
@@ -112,18 +78,12 @@ def _apply_migrations(conn: sqlite3.Connection) -> None:
11278
11379
11480def _read_schema_sql () -> str :
115- schema_dir = _find_schema_dir ()
116- if schema_dir is None :
117- raise FileNotFoundError (
118- "Could not locate schema/duc.sql. "
119- "Ensure you are running from within the DUC repository."
120- )
121- parts : list [str ] = []
122- for filename in ("duc.sql" , "version_control.sql" , "search.sql" ):
123- path = schema_dir / filename
124- if path .exists ():
125- parts .append (path .read_text (encoding = "utf-8" ))
126- return "\n " .join (parts )
81+ """Concatenate the three schema SQL strings shipped by the Rust crate."""
82+ return "\n " .join ([
83+ ducpy_native .get_duc_schema_sql (),
84+ ducpy_native .get_version_control_schema_sql (),
85+ ducpy_native .get_search_schema_sql (),
86+ ])
12787
12888
12989def _apply_pragmas (conn : sqlite3 .Connection ) -> None :
0 commit comments