Skip to content

BookiE 0.1.5

Latest

Choose a tag to compare

@cursor cursor released this 27 Sep 23:47
· 1187 commits to main since this release
34ea8c0

BookiE 0.1.5 for Linux.

Ubuntu 26.04+ / Debian with GTK 4.22, libadwaita 1.9, GtkSourceView 5.18, and GLib 2.88 (amd64). Arch Linux / Omarchy (x86_64). Ubuntu 25.10 and 24.04 cannot run this build. Launch with bookie. tablepro remains an alias. Apt package name is tablepro.

Commit 34ea8c0a894e356e4f88d73b8c0324cec784096b.

Packages

  • Ubuntu/Debian amd64: tablepro_0.1.5-1_amd64.deb
    SHA256: a8bb8ce6d3be87e3e5dc8e30cc93483908c631f14b284a98296fa6befdeccb94
  • Arch/Omarchy x86_64: bookie-0.1.5-1-x86_64.pkg.tar.zst
    SHA256: c9d1b0ff043d0ae05cb0f26de3485928ca1c5916f9582816e459a71f2aafecd7

Changelog

[0.1.5] - 2026-09-27

Added

  • Loaded results can be exported as Markdown, HTML, XML, SQL INSERT statements, or an Excel workbook, alongside CSV and JSON. Statement export is offered only for connections whose engine can express SQL literals, and an Excel export exceeding worksheet limits leaves any existing destination untouched. Workbooks preserve fractional seconds, timezone-bearing timestamps and dates outside 1900–9999 as exact text; ordinary supported dates and whole-second times remain native spreadsheet cells. Empty text is refused with CSV/JSON alternatives instead of being silently collapsed into NULL, preserving any existing destination. XML and HTML preserve carriage returns when parsed. XML refuses unsupported XML 1.0 characters and HTML refuses NUL characters with a row/column error instead of replacing or dropping them.
  • Saved queries have a management dialog (Ctrl+Shift+D): search them, open one in a new editor tab, rename it, or delete it. Until now a saved query could only be reached through the quick switcher and could not be removed.
  • A query that runs for 10 seconds or longer shows a desktop notification when it finishes while the window is not focused.
  • Ctrl+O opens a .sql file in a new editor tab. A file larger than the editor's limit is refused with an explanation instead of being cut short.
  • An editor tab opened from a .sql file is titled by the file, marked while it has unsaved changes, and saves back to it with Ctrl+S; Ctrl+Shift+S saves to a new file, and Ctrl+S on an unsaved query asks where to save it. If another program changed or removed the file since it was opened, the save stops and offers Overwrite or Save As instead of replacing the other program's changes. Closing a tab with unsaved file changes asks first, and after a restart the tab is linked to its file again; if the file is gone, the tab keeps its text and says it is no longer linked.
  • Query history now also records the statements the app itself runs when you save a table structure change or save edited rows, and the history dialog can filter by where a statement came from.
  • Logs can be written as structured JSON lines by setting the log format environment variable, for collection by a log agent. Any other value keeps the human-readable format.
  • A CSV file can be loaded into an existing table from the table's context menu. The file's separator and header row are detected and can be changed, each table column is mapped to a field before anything runs, and the whole import is approved once. It commits in bounded batches, shows progress, can be cancelled, and reports how many rows were written when it stops early.
  • A CSV file can also create the table it is loaded into, from the schema header in the sidebar. The column names and a type guessed from the first rows of the file are shown for every column and can be changed before the table is created. A guess falls back to text whenever any value in the sample does not fit a narrower type.
  • The structure editor shows a Comment field for each column, and reads each column's comment on PostgreSQL, MySQL, SQL Server and ClickHouse, and writes it when creating a table, adding a column or editing one. SQLite refuses a comment with a clear message instead of dropping it silently.
  • Open Quickly (Ctrl+P) lists the connection's tables and views across every schema. Typing a name or a schema-qualified name such as sales.orders finds them, and choosing one opens it.
  • A browsed table's cell menu has Filter by This Value, which narrows the table to rows holding that value, or to rows where the column is NULL for an empty cell. It replaces an existing rule on the same column and keeps the others.
  • PostgreSQL sessions opened by the app report the application name BookiE, and those opened for agents report BookiE agent, so they can be told apart in pg_stat_activity.
  • PostgreSQL materialized views are listed with views in the sidebar and open read-only.
  • The built-in SSH client can authenticate with keys held by ssh-agent, chosen as "SSH agent" in the SSH section, including in the Flatpak build; a missing agent or an agent with no keys is reported plainly.
  • An SSH tunnel can use the system OpenSSH client instead of the built-in one, so ~/.ssh/config, ProxyJump, ssh-agent and host certificates apply. Host keys are always checked: the app asks before trusting a new host even if ~/.ssh/config would accept it, and the agent daemon refuses an unknown host. A saved password or passphrase is only given to the host or key it belongs to, never to a jump host. Not available in the Flatpak build, which cannot run the host's ssh.
  • An editor tab can turn on Session to run on its own PostgreSQL, MySQL, SQL Server or SQLite file connection, so settings, temporary tables and a transaction started with BEGIN carry over between runs. The button shows when a transaction is open, and turning Session off or closing the tab with one open asks whether to commit or roll back. Every statement still goes through policy, approval and the audit journal, and COMMIT and ROLLBACK are recorded as transaction outcomes.
  • A Catalog window in the main menu lists a PostgreSQL connection's functions and procedures, triggers, sequences, extensions, roles, user-defined types and each table's privileges by role, optionally within one schema. An engine without catalog support, a listing refused by policy, a failed listing and an empty one each say so differently.
  • Agents can list a PostgreSQL connection's routines, triggers, sequences, extensions, roles, user-defined types and table privileges through the new list_objects MCP tool, optionally within one schema. It needs only a read token, is limited to the token's allowed connections, and is audited like other catalog reads; an engine without catalog support answers that the listing is unsupported rather than returning an empty list.
  • A saved connection can have its own connect timeout and query timeout, set when it is created. The connect timeout also applies to agent connections; 0 keeps the defaults.
  • A saved connection can be given a name; leaving the name blank keeps the address-derived label.
  • A saved connection can be duplicated; the copy starts without saved credentials.
  • A saved connection can carry a colour tag from a fixed palette, shown beside it in the connection list.
  • The connection list is split into a section per group, with ungrouped connections in their own section.
  • Saved connections can be exported to and imported from a connection bundle file. A bundle without a passphrase carries no credentials, a passphrase-protected bundle encrypts them, and an import shows every connection and what will happen to it before anything is written.

Changed

  • The built-in SSH client's unknown-host-key error no longer suggests connecting once with the system ssh command, which writes to a different known_hosts file than the one this client reads.
  • The built-in SSH client reports plainly when a server accepts only keyboard-interactive authentication, which it does not support, instead of a generic authentication failure.
  • The built-in SSH client now sends keepalives and can report a tunnel as closed once a bastion stops responding, instead of leaving a dead tunnel looking alive until a database driver's own timeout notices.
  • When a saved password can't be read because no keyring is running, the keyring is locked, or its unlock prompt was cancelled, the connection error now says which one and what to do, instead of showing the raw D-Bus error.
  • The keyboard-shortcuts dialog and date editor now use the GNOME 50 APIs.
  • Development builds isolate connections, history, audit, drafts, settings, the policy file, locks, and keyring items from installed builds.
  • Column-width and filter persistence is owned by the application and shared explicitly with its windows and tabs.
  • Query history is owned by the application and passed explicitly to editors, dialogs, preferences, and retention work.
  • Workspace cache, coalesced writer, and close-time flush are owned by the application and shared explicitly across windows. A connection whose editor draft cannot be read no longer blocks restoring every other open connection's tabs, and deleting a saved connection now removes its drafts from disk instead of leaving them behind.
  • Database connections, user preferences, and the MCP agent bridge are owned by the application and shared explicitly with its windows and dialogs.

