Skip to content

fix(ios): make the Shortcuts insert actions findable and write where you told them to - #2218

Merged
datlechin merged 2 commits into
mainfrom
fix/ios-shortcuts-insert-actions
Aug 19, 2026
Merged

fix(ios): make the Shortcuts insert actions findable and write where you told them to#2218
datlechin merged 2 commits into
mainfrom
fix/ios-shortcuts-insert-actions

Conversation

@datlechin

Copy link
Copy Markdown
Member

A user reported that searching "tablepro" in the iOS Shortcuts app shows only Open Connection, while the changelog and the docs promise three actions.

The App Intents code was never broken

Measured two ways against the current tree:

  • The real TableProMobile.app built from main already ships all three actions in Metadata.appintents/extract.actionsdata (AddRowToTableIntent, AddRowsToTableIntent, OpenConnectionIntent), every one isDiscoverable, plus all three App Shortcuts in autoShortcuts.
  • A standalone swiftc + appintentsmetadataprocessor probe reproducing the exact shape of the real code (the RowInsertingIntent intermediate protocol, .requiresAuthentication, openAppWhenRun = false, parameterSummary, an optional entity parameter, IntentFile, @IntentParameterDependency, a three-entry AppShortcutsProvider) extracts all three too.

So the intermediate protocol is innocent and RowInsertingIntent is left alone.

Two things did go wrong.

The feature has never been in a shipped iOS build. TableProShortcuts held exactly one shortcut, Open Connection, until c403e1f on 2026-07-02, which is exactly what the reporter sees. CURRENT_PROJECT_VERSION has been 16 since 2026-06-01 and there is no iOS release workflow, so the insert actions have never left the repo. Meanwhile the 0.55.0 changelog entry sits under a macOS version heading and the docs page documented all three actions with no availability information.

Even once shipped, an app-name search would not have reached them. Neither insert action carried categoryName or searchKeywords, and neither title contains a brand token.

What this changes

  • Bumps the iOS build to 17 and documents that the two insert actions need build 17 or later, that the iOS app updates separately from the Mac app, and that Apps > TablePro is the complete action list. Adds Oracle to the supported-types list, which has been supported since feat(ios): Oracle support in TablePro Mobile #2034 but was never documented.
  • Adds categoryName: "Database" and searchKeywords to all three intents. Verified in the built app: every action now carries the "TablePro" keyword in descriptionMetadata.

Two data bugs found in the same insert path

Both were measured, and both are worse than the reported issue.

String values were escaped with MySQL rules on every engine. SQLBuilder.escapeString doubled backslashes and rewrote newlines regardless of database type, and it backed INSERT, UPDATE and WHERE, so this hit the ordinary iOS app UI too, not just Shortcuts. Measured on sqlite3 and duckdb: C:\Users\dat (13 chars) stored as C:\\Users\\dat (14), a real newline stored as the two characters \n, and a WHERE on a stored C:\Users\dat matched 0 rows instead of 1, so editing or deleting such a row silently changed nothing.

Per the chosen approach, escapeStringLiteral is now a DatabaseDriver requirement with an ANSI default (SQLEscaping.ansiStringLiteral) and a MySQL/MariaDB override (SQLEscaping.backslashStringLiteral), mirroring how the macOS app already does it. The driver is threaded through buildInsert, buildUpdate and buildDelete and their call sites, including loadFullValue, which was hand-rolling quote doubling and would have produced an unterminated literal on MySQL for a key ending in a backslash.

The Shortcuts insert ignored the schema the user picked. resolveSchema returned it and it reached fetchColumns, but the generated statement used a bare table name. Calling driver.switchSchema(to:) would not have been enough: MSSQLDriver.switchSchema only assigns a local property and execute(query:) never reads it, so SQL Server would still have written to dbo. The statement is schema-qualified instead. Measured on a live PostgreSQL inside a rolled-back transaction: an unqualified insert landed in public.events_probe while the picked s_reporting.events_probe stayed empty, even though the columns had been validated against s_reporting.

Qualification is driven by what the user actually picked, not by driver.currentSchema. PostgreSQLDriver hardcodes currentSchema to public at init and never reads the server's search_path, so qualifying from it would have pinned every unpicked insert to public and broken connections whose search path points elsewhere. Leaving the picker empty still emits an unqualified statement, exactly as before. The in-app Insert Row screen is likewise left unqualified, so it stays consistent with the SELECT, UPDATE and DELETE on the same screen.

Security

Dropping backslash escaping on PostgreSQL is only safe while standard_conforming_strings is on. It has defaulted to on since PostgreSQL 9.1, but a session with it off would treat a trailing backslash in a value as an escape and let a crafted value break out of the literal, and a Shortcut that feeds fetched web data into Add Rows to Table is a real path for untrusted input. PostgreSQLDriver.connect() now sets it explicitly.

The statement is best-effort on purpose. Redshift runs through the same driver and does not have the parameter at all, so a hard failure would have made every Redshift connection unopenable. The servers that reject it are exactly the ones where the ANSI assumption already holds: Redshift follows the SQL standard for string literals, and PostgreSQL 8.1 and older are far outside what TablePro supports.

Verification

  • xcodebuild build of the TableProMobile scheme: passed.
  • RowInsertPlannerTests, RowInserterTests, RowDetailViewModelTests, DataBrowserViewModelTests, RowPayloadTests: 48 tests, ** TEST SUCCEEDED **. Seven are new: schema qualification on PostgreSQL and SQL Server, an unpicked schema staying unqualified, a backslash and a newline surviving on an ANSI dialect, and backslashes still being escaped on MySQL.
  • swiftlint --strict on every changed path: clean. TableProMobile/ is outside .swiftlint.yml's included:, so this also cleared a pre-existing set_ / where_ identifier violation in the function being edited.
  • Re-dumped Metadata.appintents/extract.actionsdata from the built app to confirm the keywords landed.

No screenshots: the visible change is in Apple's Shortcuts app on a device, which needs a shipped TestFlight build to show.

Not included

Archiving and submitting the TestFlight build. The build number is bumped, but cutting the release is yours.

@mintlify

mintlify Bot commented Aug 19, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Aug 19, 2026, 3:50 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
@datlechin
datlechin merged commit dadc48d into main Aug 19, 2026
7 checks passed
@datlechin
datlechin deleted the fix/ios-shortcuts-insert-actions branch August 19, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant