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
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.build/
.git/
.swiftpm/
4 changes: 2 additions & 2 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ on:
jobs:

create-docc-and-deploy:
uses: BinaryBirds/github-workflows/.github/workflows/docc_deploy.yml@main
uses: BinaryBirds/github-workflows/.github/workflows/docc_deploy.yml@0.2.0
permissions:
contents: read
pages: write
id-token: write
id-token: write
39 changes: 12 additions & 27 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ on:

jobs:

api_breakage:
name: Check API breakage
uses: BinaryBirds/github-workflows/.github/workflows/api_breakage.yml@main

swiftlang_checks:
name: Swiftlang Checks
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@0.0.7
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@0.0.16
with:
license_header_check_project_name: "project"
format_check_enabled : true
Expand All @@ -26,28 +22,17 @@ jobs:
yamllint_check_enabled : false
python_lint_check_enabled : false

bb_checks:
name: BB Checks
if: ${{ github.actor != 'nektos/act' }}
uses: BinaryBirds/github-workflows/.github/workflows/extra_soundness.yml@main
with:
local_swift_dependencies_check_enabled : true
headers_check_enabled : false
docc_warnings_check_enabled : true

swiftlang_tests:
name: Swiftlang Tests
if: ${{ github.actor != 'nektos/act' }}
docker_tests:
name: Docker Tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
traits:
- name: AllTraits
command: "swift test --parallel --enable-code-coverage --enable-all-traits"
- name: NoDefaultTraits
command: "swift test --parallel --enable-code-coverage --disable-default-traits"
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
with:
enable_windows_checks : false
linux_build_command: ${{ matrix.traits.command }}
linux_exclude_swift_versions: "[{\"swift_version\": \"5.8\"}, {\"swift_version\": \"5.9\"}, {\"swift_version\": \"5.10\"}, {\"swift_version\": \"nightly\"}, {\"swift_version\": \"nightly-main\"}, {\"swift_version\": \"6.0\"}, {\"swift_version\": \"nightly-6.0\"}, {\"swift_version\": \"nightly-6.1\"}, {\"swift_version\": \"nightly-6.3\"}]"
swift-version: ["6.3", "6.4"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Docker Tests
run: make docker-test
env:
SWIFT_VERSION: ${{ matrix.swift-version }}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ test:
swift test --parallel

docker-test:
docker build -t feather-database-sqlite-tests . -f ./docker/tests/Dockerfile && docker run --rm feather-database-sqlite-tests
docker compose run --build --rm test bash -lc 'swift test --build-path /tmp/swift-build --parallel --enable-code-coverage --enable-all-traits && swift test --build-path /tmp/swift-build --parallel --enable-code-coverage --disable-default-traits'
26 changes: 13 additions & 13 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 23 additions & 24 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
// swift-tools-version:6.1
// swift-tools-version:6.3
import PackageDescription

// NOTE: https://github.com/swift-server/swift-http-server/blob/main/Package.swift
var defaultSwiftSettings: [SwiftSetting] =
[
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0441-formalize-language-mode-terminology.md
let swiftSettings: [SwiftSetting] = [
.swiftLanguageMode(.v6),
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
.strictMemorySafety(),
.treatAllWarnings(as: .error),
.enableUpcomingFeature("InternalImportsByDefault"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("MemberImportVisibility"),
// https://forums.swift.org/t/experimental-support-for-lifetime-dependencies-in-swift-6-2-and-beyond/78638
.enableUpcomingFeature("InferIsolatedConformances"),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("ImmutableWeakCaptures"),
.enableUpcomingFeature("StrictConcurrency"),
.enableExperimentalFeature("SuppressedAssociatedTypes"),
.enableExperimentalFeature("LifetimeDependence"),
.enableExperimentalFeature("Lifetimes"),
// https://github.com/swiftlang/swift/pull/65218
.enableExperimentalFeature("AvailabilityMacro=FeatherDatabaseSQLite 1.0:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, visionOS 2.0"),
]

#if compiler(>=6.2)
defaultSwiftSettings.append(
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0461-async-function-isolation.md
.enableUpcomingFeature("NonisolatedNonsendingByDefault")
)
#endif


let package = Package(
name: "feather-database-sqlite",
Expand All @@ -32,6 +28,7 @@ let package = Package(
.visionOS(.v2),
],
products: [
.library(name: "SQLiteNIOExtras", targets: ["SQLiteNIOExtras"]),
.library(name: "FeatherDatabaseSQLite", targets: ["FeatherDatabaseSQLite"]),
],
traits: [
Expand All @@ -43,11 +40,13 @@ let package = Package(
),
],
dependencies: [
.package(url: "https://github.com/apple/swift-log", from: "1.14.0"),
.package(url: "https://github.com/vapor/sqlite-nio", from: "1.12.0"),
.package(url: "https://github.com/apple/swift-log", from: "1.16.1"),
.package(url: "https://github.com/vapor/sqlite-nio", from: "1.13.2"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle", from: "2.8.0"),
.package(url: "https://github.com/feather-framework/feather-database", exact: "1.0.0-rc.2"),
// [docc-plugin-placeholder]
.package(
url: "https://github.com/feather-framework/feather-database",
exact: "1.0.0-rc.3"
),
],
targets: [
.target(
Expand All @@ -56,7 +55,7 @@ let package = Package(
.product(name: "Logging", package: "swift-log"),
.product(name: "SQLiteNIO", package: "sqlite-nio"),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
.target(
name: "FeatherDatabaseSQLite",
Expand All @@ -69,14 +68,14 @@ let package = Package(
condition: .when(traits: ["ServiceLifecycle"])
),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
.testTarget(
name: "SQLiteNIOExtrasTests",
dependencies: [
.target(name: "SQLiteNIOExtras"),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
.testTarget(
name: "FeatherDatabaseSQLiteTests",
Expand All @@ -90,7 +89,7 @@ let package = Package(
)
),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
]
)
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

SQLite driver implementation for the abstract [Feather Database](https://github.com/feather-framework/feather-database) Swift API package.

[![Release: 1.0.0-rc.2](https://img.shields.io/badge/Release-1%2E0%2E0--rc%2E2-F05138)](https://github.com/feather-framework/feather-database-sqlite/releases/tag/1.0.0-rc.2)
[![Release: 1.0.0-rc.3](https://img.shields.io/badge/Release-1%2E0%2E0--rc%2E3-F05138)](https://github.com/feather-framework/feather-database-sqlite/releases/tag/1.0.0-rc.3)

## Features

Expand All @@ -15,10 +15,10 @@ SQLite driver implementation for the abstract [Feather Database](https://github.

## Requirements

![Swift 6.1+](https://img.shields.io/badge/Swift-6%2E1%2B-F05138)
![Swift 6.3+](https://img.shields.io/badge/Swift-6%2E3%2B-F05138)
![Platforms: Linux, macOS, iOS, tvOS, watchOS, visionOS](https://img.shields.io/badge/Platforms-Linux_%7C_macOS_%7C_iOS_%7C_tvOS_%7C_watchOS_%7C_visionOS-F05138)

- Swift 6.1+
- Swift 6.3+
- Platforms:
- Linux
- macOS 15+
Expand All @@ -32,7 +32,7 @@ SQLite driver implementation for the abstract [Feather Database](https://github.
Add the dependency to your `Package.swift`:

```swift
.package(url: "https://github.com/feather-framework/feather-database-sqlite", exact: "1.0.0-rc.2"),
.package(url: "https://github.com/feather-framework/feather-database-sqlite", exact: "1.0.0-rc.3"),
```

Then add `FeatherDatabaseSQLite` to your target dependencies:
Expand All @@ -49,7 +49,7 @@ To enable an additional trait on the package, update the package dependency:
```diff
.package(
url: "https://github.com/feather-framework/feather-database-sqlite",
exact: "1.0.0-rc.2",
exact: "1.0.0-rc.3",
+ traits: [
+ .defaults,
+ "ServiceLifecycle",
Expand Down
4 changes: 2 additions & 2 deletions Sources/FeatherDatabaseSQLite/DatabaseClientSQLite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// Created by Tibor Bödecs on 2026. 01. 10..
//

import FeatherDatabase
import SQLiteNIOExtras
public import FeatherDatabase
public import SQLiteNIOExtras

/// A SQLite-backed database client.
///
Expand Down
23 changes: 22 additions & 1 deletion Sources/FeatherDatabaseSQLite/DatabaseConnectionSQLite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@
// Created by Tibor Bödecs on 2026. 01. 10.
//

import FeatherDatabase
public import FeatherDatabase
import NIOCore
import SQLiteNIO

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif

extension DatabaseQuery {

fileprivate struct SQLiteQuery {
Expand All @@ -30,10 +37,24 @@ extension DatabaseQuery {
sqliteBindings.append(.integer(value ? 1 : 0))
case .int(let value):
sqliteBindings.append(.integer(value))
case .int32(let value):
sqliteBindings.append(.integer(Int(value)))
case .double(let value):
sqliteBindings.append(.float(value))
case .float(let value):
sqliteBindings.append(.float(Double(value)))
case .string(let value):
sqliteBindings.append(.text(value))
case .uuid(let value):
sqliteBindings.append(.text(value.uuidString))
case .date(let value):
sqliteBindings.append(.text(value.ISO8601Format()))
case .data(let value):
sqliteBindings.append(.blob(ByteBuffer(bytes: value)))
case .json(let value):
sqliteBindings.append(
.text(String(decoding: value, as: UTF8.self))
)
}
}

Expand Down
30 changes: 29 additions & 1 deletion Sources/FeatherDatabaseSQLite/DatabaseRowSQLite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,33 @@
// Created by Tibor Bödecs on 2026. 01. 10.
//

import FeatherDatabase
public import FeatherDatabase
import SQLiteNIO

public struct DatabaseRowSQLite: DatabaseRow {
var row: SQLiteRow

public var columns: [String] {
row.columns.map(\.name)
}

public func contains(column: String) -> Bool {
row.column(column) != nil
}

public func decodeNil(column: String) throws(DecodingError) -> Bool {
guard let data = row.column(column) else {
throw .keyNotFound(
SQLiteColumnKey(stringValue: column),
.init(
codingPath: [],
debugDescription: "Missing data for column \(column)."
)
)
}
return data.isNull
}

struct SingleValueDecoder: Decoder, SingleValueDecodingContainer {

var codingPath: [any CodingKey] { [] }
Expand Down Expand Up @@ -118,3 +139,10 @@ public struct DatabaseRowSQLite: DatabaseRow {
}
}
}

private struct SQLiteColumnKey: CodingKey {
let stringValue: String
let intValue: Int? = nil
init(stringValue: String) { self.stringValue = stringValue }
init?(intValue: Int) { return nil }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Tibor Bödecs on 2026. 01. 10.
//

import FeatherDatabase
public import FeatherDatabase
import SQLiteNIO

/// A query result backed by SQLite rows.
Expand Down
Loading
Loading