6.3 KiB
Read contract for the WCX reference database
Purpose and ownership
This document defines the current SQLite read contract used by
scripts/match_filenames.py when matching local video filenames against the
WCX reference database. The contract identifies the database objects that the
file-management code depends on and the compatibility boundary that the
reference-data project must preserve.
The reference-data project owns the database schema, canonical metadata,
history, and aliases. It is the sole writer to the reference database.
File-management code is a consumer only and must open the database through a
SQLite URI with mode=ro and uri=True.
Local file paths, local processing state, matching decisions, and collection state are outside this contract and must not be written to the reference database.
Connection contract
scripts/match_filenames.py resolves the configured database path, converts
it to a file URI, appends ?mode=ro, and opens it as follows:
database_uri = f"{database_file.resolve().as_uri()}?mode=ro"
with sqlite3.connect(database_uri, uri=True) as connection:
connection.row_factory = sqlite3.Row
The database file must already exist. The consumer must not fall back to a normal writable SQLite connection.
Tables and columns read
The current contract contains exactly three tables and ten selected columns:
| Table | Columns read |
|---|---|
movie |
id, name, duration_seconds |
movie_name_alias |
movie_id, alias, normalized_alias, source |
movie_history |
movie_id, duration_seconds, archived_at |
No other table or column is read by load_movies().
Column meanings for matching
| Column | Meaning in the file matcher |
|---|---|
movie.id |
Stable external identity for a movie. It links the current movie to aliases and historical durations and is the identifier that file-management data may reference externally. |
movie.name |
Current canonical display name and the primary name used to generate filename candidates. Empty names are excluded. |
movie.duration_seconds |
Current known duration. It supplies the current duration version used to support or distinguish name matches. |
movie_name_alias.movie_id |
Associates an alias with movie.id. |
movie_name_alias.alias |
Human-readable alternative name used to generate additional filename candidates. Empty aliases are excluded. |
movie_name_alias.normalized_alias |
Stored normalized form used directly for name comparison and duplicate suppression. |
movie_name_alias.source |
Describes the alias source and is retained in match results so the reported match can identify how the alias was obtained. |
movie_history.movie_id |
Associates a historical duration with movie.id. |
movie_history.duration_seconds |
Earlier known duration. Positive values are used as historical duration versions so an older local release can still support a match. |
movie_history.archived_at |
Identifies when the historical version was archived and is retained with the historical duration for diagnostics and reporting. |
movie.id is the stable external identity in this contract. movie.name is
not an external identity: the site importer can update the current name and
archives the previous movie state in movie_history. File-management records
must therefore refer to movie.id, never to a name as an identifier.
SQL queries
The current implementation executes exactly these three queries.
Current movies
SELECT
id,
name,
duration_seconds
FROM movie
WHERE name IS NOT NULL
AND TRIM(name) <> ''
ORDER BY name, id
Aliases
SELECT
movie_id,
alias,
normalized_alias,
source
FROM movie_name_alias
WHERE alias IS NOT NULL
AND TRIM(alias) <> ''
ORDER BY movie_id, alias
Historical durations
SELECT
movie_id,
duration_seconds,
archived_at
FROM movie_history
WHERE duration_seconds IS NOT NULL
AND duration_seconds > 0
ORDER BY movie_id, archived_at
These are read-only SELECT statements. The matcher does not issue database
writes or invoke another database-writing component.
Backward compatibility
The following schema or semantic changes would be backward-incompatible for the current file-management code:
- removing or renaming any of the three contracted tables,
- removing or renaming any selected column,
- changing a selected value so it can no longer be converted as currently
expected (
id, names, alias source, and archive time to text; durations to positive integer seconds), - making
movie.idunstable or reusing an ID for another movie, - breaking the relationships from
movie_name_alias.movie_idormovie_history.movie_idtomovie.id, - changing
duration_secondsto another unit or meaning, - changing
normalized_aliasso it no longer represents the normalized alias expected by filename comparison, - changing the meaning of
sourcesuch that it can no longer identify the alias provenance shown in match output, or - preventing the three queries from running through a SQLite
mode=roconnection.
Adding unrelated tables or columns is compatible. Adding rows, updating a
movie name while retaining the same movie.id, adding aliases, and appending
historical durations are also compatible with the current query contract.
Process for contract changes
Before the reference-data project makes an incompatible change:
- Identify the affected table, column, value semantics, or relationship and document the proposed replacement.
- Update the file-management consumer to support the new contract, preferably with a transition period in which it can read both forms.
- Create a disposable database containing representative current names, aliases, current durations, and historical durations under the proposed schema.
- Verify all three queries and representative filename matching against that
database through
mode=ro. - Verify that a write through the same connection is rejected.
- Release or deploy the compatible file-management version before removing the old contract from the reference database.
- Remove the old contract only after both projects explicitly agree that no active consumer depends on it.
The projects must coordinate any incompatible change; the reference-data project must not silently break or reinterpret the documented read contract.