under the hood
A native Rust backend, one dialect abstraction for SQLite and Postgres, and an edit model built around staging changes before anything is written.
QuerySQL is a Tauri app: a Rust backend paired with a React and TypeScript frontend, rendered in the operating system's own webview rather than a bundled Chromium runtime. The two sides communicate over Tauri's command layer.
Database access lives behind a DbConnection enum in
src-tauri/src/db/. SQLite is implemented with rusqlite; Postgres with
the postgres crate. Both dialects expose the same shape — schema introspection,
query execution, paginated table reads, and transactional row mutations — so the frontend
doesn't need to know which one it's talking to. That shared interface is also what makes adding
another dialect later (SQL Server, for instance) a matter of implementing the same commands
rather than reworking the app.
A few deliberate tradeoffs in how the Postgres dialect talks to the wire protocol.
TEXT and cast to the destination column's real type in the SQL itself ($1::int4, $1::timestamp, etc.) — the standard way to send dynamically-typed values through tokio-postgres without knowing column types at compile time.rowid — ctid changes across updates and vacuums — so QuerySQL falls back to using every column as a composite identity for edits.public schema is introspected for now.Identifiers can't be parameterized the way values can, so both dialects validate them before they ever reach a query string.
Table and column names are checked against sqlite_master /
PRAGMA table_info on SQLite, or information_schema on Postgres,
before being interpolated into generated SQL — for the paginated table view and the row
mutation commands, where identifiers have to be built dynamically. Query values themselves go
through parameterized queries the normal way.
Why the table editor works the way it does.
Every edit is staged first. Fix a typo, add a row, drop a record — nothing reaches the database until you commit. Change your mind? Discard, and it's like it never happened.
Everything QuerySQL remembers between launches stays on your machine.
Recent connections and query history are persisted through tauri-plugin-store
to JSON files in the app's config directory. Postgres passwords are never included — recent
Postgres connections are saved without one, so reconnecting from the list always re-prompts.
Theme preference is stored in localStorage.
The frontend keeps open connections, query and table tabs, and theme state in Zustand stores, with a CodeMirror-powered editor for schema-aware autocomplete and a virtualized grid for large result sets.