Skip to content

Commit 98d2894

Browse files
authored
A minor overhaul (#68)
* Bump minimum Swift version to 5.8. Update CI. General package cleanup. General docs cleanup. * Add explicit async versions of all ELF methods of SQLiteConnection * Improve handling of blob and text data in SQLiteData * Make `String` accept integer and real values as well as textual values when being decoded, make `Double` and `Float` accept integer values, use recommended APIs for translating between ByteBuffer and Data * SQLiteStatement: Use sqlite_prepare_v3() instead of _v2(). Factor out error handling. Make sure statements get finalized when errors occur. Use sqlite3_bind_blob64() and sqlite3_bind_text64() instead of the 32-bit ones. Simplify reading of blob data. * Misc minor cleanup (Style only, nothing functional) * Tests: Make all tests async. Add helper to replace use of defer {}. Add set of async assertions. Make tests resilient against array index range violations. Handle blobs more sensibly instead of torturing Data. Get rid of lots of force-unwraps. Use "throws error" assertion instead of messy do/catch clauses. Avoid crashing if opening a DB fails. Use singleton thread pool and MTELG always. * Remove incorrect new protocol requirements. Add passthroughs for the convenience methods. Factor out the `open()` implementation so the core part can be shared by the ELF and async versions. Don't leak sqlite3* handles if sqlite3_busy_handler() fails for some reason. Throw more specific errors from `open()`. Don't log at error level. Use the async version of NIOThreadPool.runIfActive() when possible. * Split the SQLDatabase protocol into its own file. Group SQLiteConnnection's async methods together. * We always pass SQLITE_OPEN_FULLMUTEX (serialized mode) to sqlite3_open_v2(), so there's no point in setting multithread mode as the default during compilation; use serialized as the default instead. * Add test that validates we're using SQLite in the correct (safest) threading mode. * Fix a couple of log messages * Apply several SQLite compilation settings according to upstream documentation, plus omitting several APIs that aren't usable through this package anyway. * As recommended in the docs, mark custom functions SQLITE_DIRECTONLY by default (security hardening). Provide an initializer flag to override it if needed. * Remove not yet available upcoming/experimental feature flags from the 5.8 manifest * Update dependency minimums * Add support for SQLite's extended result codes * Lots of documentation comments. Reorganize SQLiteConnection a little. SQLiteDatabase is Sendable. * Try to silence TSan false positives in 5.8
1 parent e79d223 commit 98d2894

21 files changed

+1696
-866
lines changed

.github/dependabot.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
version: 2
2-
enable-beta-ecosystems: true
32
updates:
43
- package-ecosystem: "github-actions"
54
directory: "/"
@@ -11,14 +10,3 @@ updates:
1110
dependencies:
1211
patterns:
1312
- "*"
14-
- package-ecosystem: "swift"
15-
directory: "/"
16-
schedule:
17-
interval: "daily"
18-
open-pull-requests-limit: 6
19-
allow:
20-
- dependency-type: all
21-
groups:
22-
all-dependencies:
23-
patterns:
24-
- "*"

.github/workflows/test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
dependents-check:
1717
if: ${{ !(github.event.pull_request.draft || false) }}
1818
runs-on: ubuntu-latest
19-
container: swift:5.9-jammy
19+
container: swift:5.10-jammy
2020
steps:
2121
- name: Check out package
2222
uses: actions/checkout@v4
@@ -38,3 +38,4 @@ jobs:
3838

3939
unit-tests:
4040
uses: vapor/ci/.github/workflows/run-unit-tests.yml@main
41+
secrets: inherit

Package.swift

Lines changed: 67 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.7
1+
// swift-tools-version:5.8
22
import PackageDescription
33

44
let package = Package(
@@ -13,8 +13,8 @@ let package = Package(
1313
.library(name: "SQLiteNIO", targets: ["SQLiteNIO"]),
1414
],
1515
dependencies: [
16-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.58.0"),
17-
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
16+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
17+
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
1818
],
1919
targets: [
2020
.plugin(
@@ -25,38 +25,69 @@ let package = Package(
2525
),
2626
exclude: ["001-warnings-and-data-race.patch"]
2727
),
28-
.target(name: "CSQLite", cSettings: [
29-
// Derived from sqlite3 version 3.43.0
30-
.define("SQLITE_DQS", to: "0"),
31-
.define("SQLITE_ENABLE_API_ARMOR"),
32-
.define("SQLITE_ENABLE_COLUMN_METADATA"),
33-
.define("SQLITE_ENABLE_DBSTAT_VTAB"),
34-
.define("SQLITE_ENABLE_FTS3"),
35-
.define("SQLITE_ENABLE_FTS3_PARENTHESIS"),
36-
.define("SQLITE_ENABLE_FTS3_TOKENIZER"),
37-
.define("SQLITE_ENABLE_FTS4"),
38-
.define("SQLITE_ENABLE_FTS5"),
39-
.define("SQLITE_ENABLE_MEMORY_MANAGEMENT"),
40-
.define("SQLITE_ENABLE_PREUPDATE_HOOK"),
41-
.define("SQLITE_ENABLE_RTREE"),
42-
.define("SQLITE_ENABLE_SESSION"),
43-
.define("SQLITE_ENABLE_STMTVTAB"),
44-
.define("SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION"),
45-
.define("SQLITE_ENABLE_UNLOCK_NOTIFY"),
46-
.define("SQLITE_MAX_VARIABLE_NUMBER", to: "250000"),
47-
.define("SQLITE_LIKE_DOESNT_MATCH_BLOBS"),
48-
.define("SQLITE_OMIT_DEPRECATED"),
49-
.define("SQLITE_OMIT_LOAD_EXTENSION"),
50-
.define("SQLITE_OMIT_SHARED_CACHE"),
51-
.define("SQLITE_SECURE_DELETE"),
52-
.define("SQLITE_THREADSAFE", to: "2"),
53-
.define("SQLITE_USE_URI"),
54-
]),
55-
.target(name: "SQLiteNIO", dependencies: [
56-
.target(name: "CSQLite"),
57-
.product(name: "Logging", package: "swift-log"),
58-
.product(name: "NIO", package: "swift-nio"),
59-
]),
60-
.testTarget(name: "SQLiteNIOTests", dependencies: ["SQLiteNIO"]),
28+
.target(
29+
name: "CSQLite",
30+
cSettings: sqliteCSettings
31+
),
32+
.target(
33+
name: "SQLiteNIO",
34+
dependencies: [
35+
.target(name: "CSQLite"),
36+
.product(name: "Logging", package: "swift-log"),
37+
.product(name: "NIOCore", package: "swift-nio"),
38+
.product(name: "NIOPosix", package: "swift-nio"),
39+
.product(name: "NIOFoundationCompat", package: "swift-nio"),
40+
],
41+
swiftSettings: swiftSettings
42+
),
43+
.testTarget(
44+
name: "SQLiteNIOTests",
45+
dependencies: [
46+
.target(name: "SQLiteNIO"),
47+
],
48+
swiftSettings: swiftSettings
49+
),
6150
]
6251
)
52+
53+
var swiftSettings: [SwiftSetting] { [
54+
.enableUpcomingFeature("ConciseMagicFile"),
55+
.enableUpcomingFeature("ForwardTrailingClosures"),
56+
] }
57+
58+
var sqliteCSettings: [CSetting] { [
59+
// Derived from sqlite3 version 3.43.0
60+
.define("SQLITE_DEFAULT_MEMSTATUS", to: "0"),
61+
.define("SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS"),
62+
.define("SQLITE_DQS", to: "0"),
63+
.define("SQLITE_ENABLE_API_ARMOR", .when(configuration: .debug)),
64+
.define("SQLITE_ENABLE_COLUMN_METADATA"),
65+
.define("SQLITE_ENABLE_DBSTAT_VTAB"),
66+
.define("SQLITE_ENABLE_FTS3"),
67+
.define("SQLITE_ENABLE_FTS3_PARENTHESIS"),
68+
.define("SQLITE_ENABLE_FTS3_TOKENIZER"),
69+
.define("SQLITE_ENABLE_FTS4"),
70+
.define("SQLITE_ENABLE_FTS5"),
71+
.define("SQLITE_ENABLE_NULL_TRIM"),
72+
.define("SQLITE_ENABLE_RTREE"),
73+
.define("SQLITE_ENABLE_SESSION"),
74+
.define("SQLITE_ENABLE_STMTVTAB"),
75+
.define("SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION"),
76+
.define("SQLITE_ENABLE_UNLOCK_NOTIFY"),
77+
.define("SQLITE_MAX_VARIABLE_NUMBER", to: "250000"),
78+
.define("SQLITE_LIKE_DOESNT_MATCH_BLOBS"),
79+
.define("SQLITE_OMIT_AUTHORIZATION"),
80+
.define("SQLITE_OMIT_COMPLETE"),
81+
.define("SQLITE_OMIT_DEPRECATED"),
82+
.define("SQLITE_OMIT_DESERIALIZE"),
83+
.define("SQLITE_OMIT_GET_TABLE"),
84+
.define("SQLITE_OMIT_LOAD_EXTENSION"),
85+
.define("SQLITE_OMIT_PROGRESS_CALLBACK"),
86+
.define("SQLITE_OMIT_SHARED_CACHE"),
87+
.define("SQLITE_OMIT_TCL_VARIABLE"),
88+
.define("SQLITE_OMIT_TRACE"),
89+
.define("SQLITE_SECURE_DELETE"),
90+
.define("SQLITE_THREADSAFE", to: "1"),
91+
.define("SQLITE_UNTESTABLE"),
92+
.define("SQLITE_USE_URI"),
93+
] }

[email protected]

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// swift-tools-version:5.9
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "sqlite-nio",
6+
platforms: [
7+
.macOS(.v10_15),
8+
.iOS(.v13),
9+
.watchOS(.v6),
10+
.tvOS(.v13),
11+
],
12+
products: [
13+
.library(name: "SQLiteNIO", targets: ["SQLiteNIO"]),
14+
],
15+
dependencies: [
16+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
17+
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
18+
],
19+
targets: [
20+
.plugin(
21+
name: "VendorSQLite",
22+
capability: .command(
23+
intent: .custom(verb: "vendor-sqlite", description: "Vendor SQLite"),
24+
permissions: [
25+
.allowNetworkConnections(scope: .all(ports: [443]), reason: "Retrieve the latest build of SQLite"),
26+
.writeToPackageDirectory(reason: "Update the vendored SQLite files"),
27+
]
28+
),
29+
exclude: ["001-warnings-and-data-race.patch"]
30+
),
31+
.target(
32+
name: "CSQLite",
33+
cSettings: sqliteCSettings
34+
),
35+
.target(
36+
name: "SQLiteNIO",
37+
dependencies: [
38+
.target(name: "CSQLite"),
39+
.product(name: "Logging", package: "swift-log"),
40+
.product(name: "NIOCore", package: "swift-nio"),
41+
.product(name: "NIOPosix", package: "swift-nio"),
42+
.product(name: "NIOFoundationCompat", package: "swift-nio"),
43+
],
44+
swiftSettings: swiftSettings
45+
),
46+
.testTarget(
47+
name: "SQLiteNIOTests",
48+
dependencies: [
49+
.target(name: "SQLiteNIO"),
50+
],
51+
swiftSettings: swiftSettings
52+
),
53+
]
54+
)
55+
56+
var swiftSettings: [SwiftSetting] { [
57+
.enableUpcomingFeature("ExistentialAny"),
58+
.enableUpcomingFeature("ConciseMagicFile"),
59+
.enableUpcomingFeature("ForwardTrailingClosures"),
60+
.enableUpcomingFeature("DisableOutwardActorInference"),
61+
.enableExperimentalFeature("StrictConcurrency=complete"),
62+
] }
63+
64+
var sqliteCSettings: [CSetting] { [
65+
// Derived from sqlite3 version 3.43.0
66+
.define("SQLITE_DEFAULT_MEMSTATUS", to: "0"),
67+
.define("SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS"),
68+
.define("SQLITE_DQS", to: "0"),
69+
.define("SQLITE_ENABLE_API_ARMOR", .when(configuration: .debug)),
70+
.define("SQLITE_ENABLE_COLUMN_METADATA"),
71+
.define("SQLITE_ENABLE_DBSTAT_VTAB"),
72+
.define("SQLITE_ENABLE_FTS3"),
73+
.define("SQLITE_ENABLE_FTS3_PARENTHESIS"),
74+
.define("SQLITE_ENABLE_FTS3_TOKENIZER"),
75+
.define("SQLITE_ENABLE_FTS4"),
76+
.define("SQLITE_ENABLE_FTS5"),
77+
.define("SQLITE_ENABLE_NULL_TRIM"),
78+
.define("SQLITE_ENABLE_RTREE"),
79+
.define("SQLITE_ENABLE_SESSION"),
80+
.define("SQLITE_ENABLE_STMTVTAB"),
81+
.define("SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION"),
82+
.define("SQLITE_ENABLE_UNLOCK_NOTIFY"),
83+
.define("SQLITE_MAX_VARIABLE_NUMBER", to: "250000"),
84+
.define("SQLITE_LIKE_DOESNT_MATCH_BLOBS"),
85+
.define("SQLITE_OMIT_AUTHORIZATION"),
86+
.define("SQLITE_OMIT_COMPLETE"),
87+
.define("SQLITE_OMIT_DEPRECATED"),
88+
.define("SQLITE_OMIT_DESERIALIZE"),
89+
.define("SQLITE_OMIT_GET_TABLE"),
90+
.define("SQLITE_OMIT_LOAD_EXTENSION"),
91+
.define("SQLITE_OMIT_PROGRESS_CALLBACK"),
92+
.define("SQLITE_OMIT_SHARED_CACHE"),
93+
.define("SQLITE_OMIT_TCL_VARIABLE"),
94+
.define("SQLITE_OMIT_TRACE"),
95+
.define("SQLITE_SECURE_DELETE"),
96+
.define("SQLITE_THREADSAFE", to: "1"),
97+
.define("SQLITE_UNTESTABLE"),
98+
.define("SQLITE_USE_URI"),
99+
] }

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
<a href="https://docs.vapor.codes/4.0/"><img src="https://design.vapor.codes/images/readthedocs.svg" alt="Documentation"></a>
1010
<a href="https://discord.gg/vapor"><img src="https://design.vapor.codes/images/discordchat.svg" alt="Team Chat"></a>
1111
<a href="LICENSE"><img src="https://design.vapor.codes/images/mitlicense.svg" alt="MIT License"></a>
12-
<a href="https://github.com/vapor/sqlite-nio/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/vapor/sqlite-nio/test.yml?event=push&style=plastic&logo=github&label=test&logoColor=%23ccc" alt="Continuous Integration"></a>
13-
<a href="https://codecov.io/github/vapor/sqlite-nio"><img src="https://img.shields.io/codecov/c/github/vapor/sqlite-nio?style=plastic&logo=codecov&label=Codecov"></a>
14-
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift57up.svg" alt="Swift 5.7+"></a>
12+
<a href="https://github.com/vapor/sqlite-nio/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/vapor/sqlite-nio/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="Continuous Integration"></a>
13+
<a href="https://codecov.io/github/vapor/sqlite-nio"><img src="https://img.shields.io/codecov/c/github/vapor/sqlite-nio?style=plastic&logo=codecov&label=codecov"></a>
14+
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift58up.svg" alt="Swift 5.8+"></a>
1515
</p>
1616

