Skip to content

feat(windows): rebuild the Windows app on the shared Rust core - #3867

Merged
datlechin merged 229 commits into
TableProApp:mainfrom
countradooku:feat/windows-app
Nov 3, 2026
Merged

datlechin merged 229 commits into
TableProApp:mainfrom
countradooku:feat/windows-app

Conversation

@countradooku

@countradooku countradooku commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replaces the first version of this PR's Windows app. None of its code or design is kept.
  • core/crates/ffi (tablepro-ffi): one UniFFI API over the core's sessions, drivers, catalog and connection library, with the 9 engines of the first release linked in.
    • Rows go into a columnar result set in the core. The grid reads it through a C ABI, tablepro_cursor_fetch, one packed window per visible range.
    • The core keeps saved connections, groups, favorites and tags, and their secrets (Credential Manager on Windows). It connects them, tests a connection and parses connection URLs.
    • The core writes every sorted and paged statement: DatabaseSession::table_query over build_page, sorted_query over sql_syntax::with_order_by and sort_reference, and counts a table's rows.
    • value::order moves from the Linux app into the core, and ResultSet::sorted sorts the rows a result holds (core ADR 0007).
    • The FFI also reports the transaction a run leaves open, session health and which secret is missing. Each engine's family comes from the core.
  • windows/: .NET 10 and WinUI 3, Windows 10 1809+ and 11, x64 and Arm64 (ADR 0001).
    • TablePro.Interop: committed, internal UniFFI and csbindgen bindings under a hand-written public API. Calls start on the thread pool; a CancellationToken fires the core's cancel token.
    • TablePro.Editor: our own SQL editor. A rope with its own undo, multiple carets and find in a plain .NET model; Direct2D and DirectWrite in a SwapChainPanel; TSF for input methods; a UIA text provider; colors from the core's lexer (ADR 0002).
    • TablePro.DataGrid: our own read-only grid. ItemsRepeater rows draw their visible cells with DirectWrite into composition surfaces; frozen columns, Excel keys and copy, UIA peers, header sort and resize, columns sized to content (ADR 0003).
    • TablePro.App: one window with the TitleBar, a MenuBar and a NavigationView rail of open connections, each item with its engine's icon in the connection's color (ADR 0004).
    • Connections page: groups, favorites, tags, search, selection mode, drag and drop into groups and Favorites, rename in place.
    • Connection form in an owned window: engines by family with their artwork, URL paste, SSH, SSL and options sections, Test, Connect and Save.
    • Workspace per connection: object tree in a resizable pane, query and table tabs, Reopen closed tab, table paging with the server's row count.
    • Bars: a password prompt when none is saved, a transaction bar with Commit and Roll back, a bar naming another tab's open transaction, and a reconnect bar from the session's health.
    • Settings as a page; window placement and the session are restored.
  • CI: a windows suite in the change detector and windows.yml. Core and .NET tests on windows-2025, windows-11-arm and macos-15; the app's UI tests with screenshots on both Windows runners; a stale bindings check on macOS. The grid's timing gate runs by dispatch (windows-grid-gate.yml).
  • test_unknown_suite_exits_2 used windows as its unknown suite and now uses android.
  • Not in this PR: cell editing, packaging and signing, importers from other apps, tab tear-out, a page size picker, the driver plugin ABI on Windows.

Test plan

  • cargo test -p tablepro-ffi and the core's ordering, sort reference, tag, paging and health tests. Linux CI runs the workspace: 871 core tests and the app suite.
  • dotnet test --solution TablePro.slnx on x64, Arm64 and macOS: 217 tests over the interop library against real SQLite files, the editor model, the grid model with the real core and the app model.
  • TablePro.App.UITests (FlaUI), light and dark, on both Windows runners: first run, Settings, the form, connecting, password prompt, a table, its sort and paging, a width set through UIA kept across sorts, a query and its sort, a script's rows sorted where they are, transactions, reopened tabs, pane resize, window placement, tags, rename, drag and drop, selection, a failed connect, session restore.
  • 32 UI tests per runner in run 41588147784. Run 41575653721 ran them 4 times on each runner: 128/128 on x64 and 128/128 on Arm64.
  • Editor gate on a 5 MB script: typing p95 under 11 ms on both runners; Telex and Pinyin compose at the caret (ADR 0002).
  • Grid gate over a million rows by 200 columns, worst step in ms, Arm64 / x64 (run 41530931997): page down 22.6 / 15.9, random rows 25.3 / 14.0, page right 30.0 / 22.9, random x and y 32.5 / 27.9.

Screenshots

From the UI tests on windows-2025 (WARP), run 41588147784. Arm64 matches. The two reconnect bars come from run 41577633514, with an uncommitted patch that forces the session's health; a runner cannot drop a session.

