Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
a8f15a1
Recover minimal catalog and Dolt lifecycle checkpoint
TonisOrmisson Aug 3, 2026
b9650a3
Restore public SQL storage type helper
TonisOrmisson Aug 3, 2026
c527b68
Bind specification provenance and normalize server versions
TonisOrmisson Aug 3, 2026
25089a1
Bind specification provenance and normalize server versions
TonisOrmisson Aug 3, 2026
17f3c47
Bind specification provenance and normalize server versions
TonisOrmisson Aug 3, 2026
a650220
Bind specification provenance and normalize server versions
TonisOrmisson Aug 3, 2026
873dc22
Fix lifecycle runtime regressions
TonisOrmisson Aug 3, 2026
3e129d1
Fix lifecycle runtime regressions
TonisOrmisson Aug 3, 2026
d2ec6aa
Fix lifecycle runtime regressions
TonisOrmisson Aug 3, 2026
5f2d85a
[skip ci] Migrate workflow tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
bc8e187
[skip ci] Migrate conformance tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
4045d43
Migrate service tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
bdd30dd
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
83d701d
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
8d79993
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
58f764a
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
edbbae0
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
0385537
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
002b3c0
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
a5f7139
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
558ba5b
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
2c17f64
[skip ci] Migrate tests to explicit catalog initialization
TonisOrmisson Aug 3, 2026
3705ee3
[skip ci] Publish exact SQL test evidence
TonisOrmisson Aug 3, 2026
8031b39
[skip ci] Align atomic tests with explicit lifecycle
TonisOrmisson Aug 3, 2026
73a3cca
[skip ci] Make unbound specification test explicit
TonisOrmisson Aug 3, 2026
2ea59fc
[skip ci] Fail closed on SQL identity probe ambiguity
TonisOrmisson Aug 3, 2026
92a3d4b
[skip ci] Align SQL profile tests with fail-closed Dolt evidence
TonisOrmisson Aug 3, 2026
f53440f
[skip ci] Normalize reflected SQL catalog shapes
TonisOrmisson Aug 3, 2026
37de8c4
Migrate lifecycle tests and normalize reflected catalog shapes
TonisOrmisson Aug 3, 2026
a88f0cc
Normalize database DOUBLE wrappers on read [skip ci]
TonisOrmisson Aug 3, 2026
2c769fa
Cover SQL numeric read normalization [skip ci]
TonisOrmisson Aug 3, 2026
af52e51
Run import preflight before physical table construction [skip ci]
TonisOrmisson Aug 3, 2026
df1888e
Distinguish Dolt profile id from product label [skip ci]
TonisOrmisson Aug 3, 2026
31d0e53
Make mocked SAV writer honor staging contract [skip ci]
TonisOrmisson Aug 3, 2026
06817f6
Align atomic-import tests with strict preflight [skip ci]
TonisOrmisson Aug 3, 2026
bff1605
Keep Dolt out of operational conformance matrices [skip ci]
TonisOrmisson Aug 3, 2026
c6a711f
Make Dolt CI assert fail-closed behavior [skip ci]
TonisOrmisson Aug 3, 2026
3fb04c3
Separate candidate evidence from release gates [skip ci]
TonisOrmisson Aug 3, 2026
40595da
Test undeclared Dolt support as read-only and fail-closed [skip ci]
TonisOrmisson Aug 3, 2026
606f3aa
Verify SQL Decimal normalization preserves nonfinite rejection
TonisOrmisson Aug 3, 2026
358baef
Pin specification validator package 0.2.1 source [skip ci]
TonisOrmisson Aug 3, 2026
73813c8
Require specification validator package 0.2.1 [skip ci]
TonisOrmisson Aug 3, 2026
10906aa
Bind Dolt lifecycle to specification validator 0.2.1 commit [skip ci]
TonisOrmisson Aug 3, 2026
3e06a94
Update CLI specification provenance expectation [skip ci]
TonisOrmisson Aug 3, 2026
63a52ec
Verify final specification validator provenance
TonisOrmisson Aug 3, 2026
dd680a1
ci: pin reviewed specification candidate
TonisOrmisson Aug 3, 2026
359e390
fix: align specification release provenance
TonisOrmisson Aug 3, 2026
647d9de
fix: align specification release provenance
TonisOrmisson Aug 3, 2026
3cf7dd0
fix: align specification release provenance
TonisOrmisson Aug 3, 2026
cb4829d
Enforce declared limits and explicit drivers
TonisOrmisson Aug 3, 2026
3ee9fba
Use effective string storage in wide tables
TonisOrmisson Aug 3, 2026
c9ff699
Gate schema installation before DDL
TonisOrmisson Aug 3, 2026
b9241b0
Cover effective profile driver, identifier, and string storage
TonisOrmisson Aug 3, 2026
0a7495e
Cover fail-closed schema installation gate
TonisOrmisson Aug 3, 2026
9210339
Report unbound Dolt capabilities as disabled
TonisOrmisson Aug 3, 2026
0543648
Allow conformance-gated Dolt export audits
TonisOrmisson Aug 3, 2026
3b67886
Cover disabled Dolt capabilities and gated audit
TonisOrmisson Aug 3, 2026
2aa076b
Require the claimed driver after Dolt identity
TonisOrmisson Aug 3, 2026
cd09b62
Preserve dangling symlinks during export recovery
TonisOrmisson Aug 3, 2026
ef0e310
Cover Dolt driver recheck after identity
TonisOrmisson Aug 3, 2026
5d4e46c
Cover dangling symlink export recovery
TonisOrmisson Aug 3, 2026
795d8de
Include driver eligibility in Dolt write capability
TonisOrmisson Aug 3, 2026
cab47e9
Align Dolt snapshot write flag with driver eligibility
TonisOrmisson Aug 3, 2026
b38350c
Centralize Dolt operational eligibility
TonisOrmisson Aug 3, 2026
2e2e8c9
Reuse Dolt operational eligibility in snapshot
TonisOrmisson Aug 3, 2026
0d24d59
Cover Dolt operational driver eligibility
TonisOrmisson Aug 3, 2026
b10926b
Keep Dolt driver rejection independent of active metadata
TonisOrmisson Aug 3, 2026
53f05ca
Cap MySQL text values at emitted TEXT storage
TonisOrmisson Aug 3, 2026
d9fa47e
Gate active non-Dolt write capability consistently
TonisOrmisson Aug 3, 2026
f1c56df
Use symlink-aware backup cleanup checks
TonisOrmisson Aug 3, 2026
c923f72
Cover emitted text and active write capability gates
TonisOrmisson Aug 3, 2026
db94767
Cover successful dangling backup disposal
TonisOrmisson Aug 3, 2026
970486d
Track successful import table ownership before cleanup
TonisOrmisson Aug 3, 2026
192d7d7
Cover concurrent import table ownership
TonisOrmisson Aug 3, 2026
148c988
Recognize supported MySQL-wire driver pairings
TonisOrmisson Aug 3, 2026
98866ed
Require LONGTEXT when validating Dolt datasets
TonisOrmisson Aug 3, 2026
6b95895
Cover MariaDB driver and Dolt LONGTEXT validation
TonisOrmisson Aug 3, 2026
dff51d1
Keep Dolt validation propagation test independent of SQL extras
TonisOrmisson Aug 3, 2026
cc05979
Propagate Dolt conformance through in-place writes
TonisOrmisson Aug 3, 2026
2da412e
Propagate Dolt conformance through SPSS apply
TonisOrmisson Aug 3, 2026
63bb245
Expose Dolt conformance for in-place public APIs
TonisOrmisson Aug 3, 2026
730e122
Expose generated identifier preflight
TonisOrmisson Aug 3, 2026
30858ae
Preflight generated table identifier before DDL
TonisOrmisson Aug 3, 2026
60a0eac
Cover in-place Dolt conformance propagation
TonisOrmisson Aug 3, 2026
0af6c40
Cover generated table identifier preflight
TonisOrmisson Aug 3, 2026
fd42939
Update Dolt apply mocks for conformance keyword
TonisOrmisson Aug 3, 2026
db7477e
Avoid stale compensation after transactional rollback
TonisOrmisson Aug 3, 2026
ffcfb56
Cover transactional rollback cleanup boundary
TonisOrmisson Aug 3, 2026
5ed2ce6
Test cleanup failure on nontransactional profile path
TonisOrmisson Aug 3, 2026
ee3dfd6
Recognize in-place audit as optional catalog relation
TonisOrmisson Aug 3, 2026
306b4a9
Cover optional in-place audit catalog ownership
TonisOrmisson Aug 3, 2026
cd1c128
Use core catalog kind in audit ownership regression
TonisOrmisson Aug 3, 2026
8ffa2a1
Assert nested core catalog result in audit ownership test
TonisOrmisson Aug 3, 2026
1e22ac0
Expose full catalog verification for mutation gates
TonisOrmisson Aug 3, 2026
073a659
Gate in-place schema and applies on verified catalog
TonisOrmisson Aug 3, 2026
b078a6a
Preserve newer concurrent export destinations
TonisOrmisson Aug 3, 2026
6f81a18
Cover catalog gates for in-place lifecycle
TonisOrmisson Aug 3, 2026
70991e9
Cover concurrent export recovery ownership
TonisOrmisson Aug 3, 2026
b45a4d0
Delete actual legacy row in divergence regression
TonisOrmisson Aug 3, 2026
b68f7ce
Scope audit migration and reject ephemeral catalog URLs
TonisOrmisson Aug 3, 2026
cbafaee
Verify audit migration before and after upgrade
TonisOrmisson Aug 3, 2026
c8b4fad
Cover legacy in-place audit migration
TonisOrmisson Aug 3, 2026
85d4a85
Cover ephemeral SQLite initialization rejection
TonisOrmisson Aug 3, 2026
5c4bf8b
Keep export audits out of import fidelity reads
TonisOrmisson Aug 3, 2026
3db6c19
Claim export destinations without clobbering races
TonisOrmisson Aug 3, 2026
6252f70
Cover import-only fidelity reads
TonisOrmisson Aug 3, 2026
f18e02b
Cover export preparation publication race
TonisOrmisson Aug 3, 2026
1185c3b
Verify variable mappings and concurrent init ownership
TonisOrmisson Aug 3, 2026
0f3c885
Cover concurrent initializer compensation guard
TonisOrmisson Aug 3, 2026
04f86fa
Cover variable catalog bijection gate
TonisOrmisson Aug 3, 2026
a627645
Serialize MySQL-wire catalog initialization
TonisOrmisson Aug 3, 2026
6d7e3e2
Cover catalog initialization serialization boundary
TonisOrmisson Aug 3, 2026
c566aaa
fix: avoid stale PostgreSQL catalog cleanup
TonisOrmisson Aug 3, 2026
f17b3b2
Serialize SAV export publication
TonisOrmisson Aug 3, 2026
0b1e891
Support Windows SAV publication locks
TonisOrmisson Aug 3, 2026
b3a225e
Budget numeric MySQL wire parameters conservatively
TonisOrmisson Aug 3, 2026
cceff06
Support SAV publication without hard links
TonisOrmisson Aug 3, 2026
0713ca7
Serialize SQLite catalog initialization
TonisOrmisson Aug 3, 2026
e98ef83
Validate catalog storage and SQLite URI persistence
TonisOrmisson Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v7
with: &specification-checkout
repository: OpenStatSpec/specification
ref: 79339ec3d8f8aa81789b7e85f6b8afa6f1374e50
ref: 5b62bce1d2f4d719ac6ca42d73f07e7a127c7093
path: openstatspec-specification
- name: Checkout required SPSS engine
uses: actions/checkout@v7
Expand All @@ -32,6 +32,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install --upgrade pip
- run: python -m pip install ./openstatspec-specification
- run: python -m pip install ./openstatspec-pyspssio
- run: python -m pip install -e ".[dev]"
- run: python -m pytest -m "not services"
Expand All @@ -53,6 +54,7 @@ jobs:
- run: python -m pip install --upgrade pip build
- run: python -m build
- run: python -m venv /tmp/openstatspec-wheel-smoke
- run: /tmp/openstatspec-wheel-smoke/bin/python -m pip install ./openstatspec-specification
- run: /tmp/openstatspec-wheel-smoke/bin/python -m pip install ./openstatspec-pyspssio
- run: /tmp/openstatspec-wheel-smoke/bin/python -m pip install dist/*.whl
- run: /tmp/openstatspec-wheel-smoke/bin/openstatspec capabilities
Expand Down Expand Up @@ -90,6 +92,7 @@ jobs:
with:
python-version: "3.12"
- run: python -m pip install --upgrade pip
- run: python -m pip install ./openstatspec-specification
- run: python -m pip install ./openstatspec-pyspssio
- run: python -m pip install -e ".[dev,sql]"
- run: python -m pytest -m services
Expand Down Expand Up @@ -143,7 +146,7 @@ jobs:
steps: *sql-test-steps

dolt-integration:
name: Dolt ${{ matrix.dolt }} integration
name: Dolt ${{ matrix.dolt }} read-only / fail-closed integration
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -192,6 +195,7 @@ jobs:
--workdir /var/lib/dolt \
"$OPENSTATSPEC_DOLT_IMAGE" sql-server -H 0.0.0.0 -l warning
- run: python -m pip install --upgrade pip
- run: python -m pip install ./openstatspec-specification
- run: python -m pip install ./openstatspec-pyspssio
- run: python -m pip install -e ".[dev,sql]"
- name: Wait for Dolt
Expand All @@ -217,7 +221,7 @@ jobs:
connection.close()
break
PY
- run: python -m pytest -m services
- run: python -m pytest -m "services and not candidate_evidence"
- name: Show Dolt logs on failure and stop server
if: always()
run: |
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ SPSS profile.
- Export of supported dataset semantics to SAV and ZSAV.
- SQLite, PostgreSQL, MySQL, and MariaDB profiles, including service-backed
PostgreSQL 17/18, MySQL 8.4/9.7, and MariaDB 11.4/11.8/12.3 CI coverage.
- Read-only positive Dolt identity and working-set inspection. Operational
Dolt writes load the shared `openstatspec-specification` declaration
validator and remain fail-closed because the packaged concrete declaration
set is empty.
- Added explicit packaged/directory conformance-source injection and exact
single-match binding across active Dolt product version, adapter
implementation and version, and specification commit before mutation.
- Explicit catalog initialization/migration through `initialize_catalog` and
`openstatspec init`; data operations never auto-create catalog relations.
- Read-only Dolt working-set evidence through `dolt_state_snapshot` and
`openstatspec dolt-state`; core performs no Dolt version-control mutations.
- Preflight checks for target profile limits, atomic imports, validation, a
command-line interface, and machine-readable capability and loss reports.

Expand All @@ -121,3 +132,11 @@ SPSS profile.
- Multiple-response sets, variable alignment, variable sets, and custom
attributes have explicit capability diagnostics; see the SAV profile.
- Encrypted SPSS files are not supported.
- Dolt adapter-envelope values are not claims about Dolt server limits. Failure
recovery is compensating and reports deterministic residual inventory; a
verified catalog receives a best-effort failed-operation audit when cleanup
itself fails.
- Export publication uses a durable, audit-recorded prior-file backup through
SQL finalization. Post-success backup retention is reported separately and
does not rewrite a successful export as failed; pre-success failures restore
the prior destination and close the running operation as failed.
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ readme = "README.md"
requires-python = ">=3.11"
license = {text = "Apache-2.0"}
authors = [{name = "OpenStatSpec"}]
dependencies = ["SQLAlchemy>=2.0", "pandas>=2.2", "openstatspec-pyspssio==0.5.1.post2", "sqlglot>=30.14", "rfc8785>=0.1.4"]
dependencies = ["SQLAlchemy>=2.0", "pandas>=2.2", "openstatspec-pyspssio==0.5.1.post2", "openstatspec-specification==0.2.1", "sqlglot>=30.14", "rfc8785>=0.1.4"]

[project.optional-dependencies]
dev = ["pytest>=8"]
Expand All @@ -22,7 +22,10 @@ openstatspec = "openstatspec.cli:main"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q"
markers = ["services: requires a configured PostgreSQL, MySQL, MariaDB, or Dolt service"]
markers = [
"services: requires a configured PostgreSQL, MySQL, MariaDB, or Dolt service",
"candidate_evidence: non-claiming manual probe excluded from release gates",
]

[tool.hatch.build.targets.wheel]
packages = ["src/openstatspec"]
23 changes: 11 additions & 12 deletions src/openstatspec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

from .api import (
apply_spss_in_place, apply_transformation_plan_in_place,
capabilities, capability_matrix, derive_sql_dataset,
execute_sql_transformation,
export_sav, get_dataset, import_sav, inspect,
install_in_place_transformation_schema, list_datasets,
capabilities, capability_matrix, derive_sql_dataset, dolt_state_snapshot, execute_sql_transformation,
export_sav, get_dataset, import_sav, initialize_catalog, inspect, list_datasets,
install_in_place_transformation_schema,
register_sql_transformation, reconcile_derived_removals,
reconcile_sql_transformation_runs,
remove_derived_physical_relation, retire_derived, validate, validate_derived,
)
from .core import CapabilityDeclaration, LossReport, UnsupportedOperationError
from .sql.workflow import TransformationError
from .frontends.spss import SpssFrontendCompilation, compile_spss_syntax
from .sql import DoltConformanceSource
from .sql.workflow import TransformationError
from .transform import (
RecodeMatch, RecodeOperation, RecodeResult, RecodeRule,
ReplaceValueLabelsOperation, SetVariableLabelOperation,
Expand All @@ -21,18 +21,17 @@
)

__all__ = [
"CapabilityDeclaration", "LossReport", "SpssFrontendCompilation",
"TransformationError", "TransformationFrontendError",
"CapabilityDeclaration", "DoltConformanceSource", "LossReport", "TransformationError",
"SpssFrontendCompilation", "TransformationFrontendError",
"RecodeMatch", "RecodeOperation", "RecodeResult", "RecodeRule",
"ReplaceValueLabelsOperation", "SetVariableLabelOperation",
"TransformationPlan", "TypedValue", "ValueLabel",
"VariableDefinition", "VariableSchema", "transformation_plan_from_dict",
"UnsupportedOperationError", "capabilities", "capability_matrix",
"apply_spss_in_place", "apply_transformation_plan_in_place",
"compile_spss_syntax", "derive_sql_dataset",
"execute_sql_transformation", "export_sav",
"get_dataset", "import_sav", "inspect",
"install_in_place_transformation_schema", "list_datasets",
"compile_spss_syntax", "install_in_place_transformation_schema",
"UnsupportedOperationError", "capabilities", "capability_matrix",
"derive_sql_dataset", "dolt_state_snapshot", "execute_sql_transformation", "export_sav", "get_dataset",
"import_sav", "initialize_catalog", "inspect", "list_datasets",
"register_sql_transformation", "reconcile_derived_removals",
"reconcile_sql_transformation_runs",
"remove_derived_physical_relation", "retire_derived", "validate",
Expand Down
116 changes: 102 additions & 14 deletions src/openstatspec/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
from .core.results import result
from .spss import export_dataset, import_dataset, inspect_source
from .spss.sav import engine_identity
from .sql import declared_profiles, validate_dataset
from .sql import (
DoltConformanceSource,
declared_profiles,
dolt_state_snapshot as _dolt_state_snapshot,
initialize_catalog as _initialize_catalog,
validate_dataset,
)
from .sql.catalog_api import catalog_dataset as _catalog_dataset, catalog_datasets as _catalog_datasets
from .sql.workflow import (
derive_dataset as _derive_dataset,
Expand All @@ -33,7 +39,11 @@



def capability_matrix(database_url: str | None = None) -> Mapping[str, Any]:
def capability_matrix(
database_url: str | None = None,
*,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
"""Return the pyspssio-backed SAV/ZSAV fidelity boundary.

supported means that the adapter has a tested faithful path.
Expand Down Expand Up @@ -86,9 +96,18 @@ def capability_matrix(database_url: str | None = None) -> Mapping[str, Any]:
"maximum_source_file_bytes": None,
"limit_basis": "runtime memory and active SQL connection limits",
},
"active_connection": active_connection(database_url) if database_url else None,
"active_connection": (
active_connection(
database_url,
dolt_conformance_source=dolt_conformance_source,
)
if database_url else None
),
"catalog_binding": catalog_binding(database_url) if database_url else None,
"sql_profiles": declared_profiles(database_url),
"sql_profiles": declared_profiles(
database_url,
dolt_conformance_source=dolt_conformance_source,
),
"optional_profiles": {
"sql_transformation_workflow": transformation_capabilities(database_url),
"spss_in_place_transformation": (
Expand All @@ -98,26 +117,84 @@ def capability_matrix(database_url: str | None = None) -> Mapping[str, Any]:
}
return declaration

def capabilities(database_url: str | None = None) -> Mapping[str, Any]:
return capability_matrix(database_url)
def capabilities(
database_url: str | None = None,
*,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
return capability_matrix(
database_url, dolt_conformance_source=dolt_conformance_source,
)


def inspect(source: str | Path, /, **options: Any) -> Mapping[str, Any]:
return result(inspect_source(source, **options))


def import_sav(source: str | Path, /, *, database_url: Any, dataset_id: str, **options: Any) -> Mapping[str, Any]:
def dolt_state_snapshot(
*,
database_url: Any,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
"""Return read-only Dolt branch, HEAD, status, and diff-summary evidence."""
return result(_dolt_state_snapshot(
database_url=database_url,
dolt_conformance_source=dolt_conformance_source,
))


def initialize_catalog(
*,
database_url: Any,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
"""Install or explicitly migrate a dedicated OpenStatSpec catalog."""
return result(_initialize_catalog(
database_url=database_url,
dolt_conformance_source=dolt_conformance_source,
))


def import_sav(
source: str | Path, /, *, database_url: Any, dataset_id: str,
dolt_conformance_source: DoltConformanceSource | None = None,
**options: Any,
) -> Mapping[str, Any]:
"""Import one source file into one dedicated wide SQL table."""
return result(import_dataset(source, database_url=database_url, dataset_id=dataset_id, **options))
return result(import_dataset(
source, database_url=database_url, dataset_id=dataset_id,
dolt_conformance_source=dolt_conformance_source,
**options,
))


def export_sav(*, database_url: Any, dataset_id: str, destination: str | Path, **options: Any) -> Mapping[str, Any]:
def export_sav(
*, database_url: Any, dataset_id: str, destination: str | Path,
dolt_conformance_source: DoltConformanceSource | None = None,
**options: Any,
) -> Mapping[str, Any]:
"""Export one database-resident conforming dataset to SAV/ZSAV."""
return result(export_dataset(database_url=database_url, dataset_id=dataset_id, destination=destination, **options))
return result(export_dataset(
database_url=database_url, dataset_id=dataset_id,
destination=destination,
dolt_conformance_source=dolt_conformance_source,
**options,
))


def validate(*, database_url: Any, dataset_id: str, **options: Any) -> Mapping[str, Any]:
return result(validate_dataset(database_url=database_url, dataset_id=dataset_id, **options))
def validate(
*,
database_url: Any,
dataset_id: str,
dolt_conformance_source: DoltConformanceSource | None = None,
**options: Any,
) -> Mapping[str, Any]:
return result(validate_dataset(
database_url=database_url,
dataset_id=dataset_id,
dolt_conformance_source=dolt_conformance_source,
**options,
))


def list_datasets(*, database_url: Any, kind: str | None = None) -> Mapping[str, Any]:
Expand All @@ -144,6 +221,7 @@ def apply_spss_in_place(
*, database_url: Any, dataset_id: str, source_text: str,
actor: str, expected_branch: str | None = None,
expected_head: str | None = None,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
"""Apply supported SPSS-like syntax to the same SQL dataset/table."""
return result(_apply_spss_in_place(
Expand All @@ -153,6 +231,7 @@ def apply_spss_in_place(
actor=actor,
expected_branch=expected_branch,
expected_head=expected_head,
dolt_conformance_source=dolt_conformance_source,
))


Expand All @@ -161,6 +240,7 @@ def apply_transformation_plan_in_place(
plan: TransformationPlan | Mapping[str, Any],
actor: str, expected_branch: str | None = None,
expected_head: str | None = None,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> Mapping[str, Any]:
"""Apply a canonical plan to the same logical dataset and physical table."""
return result(_apply_transformation_plan_in_place(
Expand All @@ -170,12 +250,20 @@ def apply_transformation_plan_in_place(
actor=actor,
expected_branch=expected_branch,
expected_head=expected_head,
dolt_conformance_source=dolt_conformance_source,
))


def install_in_place_transformation_schema(*, database_url: Any) -> None:
def install_in_place_transformation_schema(
*,
database_url: Any,
dolt_conformance_source: DoltConformanceSource | None = None,
) -> None:
"""Install the compact apply-audit relation before the first apply."""
_install_in_place_schema(database_url=str(database_url))
_install_in_place_schema(
database_url=str(database_url),
dolt_conformance_source=dolt_conformance_source,
)


def validate_derived(*, database_url: Any, derived_dataset_id: str) -> Mapping[str, Any]:
Expand Down
12 changes: 10 additions & 2 deletions src/openstatspec/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

from .api import (
apply_spss_in_place, apply_transformation_plan_in_place,
capability_matrix, derive_sql_dataset,
capability_matrix, derive_sql_dataset, dolt_state_snapshot,
execute_sql_transformation,
export_sav, get_dataset, import_sav, inspect, list_datasets,
export_sav, get_dataset, import_sav, initialize_catalog, inspect, list_datasets,
install_in_place_transformation_schema, register_sql_transformation,
validate, validate_derived,
)
Expand All @@ -29,6 +29,10 @@ def main(argv: Sequence[str] | None = None) -> int:
commands = parser.add_subparsers(dest="command", required=True)
capability_parser = commands.add_parser("capabilities", help="show supported and lossy feature matrix")
capability_parser.add_argument("--database-url", help="include active connection limits")
dolt_state = commands.add_parser("dolt-state", help="show read-only Dolt branch, HEAD, status, and diff evidence")
dolt_state.add_argument("--database-url", required=True)
initializer = commands.add_parser("init", help="initialize or migrate a dedicated catalog")
initializer.add_argument("--database-url", required=True)
importer = commands.add_parser("import", help="import one SAV/ZSAV file")
importer.add_argument("source")
importer.add_argument("--database-url", required=True)
Expand Down Expand Up @@ -114,6 +118,10 @@ def main(argv: Sequence[str] | None = None) -> int:
args = parser.parse_args(argv)
if args.command == "capabilities":
output = capability_matrix(database_url=args.database_url)
elif args.command == "dolt-state":
output = dolt_state_snapshot(database_url=args.database_url)
elif args.command == "init":
output = initialize_catalog(database_url=args.database_url)
elif args.command == "import":
output = import_sav(args.source, database_url=args.database_url, dataset_id=args.dataset_id)
elif args.command == "export":
Expand Down
Loading