Skip to content
Merged
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
92 changes: 92 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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'
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"]),
],
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<img src="https://img.shields.io/badge/Swift-6.2-orange.svg?style=flat" alt="Swift 6.2">
</a>
<a href="#building">
<img src="https://img.shields.io/badge/Platforms-macOS%2012%2B%20%7C%20Linux-lightgray.svg?style=flat" alt="Platforms macOS 12+ | Linux">
<img src="https://img.shields.io/badge/Platforms-macOS%2012%2B%20%7C%20iOS%2015%2B%20%7C%20Linux-lightgray.svg?style=flat" alt="Platforms macOS 12+ | iOS 15+ | Linux">
</a>
<a href="./LICENSE" target="_blank">
<img src="https://img.shields.io/badge/License-Apache-lightgrey.svg?style=flat" alt="License Apache">
Expand All @@ -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.

Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ func getDB(reset: Bool = true) throws -> Database<DBConfiguration> {
func getTestDB() throws -> Database<DBConfiguration> {
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)
Expand Down Expand Up @@ -326,7 +326,7 @@ func getDB(reset: Bool = true) throws -> Database<DBConfiguration> {
@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)])
Expand Down
4 changes: 2 additions & 2 deletions Tests/PerfectSQLiteTests/ReconcileTableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
Loading