Ported back to original Go version#20
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JSON omits both when nil and round-trips when set. content_hash flips whenever either field changes so DDL-shifting ALTERs produce a fresh snapshot, while pure stats writes stay stable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the production file naming after refactor e0a58d5: - server_test.go — setupOfflineTest helpers + getSchema contract - helpers_test.go — filterSnap, injectMeta, metaJSONResult - handlers_schema_test.go — list/describe/search/find_related - handlers_query_test.go — validate/explain/check_migration/suggest - handlers_lint_test.go — lint_schema scopes and filters - handlers_health_test.go — compare_nodes/detect*/vacuum_health - handlers_snapshot_test.go — reload_schema candidate handling Add tools_registration_test.go: round-trips the registered tool list through ListTools and asserts every listed tool resolves to a handler. Catches drift between tools.go (registration) and handlers_*.go (implementations). Also pins the offline tool surface — online-only tools (explain_query, refresh_schema, check_drift) must not appear without a live pool. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9 tests for SnapshotStore: Put insert/dedup/key-scoping, Get across all three SnapshotRef variants plus not-found sentinel, List with half-open TimeRange, DeleteBefore retention, Latest on empty key. 8 tests for config: ProjectID precedence and basename fallback, CLI-override invariants, per-profile database_id round-trip, missing profile error, demo fixture parses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Walks each rung of the precedence ladder (--db > --schema > --profile > [default].profile > single-profile fallback) at the resolver layer, plus on-disk CLI tests that exercise requireDB and resolveSnapshotKey through a real dryrun.toml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seeds two streams / three snapshots through history.Open, runs export, walks the output tree and asserts each .json.zst decompresses back to a SchemaSnapshot whose ContentHash matches the filename. Adds ListKeys coverage for distinct-key ordering and the legacy NULL-keyed skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ariants JSON round-trip for the PlannerStatsSnapshot / ActivityStatsSnapshot shapes (plus QualifiedName), content_hash sensitivity across add/remove column, add/remove index, PK move, FK add, RLS toggle, and the schema_ref_hash binding planner/activity to a fresh schema content_hash. History store coverage for PutPlanner idempotency on (schema_ref, content_hash), PutActivity append-only semantics, LatestPlanner ordering, LatestActivity per-node collapse, and GetPlanner/GetActivity schema_ref scoping. Live-DB capture tests gated on TEST_DATABASE_URL since the repo carries no testcontainers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s paths bloat, summarize, and vacuum tests rebuilt around AnnotatedSchema fixtures (planner sizing + merged activity) so DetectUnusedIndexes, DetectBloatedIndexes, EstimateIndexBloat and AnalyzeVacuumHealth get coverage in the new shape. advise tests in query/ migrate to *AnnotatedSchema via a small fixture helper; perNodeBreakdown now drives off MergedActivity. audit indexes/bloated and vacuum/large_table_defaults tests removed since those rules are stubs without AnnotatedSchema; equivalent coverage lives in schema/summarize_test.go. SuggestedVacuumKnobs keeps a standalone sanity check. mcp/helpers_test loses the NodeStats branch of filterSnap. schema/clone_test is deleted along with CloneForStats. schema/hash_test drops the stats-only stability case (impossible by construction now). query/validate_test skips the unbounded-query assertion until ValidateQuery accepts AnnotatedSchema. Tests that used inline TableStats / IndexStats / NodeStats literals are purged; migration_test / validate_test fixtures stripped of those fields. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lock down the three init.go branches with a stub Capturer/Writer so future changes can't silently re-enable schema capture on a standby or drop the planner stream on a primary. Adds a companion MCP test ensuring reload_schema prefers history.db over a stray schema.json — otherwise stats apply loses its planner/activity binding.
The tool() shorthand returned a bare mcp.Tool with no parameter
declarations, serializing as {"properties":{},"required":[],"type":""}.
Clients couldn't validate args or render parameter UIs.
Replace eight call sites with mcp.NewTool(...) declaring real schemas:
find_related, validate_query, check_migration, suggest_index,
compare_nodes get their required/optional params; reload_schema,
refresh_schema, check_drift declare empty object schemas.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Iterate the registered tool list and assert inputSchema.type == "object" on each. Pin the required-args contract for tools that have any so future helper changes that drop required markers fail loudly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- advise: offline produces JSON wrapper with validation + offline hint;
include_index_suggestions=false omits the key; malformed SQL surfaces
a parse error instead of panicking.
- analyze_plan: accepts both {"Plan":...} and [{"Plan":...}] shapes;
missing or malformed plan_json returns a typed error.
- schema_diff: graceful error path when neither history store nor live
DB is available; handler is reachable through the MCP client.
Also refreshes tools_registration_test fixtures for the new surface
(advise, analyze_plan, schema_diff added; suggest_index removed) and
the DetectPlanWarnings export rename.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drive runSnapshotActivity across primary-refused, standby-without- snapshot-refused, standby-binds-to-stored-hash, and --allow-orphan unbound-row cases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eams New store_kind_aware_test.go drives StoredSnapshot of each variant through Put -> Get -> List, asserts ListKinds returns the populated subset (with activity entries fanning out per node_source), and pins that Latest / DeleteBefore isolate per kind so V3's per-kind sync diff and retention loops can't bleed across streams. Existing tests in snapshot_store_test.go, store_test.go, stats_test.go, and the cmd/mcp stubs were retargeted at the schema-specific wrappers (PutSchema / GetSchema / ...) so coverage of the v0.6 surface stays intact through the interface widening. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight tests pin the bundle contract:
- Round-trip schema/planner/activity through Put -> Get -> List.
- Bundle JSON shape: top-level {schema, planner, activity} with planner
null when absent and activity keyed by node_source. Asserted at the
raw-JSON level so a Go struct rename can't silently break Rust compat.
- Schema dedup: byte-identical re-put returns PutDeduped, dir holds one
bundle file.
- Orphan: putting planner / activity without a matching schema bundle
errors out (ErrOrphanSnapshot).
- Activity by node: two node_source puts populate bundle.activity as a
two-entry map inside a single bundle, not as separate files.
- Concurrent put idempotency: 16 goroutines racing the same schema land
exactly one bundle and zero .bundle-*.tmp leftovers.
- Planner / activity dedup compares against the existing slot and skips
the bundle rewrite (verified by mtime equality).
- ListKeys ignores empty (project, database) directories left behind by
an aborted write.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seven tests pin the diff-by-content-hash sync loop and the cross-store wire format: - Empty dst gets every row Copied, zero UpToDate. - Pre-seeded dst reports UpToDate for matching hashes and Copied for the rest; dst ends up holding both. - Multi-node activity copies each node_source as its own row, no collisions, label preserved through List -> Get -> Put. - Kind order is schema -> planner -> activity, verified by pushing into a FilesystemStore dst (which enforces the orphan rule). - --all routes through src.ListKeys and surfaces every key in the output block. - The acceptance round trip: SQLite -> FilesystemStore -> fresh SQLite, asserting content_hashes match per kind. If the bundle JSON layout ever drifts between encoder and decoder, this loses symmetry first. - Empty-key sync prints a human notice, not an empty buffer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
It's complicated..