diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..3f7257b
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,92 @@
+name: CI
+
+on:
+ push:
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ linux:
+ name: Linux (Swift ${{ matrix.swift }}, ${{ matrix.configuration }})
+ runs-on: ubuntu-24.04
+ container: swift:${{ matrix.swift }}-noble
+ timeout-minutes: 30
+ strategy:
+ fail-fast: false
+ matrix:
+ # The oldest supported Swift (swift-tools-version 6.2) and the newest.
+ swift: ["6.2", "6.4"]
+ configuration: [debug, release]
+ steps:
+ - uses: actions/checkout@v7
+
+ - name: Install SQLite
+ run: |
+ apt-get update
+ apt-get install -y --no-install-recommends pkg-config libsqlite3-dev
+
+ - name: Toolchain
+ run: swift --version
+
+ - name: Build (warnings are errors)
+ run: |
+ flags="-c ${{ matrix.configuration }} -Xswiftc -warnings-as-errors"
+ # @testable imports need testing enabled in an optimized build.
+ [ "${{ matrix.configuration }}" = release ] && flags="$flags -Xswiftc -enable-testing"
+ echo "FLAGS=$flags" >> "$GITHUB_ENV"
+ swift build --build-tests $flags
+
+ - name: Test
+ run: swift test $FLAGS
+
+ macos:
+ name: macOS (Xcode ${{ matrix.xcode }}, ${{ matrix.configuration }})
+ runs-on: macos-26
+ timeout-minutes: 30
+ strategy:
+ fail-fast: false
+ matrix:
+ # The oldest Xcode with Swift 6.2, and the runner's default.
+ xcode: ["26.0.1", "26.6"]
+ configuration: [debug, release]
+ steps:
+ - uses: actions/checkout@v7
+
+ - name: Select Xcode
+ run: |
+ sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
+ swift --version
+
+ - name: Build (warnings are errors)
+ run: |
+ flags="-c ${{ matrix.configuration }} -Xswiftc -warnings-as-errors"
+ # @testable imports need testing enabled in an optimized build.
+ [ "${{ matrix.configuration }}" = release ] && flags="$flags -Xswiftc -enable-testing"
+ echo "FLAGS=$flags" >> "$GITHUB_ENV"
+ swift build --build-tests $flags
+
+ - name: Test
+ run: swift test $FLAGS
+
+ ios:
+ name: iOS Simulator
+ runs-on: macos-26
+ timeout-minutes: 30
+ steps:
+ - uses: actions/checkout@v7
+
+ - name: Select Xcode
+ run: |
+ sudo xcode-select -s /Applications/Xcode_26.6.app
+ xcodebuild -version
+
+ # The test target builds at the package's iOS 15 deployment target, so this also
+ # catches APIs that need a newer iOS. No SWIFT_TREAT_WARNINGS_AS_ERRORS: Xcode builds the
+ # Perfect-CRUD dependency with warnings suppressed, and the two flags conflict. The macOS
+ # and Linux jobs check warnings.
+ - name: Test
+ run: |
+ xcodebuild test -scheme PerfectSQLite \
+ -destination 'platform=iOS Simulator,name=iPhone 17,OS=latest'
diff --git a/Package.swift b/Package.swift
index 93b1298..f52f24e 100644
--- a/Package.swift
+++ b/Package.swift
@@ -3,7 +3,7 @@ import PackageDescription
let package = Package(
name: "PerfectSQLite",
- platforms: [.macOS(.v12)],
+ platforms: [.macOS(.v12), .iOS(.v15)],
products: [
.library(name: "PerfectSQLite", targets: ["PerfectSQLite"]),
],
diff --git a/README.md b/README.md
index 11ce8aa..c32d5be 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
+
@@ -14,7 +14,7 @@
This project provides a Swift wrapper around the SQLite 3 C library, plus a [Perfect-CRUD](https://github.com/PerfectlySoft/Perfect-CRUD) database driver built on top of it.
-**Modernized for Swift 6.** Requires **swift-tools-version 6.2** and builds under full **Swift 6 language mode** (strict concurrency checking on for both the library and test targets). Supports **macOS 12+** (`platforms: [.macOS(.v12)]`) and **Linux** (tested with Swift 6.2.4, 6.3.2 and 6.4 on Ubuntu 24.04). iOS/tvOS/watchOS aren't declared or tested.
+**Modernized for Swift 6.** Requires **swift-tools-version 6.2** and builds under full **Swift 6 language mode** (strict concurrency checking on for both the library and test targets). Supports **macOS 12+** and **iOS 15+** (`platforms: [.macOS(.v12), .iOS(.v15)]`) and **Linux** (tested with Swift 6.2.4, 6.3.2 and 6.4 on Ubuntu 24.04). CI runs the tests on Linux (Swift 6.2 and 6.4), macOS (Xcode 26.0.1 and 26.6) and the iOS Simulator. tvOS/watchOS/visionOS aren't declared or tested.
The pre-Swift-6 version of this package is preserved on the [`legacy`](../../tree/legacy) branch.
@@ -57,7 +57,7 @@ dependencies: [
and add `"PerfectSQLite"` to your target's `dependencies` array. You need the Swift 6.2 toolchain (or newer).
-- **macOS:** SQLite ships with the macOS 12+ SDK; nothing else to install. If the build fails on `PerfectCSQLite` (`no such module 'PerfectCSQLite'` or `unable to resolve module dependency: 'PerfectCSQLite'`), the SDK's `SQLite3` module wasn't found: check the selected toolchain and SDK (`xcode-select -p`, `xcrun --show-sdk-path`).
+- **macOS / iOS:** SQLite ships with the macOS 12+ and iOS 15+ SDKs; nothing else to install. If the build fails on `PerfectCSQLite` (`no such module 'PerfectCSQLite'` or `unable to resolve module dependency: 'PerfectCSQLite'`), the SDK's `SQLite3` module wasn't found: check the selected toolchain and SDK (`xcode-select -p`, `xcrun --show-sdk-path`).
- **Linux:** install the SQLite development package (`sqlite-devel` on Fedora/RHEL), e.g. on Debian/Ubuntu:
```bash
diff --git a/Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift b/Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift
index 505888e..66edfa2 100644
--- a/Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift
+++ b/Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift
@@ -52,14 +52,14 @@ func getDB(reset: Bool = true) throws -> Database {
func getTestDB() throws -> Database {
let db = try getDB()
try db.create(TestTable1.self, policy: .dropTable)
- try db.transaction {
+ _ = try db.transaction {
try db.table(TestTable1.self).insert((1...5).map { num -> TestTable1 in
let n = UInt8(num)
let blob: [UInt8]? = (num % 2 != 0) ? nil : [UInt8](arrayLiteral: n+1, n+2, n+3, n+4, n+5)
return TestTable1(id: num, name: "This is name bind \(num)", integer: num, double: Double(num), blob: blob)
})
}
- try db.transaction {
+ _ = try db.transaction {
try db.table(TestTable2.self).insert((1...5).flatMap { parentId -> [TestTable2] in
(1...5).map { num -> TestTable2 in
let n = UInt8(num)
@@ -326,7 +326,7 @@ func getDB(reset: Bool = true) throws -> Database {
@Test func selfJoin() throws {
struct Me: Codable { let id: Int; let parentId: Int; let mes: [Me]?; init(id i: Int, parentId p: Int) { id = i; parentId = p; mes = nil } }
let db = try getTestDB()
- try db.transaction {
+ _ = try db.transaction {
try db.create(Me.self, policy: .dropTable)
.insert([Me(id: 1, parentId: 0), Me(id: 2, parentId: 1),
Me(id: 3, parentId: 1), Me(id: 4, parentId: 1), Me(id: 5, parentId: 1)])
diff --git a/Tests/PerfectSQLiteTests/ReconcileTableTests.swift b/Tests/PerfectSQLiteTests/ReconcileTableTests.swift
index 6b2647b..d33cda1 100644
--- a/Tests/PerfectSQLiteTests/ReconcileTableTests.swift
+++ b/Tests/PerfectSQLiteTests/ReconcileTableTests.swift
@@ -181,7 +181,7 @@ extension PerfectSQLiteTests {
#expect(try columnNames(db, of: TestTable1.tableName).contains("int"))
#expect(try db.table(TestTable2.self).count() == 25)
// A table nothing references can still be rebuilt in one.
- try db.transaction {
+ _ = try db.transaction {
try db.create(ReducedTestTable2.self, policy: [.reconcileTable, .shallow])
}
let childTable = TestTable2.CRUDTableName
@@ -206,7 +206,7 @@ extension PerfectSQLiteTests {
foreignKeysOn = stmt.columnInt(position: 0)
}
#expect(foreignKeysOn == 1)
- try db.transaction {
+ _ = try db.transaction {
try db.table(TestTable1.self).where(\TestTable1.id == 3).delete()
}
#expect(try db.table(TestTable2.self).count() == 20)