Skip to content

docs: planning doc for data compare & diff tool - #527

Draft
aesslinger wants to merge 6 commits into
TabularisDB:mainfrom
aesslinger:data-compare-diff-tool
Draft

docs: planning doc for data compare & diff tool#527
aesslinger wants to merge 6 commits into
TabularisDB:mainfrom
aesslinger:data-compare-diff-tool

Conversation

@aesslinger

@aesslinger aesslinger commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Planning document and mockups for a new Compare & Diff feature. Looking for design feedback before implementation begins.

Ref #21

What's in this PR

No code changes — just a comprehensive planning doc at .github/planning/data-compare-feature.md with 5 SVG mockups.

Feature Summary

A unified comparison tool with two modes:

  • Data Compare — row-level diffs between tables/query results, with sync script generation
  • Schema Compare — structural DDL diffs (columns, indexes, FKs), with migration script generation

Both modes share the same UI shell (source/target selectors, summary bar, sync script panel) with a Data/Schema mode toggle.

Key Design Decisions (seeking feedback)

  1. Architecture: New "compare" tab type in the Editor (not a separate page), with pop-out window support
  2. Combined tool: Data + Schema as modes in one tab, not separate features
  3. Safety: Dry-run by default, transaction wrapping, optional rollback script generation
  4. Performance: Frontend comparison for MVP (<10K rows), Rust backend for Phase 4 (100K+)
  5. Cross-driver: Same-driver comparisons first; cross-driver schema compare with type normalization in Phase 3

Open Questions (10)

Listed at the bottom of the doc — would especially appreciate input on:

  • How to handle the 10K-100K row transition before Rust backend exists
  • Dialect-specific DDL generation effort
  • Keyboard shortcuts for diff navigation

Mockups

5 SVG mockups in .github/planning/mockups/:

  1. Compare Setup Panel
  2. Data Comparison Results (side-by-side)
  3. Data Sync Script Preview
  4. Schema Compare Results
  5. Schema Migration Script Preview

aesslinger and others added 3 commits July 24, 2026 10:06
Covers data comparison (row-level diffs) and schema comparison (DDL diffs)
as a combined tool with mode toggle. Includes:

- 5 SVG mockups (setup panel, results view, sync script, schema compare,
  schema migration script)
- Architecture decision (new tab type + pop-out window)
- Phased implementation plan (4 phases, ~11 weeks)
- State model and component tree
- Driver abstraction analysis (multi-database nuances)
- Safety & permissions design (dry-run, transactions, rollback scripts)
- Row ordering strategy (merge-join on sorted comparison key)
- Composite key handling
- Value serialization by dialect
- Live vs snapshot query semantics
- Connection error handling
- Partial sync selection UX
- Accessibility requirements (color + icon markers)
- Comprehensive testing strategy
- 10 open questions for discussion
@debba

debba commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Hi @aesslinger

Here are my thoughts on the open questions:

  1. Tab vs. Page: always a tab, with the pop-out window covering the "more screen real estate" case. This is basically what the Architecture Decision section already recommends, and a third dedicated-page mode would lose the sidebar and tab state persistence for little gain
  2. Trigger points: yes to the Explorer right-click ("Compare with..."). It's the most natural entry point, since users almost always start from a concrete table. I would ship it in Phase 1 already, pre-filling the left side with the clicked table.
  3. Comparison direction: fixed convention, left = source (reference), right = target (what the sync script will modify), plus a swap button to invert the sides. A configurable direction multiplies the test surface of the script generator and confuses users; swap gives the same flexibility without ambiguity.
  4. Auto-refresh: always a manual snapshot, with a visible "Re-run" button and a timestamp of the last execution. Auto-refreshing a potentially expensive operation is risky for DB load, and a diff that changes while you're reviewing it is bad UX. Snapshot semantics are also the only model consistent with generating reliable sync scripts.
  5. History: yes, but in Phase 3 as already planned. In Phase 1, persisting the tab configuration (which the tab model gives us almost for free) is enough. Named, re-runnable configs only become valuable once cross-connection compare exists, because that's when reconfiguring from scratch gets tedious.
  6. Keyboard shortcuts: the real answer is that these should go through the existing keybindings registry (ShortcutDef in src/utils/keybindings.ts) with overridable: true, probably under a new "compare" category, so they show up in the Shortcuts settings tab and users can remap them like everything else. That makes the default choice low-stakes. As defaults I would go with F7 / Shift+F7 for next/previous diff, consistent with Monaco's DiffEditor which we plan to use in Phase 2 anyway.
  7. Multi-table schema compare: one table at a time in Phase 2, whole schema in Phase 3 as planned. Multi-table is not just a loop over the single-table case: it needs a summary tree view, FK-aware ordering in migration scripts, and handling of tables that exist on one side only. Better to consolidate the single-table case first.
  8. Dialect-specific DDL: targeted investment, full dialect-aware support only for the dialects we already ship (PostgreSQL, MySQL, SQLite), delegating DDL generation to the driver layer. SQLite needs special care since many ALTER TABLE operations don't exist there and require the create/copy/drop/rename pattern; in that case I would generate the script with an explicit warning comment rather than pretend the ALTER works. A "generic" cross-dialect DDL is the wrong path, it produces scripts that run nowhere.
  9. 10K-100K rows: option (c), chunked client-side comparison with a progress bar and a cancel action, plus a warning threshold (~10K) informing the user before starting. Option (a) alone freezes the UI and makes the tool feel broken; (b) is an artificial limit that frustrates exactly the typical use case (mid-sized staging tables). The chunking logic is not throwaway work either: it prefigures the hash-first approach of later phases, and the Rust backend will inherit the same progress/cancellation model. Above a hard threshold (say 500K) I would show a clear error stating that support arrives with the native backend.
  10. Right sidebar detail view: I would leave this open and evaluate it in the future, once the core compare is solid. If we do it, I would lean towards a bottom panel or an inline row expansion reusing the Monaco DiffEditor rather than the right sidebar, which feels too narrow for a two-column comparison.

This is my take, but it's not set in stone. I'm more than open to discussing any of these points.

FYI @NewtTheWolf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants