diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..04f178c7 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(swift --version:*)", + "Bash(~/.swiftly/bin/swiftly list:*)", + "Bash(~/.swiftly/bin/swiftly use:*)" + ] + } +} diff --git a/Package.resolved b/Package.resolved index 419fc30f..41a5cdb7 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,22 +1,13 @@ { - "originHash" : "41f93013537f670f4fe1a235c318bee33b54528c76e4b1dd2a7675bea6c0bcde", + "originHash" : "a18b1644857cf7bbf788548464ff5983bac7f7a8faa125c59045f5d830aa5f28", "pins" : [ { "identity" : "combine-schedulers", "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/combine-schedulers", "state" : { - "revision" : "5928286acce13def418ec36d05a001a9641086f2", - "version" : "1.0.3" - } - }, - { - "identity" : "grdb.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/groue/GRDB.swift", - "state" : { - "revision" : "18497b68fdbb3a09528d260a0a0e1e7e61c8c53d", - "version" : "7.8.0" + "revision" : "fd16d76fd8b9a976d88bfb6cacc05ca8d19c91b6", + "version" : "1.1.0" } }, { @@ -118,15 +109,6 @@ "version" : "1.18.7" } }, - { - "identity" : "swift-structured-queries", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-structured-queries", - "state" : { - "revision" : "3a95b70a81b7027b8a5117e7dd08188837e5f54e", - "version" : "0.24.0" - } - }, { "identity" : "swift-syntax", "kind" : "remoteSourceControl", @@ -141,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", "state" : { - "revision" : "4c27acf5394b645b70d8ba19dc249c0472d5f618", - "version" : "1.7.0" + "revision" : "31073495cae9caf243c440eac94b3ab067e3d7bc", + "version" : "1.8.0" } } ], diff --git a/Package.swift b/Package.swift index e526eff8..fa9fcc85 100644 --- a/Package.swift +++ b/Package.swift @@ -1,107 +1,108 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.2.1 import PackageDescription let package = Package( - name: "sqlite-data", - platforms: [ - .macOS(.v15), - ], - products: [ - .library( - name: "SQLiteData", - targets: ["SQLiteData"] - ), - .library( - name: "SQLiteDataTestSupport", - targets: ["SQLiteDataTestSupport"] - ), - ], - traits: [ - .trait( - name: "SQLiteDataTagged", - description: "Introduce SQLiteData conformances to the swift-tagged package." - ) - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-collections", from: "1.0.0"), - .package(url: "https://github.com/groue/GRDB.swift", from: "7.6.0"), - .package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.0.0"), - .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.3"), - .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.9.0"), - .package(url: "https://github.com/pointfreeco/swift-sharing", from: "2.3.0"), - .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), - .package( - url: "https://github.com/pointfreeco/swift-structured-queries", - from: "0.24.0", - traits: [ - .trait(name: "StructuredQueriesTagged", condition: .when(traits: ["SQLiteDataTagged"])) - ] - ), - .package(url: "https://github.com/pointfreeco/swift-tagged", from: "0.10.0"), - .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.5.0"), - ], - targets: [ - .target( - name: "SQLiteData", - dependencies: [ - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "Dependencies", package: "swift-dependencies"), - .product(name: "GRDB", package: "GRDB.swift"), - .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), - .product(name: "OrderedCollections", package: "swift-collections"), - .product(name: "Sharing", package: "swift-sharing"), - .product(name: "StructuredQueriesSQLite", package: "swift-structured-queries"), - .product( - name: "Tagged", - package: "swift-tagged", - condition: .when(traits: ["SQLiteDataTagged"]) + name: "sqlite-data", + platforms: [ + .macOS(.v15) + ], + products: [ + .library( + name: "SQLiteData", + targets: ["SQLiteData"] + ), + .library( + name: "SQLiteDataTestSupport", + targets: ["SQLiteDataTestSupport"] + ), + ], + traits: [ + .trait( + name: "SQLiteDataTagged", + description: "Introduce SQLiteData conformances to the swift-tagged package." + ) + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-collections", from: "1.0.0"), + .package(name: "GRDB.swift", path: "../GRDB-swift"), + .package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.0.0"), + .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.3"), + .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.9.0"), + .package(url: "https://github.com/pointfreeco/swift-sharing", from: "2.3.0"), + .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), + .package( + path: "../swift-structured-queries", + traits: [ + .trait( + name: "StructuredQueriesTagged", + condition: .when(traits: ["SQLiteDataTagged"])) + ] + ), + .package(url: "https://github.com/pointfreeco/swift-tagged", from: "0.10.0"), + .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.5.0"), + ], + targets: [ + .target( + name: "SQLiteData", + dependencies: [ + .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), + .product(name: "Dependencies", package: "swift-dependencies"), + .product(name: "GRDB", package: "GRDB.swift"), + .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), + .product(name: "OrderedCollections", package: "swift-collections"), + .product(name: "Sharing", package: "swift-sharing"), + .product(name: "StructuredQueriesSQLite", package: "swift-structured-queries"), + .product( + name: "Tagged", + package: "swift-tagged", + condition: .when(traits: ["SQLiteDataTagged"]) + ), + ] ), - ] - ), - .target( - name: "SQLiteDataTestSupport", - dependencies: [ - "SQLiteData", - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "CustomDump", package: "swift-custom-dump"), - .product(name: "Dependencies", package: "swift-dependencies"), - .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), - .product(name: "StructuredQueriesTestSupport", package: "swift-structured-queries"), - ] - ), - .testTarget( - name: "SQLiteDataTests", - dependencies: [ - "SQLiteData", - "SQLiteDataTestSupport", - .product(name: "DependenciesTestSupport", package: "swift-dependencies"), - .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), - .product(name: "SnapshotTestingCustomDump", package: "swift-snapshot-testing"), - .product(name: "StructuredQueries", package: "swift-structured-queries"), - ] - ), - ], - swiftLanguageModes: [.v6] + .target( + name: "SQLiteDataTestSupport", + dependencies: [ + "SQLiteData", + .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), + .product(name: "CustomDump", package: "swift-custom-dump"), + .product(name: "Dependencies", package: "swift-dependencies"), + .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), + .product(name: "StructuredQueriesTestSupport", package: "swift-structured-queries"), + ] + ), + .testTarget( + name: "SQLiteDataTests", + dependencies: [ + "SQLiteData", + "SQLiteDataTestSupport", + .product(name: "DependenciesTestSupport", package: "swift-dependencies"), + .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), + .product(name: "SnapshotTestingCustomDump", package: "swift-snapshot-testing"), + .product(name: "StructuredQueries", package: "swift-structured-queries"), + ] + ), + ], + swiftLanguageModes: [.v6] ) let swiftSettings: [SwiftSetting] = [ - .enableUpcomingFeature("MemberImportVisibility") - // .unsafeFlags([ - // "-Xfrontend", - // "-warn-long-function-bodies=50", - // "-Xfrontend", - // "-warn-long-expression-type-checking=50", - // ]) + .enableUpcomingFeature("MemberImportVisibility") + // .unsafeFlags([ + // "-Xfrontend", + // "-warn-long-function-bodies=50", + // "-Xfrontend", + // "-warn-long-expression-type-checking=50", + // ]) ] for index in package.targets.indices { - package.targets[index].swiftSettings = swiftSettings + package.targets[index].swiftSettings = swiftSettings } #if !os(Windows) - // Add the documentation compiler plugin if possible - package.dependencies.append( - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") - ) + // Add the documentation compiler plugin if possible + package.dependencies.append( + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") + ) #endif diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift deleted file mode 100644 index 76704aab..00000000 --- a/Package@swift-6.0.swift +++ /dev/null @@ -1,89 +0,0 @@ -// swift-tools-version: 6.0 - -import PackageDescription - -let package = Package( - name: "sqlite-data", - platforms: [ - .macOS(.v15), - ], - products: [ - .library( - name: "SQLiteData", - targets: ["SQLiteData"] - ), - .library( - name: "SQLiteDataTestSupport", - targets: ["SQLiteDataTestSupport"] - ), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-collections", from: "1.0.0"), - .package(url: "https://github.com/groue/GRDB.swift", from: "7.6.0"), - .package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.0.0"), - .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.3"), - .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.9.0"), - .package(url: "https://github.com/pointfreeco/swift-sharing", from: "2.3.0"), - .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), - .package(url: "https://github.com/pointfreeco/swift-structured-queries", from: "0.24.0"), - .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.5.0"), - ], - targets: [ - .target( - name: "SQLiteData", - dependencies: [ - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "Dependencies", package: "swift-dependencies"), - .product(name: "GRDB", package: "GRDB.swift"), - .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), - .product(name: "OrderedCollections", package: "swift-collections"), - .product(name: "Sharing", package: "swift-sharing"), - .product(name: "StructuredQueriesSQLite", package: "swift-structured-queries"), - ] - ), - .target( - name: "SQLiteDataTestSupport", - dependencies: [ - "SQLiteData", - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "CustomDump", package: "swift-custom-dump"), - .product(name: "Dependencies", package: "swift-dependencies"), - .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), - .product(name: "StructuredQueriesTestSupport", package: "swift-structured-queries"), - ] - ), - .testTarget( - name: "SQLiteDataTests", - dependencies: [ - "SQLiteData", - "SQLiteDataTestSupport", - .product(name: "DependenciesTestSupport", package: "swift-dependencies"), - .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), - .product(name: "SnapshotTestingCustomDump", package: "swift-snapshot-testing"), - .product(name: "StructuredQueries", package: "swift-structured-queries"), - ] - ), - ], - swiftLanguageModes: [.v6] -) - -let swiftSettings: [SwiftSetting] = [ - .enableUpcomingFeature("MemberImportVisibility") - // .unsafeFlags([ - // "-Xfrontend", - // "-warn-long-function-bodies=50", - // "-Xfrontend", - // "-warn-long-expression-type-checking=50", - // ]) -] - -for index in package.targets.indices { - package.targets[index].swiftSettings = swiftSettings -} - -#if !os(Windows) - // Add the documentation compiler plugin if possible - package.dependencies.append( - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") - ) -#endif diff --git a/Sources/SQLiteData/CloudKit/CloudKit+StructuredQueries.swift b/Sources/SQLiteData/CloudKit/CloudKit+StructuredQueries.swift index 6e9eacd9..5c53bb93 100644 --- a/Sources/SQLiteData/CloudKit/CloudKit+StructuredQueries.swift +++ b/Sources/SQLiteData/CloudKit/CloudKit+StructuredQueries.swift @@ -284,7 +284,7 @@ self.userModificationTime = other.userModificationTime for column in T.TableColumns.writableColumns { - func open(_ column: some WritableTableColumnExpression) { + func open(_ column: some WritableTableColumnExpression) { let key = column.name let keyPath = column.keyPath as! KeyPath let didSet: Bool diff --git a/Sources/SQLiteData/CloudKit/PrimaryKeyMigration.swift b/Sources/SQLiteData/CloudKit/PrimaryKeyMigration.swift index 9a97fb0b..8616c8bc 100644 --- a/Sources/SQLiteData/CloudKit/PrimaryKeyMigration.swift +++ b/Sources/SQLiteData/CloudKit/PrimaryKeyMigration.swift @@ -181,25 +181,18 @@ newColumns.append(columns.primaryKey.name) } newColumns.append(contentsOf: tableInfo.map(\.name)) - convertedColumns.append( - contentsOf: tableInfo.map { tableInfo -> QueryFragment in - if tableInfo.name == primaryKey.name, tableInfo.isInt { - return $backfillUUID(id: #sql("\(quote: tableInfo.name)"), table: tableName, salt: salt) - .queryFragment - } else if tableInfo.isInt, - let foreignKey = foreignKeys.first(where: { $0.from == tableInfo.name }) - { - return $backfillUUID( - id: #sql("\(quote: foreignKey.from)"), - table: foreignKey.table, - salt: salt - ) - .queryFragment - } else { - return QueryFragment(quote: tableInfo.name) - } - } - ) + // NB: Swift 6.3-dev crashes on complex closures with #sql macro interpolation. + // Extracted to helper function to work around compiler bug. + for info in tableInfo { + let fragment = convertTableInfoToQueryFragment( + info, + primaryKeyName: primaryKey.name, + foreignKeys: foreignKeys, + tableName: tableName, + salt: salt + ) + convertedColumns.append(fragment) + } try #sql(QueryFragment(stringLiteral: newSchema)).execute(db) try #sql( @@ -225,6 +218,32 @@ ) .execute(db) } + + // NB: Extracted from closure to work around Swift 6.3-dev compiler crash. + // The compiler crashes on complex closures mixing #sql macro interpolation with nested closures. + private static func convertTableInfoToQueryFragment( + _ tableInfo: PragmaTableInfo, + primaryKeyName: String, + foreignKeys: [PragmaForeignKeyList], + tableName: String, + salt: String + ) -> QueryFragment { + if tableInfo.name == primaryKeyName, tableInfo.isInt { + return $backfillUUID(id: #sql("\(quote: tableInfo.name)"), table: tableName, salt: salt) + .queryFragment + } else if tableInfo.isInt, + let foreignKey = foreignKeys.first(where: { $0.from == tableInfo.name }) + { + return $backfillUUID( + id: #sql("\(quote: foreignKey.from)"), + table: foreignKey.table, + salt: salt + ) + .queryFragment + } else { + return QueryFragment(quote: tableInfo.name) + } + } } extension StringProtocol {