1717
<br>

Sources/SQLiteNIO/Docs.docc/Documentation.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
@TitleHeading(Package)
55
}
66

7-
🪶 Non-blocking, event-driven Swift client for SQLite with embedded libsqlite
7+
🪶 Non-blocking, event-driven Swift client for SQLite with embedded `libsqlite`.
88

99
## Supported Versions
1010

11-
This package is compatible with all platforms supported by [SwiftNIO 2.x](https://github.com/apple/swift-nio/). It has
12-
been specifically tested on the following platforms:
11+
This package is compatible with all platforms supported by [SwiftNIO 2.x](https://github.com/apple/swift-nio/). It has been specifically tested on the following platforms:
1312

1413
- Ubuntu 20.04 ("Focal") and 22.04 ("Jammy")
1514
- Amazon Linux 2

Sources/SQLiteNIO/Docs.docc/theme-settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"theme": {
3-
"aside": { "border-radius": "6px", "border-style": "double", "border-width": "3px" },
3+
"aside": { "border-radius": "16px", "border-style": "double", "border-width": "3px" },
44
"border-radius": "0",
55
"button": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
66
"code": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },

Sources/SQLiteNIO/Exports.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
1-
#if swift(>=5.8)
2-
31
@_documentation(visibility: internal) @_exported import struct NIOCore.ByteBuffer
42
@_documentation(visibility: internal) @_exported import class NIOPosix.NIOThreadPool
53
@_documentation(visibility: internal) @_exported import protocol NIOCore.EventLoop
64
@_documentation(visibility: internal) @_exported import protocol NIOCore.EventLoopGroup
75
@_documentation(visibility: internal) @_exported import class NIOPosix.MultiThreadedEventLoopGroup
8-
9-
#else
10-
11-
@_exported import struct NIOCore.ByteBuffer
12-
@_exported import class NIOPosix.NIOThreadPool
13-
@_exported import protocol NIOCore.EventLoop
14-
@_exported import protocol NIOCore.EventLoopGroup
15-
@_exported import class NIOPosix.MultiThreadedEventLoopGroup
16-
17-
#endif

0 commit comments

Comments
 (0)