Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- SAP HANA database driver plugin. (#1966)
- Folders for tables and views in the sidebar. (#3167)
- iCloud sync for table folders between Macs.
- Shift JIS, EUC-JP, GB 18030, Big5, EUC-KR and UTF-16 options for CSV and SQL import.

### Changed
Expand Down
40 changes: 40 additions & 0 deletions CloudKit/production-schema.ckdb
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,46 @@ DEFINE SCHEMA
GRANT READ TO "_world"
);

RECORD TYPE TableFolder (
"___createTime" TIMESTAMP,
"___createdBy" REFERENCE,
"___etag" STRING,
"___modTime" TIMESTAMP,
"___modifiedBy" REFERENCE,
"___recordID" REFERENCE,
connectionId STRING QUERYABLE SEARCHABLE SORTABLE,
createdAt TIMESTAMP QUERYABLE SORTABLE,
database STRING QUERYABLE SEARCHABLE SORTABLE,
folderId STRING QUERYABLE SEARCHABLE SORTABLE,
modifiedAtLocal TIMESTAMP QUERYABLE SORTABLE,
name STRING QUERYABLE SEARCHABLE SORTABLE,
schema STRING QUERYABLE SEARCHABLE SORTABLE,
schemaVersion INT64 QUERYABLE SORTABLE,
updatedAt TIMESTAMP QUERYABLE SORTABLE,
GRANT WRITE TO "_creator",
GRANT CREATE TO "_icloud",
GRANT READ TO "_world"
);

RECORD TYPE TableFolderItem (
"___createTime" TIMESTAMP,
"___createdBy" REFERENCE,
"___etag" STRING,
"___modTime" TIMESTAMP,
"___modifiedBy" REFERENCE,
"___recordID" REFERENCE,
connectionId STRING QUERYABLE SEARCHABLE SORTABLE,
database STRING QUERYABLE SEARCHABLE SORTABLE,
folderId STRING QUERYABLE SEARCHABLE SORTABLE,
modifiedAtLocal TIMESTAMP QUERYABLE SORTABLE,
name STRING QUERYABLE SEARCHABLE SORTABLE,
schema STRING QUERYABLE SEARCHABLE SORTABLE,
schemaVersion INT64 QUERYABLE SORTABLE,
GRANT WRITE TO "_creator",
GRANT CREATE TO "_icloud",
GRANT READ TO "_world"
);

RECORD TYPE Users (
"___createTime" TIMESTAMP,
"___createdBy" REFERENCE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,6 @@ public enum SQLFavoriteFolderSyncField: String, SyncSchemaField {
]
}

/// Empty until `TableFolder` is deployed to Production, for the reason `FavoriteDatabaseSyncField`
/// once gave: the gated subscript drops every write, so the type stays inert rather than rejected.
/// Flip this set and `SyncRecordType.verifiedInProduction` in the commit that carries the refreshed
/// `production-schema.ckdb`.
public enum TableFolderSyncField: String, SyncSchemaField {
case folderId
case connectionId
Expand All @@ -118,7 +114,10 @@ public enum TableFolderSyncField: String, SyncSchemaField {
case modifiedAtLocal
case schemaVersion

public static let verifiedInProduction: Set<Self> = []
public static let verifiedInProduction: Set<Self> = [
.folderId, .connectionId, .database, .schema, .name,
.createdAt, .updatedAt, .modifiedAtLocal, .schemaVersion
]
}

/// One object filed in a folder. The record is named after the object, not the folder, so moving a
Expand All @@ -132,7 +131,9 @@ public enum TableFolderItemSyncField: String, SyncSchemaField {
case modifiedAtLocal
case schemaVersion

public static let verifiedInProduction: Set<Self> = []
public static let verifiedInProduction: Set<Self> = [
.connectionId, .database, .schema, .name, .folderId, .modifiedAtLocal, .schemaVersion
]
}

/// Everything except the password, which stays in the Keychain, and except the payload of a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public extension SyncRecordType {
static let verifiedInProduction: Set<SyncRecordType> = [
.connection, .group, .tag, .settings,
.favorite, .favoriteFolder, .tableFavorite, .sshProfile, .credentialProfile,
.favoriteDatabase
.favoriteDatabase, .tableFolder, .tableFolderItem
]

var productionSchemaState: ProductionSchemaState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct SyncSchemaGateTests {
/// refreshed `production-schema.ckdb`. Anything gated and unlisted is a type that will never
/// sync, which is what this test exists to catch; anything listed and no longer gated means the
/// deploy landed and the entry is stale. Comparing sets catches both.
private static let pendingProductionDeploy: Set<SyncRecordType> = [.tableFolder, .tableFolderItem]
private static let pendingProductionDeploy: Set<SyncRecordType> = []

@Test("Every record type the app declares is deployed, or is explicitly awaiting deployment")
func allRecordTypesAreWritable() {
Expand Down
2 changes: 1 addition & 1 deletion docs/features/icloud-sync.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Each synced category has its own toggle under **Sync Categories**.
| **SSH Profiles** | Yes | Named [SSH profiles](/connections/ssh-profiles) |
| **Credential Profiles** | Not yet | Named [credential profiles](/connections/credential-profiles) stay on the Mac that created them until their CloudKit schema ships |
| **Table Favorites** | Yes | The names shown in the Favorites tab and pinned in table lists |
| **Table Folders** | Not yet | The sidebar's [folders](/features/connection-window#folders) stay on the Mac that created them until their CloudKit schema ships |
| **Table Folders** | Yes | Between Macs only. The sidebar's [folders](/features/connection-window#folders) and the tables and views filed in them |
| **Database Favorites** | Yes | Favorited databases and their Development / Testing / Production tags |
| **Saved Queries** | Yes | Saved SQL and their folders |
| **Settings** | Yes | Between Macs only. General, Appearance, Editor, Data Grid, History, Tabs, Keyboard, and AI settings, plus custom AI slash commands and saved per-table column widths and order |
Expand Down
Loading