Fixed

  • Browse shortcuts for Left, Right, and space showed keypad keys, and click shortcuts showed Shift and Ctrl alone.

  • New connection opened on the first driver with port 5432, database postgres, and username postgres.

  • Browse shortcuts for Left, Right, and space showed a blank key.

  • Click shortcuts were labeled Pointer_Button1.

  • Test and Connect sat at opposite ends of the connection header, and a long title ran into the buttons.

  • A ClickHouse connection with Verify CA or Verify Full through an SSH tunnel checked the certificate against the tunnel's local address instead of the database's own hostname, so both modes always failed. They now verify against the database's hostname.

  • A MongoDB connection with Verify CA or Verify Full through an SSH tunnel checked the certificate against the tunnel's local address instead of the database's own hostname, so both modes always failed. They now verify against the database's hostname.

  • A Redis connection with Verify CA or Verify Full through an SSH tunnel checked the certificate against the tunnel's local address instead of the database's own hostname, so both modes always failed. They now verify against the database's hostname.

  • A session whose connection was lost now refuses any further statement instead of dispatching it and letting the resulting error turn off governed writes for every connection.

  • Stopping the MCP agent server while a write was still in progress could tear down the server before that write reached a recorded outcome, leaving its audit entry open. The server now waits at least as long as a write is allowed to run before it finishes shutting down, so an interrupted write is always recorded as cancelled or unknown.

  • A session that loses its connection mid-transaction now has its transaction outcome recorded as uncertain, and the session itself stops accepting statements even if the driver still reports it usable.

  • A session COMMIT with no preceding BEGIN, and a BEGIN sent while a session transaction is already open, are now refused instead of being sent to the database unaudited.

  • A session COMMIT that only succeeded because PostgreSQL had already rolled back an aborted transaction is now audited as rolled back instead of committed.

  • A cancelled or timed-out session COMMIT or ROLLBACK is now audited with a cancelled or timed-out outcome instead of a generic failure.

  • A session COMMIT that fails because the database already ended the transaction, such as a deferred foreign key violation, no longer leaves the session's transaction marked open.

  • Cancelling a connection attempt over the system OpenSSH client now stops its ssh master process and cleans up its private directory, instead of leaving it running in the background.

  • MongoDB nested documents, arrays and uncommon top-level BSON kinds retain their BSON markers as canonical Extended JSON instead of debug text. Nested documents and arrays plus top-level BSON Timestamp, regex and MinKey cells can be edited in the grid and write back as native BSON; canonical Extended JSON imports reconstruct nested Decimal128, date and binary subtypes. Real-server JSON, CSV and XLSX exports and the MCP browse tool preserve those markers.

  • CSV imports into SQLite INTEGER, REAL and NUMERIC affinity columns pass unparseable values as text, allowing SQLite to store them without rejecting valid mixed storage classes.

  • Duplicate Row refuses rows with undecodable cells or a mismatched cell count instead of inserting a silently substituted NULL.

  • ClickHouse rejects response rows whose value count does not match the column metadata instead of padding or truncating the row.

  • A driver that reports its connection as disconnected now triggers an immediate reconnect attempt instead of waiting up to 30 seconds for the next scheduled connection check.

  • SQL Server decimals wider than the editable range keep their sign and digits. A negative value no longer shows a minus sign inside its fraction, and a whole number no longer gains a trailing ".0".

  • MySQL zero dates such as 0000-00-00 are shown as their stored text instead of an empty cell. Negative TIME values keep their sign, times outside one day and dates with zero parts are shown exactly instead of as undecodable, and YEAR values appear as numbers. All of them can be written back through edits, parameters and SQL exports.

  • DuckDB dates, times, timestamps and enum labels decode as usable values instead of debug strings. Temporal precision, timezone instants, infinities and end-of-day times survive parameter and SQL round trips; unsupported intervals, collections and calendar ranges remain visibly undecodable and cannot be written back.

  • PostgreSQL intervals retain independently signed fields under every interval style, and extreme durations use a re-importable seconds representation. Date and timestamp infinities remain distinct from NULL.

  • PostgreSQL arrays of common scalar and temporal types preserve NULL elements, empty values, nesting, lower bounds and exact numeric digits through query results and SQL exports. int2vector and oidvector values keep their space-separated form. Unsupported element types and oversized decoded arrays remain visibly undecodable.

  • PostgreSQL end-of-day times remain 24:00:00 instead of silently becoming midnight, and times with time zones retain their stored offsets and microseconds through queries and SQL exports.

  • PostgreSQL SQL exports preserve BC dates and years above 9999 using valid era and year syntax, including fractional timestamps and UTC instants.

  • PostgreSQL numeric results preserve wide integers, long fractions, decimal scale, NaN and infinities. Values beyond the editable decimal range remain exact text instead of appearing undecodable.

  • Excel exports preserve integers beyond 15 digits and all exact decimals as text cells, retaining every digit and decimal scale. These cells require explicit numeric conversion for spreadsheet arithmetic.

  • Numeric input in grid edits, filters and CSV imports rejects overflow to infinity and nonzero underflow to zero. Named decimal parameters stay exact, SQLite still compares them as numbers, and automatic parameter typing keeps values as text when they exceed the exact decimal range.

  • SQL copy and export use scientific float literals to avoid tiny values becoming zero or overflowing an engine's decimal parser; ClickHouse decimal literals retain their full precision.

  • Redis commands preserve empty quoted arguments instead of dropping them.

  • DuckDB accepts bound parameters in result queries instead of reporting the operation as unimplemented. Decimal parameters and results stay exact numbers, so arithmetic on a bound decimal is no longer rounded to a whole number. DATE and microsecond TIME/TIMESTAMP parameters bind natively. Finer-than-microsecond TIME/TIMESTAMP and all TIMESTAMPTZ parameters remain exact text and may need an explicit cast for expressions.

  • MySQL and ClickHouse decimals retain their exact digits, including values beyond the editable decimal range. Grid edits and filters reject decimals that would need rounding.

  • ClickHouse non-finite numbers remain distinct from NULL, and JSON exports and agent responses retain NaN and infinity as text instead of substituting NULL.

  • SQL Server INSERT exports preserve Unicode text and render booleans as valid numeric literals.

  • App shutdown now cancels MCP operations and waits for its owned HTTP server before flushing persistence.

  • Preferences migration persists its completion marker across fresh handles, preserves malformed legacy files, and rolls back a settings update if its rollback JSON mirror cannot be written.

  • Repeated CSV headers at the maximum identifier length retain a unique suffix instead of looping during column inference.

  • Editing a long text or JSON cell in the grid now starts from its full value instead of the shortened text shown for display, so a small edit no longer truncates the rest of the value.

  • The server activity view shows a binary value as its byte count instead of a label that read like a hexadecimal escape.

  • The structure editor shows a column default as the SQL that defines it, so an empty-string default no longer reads as no default, and a MySQL column edit no longer drops an empty-string default or fails on a text default.

  • On X11 the app's windows now group under its launcher in docks and task switchers, whichever command started it.

  • Changing a PostgreSQL column's type in the structure editor keeps the column's own collation instead of resetting it to the type default, and a MySQL column edit keeps its collation instead of taking the table default.

  • A database driver that stops unexpectedly is reported as a failed operation, with writes marked as having an unknown result, instead of leaving the request waiting forever. The connection is then replaced rather than reused.

  • Embedded application icons now use the same BookiE artwork as installed packages.

  • Malformed MongoDB SCRAM nonces are rejected instead of crashing authentication.

  • SSH key and TLS certificate reads remain bounded if a file changes while it is read.

  • SSH socket forwarding falls back to a short private path when the runtime directory would exceed Unix limits.

  • ClickHouse connection timeouts no longer misreport a certificate hostname mismatch.

  • MongoDB server-selection failures (for example, an unreachable host) no longer misreport a certificate hostname mismatch.

  • A SQL Server script now keeps running the next GO batch after one batch fails, instead of stopping the whole script.

  • PostgreSQL indexes built on an expression now appear in the structure tab with the expression as their key, a partial index shows its WHERE condition, and INCLUDE columns are no longer listed as index keys.

  • SQLite foreign keys that reference the parent table without naming its columns now show the parent's primary key columns instead of blanks.

  • SQLite foreign keys, indexes and columns read right after a structure change are no longer missing when the read lands on another pooled connection.

  • A SQL Server batch that raises an error after its first result set now reports the error instead of showing the first result as a success.

  • A SQL Server result cut at the row limit now waits for the rest of the batch to finish, instead of leaving it running on the server with its locks held until the next query.

  • MongoDB accepts DROP TABLE people as well as the quoted form, instead of reporting the statement as unsupported.

  • Renaming a column and changing nothing else now saves. On SQLite the whole save was refused, and on MySQL the column definition was restated without its collation, character set or comment.

  • MySQL and SQL Server values that the driver cannot decode now show as undecodable instead of as an empty cell. Such a cell stays read-only, and a row whose key could not be read is refused rather than updated or deleted silently.

  • A PostgreSQL result with one undecodable value (for example, a NUMERIC too wide to represent) shows that cell as undecodable, logs the column so the cause can be traced, and keeps the rest of the row and result instead of failing the whole query. An undecodable cell stays read-only, and a row whose key could not be read is refused instead of being changed or deleted silently.

  • Redis binary values with invalid UTF-8 retain their original bytes. SQL statement export preserves binary values using exact literals on PostgreSQL, MySQL, SQLite, SQL Server, ClickHouse and DuckDB; unsupported binary exports, undecodable values and non-finite numbers are refused instead of substituting NULL. Copy as IN continues to skip binary and undecodable cells.

  • CSV export and Copy as CSV write empty text as a quoted empty field and NULL as a bare empty field, so the two stay distinct. With quoting set to Always, NULL was also written as a quoted empty field.

  • SQL Server INSERT statements copied or exported from a datetime column with milliseconds now run and restore the same value. SQL Server rejected them with a conversion error.

  • ClickHouse decimals keep their declared scale, so 2.50 in a Decimal(10, 2) column no longer shows as 2.5.

  • ClickHouse timestamp parameters keep their fractional seconds. Local timestamps lost every fraction and timezone timestamps were cut to milliseconds.

  • ClickHouse SQL INSERT exports of timezone timestamps now run and keep every fractional digit. ClickHouse rejected them with a parse error.

  • ClickHouse DateTime64(9) parameters and SQL exports outside its exact nanosecond range are refused locally instead of reaching an engine range failure or conversion.

  • ClickHouse DateTime and DateTime64 results with named IANA timezones now preserve their instant. Ambiguous or nonexistent local clock values are shown as undecodable rather than guessed.

  • SQL Server datetimeoffset values keep their stored instant, original offset and all seven fractional digits in the grid, in edits and in copied or exported INSERT statements. A non-UTC value was shifted by its offset a second time, and every value was converted to UTC.

  • MySQL and MariaDB INSERT statements copied or exported from text or JSON holding a backslash or NUL character now restore the same value when the server runs with NO_BACKSLASH_ESCAPES. Each backslash was doubled, or the statement was rejected.

  • MySQL column-comment DDL refuses comments containing backslashes until it can execute with a known session SQL mode, rather than silently storing a different comment.

  • MySQL BIT columns show their numeric value, supported widths can be edited within range, and spatial columns show their stored geometry bytes as read-only values; copied or exported INSERT statements restore the same data. These columns were shown as empty or unreadable cells, or could not be edited safely.

Security

  • The agent daemon no longer trusts an SSH host key it has not seen before. An unattended connection to an unknown host fails and names the key's fingerprint; connecting once from the app or with ssh records it. A changed key is still refused everywhere.
  • A lone BEGIN, COMMIT or ROLLBACK on a shared connection is refused with an explanation, in the SQL editor and through MCP. Each statement ran on a shared connection, so a script such as BEGIN; UPDATE …; ROLLBACK; committed the update while reporting every step as successful. A whole transaction sent as one batch, such as a SQL Server GO batch, still runs.
  • A saved connection's SSH jump chain is capped at eight hops, so an edited connection file cannot force a deep recursive parse.