fix(zq): stop defaulting the database path into the repo being deleted

`zq.py` hardcoded one absolute path, and it pointed inside `xenia-rs` --
a repository CONSOLIDATION.md archives in Phase 5 and drops in Phase 7. It
resolved on exactly one machine, and on that machine it was days from becoming
a `duckdb` exception about a missing file, with nothing saying why.

Resolution order is now `$SYLPH_XEXDB`, else `<repo root>/sylpheed.db`, else a
refusal that names both. The repo-root path is taken relative to this script,
not the caller's cwd, because zq.py is run from wherever the investigation is.

No fallback beyond that, on purpose. The database is a build artefact of a few
hundred MB and is not tracked, so there is nothing to fall back *to*; a default
that silently resolves to the wrong database is worse than no default. That is
issue #16's lesson, which was about exactly this shape in the test suite.

Both failure paths say what to do and exit 1:

  $ zq.py fn 82000000            # nothing set, nothing at the repo root
  no database found.
    looked for: /…/Sylpheed/sylpheed.db
    set $SYLPH_XEXDB to an existing one, or build it with:
      sylph-xexdb dis <xex|iso> --db sylpheed.db --analyze sql

  $ SYLPH_XEXDB=/nope/missing.db zq.py fn 82000000
  $SYLPH_XEXDB is set but is not a file:
    /nope/missing.db

Also fixes the regeneration hint, which still named `xenia-rs dis` -- the
retired binary. It is `sylph-xexdb dis`.

Connecting is skipped when there is no subcommand, so `zq.py` still prints its
usage on a machine that has no database yet.

Verified: usage with no db (rc 0); missing db (rc 1); `$SYLPH_XEXDB` set to a
non-file (rc 1); and `$SYLPH_XEXDB` pointed at a real 336 MB database, where
`imp Rtl` returns its 1,280 `RtlLeaveCriticalSection` call sites. That database
turns out to have been generated from the uncommitted tree this branch ports:
it carries `import_address`, `import_role` and all 16 foreign keys -- an
independent confirmation of the schema the golden test now locks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 20:49:49 +02:00
parent 13c895abff
commit 5f623bf110

View File

@@ -38,18 +38,59 @@ Usage:
A command that needs a table the current DB predates prints what to regenerate
rather than a SQL error.
The database is found via `$SYLPH_XEXDB`, else `<repo root>/sylpheed.db`. It is a
build artefact, not a tracked file; if neither exists, zq.py says so and prints
the command that builds one.
"""
import duckdb, sys, signal
import duckdb, sys, os, pathlib, signal
# Output is routinely piped into `head`; without this Python prints a
# BrokenPipeError traceback when the reader closes early.
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
DB = '/home/fabi/RE - Project Sylpheed/xenia-rs/sylpheed.db'
c = duckdb.connect(DB, read_only=True)
H = lambda x: '0x%08x' % x
REGEN = "sylph-xexdb dis <xex|iso> --db sylpheed.db --analyze sql"
REGEN = ("xenia-rs dis <xex|iso> --db sylpheed.db --analyze sql")
def _resolve_db():
"""Locate the database: `$SYLPH_XEXDB`, else `<repo root>/sylpheed.db`.
🔴 This used to be one hardcoded absolute path, and it pointed *inside*
`xenia-rs` -- a repository `docs/agents/CONSOLIDATION.md` archives in Phase 5
and drops in Phase 7. It resolved on exactly one machine and would have
started failing there too, with `duckdb` raising about a missing file rather
than anything saying why.
The database is a build artefact of several hundred MB and is not in the
repository, so there is nothing to fall back *to*: if neither location has
one, say so and print how to build it. A default that silently resolves to
the wrong database is worse than no default -- see issue #16.
"""
env = os.environ.get('SYLPH_XEXDB')
if env:
p = pathlib.Path(env).expanduser()
if not p.is_file():
sys.exit(f'$SYLPH_XEXDB is set but is not a file:\n {p}')
return p
# Relative to this script, not to the caller's cwd: `zq.py` is run from
# wherever the investigation happens to be.
p = pathlib.Path(__file__).resolve().parent.parent / 'sylpheed.db'
if p.is_file():
return p
sys.exit(
f'no database found.\n'
f' looked for: {p}\n'
f' set $SYLPH_XEXDB to an existing one, or build it with:\n'
f' {REGEN}'
)
# Resolved lazily enough that `zq.py` with no command still prints its usage on
# a machine that has no database yet.
_WANTS_DB = len(sys.argv) > 1 and sys.argv[1] not in ('-h', '--help', 'help')
DB = _resolve_db() if _WANTS_DB else None
c = duckdb.connect(str(DB), read_only=True) if DB is not None else None
H = lambda x: '0x%08x' % x
def _need(*tables):