Light Dark
First run First run, light First run, dark
New connection: engine New connection: engine, light New connection: engine, dark
New connection: details New connection: details, light New connection: details, dark
Form error Form error, light Form error, dark
Connecting Connecting, light Connecting, dark
Connect failed Connect failed, light Connect failed, dark
Password prompt Password prompt, light Password prompt, dark
Workspace Workspace, light Workspace, dark
Rail item in the connection's color Rail item in the connection's color, light Rail item in the connection's color, dark
Object pane resized Object pane resized, light Object pane resized, dark
Table Table, light Table, dark
Table sorted by Title Table sorted by Title, light Table sorted by Title, dark
Table paged Table paged, light Table paged, dark
Script sorted where it is Script sorted where it is, light Script sorted where it is, dark
Closed tab reopened Closed tab reopened, light Closed tab reopened, dark
Open transaction Open transaction, light Open transaction, dark
Transaction in another tab Transaction in another tab, light Transaction in another tab, dark
Reconnecting Reconnecting, light Reconnecting, dark
Reconnect failed Reconnect failed, light Reconnect failed, dark
Settings Settings, light Settings, dark
Connections with engine marks Connections with engine marks, light Connections with engine marks, dark
Rename in place Rename in place, light Rename in place, dark
Tagged connection Tagged connection, light Tagged connection, dark
Dropped into a group Dropped into a group, light Dropped into a group, dark
Selection mode: one connection, both rows Selection mode, light Selection mode, dark

countradooku and others added 29 commits October 28, 2026 17:22
A Windows sibling of the macOS and Linux apps under windows/: .NET 10, WinUI 3 on
Windows App SDK 2.6 with acrylic and Fluent Design, and one project per layer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cessible names

Also folds the SSH askpass helper into TablePro.exe, adds edit buffer, completion,
formatter and CSV tests, and uppercases known functions in the formatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the windows suite to the change detector, build-windows.yml on windows-2025,
the parity roadmap, the architecture notes and the folder's agent guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r non-SQL languages

Adds the remaining engines from tablepro.app/databases with their families and data
models, dialect hooks for splitting, classifying and keywords, dialects for Redis,
mongosh, etcd, KafkaQL, the Query DSL and Typesense consoles, GraphQL, SurrealQL,
CQL, PartiQL and the analytical SQL engines, and opens CockroachDB, Redshift, PGlite,
TiDB, OceanBase and Databend through the PostgreSQL and MySQL drivers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hile typing

The editor asks for values of ?, :name and $1 placeholders and writes them as literals,
results export to Excel workbooks, table import reads JSON and NDJSON beside CSV, the
assistant suggests text when typing pauses at a line end, and the workspace, editor and
connection form follow each engine's language: keywords, comment prefix, server-side key
search, starter queries and field labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… suggestions built

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es and server info

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Oracle scripts split at a lone slash for PL/SQL blocks. ClickHouse binds
@pn so change previews show values, and defaults to 8443 under TLS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent editing

Saves on engines that do not write SQL show their own commands for review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Browse notices travel on the result and show under the grid; CQL batches
split as one statement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GoogleSQL and SurrealQL names escape a backtick with a backslash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…DB drivers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and Turso drivers

KafkaQL SELECT and DESC classify as reads for Safe Mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sends

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Kafka and etcd

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dameng and HANA connect through the vendor ODBC drivers; Beancount projects a
ledger into SQLite through beancount or rledger, as on macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ly engines

The grid treated every non-table as read-only, so MongoDB collections and
Redis keys could not be edited. Beancount and R2 SQL are now read-only
whatever the Safe Mode level. Previews fill positional ? parameters in order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Modes, counts, operators, motions, text objects, registers, marks, macros,
search and dot repeat run in a UI-free engine in Core over a buffer
interface; the editor routes keys to it and draws a block caret.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rison

PostgreSQL, MySQL, SQL Server, SQLite, DuckDB, ClickHouse and Oracle plans
parse into one model with cost shares and severity; Explain Analyze runs
under Safe Mode like the statement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ap :q and gt to tabs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erver

Principals, memberships and grants at every scope are staged with undo,
reviewed with passwords hidden, and applied in a transaction where the
engine allows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ncount

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…roadmap

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@datlechin
datlechin marked this pull request as draft October 28, 2026 18:20
# Conflicts:
#	core/crates/drivers/clickhouse/src/endpoint.rs
@datlechin
datlechin marked this pull request as ready for review November 3, 2026 07:04
@datlechin
datlechin enabled auto-merge (squash) November 3, 2026 07:04
@datlechin
datlechin merged commit 09c18ef into TableProApp:main Nov 3, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants