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
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
26 changes: 10 additions & 16 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,25 @@ on:
- main

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@main
soundness:
name: Soundness
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@0.0.16
with:
license_header_check_project_name: "project"
format_check_enabled: true
broken_symlink_check_enabled: true
unacceptable_language_check_enabled: true
shell_check_enabled: false
shell_check_enabled: true
docs_check_enabled: false
api_breakage_check_enabled: false
license_header_check_enabled: false
yamllint_check_enabled: false
python_lint_check_enabled: false

bb_checks:
name: BB Checks
uses: BinaryBirds/github-workflows/.github/workflows/extra_soundness.yml@main
tests:
name: Tests
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@0.0.16
with:
local_swift_dependencies_check_enabled: true
run_tests_with_cache_enabled: true
headers_check_enabled: false
docc_warnings_check_enabled: true
run_tests_swift_versions: '["6.1", "6.2", "6.3"]'
enable_windows_checks: false
linux_build_command: "swift test --parallel --enable-code-coverage"
linux_swift_versions: '["6.3", "6.4"]'
43 changes: 23 additions & 20 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,27 +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=featherDatabase 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",
platforms: [
Expand All @@ -33,22 +28,30 @@ let package = Package(
],
products: [
.library(name: "FeatherDatabase", targets: ["FeatherDatabase"]),
.library(name: "FeatherDatabaseTesting", targets: ["FeatherDatabaseTesting"]),
],
dependencies: [
// [docc-plugin-placeholder]
],
targets: [
.target(
name: "FeatherDatabase",
dependencies: [],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
.target(
name: "FeatherDatabaseTesting",
dependencies: [
.target(name: "FeatherDatabase"),
],
path: "Sources/Testing",
swiftSettings: swiftSettings
),
.testTarget(
name: "FeatherDatabaseTests",
dependencies: [
.target(name: "FeatherDatabase"),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
]
)
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Abstract database component, providing a shared API surface for database drivers written in Swift.

[![Release: 1.0.0-rc.2](https://img.shields.io/badge/Release-1%2E0%2E0--rc%2E1-F05138)](https://github.com/feather-framework/feather-database/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/releases/tag/1.0.0-rc.3)

## Features

Expand All @@ -13,10 +13,10 @@ Abstract database component, providing a shared API surface for database drivers

## 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
Expand All @@ -31,7 +31,7 @@ Abstract database component, providing a shared API surface for database drivers
Use Swift Package Manager; add the dependency to your `Package.swift` file:

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

Then add `FeatherDatabase` to your target dependencies:
Expand Down
6 changes: 3 additions & 3 deletions Sources/FeatherDatabase/DatabaseError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ public enum DatabaseError: Error {
/// A connection-level failure.
///
/// The associated error provides the underlying cause.
case connection(Error)
case connection(any Error)

/// A transaction failure.
///
/// The associated error includes phase-specific details.
case transaction(DatabaseTransactionError)
case transaction(any DatabaseTransactionError)

/// A query execution failure.
///
/// The associated error provides the underlying cause.
case query(Error)
case query(any Error)

}
18 changes: 18 additions & 0 deletions Sources/FeatherDatabase/DatabaseQueryBinding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,32 @@
// Created by Tibor Bödecs on 2026. 02. 07..
//

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

/// A single bindable value used by a database query.
public enum DatabaseQueryBinding: Sendable, Equatable, Hashable, Codable {
/// A text value.
case string(String)
/// An integer value.
case int(Int)
/// A 32-bit integer value.
case int32(Int32)
/// A floating-point value.
case double(Double)
/// A 32-bit floating-point value.
case float(Float)
/// A boolean value.
case bool(Bool)
/// A UUID value.
case uuid(UUID)
/// A date and time value.
case date(Date)
/// A binary value.
case data(Data)
/// A JSON document encoded as UTF-8.
case json(Data)
}
22 changes: 22 additions & 0 deletions Sources/FeatherDatabase/DatabaseRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@
/// Conforming types provide type-safe decoding for column values.
public protocol DatabaseRow: Sendable {

/// The names of the columns available in this row.
var columns: [String] { get }

/// Returns whether this row contains a column with the given name.
func contains(column: String) -> Bool

/// Returns whether the given column is SQL `NULL`.
///
/// Missing columns should throw `DecodingError.keyNotFound`.
func decodeNil(column: String) throws(DecodingError) -> Bool

/// Decode a column value as the given type.
///
/// This method converts the column value into a `Decodable` type.
Expand All @@ -23,3 +34,14 @@ public protocol DatabaseRow: Sendable {
as: T.Type
) throws(DecodingError) -> T
}

extension DatabaseRow {

/// Decode this row into a flat `Decodable` value.
public func decode<T: Decodable>(
model type: T.Type,
with decoder: DatabaseRowDecoder = .init()
) throws -> T {
try decoder.decode(type, from: self)
}
}
Loading
Loading