Connections and safety
Production mode, read-only mode, TLS and SSH tunnels are enforced on the server session, not painted on the UI.
A SQLite file is a connection
SQLite has no server, so it has no host, port, user or password. Drop a .sqlite or .db file on the window, open it from Finder, or pick it from the File menu, and it is a connection like any other: tables, structure, queries, export and dump all behave the same way they do against a server.
- Foreign keys are enforced by default, which is not SQLite's own default.
- Read-only holds on the file itself, not only on the session, so a connection marked read-only cannot be written through by any route.
lower()andupper()fold more than ASCII, so a case-insensitive comparison behaves the way the rest of the app does.- The status bar reads Local file where a server connection names its transport, because there is no wire to encrypt.
Production connections
Mark a connection as Production and Tinker changes its behaviour, not just its colour. A production connection never auto-commits — not for a grid edit, and not for a statement typed in a query tab, where the Auto-commit checkbox gives way to a red MANUAL COMMIT mark and every write waits in a transaction for Commit or Rollback. The commit preview’s Execute button is disabled for 1.5 seconds and labelled with the connection name in red. Destructive actions such as Truncate and Drop require the table name to be typed.
Read-only connections
A read-only connection sets the session read-only on the server (SET default_transaction_read_only on PostgreSQL, SET SESSION TRANSACTION READ ONLY on MySQL). Commit is disabled in the grid. ⌘⇧L unlocks it for the current session only; the stored connection stays read-only.
TLS
New connections require TLS. The mode picker offers the usual set, plus a CA file, a client certificate and key, and a server-name override. What matters is what was negotiated, not what was asked for: the status bar shows the transport the session actually holds, and it says plainly when a connection is not encrypted.
SSH tunnels
Enable SSH on a connection and Tinker forwards a local port through the host before it connects. Authentication is by password or key file, with a passphrase where needed, and a jump host can sit in between. The tunnel is pure Swift over SwiftNIO (Citadel); nothing shells out to ssh. Known hosts are checked and a changed host key is reported, not accepted.
Where secrets live
Passwords and passphrases are stored in the macOS Keychain under the service com.tinker.connection. The connection store at ~/Library/Application Support/Tinker/store.sqlite holds only a reference to them. A test greps the store file to prove no secret ever lands there. Query history and error logs are redacted before they are written.
Connection errors
A failed connection opens a sheet that names the stage where it failed (DNS, TCP, SSH, TLS, auth), quotes the underlying message verbatim, and offers Retry. Connecting to a stopped server surfaces the TCP stage within the timeout instead of hanging.
Pooled connections
A session keeps a small pool. Before a pooled connection is reused, it is reset: open transactions are rolled back, session variables cleared, and the search path or database restored. One tab’s state never leaks into another’s.