CONNECT to …

Your databases, as they are.

Servers reached by their own protocol or over HTTP, two databases that live in a file, and three relatives of PostgreSQL the app recognises on its own. Each dialect keeps its rules: quoting, script separators, plans, transactions.

FROM nineteen kinds of database

What it speaks.

PostgreSQL

Dollar quoting in scripts, EXPLAIN as JSON, sessions that are read only on the server, roles with SCRAM.

pg_dump · pg_restore · psql

MySQL

DELIMITER in scripts, backticks for names, users with hosts. One driver for MySQL and MariaDB.

mysqldump · mysql

MariaDB

Recognised by what the server says about itself. Its own tools (mariadb-dump, mariadb) are found as well.

mariadb-dump · mariadb

SQL Server

GO splits batches, names in brackets, plans as XML, logins and users.

simple SQL export

SQLite

A file on your disk. And a demo database in memory, there from the first start, to try everything without a server.

a copy of the file

CockroachDB · TimescaleDB · YugabyteDB

They speak PostgreSQL’s protocol. The app finds out who answers and adapts: cancel, transaction state, catalog.

connect as PostgreSQL

Oracle

A driver in pure Rust: no Instant Client to install. PL/SQL blocks end at a line with /, dates are bound as dates. Run, browse, details with DDL, edit rows, search.

plans, monitor, rights: not yet

ClickHouse

Over its HTTP interface, to read and analyse: run, cancel, browse, filter, search. It has no transactions and no unique keys, so rows are not edited in the grid.

read and analyse

DuckDB

Built in. A file or :memory:, and SELECT * FROM 'sales.parquet' just works. Nothing is downloaded: extensions are never loaded on their own.

Parquet · CSV · JSON

Trino · Presto

Over HTTP, one profile per catalog: run, cancel, browse, filter, search. The driver itself keeps a session to reading; values become checked literals, because the protocol binds none.

read and analyse

libSQL · Turso

SQLite’s dialect behind a server: everything that works for a SQLite file, but the copy as a backup. An open transaction is kept alive by a heartbeat.

token over TLS

Cloudflare D1

Over Cloudflare’s REST API with an API token: run and read in SQLite’s dialect. One request per statement, so there are no transactions and rows are not edited.

not yet run against Cloudflare

Firebird

A driver in pure Rust. Run, cancel, browse, details, edit rows, search; NUMERIC values keep every digit, SET TERM splits scripts.

plans, monitor, rights: not yet

BigQuery

Over Google’s REST API with the key file of a service account: run, cancel, browse datasets, filter, search. Mind the cost: a table view reads the table.

checked against the emulator only

Snowflake

Over its SQL API with a programmatic access token or a key pair: run, cancel, browse, filter, search, with the default warehouse and role of the user.

not yet run against a real account

Db2

Db2 for Linux, UNIX and Windows with a driver in pure Rust: no IBM client to install. Run, cancel, browse, filter, search; every statement is committed as it ran.

never run against a server yet

The drivers are tested against real servers, started in containers; SQLite and DuckDB run inside the tests. The exceptions are named on their cards: Cloudflare D1, Snowflake and Db2 are written from their documentation, BigQuery ran against its emulator.

USING a profile

Connecting.

A connection is a profile: where, as whom, how secured. Profiles live in folders, carry a colour that marks their tabs, and never hold a secret.

Passwords in the keychain

Not in a file. Not in an export.

After a login that worked, the password goes to the keychain of your system: Keychain on macOS, Credential Manager on Windows, the Secret Service on Linux. The file with the profiles can be read by anyone without telling them anything.

connections.json
{ "name": "shop-live",  "kind": "postgres",  "host": "db.internal", "port": 5432,  "user": "marc", "database": "shop",  "protection": "ask", "color": 7 }// no password here, ever

SSH tunnel

For the database that is not on the internet. Most are not.

Sign in with the SSH agent, a key or a password. The host key is checked against your known_hosts; an unknown key asks you to confirm its fingerprint, a changed key is refused. ~/.ssh/config is read for host names and users, and nothing in it is ever executed.

shop-live · tunnel
# you → bastion → databasessh   marc@bastion.example.com:22      key   ~/.ssh/id_ed25519 (agent)      host  SHA256:… knownthen  db.internal:5432  TLS verify-full

TLS, the way your server wants it

From “off” to “verify everything”.

Choose the mode per connection, bring your own certificate authority, and a client certificate if the server asks for one. The same settings are handed to the backup tools, so a dump runs as securely as the session.

shop-live · TLS
mode         verify the certificate and the host nameCA           /certs/company-ca.pemclient cert  /certs/marc.pemclient key   /certs/marc.key
connectedPostgreSQL · certificate and host name checked · through bastion.example.com
postgres://user@host/db

From a URL

Paste a connection URL and the profile is filled in. A password in the URL goes to the keychain, not into the profile.

DBeaver · DataGrip

From other tools

Read the connections of DBeaver and DataGrip, and what .pgpass, pg_service.conf, .my.cnf and the environment know.

export

Take them with you

Export your profiles to a file and import them elsewhere. Without passwords.

REVOKE the accident

Protection for production.

Every connection has a level. The backend classifies each statement as reading, writing, DDL or dangerous and decides; the window only shows the question.

free

Free

Only what is dangerous asks first: a DELETE or UPDATE without WHERE, a DROP, a TRUNCATE.

ask

Ask

Everything but reading asks first. For what is dangerous you type the name of the connection.

read only

Read only

Nothing but reading runs. Editing, importing, copying into it and restoring are refused in the backend.

The same check guards everything that writes: the editor, the grid, structure changes, import, copying tables, test data, rights, ending a session.

CASE dialect

What differs, and how the app deals with it.

PostgreSQLMySQL · MariaDBSQL ServerSQLite
Scripts are split at;, with dollar quoting; and DELIMITER; and GO;
Names are quoted as"name"`name`[name]"name"
Parameters:name, ${name}, ?, $1: which forms count is set per connection; the driver binds the values
Reading only, for an assistantread-only transaction on the serverread-only session on the servera transaction that is rolled backquery_only
Back up and restorepg_dump, pg_restore, psqlmysqldump or mariadb-dump, mysqlsimple SQL exporta copy of the file
Without toolsa simple SQL export written by the app, and its restore
OracleClickHouseDuckDB
Scripts are split at;, PL/SQL blocks at a line with /;, with backslash escapes;, with dollar quoting
Names are quoted as"name"`name`"name"
Values are bound as:1, a date as a date{p1:String}?
Reading only, for an assistanta transaction that is rolled backreadonly = 1 on the session of the serverstructure only: a query there could read any file
Transactionsauto-commit by the app, or manualnoneyes, one database shared by all tabs of a profile
Not there yetplan, monitor, rights, edit structure, backupedit rows, import, copy tables, plan, monitor, rightsplan, edit structure

Plans, object details, DDL, the ER diagram, schema compare, the monitor and rights read the catalog of each database with bound parameters. What a database does not offer yet is hidden for its connections, not left to fail.

SELECT * FROM your_database;

Run it.

Free and open source under the MIT license. The packages are not signed yet.