Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLite Custom Functions are now supported #25

Merged
merged 43 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6d92047
wip - integrating from GRDB
Jun 18, 2021
f6d491e
database function passes
Jun 19, 2021
0efcbb6
error status code
Jun 19, 2021
333d9e0
aggregate succeeded
Jun 19, 2021
f82e5ba
reneames
Jun 19, 2021
fe5bf06
ad/remove with eventloop
Jun 19, 2021
dcac9df
cleanup
Jun 19, 2021
084326d
adding some tests
Jun 19, 2021
50e3fd1
more tests
Jun 19, 2021
8d6e0ba
all tests pass
Jun 19, 2021
599c7be
uneeded custom function
Jun 19, 2021
8eff76c
blob
Jun 26, 2021
6488f5f
more test
Jun 26, 2021
02d799c
different error behavior on linux
Jun 26, 2021
36801ed
update from upstream
Jun 26, 2021
5cbc20a
\n
Jun 26, 2021
27034b9
Update SQLiteCustomFunction.swift
danramteke Jun 28, 2021
851a888
Update SQLiteCustomFunctionTests.swift
danramteke Jun 28, 2021
13681f1
Update Sources/SQLiteNIO/SQLiteConnection.swift
danramteke Feb 3, 2022
0650d4e
Update Sources/SQLiteNIO/SQLiteConnection.swift
danramteke Feb 3, 2022
a5579a7
Add project board workflow (#27)
BennyDeBock Mar 7, 2022
6454a9a
Add project board workflow (#28)
BennyDeBock May 3, 2022
17ba881
Add project board workflow (#29)
BennyDeBock May 13, 2022
5240fc8
add notices
Oct 26, 2022
92c32ef
Fix Date precision error (#33)
Austinpayne Nov 9, 2022
44b39bb
Support for reporting SQLite version numbers to clients (#34)
gwynne Nov 12, 2022
ff86c50
Embed sqlite amalgamation v3.40.0 source code (#35)
Austinpayne Dec 4, 2022
d47d61c
reindent SQLite error to 4 spaces. Single thread for tests
Dec 5, 2022
76c2848
threadPool.runIfActive first pass
Dec 5, 2022
c871093
flatMap -> map
Dec 5, 2022
6ff8d50
threadPool.submit -> runIfActive
Dec 5, 2022
a39b1bd
remove conformance `extension SQLiteData: SQLiteDataConvertible`
Dec 5, 2022
4900821
undo unsafe unwrap
Dec 5, 2022
63b6fdb
throw instead of fatal error
Dec 5, 2022
d166c6a
Update post-rebase for prefixed function names
gwynne Feb 22, 2023
c50cfab
Fixup indentation post-rebase
gwynne Feb 22, 2023
02648dc
Apply Cory's feedback to the `unmanagedAggregateContext()` method.
gwynne Feb 22, 2023
5ee1bbf
Merge branch 'main' into custom-functions
gwynne Feb 22, 2023
f9c4a3f
Attempt to fix build for Swift <5.7
gwynne Feb 22, 2023
1f7fefb
Normalize whitespace. \t oughtta go the way of EBCDIC...
gwynne Feb 22, 2023
8fd9fb9
Finish fixing Swift 5.5/5.6 build
gwynne Feb 22, 2023
9e20735
Address PR feedback
gwynne Feb 24, 2023
332a713
Merge branch 'main' into custom-functions
gwynne Mar 13, 2023
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
19 changes: 19 additions & 0 deletions NOTICES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Vapor open source project
//
// Copyright (c) 2017-2022 Vapor project authors
// Licensed under MIT
//
// See LICENSE for license information
//
// SPDX-License-Identifier: MIT
//
//===----------------------------------------------------------------------===//

This product contains a derivation of the custom SQLite functions from GRDB.swift

* LICENSE:
* https://raw.githubusercontent.com/groue/GRDB.swift/master/LICENSE
* HOMEPAGE:
* https://github.com/groue/GRDB.swift
49 changes: 31 additions & 18 deletions Sources/SQLiteNIO/SQLiteConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extension SQLiteDatabase {
rows.append(row)
}.map { rows }
}
}
}

extension SQLiteDatabase {
public func logging(to logger: Logger) -> SQLiteDatabase {
Expand Down Expand Up @@ -99,9 +99,11 @@ public final class SQLiteConnection: SQLiteDatabase {
}

let promise = eventLoop.makePromise(of: SQLiteConnection.self)
threadPool.submit { state in

return threadPool.runIfActive(eventLoop: eventLoop) {
var handle: OpaquePointer?
let options = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_URI

if sqlite_nio_sqlite3_open_v2(path, &handle, options, nil) == SQLITE_OK, sqlite_nio_sqlite3_busy_handler(handle, { _, _ in 1 }, nil) == SQLITE_OK {
let connection = SQLiteConnection(
handle: handle,
Expand All @@ -110,13 +112,14 @@ public final class SQLiteConnection: SQLiteDatabase {
on: eventLoop
)
logger.debug("Connected to sqlite db: \(path)")
promise.succeed(connection)
return promise.succeed(connection)
} else {
logger.error("Failed to connect to sqlite db: \(path)")
promise.fail(SQLiteError(reason: .cantOpen, message: "Cannot open SQLite database: \(storage)"))
return promise.fail(SQLiteError(reason: .cantOpen, message: "Cannot open SQLite database: \(storage)"))
}
}.flatMap {
promise.futureResult
}
return promise.futureResult
}

init(
Expand All @@ -138,14 +141,12 @@ public final class SQLiteConnection: SQLiteDatabase {
public static func libraryVersionString() -> String {
String(cString: sqlite_nio_sqlite3_libversion())
}

public func lastAutoincrementID() -> EventLoopFuture<Int> {
let promise = self.eventLoop.makePromise(of: Int.self)
self.threadPool.submit { _ in
self.threadPool.runIfActive(eventLoop: self.eventLoop) {
let rowid = sqlite_nio_sqlite3_last_insert_rowid(self.handle)
promise.succeed(numericCast(rowid))
return numericCast(rowid)
}
return promise.futureResult
}

internal var errorMessage: String? {
Expand All @@ -168,7 +169,7 @@ public final class SQLiteConnection: SQLiteDatabase {
) -> EventLoopFuture<Void> {
logger.debug("\(query) \(binds)")
let promise = self.eventLoop.makePromise(of: Void.self)
self.threadPool.submit { state in
return self.threadPool.runIfActive(eventLoop: self.eventLoop) {
do {
let statement = try SQLiteStatement(query: query, on: self)
try statement.bind(binds)
Expand All @@ -185,21 +186,33 @@ public final class SQLiteConnection: SQLiteDatabase {
} catch {
promise.fail(error)
}
}.flatMap {
promise.futureResult
}
return promise.futureResult
}

public func close() -> EventLoopFuture<Void> {
let promise = self.eventLoop.makePromise(of: Void.self)
self.threadPool.submit { state in
self.threadPool.runIfActive(eventLoop: self.eventLoop) {
sqlite_nio_sqlite3_close(self.handle)
self.eventLoop.submit {
self.handle = nil
}.cascade(to: promise)
}.map { _ in
self.handle = nil
}
return promise.futureResult
}

public func install(customFunction: SQLiteCustomFunction) -> EventLoopFuture<Void> {
logger.trace("Adding custom function \(customFunction.name)")
return self.threadPool.runIfActive(eventLoop: self.eventLoop) {
try customFunction.install(in: self)
}
}

public func uninstall(customFunction: SQLiteCustomFunction) -> EventLoopFuture<Void> {
logger.trace("Removing custom function \(customFunction.name)")
return self.threadPool.runIfActive(eventLoop: self.eventLoop) {
try customFunction.uninstall(in: self)
}
}

deinit {
assert(self.handle == nil, "SQLiteConnection was not closed before deinitializing")
}
Expand Down
Loading