Skip to content
Draft
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
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
contents: read
uses: vapor/ci/.github/workflows/run-unit-tests.yml@main
secrets: inherit
with:
with_wasm: true

# Make sure downstream dependents still work
dependents-check:
Expand Down
18 changes: 16 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// swift-tools-version:5.8
import PackageDescription

/// `.when(platforms:)` can only include, never exclude, so excluding WASI means listing everything else.
/// This list matches the [supported platforms on the Swift 5.8 release of SPM](https://github.com/swiftlang/swift-package-manager/blob/release/5.8/Sources/PackageDescription/SupportedPlatforms.swift);
/// `.visionOS` arrived in SPM 5.9, and toolchains that know it read `Package@swift-5.9.swift` instead.
/// Don't add new platforms here unless raising the swift-tools-version of this manifest.
let allPlatforms: [Platform] = [.macOS, .macCatalyst, .iOS, .tvOS, .watchOS, .driverKit, .linux, .windows, .android, .wasi, .openbsd]
let nonWASIPlatforms: [Platform] = allPlatforms.filter { $0 != .wasi }

let package = Package(
name: "sqlite-kit",
platforms: [
Expand All @@ -22,8 +29,15 @@ let package = Package(
.target(
name: "SQLiteKit",
dependencies: [
.product(name: "NIOFoundationCompat", package: "swift-nio"),
.product(name: "AsyncKit", package: "async-kit"),
// Target dependency conditions are evaluated per platform; on WASI these two
// products are not linked. AsyncKit's pool rides NIOPosix, which needs the POSIX
// sockets and threads WASI preview 1 lacks, and sqlite-nio's WASI flavor is
// SwiftNIO-free, so NIOFoundationCompat would have nothing to bridge and a linked
// NIOCore would flip the `#if canImport(NIOCore)` gates against a SQLiteNIO with no
// event loops. SQLiteKit then compiles without the connection pool and without the
// EventLoopFuture surface (see the `#if canImport(...)` gates in Sources/).
.product(name: "NIOFoundationCompat", package: "swift-nio", condition: .when(platforms: nonWASIPlatforms)),
.product(name: "AsyncKit", package: "async-kit", condition: .when(platforms: nonWASIPlatforms)),
.product(name: "SQLiteNIO", package: "sqlite-nio"),
.product(name: "SQLKit", package: "sql-kit"),
],
Expand Down
17 changes: 15 additions & 2 deletions Package@swift-5.9.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// swift-tools-version:5.9
import PackageDescription

/// `.when(platforms:)` can only include, never exclude, so excluding WASI means listing everything else.
/// This list matches the [supported platforms on the Swift 5.9 release of SPM](https://github.com/swiftlang/swift-package-manager/blob/release/5.9/Sources/PackageDescription/SupportedPlatforms.swift).
/// Don't add new platforms here unless raising the swift-tools-version of this manifest.
let allPlatforms: [Platform] = [.macOS, .macCatalyst, .iOS, .tvOS, .watchOS, .visionOS, .driverKit, .linux, .windows, .android, .wasi, .openbsd]
let nonWASIPlatforms: [Platform] = allPlatforms.filter { $0 != .wasi }

let package = Package(
name: "sqlite-kit",
platforms: [
Expand All @@ -22,8 +28,15 @@ let package = Package(
.target(
name: "SQLiteKit",
dependencies: [
.product(name: "NIOFoundationCompat", package: "swift-nio"),
.product(name: "AsyncKit", package: "async-kit"),
// Target dependency conditions are evaluated per platform; on WASI these two
// products are not linked. AsyncKit's pool rides NIOPosix, which needs the POSIX
// sockets and threads WASI preview 1 lacks, and sqlite-nio's WASI flavor is
// SwiftNIO-free, so NIOFoundationCompat would have nothing to bridge and a linked
// NIOCore would flip the `#if canImport(NIOCore)` gates against a SQLiteNIO with no
// event loops. SQLiteKit then compiles without the connection pool and without the
// EventLoopFuture surface (see the `#if canImport(...)` gates in Sources/).
.product(name: "NIOFoundationCompat", package: "swift-nio", condition: .when(platforms: nonWASIPlatforms)),
.product(name: "AsyncKit", package: "async-kit", condition: .when(platforms: nonWASIPlatforms)),
.product(name: "SQLiteNIO", package: "sqlite-nio"),
.product(name: "SQLKit", package: "sql-kit"),
],
Expand Down
3 changes: 3 additions & 0 deletions Sources/SQLiteKit/Exports.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@_documentation(visibility: internal) @_exported import SQLKit
@_documentation(visibility: internal) @_exported import SQLiteNIO
// AsyncKit, and with it the connection pool, is gated to the same platforms as SwiftNIO (see Package.swift).
#if canImport(AsyncKit)
@_documentation(visibility: internal) @_exported import AsyncKit
#endif
@_documentation(visibility: internal) @_exported import struct Logging.Logger
6 changes: 6 additions & 0 deletions Sources/SQLiteKit/SQLiteConnection+SQLKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,13 @@ struct SQLiteDatabaseVersion: SQLDatabaseReportedVersion {
@usableFromInline
let decoder: SQLiteDataDecoder

#if canImport(NIOCore)
// See `SQLDatabase.eventLoop`.
@usableFromInline
var eventLoop: any EventLoop {
self.database.eventLoop
}
#endif

// See `SQLDatabase.version`.
@usableFromInline
Expand Down Expand Up @@ -209,6 +211,9 @@ struct SQLiteDatabaseVersion: SQLDatabaseReportedVersion {
self.queryLogLevel = queryLogLevel
}

// The `EventLoopFuture` overload only exists where SwiftNIO does; SQLKit's protocol drops the
// requirement on the other platforms and the `async` overload below carries the whole surface.
#if canImport(NIOCore)
// See `SQLDatabase.execute(sql:_:)`.
@usableFromInline
func execute(
Expand All @@ -234,6 +239,7 @@ struct SQLiteDatabaseVersion: SQLDatabaseReportedVersion {
{ onRow($0.sql(decoder: self.decoder)) }
)
}
#endif // canImport(NIOCore)

// See `SQLDatabase.execute(sql:_:)`.
@usableFromInline
Expand Down
5 changes: 5 additions & 0 deletions Sources/SQLiteKit/SQLiteConnectionSource.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// ``SQLiteConnectionSource`` is a `ConnectionPoolSource`, built on AsyncKit and SwiftNIO's thread
// pool. Neither is available on every platform SQLiteKit supports; where they are absent, callers
// use sqlite-nio's concrete async `SQLiteConnection` directly and there is no pool.
#if canImport(AsyncKit)
#if canImport(Darwin)
import Foundation
#else
Expand Down Expand Up @@ -97,3 +101,4 @@ fileprivate extension SQLiteConfiguration.Storage {
}
}
}
#endif // canImport(AsyncKit)
10 changes: 10 additions & 0 deletions Sources/SQLiteKit/SQLiteDataDecoder.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Foundation
import SQLiteNIO
@_spi(CodableUtilities) import SQLKit
#if canImport(NIOFoundationCompat)
import NIOFoundationCompat
#endif

/// Translates `SQLiteData` values received from the database into `Decodable` values.
///
Expand Down Expand Up @@ -51,7 +53,15 @@ public struct SQLiteDataDecoder: Sendable {

switch data {
case .text(let str): buf = .init(str.utf8)
// N.B.: `Data.init(buffer:byteTransferStrategy:)` is NIOFoundationCompat's
// zero-copy bridge and has no `[UInt8]` equivalent. The two cases stay forked
// rather than collapsing onto a copying spelling such as
// `Data(blob.readableBytesView)`, which would add a copy where SwiftNIO is present.
#if canImport(NIOFoundationCompat)
case .blob(let blob): buf = .init(buffer: blob, byteTransferStrategy: .noCopy)
#else
case .blob(let blob): buf = .init(blob) // `SQLiteData.blob` carries `[UInt8]` without SwiftNIO
#endif
// The remaining cases should never happen, but we implement them anyway just in case.
case .integer(let n): buf = .init(String(n).utf8)
case .float(let n): buf = .init(String(n).utf8)
Expand Down
1 change: 0 additions & 1 deletion Sources/SQLiteKit/SQLiteDataEncoder.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import NIOCore
import Foundation
@_spi(CodableUtilities) import SQLKit
import SQLiteNIO
Expand Down
Loading