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

Add SQLInterface for dynamic replacement of SQLite implementations #1701

Closed
wants to merge 4 commits into from
Closed
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: 4 additions & 0 deletions GRDB/Core/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
/// Related SQLite documentation: <https://www.sqlite.org/errlog.html>
nonisolated(unsafe) public static var logError: LogErrorFunction? = nil {
didSet {
#if false // TODO: SQLiteInterface
if logError != nil {
_registerErrorLogCallback { (_, code, message) in
guard let logError = Database.logError else { return }
Expand All @@ -180,6 +181,7 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
} else {
_registerErrorLogCallback(nil)
}
#endif
}
}

Expand Down Expand Up @@ -512,11 +514,13 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
}

private func setupDoubleQuotedStringLiterals() {
#if false // TODO: SQLiteInterface
if configuration.acceptsDoubleQuotedStringLiterals {
_enableDoubleQuotedStringLiterals(sqliteConnection)
} else {
_disableDoubleQuotedStringLiterals(sqliteConnection)
}
#endif
}

private func setupForeignKeys() throws {
Expand Down
2 changes: 1 addition & 1 deletion GRDB/Core/DatabaseFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ public final class DatabaseFunction: Identifiable, Sendable {

/// A function kind: an "SQL function" or an "aggregate".
/// See <http://sqlite.org/capi3ref.html#sqlite3_create_function>
private enum Kind: Sendable {
/* SQLInterface FIXME: should be private*/ enum Kind: Sendable {
/// A regular function: SELECT f(1)
case function(@Sendable (CInt, UnsafeMutablePointer<OpaquePointer?>?) throws -> (any DatabaseValueConvertible)?)

Expand Down
6 changes: 4 additions & 2 deletions GRDB/Core/DatabasePool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,8 @@ extension DatabasePool: DatabaseReader {

// MARK: - WAL Snapshot Transactions

#if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)
#if false // SQLInterface FIXME: snapshots need work #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)

/// Returns a long-lived WAL snapshot transaction on a reader connection.
func walSnapshotTransaction() throws -> WALSnapshotTransaction {
guard let readerPool else {
Expand Down Expand Up @@ -956,7 +957,7 @@ extension DatabasePool {
purpose: "snapshot.\(databaseSnapshotCountMutex.increment())")
}

#if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)
#if false // SQLInterface FIXME: snapshots need work #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)
/// Creates a database snapshot that allows concurrent accesses to an
/// unchanging database content, as it exists at the moment the snapshot
/// is created.
Expand All @@ -970,6 +971,7 @@ extension DatabasePool {
///
/// Related SQLite documentation: <https://www.sqlite.org/c3ref/snapshot_get.html>
public func makeSnapshotPool() throws -> DatabaseSnapshotPool {
throw Error.unsupported
try unsafeReentrantRead { db in
try DatabaseSnapshotPool(db)
}
Expand Down
2 changes: 1 addition & 1 deletion GRDB/Core/DatabaseSnapshotPool.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)
#if false // SQLInterface FIXME: snapshots need work #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)
// Import C SQLite functions
#if SWIFT_PACKAGE
import GRDBSQLite
Expand Down
24 changes: 12 additions & 12 deletions GRDB/Core/DatabaseValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,18 @@ public struct DatabaseValue: Hashable {

// SQLite function argument
init(sqliteValue: SQLiteValue) {
switch sqlite3_value_type(sqliteValue) {
switch SQLite3.sqlite3_value_type(sqliteValue) {
case SQLITE_NULL:
storage = .null
case SQLITE_INTEGER:
storage = .int64(sqlite3_value_int64(sqliteValue))
storage = .int64(SQLite3.sqlite3_value_int64(sqliteValue))
case SQLITE_FLOAT:
storage = .double(sqlite3_value_double(sqliteValue))
storage = .double(SQLite3.sqlite3_value_double(sqliteValue))
case SQLITE_TEXT:
storage = .string(String(cString: sqlite3_value_text(sqliteValue)!))
storage = .string(String(cString: SQLite3.sqlite3_value_text(sqliteValue)!))
case SQLITE_BLOB:
if let bytes = sqlite3_value_blob(sqliteValue) {
let count = Int(sqlite3_value_bytes(sqliteValue))
if let bytes = SQLite3.sqlite3_value_blob(sqliteValue) {
let count = Int(SQLite3.sqlite3_value_bytes(sqliteValue))
storage = .blob(Data(bytes: bytes, count: count)) // copy bytes
} else {
storage = .blob(Data())
Expand All @@ -160,18 +160,18 @@ public struct DatabaseValue: Hashable {

/// Creates a `DatabaseValue` initialized from a raw SQLite statement pointer.
public init(sqliteStatement: SQLiteStatement, index: CInt) {
switch sqlite3_column_type(sqliteStatement, index) {
switch SQLite3.sqlite3_column_type(sqliteStatement, index) {
case SQLITE_NULL:
storage = .null
case SQLITE_INTEGER:
storage = .int64(sqlite3_column_int64(sqliteStatement, index))
storage = .int64(SQLite3.sqlite3_column_int64(sqliteStatement, index))
case SQLITE_FLOAT:
storage = .double(sqlite3_column_double(sqliteStatement, index))
storage = .double(SQLite3.sqlite3_column_double(sqliteStatement, index))
case SQLITE_TEXT:
storage = .string(String(cString: sqlite3_column_text(sqliteStatement, index)))
storage = .string(String(cString: SQLite3.sqlite3_column_text(sqliteStatement, index)))
case SQLITE_BLOB:
if let bytes = sqlite3_column_blob(sqliteStatement, index) {
let count = Int(sqlite3_column_bytes(sqliteStatement, index))
if let bytes = SQLite3.sqlite3_column_blob(sqliteStatement, index) {
let count = Int(SQLite3.sqlite3_column_bytes(sqliteStatement, index))
storage = .blob(Data(bytes: bytes, count: count)) // copy bytes
} else {
storage = .blob(Data())
Expand Down
16 changes: 8 additions & 8 deletions GRDB/Core/Row.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public final class Row {
self.statement = statement
self.sqliteStatement = statement.sqliteStatement
self.impl = StatementRowImpl(sqliteStatement: statement.sqliteStatement, statement: statement)
self.count = Int(sqlite3_column_count(sqliteStatement))
self.count = Int(SQLite3.sqlite3_column_count(sqliteStatement))
}

/// Creates a row that maps an SQLite statement. Further calls to
Expand All @@ -230,7 +230,7 @@ public final class Row {
self.statement = nil
self.sqliteStatement = sqliteStatement
self.impl = SQLiteStatementRowImpl(sqliteStatement: sqliteStatement)
self.count = Int(sqlite3_column_count(sqliteStatement))
self.count = Int(SQLite3.sqlite3_column_count(sqliteStatement))
}

/// Creates a row that contain a copy of the current state of the
Expand Down Expand Up @@ -2474,14 +2474,14 @@ extension ArrayRowImpl: Sendable { }

// TODO: merge with ArrayRowImpl eventually?
/// See Row.init(copiedFromStatementRef:sqliteStatement:)
private struct StatementCopyRowImpl: RowImpl {
/* SQLInterface FIXME: should be private*/ struct StatementCopyRowImpl: RowImpl {
let dbValues: ContiguousArray<DatabaseValue>
let columnNames: [String]

init(sqliteStatement: SQLiteStatement, columnNames: [String]) {
let sqliteStatement = sqliteStatement
self.dbValues = ContiguousArray(
(0..<sqlite3_column_count(sqliteStatement))
(0..<SQLite3.sqlite3_column_count(sqliteStatement))
.map { DatabaseValue(sqliteStatement: sqliteStatement, index: $0) }
as [DatabaseValue])
self.columnNames = columnNames
Expand Down Expand Up @@ -2510,7 +2510,7 @@ private struct StatementCopyRowImpl: RowImpl {
}

/// See Row.init(statement:)
private struct StatementRowImpl: RowImpl {
/* SQLInterface FIXME: should be private*/ struct StatementRowImpl: RowImpl {
let statement: Statement
let sqliteStatement: SQLiteStatement
let lowercaseColumnIndexes: [String: Int]
Expand All @@ -2519,8 +2519,8 @@ private struct StatementRowImpl: RowImpl {
self.statement = statement
self.sqliteStatement = sqliteStatement
// Optimize row[columnName]
let lowercaseColumnNames = (0..<sqlite3_column_count(sqliteStatement))
.map { String(cString: sqlite3_column_name(sqliteStatement, CInt($0))).lowercased() }
let lowercaseColumnNames = (0..<SQLite3.sqlite3_column_count(sqliteStatement))
.map { String(cString: SQLite3.sqlite3_column_name(sqliteStatement, CInt($0))).lowercased() }
self.lowercaseColumnIndexes = Dictionary(
lowercaseColumnNames
.enumerated()
Expand Down Expand Up @@ -2584,7 +2584,7 @@ private struct StatementRowImpl: RowImpl {
}

// This one is not optimized at all, since it is only used in fatal conversion errors, so far
private struct SQLiteStatementRowImpl: RowImpl {
/* SQLInterface FIXME: should be private*/ struct SQLiteStatementRowImpl: RowImpl {
let sqliteStatement: SQLiteStatement
var count: Int { Int(sqlite3_column_count(sqliteStatement)) }
var isFetched: Bool { true }
Expand Down
2 changes: 1 addition & 1 deletion GRDB/Core/RowDecodingError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ struct RowDecodingContext {
} else if let sqliteStatement = row.sqliteStatement {
self.key = key
self.row = row.copy()
self.sql = String(cString: sqlite3_sql(sqliteStatement)).trimmedSQLStatement
self.sql = String(cString: SQLite3.sqlite3_sql(sqliteStatement)).trimmedSQLStatement
self.statementArguments = nil // Can't rebuild them
} else {
self.key = key
Expand Down
2 changes: 1 addition & 1 deletion GRDB/Core/Statement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public final class Statement {
authorizer.reset()

var sqliteStatement: SQLiteStatement? = nil
let code = sqlite3_prepare_v3(
let code = SQLite3.sqlite3_prepare_v3(
database.sqliteConnection, statementStart, -1, prepFlags,
&sqliteStatement, statementEnd)

Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/Support/Foundation/Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import Foundation
/// Data is convertible to and from DatabaseValue.
extension Data: DatabaseValueConvertible, StatementColumnConvertible {
public init(sqliteStatement: SQLiteStatement, index: CInt) {
if let bytes = sqlite3_column_blob(sqliteStatement, index) {
let count = Int(sqlite3_column_bytes(sqliteStatement, index))
if let bytes = SQLite3.sqlite3_column_blob(sqliteStatement, index) {
let count = Int(SQLite3.sqlite3_column_bytes(sqliteStatement, index))
self.init(bytes: bytes, count: count) // copy bytes
} else {
self.init()
Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/Support/Foundation/DatabaseDateComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ extension DatabaseDateComponents: StatementColumnConvertible {
@inline(__always)
@inlinable
public init?(sqliteStatement: SQLiteStatement, index: CInt) {
guard let cString = sqlite3_column_text(sqliteStatement, index) else {
guard let cString = SQLite3.sqlite3_column_text(sqliteStatement, index) else {
return nil
}
let length = Int(sqlite3_column_bytes(sqliteStatement, index)) // avoid an strlen
let length = Int(SQLite3.sqlite3_column_bytes(sqliteStatement, index)) // avoid an strlen
let components = cString.withMemoryRebound(
to: CChar.self,
capacity: length + 1 /* trailing \0 */) { cString in
Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/Support/Foundation/Date.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ extension Date: StatementColumnConvertible {
@inline(__always)
@inlinable
public init?(sqliteStatement: SQLiteStatement, index: CInt) {
switch sqlite3_column_type(sqliteStatement, index) {
switch SQLite3.sqlite3_column_type(sqliteStatement, index) {
case SQLITE_INTEGER, SQLITE_FLOAT:
self.init(timeIntervalSince1970: sqlite3_column_double(sqliteStatement, index))
self.init(timeIntervalSince1970: SQLite3.sqlite3_column_double(sqliteStatement, index))
case SQLITE_TEXT:
guard let components = DatabaseDateComponents(sqliteStatement: sqliteStatement, index: index),
let date = Date(databaseDateComponents: components)
Expand Down
8 changes: 4 additions & 4 deletions GRDB/Core/Support/Foundation/Decimal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ extension Decimal: StatementColumnConvertible {
@inline(__always)
@inlinable
public init?(sqliteStatement: SQLiteStatement, index: CInt) {
switch sqlite3_column_type(sqliteStatement, index) {
switch SQLite3.sqlite3_column_type(sqliteStatement, index) {
case SQLITE_INTEGER:
self.init(sqlite3_column_int64(sqliteStatement, index))
self.init(SQLite3.sqlite3_column_int64(sqliteStatement, index))
case SQLITE_FLOAT:
self.init(sqlite3_column_double(sqliteStatement, index))
self.init(SQLite3.sqlite3_column_double(sqliteStatement, index))
case SQLITE_TEXT:
self.init(
string: String(cString: sqlite3_column_text(sqliteStatement, index)!),
string: String(cString: SQLite3.sqlite3_column_text(sqliteStatement, index)!),
locale: _posixLocale)
default:
return nil
Expand Down
8 changes: 4 additions & 4 deletions GRDB/Core/Support/Foundation/UUID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ extension UUID: StatementColumnConvertible {
@inline(__always)
@inlinable
public init?(sqliteStatement: SQLiteStatement, index: CInt) {
switch sqlite3_column_type(sqliteStatement, index) {
switch SQLite3.sqlite3_column_type(sqliteStatement, index) {
case SQLITE_TEXT:
let string = String(cString: sqlite3_column_text(sqliteStatement, index)!)
let string = String(cString: SQLite3.sqlite3_column_text(sqliteStatement, index)!)
guard let uuid = UUID(uuidString: string) else {
return nil
}
self.init(uuid: uuid.uuid)
case SQLITE_BLOB:
guard sqlite3_column_bytes(sqliteStatement, index) == 16,
let blob = sqlite3_column_blob(sqliteStatement, index) else
guard SQLite3.sqlite3_column_bytes(sqliteStatement, index) == 16,
let blob = SQLite3.sqlite3_column_blob(sqliteStatement, index) else
{
return nil
}
Expand Down
Loading