From ee691539d80465977bcf56e7717417e16050f7d3 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Tue, 9 Sep 2025 18:02:14 -0400 Subject: [PATCH 1/2] Attempt to dynamically load sqlite symbols from the current process in Android --- Package.swift | 1 + Sources/SkipSQL/SQLContext.swift | 4 +- Sources/SkipSQL/SQLite.swift | 5 +- Sources/SkipSQL/SQLiteCLibrary.swift | 470 +++++++++++++++--- .../SQLContextTestConfiguration.swift | 3 - 5 files changed, 420 insertions(+), 63 deletions(-) diff --git a/Package.swift b/Package.swift index 8addf95..763b74a 100644 --- a/Package.swift +++ b/Package.swift @@ -75,6 +75,7 @@ let package = Package( .define("SQLCIPHER_CRYPTO_LIBTOMCRYPT"), //.unsafeFlags(["-Wno-shorten-64-to-32", "-Wno-ambiguous-macro"]), // enabled manually in libs ], + linkerSettings: [.linkedLibrary("log", .when(platforms: [.android]))], plugins: [.plugin(name: "skipstone", package: "skip")]), ] ) diff --git a/Sources/SkipSQL/SQLContext.swift b/Sources/SkipSQL/SQLContext.swift index 844394f..250ef2e 100644 --- a/Sources/SkipSQL/SQLContext.swift +++ b/Sources/SkipSQL/SQLContext.swift @@ -72,7 +72,9 @@ public class SQLContext { if let flags = flags { return library.sqlite3_open_v2(path, ptr, flags.rawValue, nil) } else { - return library.sqlite3_open(path, ptr) + let flags: OpenFlags = [OpenFlags.create, OpenFlags.readWrite] + return library.sqlite3_open_v2(path, ptr, flags.rawValue, nil) + //return library.sqlite3_open(path, ptr) } }) diff --git a/Sources/SkipSQL/SQLite.swift b/Sources/SkipSQL/SQLite.swift index 52a477f..df8908e 100644 --- a/Sources/SkipSQL/SQLite.swift +++ b/Sources/SkipSQL/SQLite.swift @@ -30,8 +30,9 @@ public struct SQLiteConfiguration { #elseif canImport(SQLite3) SQLiteConfiguration(library: SQLiteCLibrary.shared) #else - // on Android you need to use SQLPlus - fatalError("no platform SQLiteCLibrary available; use SkipSQLPlus instead") + SQLiteConfiguration(library: SQLiteCLibrary.shared) +// // on Android you need to use SQLPlus +// fatalError("no platform SQLiteCLibrary available; use SkipSQLPlus instead") #endif }() } diff --git a/Sources/SkipSQL/SQLiteCLibrary.swift b/Sources/SkipSQL/SQLiteCLibrary.swift index a1aac3c..e8392f9 100644 --- a/Sources/SkipSQL/SQLiteCLibrary.swift +++ b/Sources/SkipSQL/SQLiteCLibrary.swift @@ -1,8 +1,18 @@ // Copyright 2023–2025 Skip // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception #if !SKIP + +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Android) +import Android +#endif + #if canImport(SQLite3) import SQLite3 +#endif /// The vendored SQLite3 library on Darwin platforms. /// The version of this library will vary between OS version, so some features (e.g., JSON support) might not be available. @@ -13,228 +23,574 @@ final class SQLiteCLibrary : SQLiteLibrary { } func sqlite3_sleep(_ duration: Int32) -> Int32 { - SQLite3.sqlite3_sleep(duration) + let sqlite3_sleep: (Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_sleep = SQLite3.sqlite3_sleep + #else + sqlite3_sleep = loadFunction("sqlite3_sleep") + #endif + return sqlite3_sleep(duration) } func sqlite3_open(_ filename: String, _ ppDb: sqlite3_openarg?) -> Int32 { - SQLite3.sqlite3_open(filename, ppDb) + let sqlite3_open: (UnsafePointer?, UnsafeMutablePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_open = SQLite3.sqlite3_open + #else + sqlite3_open = loadFunction("sqlite3_open") + #endif + return sqlite3_open(filename, ppDb) } func sqlite3_open_v2(_ filename: String, _ ppDb: sqlite3_openarg?, _ flags: Int32, _ vfs: String?) -> Int32 { - SQLite3.sqlite3_open_v2(filename, ppDb, flags, vfs) + let sqlite3_open_v2: (UnsafePointer?, UnsafeMutablePointer?, Int32, UnsafePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_open_v2 = SQLite3.sqlite3_open_v2 + #else + sqlite3_open_v2 = loadFunction("sqlite3_open_v2") + #endif + return sqlite3_open_v2(filename, ppDb, flags, vfs) } func sqlite3_close(_ db: OpaquePointer) -> Int32 { - SQLite3.sqlite3_close(db) + let sqlite3_close: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_close = SQLite3.sqlite3_close + #else + sqlite3_close = loadFunction("sqlite3_close") + #endif + return sqlite3_close(db) } func sqlite3_errcode(_ db: OpaquePointer) -> Int32 { - SQLite3.sqlite3_errcode(db) + let sqlite3_errcode: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_errcode = SQLite3.sqlite3_errcode + #else + sqlite3_errcode = loadFunction("sqlite3_errcode") + #endif + return sqlite3_errcode(db) } func sqlite3_errmsg(_ db: OpaquePointer) -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_errmsg(db) + let sqlite3_errmsg: (OpaquePointer?) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_errmsg = SQLite3.sqlite3_errmsg + #else + sqlite3_errmsg = loadFunction("sqlite3_errmsg") + #endif + return sqlite3_errmsg(db) } func sqlite3_last_insert_rowid(_ db: OpaquePointer) -> Int64 { - SQLite3.sqlite3_last_insert_rowid(db) + let sqlite3_last_insert_rowid: (OpaquePointer?) -> sqlite3_int64 + #if canImport(SQLite3) + sqlite3_last_insert_rowid = SQLite3.sqlite3_last_insert_rowid + #else + sqlite3_last_insert_rowid = loadFunction("sqlite3_last_insert_rowid") + #endif + return sqlite3_last_insert_rowid(db) } func sqlite3_total_changes(_ db: OpaquePointer) -> Int32 { - SQLite3.sqlite3_total_changes(db) + let sqlite3_total_changes: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_total_changes = SQLite3.sqlite3_total_changes + #else + sqlite3_total_changes = loadFunction("sqlite3_total_changes") + #endif + return sqlite3_total_changes(db) } func sqlite3_changes(_ db: OpaquePointer) -> Int32 { - SQLite3.sqlite3_changes(db) + let sqlite3_changes: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_changes = SQLite3.sqlite3_changes + #else + sqlite3_changes = loadFunction("sqlite3_changes") + #endif + return sqlite3_changes(db) } func sqlite3_interrupt(_ db: OpaquePointer) { - SQLite3.sqlite3_interrupt(db) + let sqlite3_interrupt: (OpaquePointer?) -> Void + #if canImport(SQLite3) + sqlite3_interrupt = SQLite3.sqlite3_interrupt + #else + sqlite3_interrupt = loadFunction("sqlite3_interrupt") + #endif + return sqlite3_interrupt(db) } func sqlite3_exec(_ db: OpaquePointer, _ sql: String, _ callback: sqlite3_callback?, _ pArg: UnsafeMutableRawPointer?, _ errmsg: sqlite_error_ptr?) -> Int32 { - SQLite3.sqlite3_exec(db, sql, callback, pArg, errmsg) + let sqlite3_exec: (OpaquePointer?, UnsafePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafeMutablePointer?>?, UnsafeMutablePointer?>?) -> Int32)?, UnsafeMutableRawPointer?, UnsafeMutablePointer?>?) -> Int32 + #if canImport(SQLite3) + sqlite3_exec = SQLite3.sqlite3_exec + #else + sqlite3_exec = loadFunction("sqlite3_exec") + #endif + return sqlite3_exec(db, sql, callback, pArg, errmsg) } func sqlite3_prepare_v2(_ db: OpaquePointer, _ sql: String, _ nBytes: Int32, _ ppStmt: sqlite3_openarg, _ tail: UnsafeMutablePointer?>?) -> Int32 { - SQLite3.sqlite3_prepare_v2(db, sql, nBytes, ppStmt, tail) + let sqlite3_prepare_v2: (OpaquePointer?, UnsafePointer?, Int32, UnsafeMutablePointer?, UnsafeMutablePointer?>?) -> Int32 + #if canImport(SQLite3) + sqlite3_prepare_v2 = SQLite3.sqlite3_prepare_v2 + #else + sqlite3_prepare_v2 = loadFunction("sqlite3_prepare_v2") + #endif + return sqlite3_prepare_v2(db, sql, nBytes, ppStmt, tail) } func sqlite3_step(_ stmt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_step(stmt) + let sqlite3_step: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_step = SQLite3.sqlite3_step + #else + sqlite3_step = loadFunction("sqlite3_step") + #endif + return sqlite3_step(stmt) } func sqlite3_finalize(_ stmt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_finalize(stmt) + let sqlite3_finalize: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_finalize = SQLite3.sqlite3_finalize + #else + sqlite3_finalize = loadFunction("sqlite3_finalize") + #endif + return sqlite3_finalize(stmt) } func sqlite3_reset(_ stmt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_reset(stmt) + let sqlite3_reset: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_reset = SQLite3.sqlite3_reset + #else + sqlite3_reset = loadFunction("sqlite3_reset") + #endif + return sqlite3_reset(stmt) } func sqlite3_column_count(_ stmt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_column_count(stmt) + let sqlite3_column_count: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_column_count = SQLite3.sqlite3_column_count + #else + sqlite3_column_count = loadFunction("sqlite3_column_count") + #endif + return sqlite3_column_count(stmt) } func sqlite3_bind_parameter_count(_ stmnt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_bind_parameter_count(stmnt) + let sqlite3_bind_parameter_count: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_parameter_count = SQLite3.sqlite3_bind_parameter_count + #else + sqlite3_bind_parameter_count = loadFunction("sqlite3_bind_parameter_count") + #endif + return sqlite3_bind_parameter_count(stmnt) } func sqlite3_bind_parameter_name(_ stmnt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_bind_parameter_name(stmnt, columnIndex) + let sqlite3_bind_parameter_name: (OpaquePointer?, Int32) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_bind_parameter_name = SQLite3.sqlite3_bind_parameter_name + #else + sqlite3_bind_parameter_name = loadFunction("sqlite3_bind_parameter_name") + #endif + return sqlite3_bind_parameter_name(stmnt, columnIndex) } func sqlite3_bind_parameter_index(_ stmnt: OpaquePointer, _ name: String) -> Int32 { - SQLite3.sqlite3_bind_parameter_index(stmnt, name) + let sqlite3_bind_parameter_index: (OpaquePointer?, UnsafePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_parameter_index = SQLite3.sqlite3_bind_parameter_index + #else + sqlite3_bind_parameter_index = loadFunction("sqlite3_bind_parameter_index") + #endif + return sqlite3_bind_parameter_index(stmnt, name) } func sqlite3_clear_bindings(_ stmnt: OpaquePointer) -> Int32 { - SQLite3.sqlite3_clear_bindings(stmnt) + let sqlite3_clear_bindings: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_clear_bindings = SQLite3.sqlite3_clear_bindings + #else + sqlite3_clear_bindings = loadFunction("sqlite3_clear_bindings") + #endif + return sqlite3_clear_bindings(stmnt) } func sqlite3_column_name(_ stmt: OpaquePointer!, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_column_name(stmt!, columnIndex) + let sqlite3_column_name: (OpaquePointer?, Int32) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_column_name = SQLite3.sqlite3_column_name + #else + sqlite3_column_name = loadFunction("sqlite3_column_name") + #endif + return sqlite3_column_name(stmt!, columnIndex) } func sqlite3_column_decltype(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_column_decltype(stmt, columnIndex) + let sqlite3_column_decltype: (OpaquePointer?, Int32) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_column_decltype = SQLite3.sqlite3_column_decltype + #else + sqlite3_column_decltype = loadFunction("sqlite3_column_decltype") + #endif + return sqlite3_column_decltype(stmt, columnIndex) } func sqlite3_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_sql(stmt) + let sqlite3_sql: (OpaquePointer?) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_sql = SQLite3.sqlite3_sql + #else + sqlite3_sql = loadFunction("sqlite3_sql") + #endif + return sqlite3_sql(stmt) } func sqlite3_expanded_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_mutptr? { - SQLite3.sqlite3_expanded_sql(stmt) + let sqlite3_expanded_sql: (OpaquePointer?) -> UnsafeMutablePointer? + #if canImport(SQLite3) + sqlite3_expanded_sql = SQLite3.sqlite3_expanded_sql + #else + sqlite3_expanded_sql = loadFunction("sqlite3_expanded_sql") + #endif + return sqlite3_expanded_sql(stmt) } func sqlite3_db_handle(_ stmt: OpaquePointer) -> OpaquePointer { - SQLite3.sqlite3_db_handle(stmt) + let sqlite3_db_handle: (OpaquePointer?) -> OpaquePointer? + #if canImport(SQLite3) + sqlite3_db_handle = SQLite3.sqlite3_db_handle + #else + sqlite3_db_handle = loadFunction("sqlite3_db_handle") + #endif + return sqlite3_db_handle(stmt)! } func sqlite3_bind_null(_ stmt: OpaquePointer, _ paramIndex: Int32) -> Int32 { - SQLite3.sqlite3_bind_null(stmt, paramIndex) + let sqlite3_bind_null: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_null = SQLite3.sqlite3_bind_null + #else + sqlite3_bind_null = loadFunction("sqlite3_bind_null") + #endif + return sqlite3_bind_null(stmt, paramIndex) } func sqlite3_bind_int(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int32) -> Int32 { - SQLite3.sqlite3_bind_int(stmt, paramIndex, value) + let sqlite3_bind_int: (OpaquePointer?, Int32, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_int = SQLite3.sqlite3_bind_int + #else + sqlite3_bind_int = loadFunction("sqlite3_bind_int") + #endif + return sqlite3_bind_int(stmt, paramIndex, value) } func sqlite3_bind_int64(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int64) -> Int32 { - SQLite3.sqlite3_bind_int64(stmt, paramIndex, value) + let sqlite3_bind_int64: (OpaquePointer?, Int32, sqlite3_int64) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_int64 = SQLite3.sqlite3_bind_int64 + #else + sqlite3_bind_int64 = loadFunction("sqlite3_bind_int64") + #endif + return sqlite3_bind_int64(stmt, paramIndex, value) } func sqlite3_bind_double(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Double) -> Int32 { - SQLite3.sqlite3_bind_double(stmt, paramIndex, value) + let sqlite3_bind_double: (OpaquePointer?, Int32, Double) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_double = SQLite3.sqlite3_bind_double + #else + sqlite3_bind_double = loadFunction("sqlite3_bind_double") + #endif + return sqlite3_bind_double(stmt, paramIndex, value) } func sqlite3_bind_text(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: String, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { - SQLite3.sqlite3_bind_text(stmt, paramIndex, value, length, destructor) + let sqlite3_bind_text: (OpaquePointer?, Int32, UnsafePointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_text = SQLite3.sqlite3_bind_text + #else + sqlite3_bind_text = loadFunction("sqlite3_bind_text") + #endif + return sqlite3_bind_text(stmt, paramIndex, value, length, destructor) } func sqlite3_bind_blob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: UnsafeRawPointer?, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { - SQLite3.sqlite3_bind_blob(stmt, paramIndex, value, length, destructor) + let sqlite3_bind_blob: (OpaquePointer?, Int32, UnsafeRawPointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_blob = SQLite3.sqlite3_bind_blob + #else + sqlite3_bind_blob = loadFunction("sqlite3_bind_blob") + #endif + return sqlite3_bind_blob(stmt, paramIndex, value, length, destructor) } func sqlite3_bind_zeroblob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ length: Int32) -> Int32 { - SQLite3.sqlite3_bind_zeroblob(stmt, paramIndex, length) + let sqlite3_bind_zeroblob: (OpaquePointer?, Int32, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_bind_zeroblob = SQLite3.sqlite3_bind_zeroblob + #else + sqlite3_bind_zeroblob = loadFunction("sqlite3_bind_zeroblob") + #endif + return sqlite3_bind_zeroblob(stmt, paramIndex, length) } func sqlite3_column_type(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - SQLite3.sqlite3_column_type(stmt, columnIndex) + let sqlite3_column_type: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_column_type = SQLite3.sqlite3_column_type + #else + sqlite3_column_type = loadFunction("sqlite3_column_type") + #endif + return sqlite3_column_type(stmt, columnIndex) } func sqlite3_column_int(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - SQLite3.sqlite3_column_int(stmt, columnIndex) + let sqlite3_column_int: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_column_int = SQLite3.sqlite3_column_int + #else + sqlite3_column_int = loadFunction("sqlite3_column_int") + #endif + return sqlite3_column_int(stmt, columnIndex) } func sqlite3_column_int64(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int64 { - SQLite3.sqlite3_column_int64(stmt, columnIndex) + let sqlite3_column_int64: (OpaquePointer?, Int32) -> sqlite3_int64 + #if canImport(SQLite3) + sqlite3_column_int64 = SQLite3.sqlite3_column_int64 + #else + sqlite3_column_int64 = loadFunction("sqlite3_column_int64") + #endif + return sqlite3_column_int64(stmt, columnIndex) } func sqlite3_column_double(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Double { - SQLite3.sqlite3_column_double(stmt, columnIndex) + let sqlite3_column_double: (OpaquePointer?, Int32) -> Double + #if canImport(SQLite3) + sqlite3_column_double = SQLite3.sqlite3_column_double + #else + sqlite3_column_double = loadFunction("sqlite3_column_double") + #endif + return sqlite3_column_double(stmt, columnIndex) } func sqlite3_column_text(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_uint8_ptr? { - SQLite3.sqlite3_column_text(stmt, columnIndex) + let sqlite3_column_text: (OpaquePointer?, Int32) -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_column_text = SQLite3.sqlite3_column_text + #else + sqlite3_column_text = loadFunction("sqlite3_column_text") + #endif + return sqlite3_column_text(stmt, columnIndex) } func sqlite3_column_blob(_ stmt: OpaquePointer, _ columnIndex: Int32) -> UnsafeRawPointer? { - SQLite3.sqlite3_column_blob(stmt, columnIndex) + let sqlite3_column_blob: (OpaquePointer?, Int32) -> UnsafeRawPointer? + #if canImport(SQLite3) + sqlite3_column_blob = SQLite3.sqlite3_column_blob + #else + sqlite3_column_blob = loadFunction("sqlite3_column_blob") + #endif + return sqlite3_column_blob(stmt, columnIndex) } func sqlite3_column_bytes(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - SQLite3.sqlite3_column_bytes(stmt, columnIndex) + let sqlite3_column_bytes: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_column_bytes = SQLite3.sqlite3_column_bytes + #else + sqlite3_column_bytes = loadFunction("sqlite3_column_bytes") + #endif + return sqlite3_column_bytes(stmt, columnIndex) } func sqlite3_backup_init(_ destDb: OpaquePointer, _ destName: String, _ sourceDb: OpaquePointer?, _ sourceName: String) -> OpaquePointer { - SQLite3.sqlite3_backup_init(destDb, destName, sourceDb, sourceName) + let sqlite3_backup_init: (OpaquePointer?, UnsafePointer?, OpaquePointer?, UnsafePointer?) -> OpaquePointer? + #if canImport(SQLite3) + sqlite3_backup_init = SQLite3.sqlite3_backup_init + #else + sqlite3_backup_init = loadFunction("sqlite3_backup_init") + #endif + return sqlite3_backup_init(destDb, destName, sourceDb, sourceName)! } func sqlite3_backup_step(_ backup: OpaquePointer, _ pages: Int32) -> Int32 { - SQLite3.sqlite3_backup_step(backup, pages) + let sqlite3_backup_step: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_backup_step = SQLite3.sqlite3_backup_step + #else + sqlite3_backup_step = loadFunction("sqlite3_backup_step") + #endif + return sqlite3_backup_step(backup, pages) } func sqlite3_backup_finish(_ backup: OpaquePointer) -> Int32 { - SQLite3.sqlite3_backup_finish(backup) + let sqlite3_backup_finish: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_backup_finish = SQLite3.sqlite3_backup_finish + #else + sqlite3_backup_finish = loadFunction("sqlite3_backup_finish") + #endif + return sqlite3_backup_finish(backup) } func sqlite3_backup_remaining(_ backup: OpaquePointer) -> Int32 { - SQLite3.sqlite3_backup_remaining(backup) + let sqlite3_backup_remaining: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_backup_remaining = SQLite3.sqlite3_backup_remaining + #else + sqlite3_backup_remaining = loadFunction("sqlite3_backup_remaining") + #endif + return sqlite3_backup_remaining(backup) } func sqlite3_backup_pagecount(_ backup: OpaquePointer) -> Int32 { - SQLite3.sqlite3_backup_pagecount(backup) + let sqlite3_backup_pagecount: (OpaquePointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_backup_pagecount = SQLite3.sqlite3_backup_pagecount + #else + sqlite3_backup_pagecount = loadFunction("sqlite3_backup_pagecount") + #endif + return sqlite3_backup_pagecount(backup) } func sqlite3_initialize() -> Int32 { - SQLite3.sqlite3_initialize() + let sqlite3_initialize: () -> Int32 + #if canImport(SQLite3) + sqlite3_initialize = SQLite3.sqlite3_initialize + #else + sqlite3_initialize = loadFunction("sqlite3_initialize") + #endif + return sqlite3_initialize() } func sqlite3_shutdown() -> Int32 { - SQLite3.sqlite3_shutdown() + let sqlite3_shutdown: () -> Int32 + #if canImport(SQLite3) + sqlite3_shutdown = SQLite3.sqlite3_shutdown + #else + sqlite3_shutdown = loadFunction("sqlite3_shutdown") + #endif + return sqlite3_shutdown() } func sqlite3_libversion() -> sqlite3_cstring_ptr? { - SQLite3.sqlite3_libversion() + let sqlite3_libversion: () -> UnsafePointer? + #if canImport(SQLite3) + sqlite3_libversion = SQLite3.sqlite3_libversion + #else + sqlite3_libversion = loadFunction("sqlite3_libversion") + #endif + return sqlite3_libversion() } func sqlite3_libversion_number() -> Int32 { - SQLite3.sqlite3_libversion_number() + let sqlite3_libversion_number: () -> Int32 + #if canImport(SQLite3) + sqlite3_libversion_number = SQLite3.sqlite3_libversion_number + #else + sqlite3_libversion_number = loadFunction("sqlite3_libversion_number") + #endif + return sqlite3_libversion_number() } func sqlite3_extended_result_codes(_ db: OpaquePointer, _ on: Int32) -> Int32 { - SQLite3.sqlite3_extended_result_codes(db, on) + let sqlite3_extended_result_codes: (OpaquePointer?, Int32) -> Int32 + #if canImport(SQLite3) + sqlite3_extended_result_codes = SQLite3.sqlite3_extended_result_codes + #else + sqlite3_extended_result_codes = loadFunction("sqlite3_extended_result_codes") + #endif + return sqlite3_extended_result_codes(db, on) } func sqlite3_free(_ ptr: sqlite3_pointer_type) { - SQLite3.sqlite3_free(ptr) + let sqlite3_free: (UnsafeMutableRawPointer?) -> Void + #if canImport(SQLite3) + sqlite3_free = SQLite3.sqlite3_free + #else + sqlite3_free = loadFunction("sqlite3_free") + #endif + return sqlite3_free(ptr) } func sqlite3_db_mutex(_ db: OpaquePointer?) -> OpaquePointer? { - SQLite3.sqlite3_db_mutex(db) + let sqlite3_db_mutex: (OpaquePointer?) -> OpaquePointer? + #if canImport(SQLite3) + sqlite3_db_mutex = SQLite3.sqlite3_db_mutex + #else + sqlite3_db_mutex = loadFunction("sqlite3_db_mutex") + #endif + return sqlite3_db_mutex(db) } func sqlite3_mutex_free(_ lock: OpaquePointer?) { - SQLite3.sqlite3_mutex_free(lock) + let sqlite3_mutex_free: (OpaquePointer?) -> Void + #if canImport(SQLite3) + sqlite3_mutex_free = SQLite3.sqlite3_mutex_free + #else + sqlite3_mutex_free = loadFunction("sqlite3_mutex_free") + #endif + return sqlite3_mutex_free(lock) } func sqlite3_mutex_enter(_ lock: OpaquePointer?) { - SQLite3.sqlite3_mutex_enter(lock) + let sqlite3_mutex_enter: (OpaquePointer?) -> Void + #if canImport(SQLite3) + sqlite3_mutex_enter = SQLite3.sqlite3_mutex_enter + #else + sqlite3_mutex_enter = loadFunction("sqlite3_mutex_enter") + #endif + return sqlite3_mutex_enter(lock) } func sqlite3_mutex_leave(_ lock: OpaquePointer?) { - SQLite3.sqlite3_mutex_leave(lock) + let sqlite3_mutex_leave: (OpaquePointer?) -> Void + #if canImport(SQLite3) + sqlite3_mutex_leave = SQLite3.sqlite3_mutex_leave + #else + sqlite3_mutex_leave = loadFunction("sqlite3_mutex_leave") + #endif + return sqlite3_mutex_leave(lock) } func sqlite3_update_hook(_ db: OpaquePointer?, _ callback: sqlite3_update_hook?, _ pArg: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { - SQLite3.sqlite3_update_hook(db, callback, pArg) + let sqlite3_update_hook: (OpaquePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafePointer?, UnsafePointer?, sqlite3_int64) -> Void)?, UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? + #if canImport(SQLite3) + sqlite3_update_hook = SQLite3.sqlite3_update_hook + #else + sqlite3_update_hook = loadFunction("sqlite3_update_hook") + #endif + return sqlite3_update_hook(db, callback, pArg) } func sqlite3_trace_v2(_ db: OpaquePointer?, _ mask: sqlite3_unsigned, _ callback: sqlite3_trace_hook?, _ pCtx: UnsafeMutableRawPointer?) -> Int32 { - SQLite3.sqlite3_trace_v2(db, mask, callback, pCtx) + let sqlite3_trace_v2: (OpaquePointer?, UInt32, (@convention(c) (UInt32, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?) -> Int32)?, UnsafeMutableRawPointer?) -> Int32 + #if canImport(SQLite3) + sqlite3_trace_v2 = SQLite3.sqlite3_trace_v2 + #else + sqlite3_trace_v2 = loadFunction("sqlite3_trace_v2") + #endif + return sqlite3_trace_v2(db, mask, callback, pCtx) + } + + private func loadFunction(_ name: String) -> T { + //fatalError("### LOADING: \(name)") + //let handle = dlopen(nil, RTLD_NOW) + //let symbol = dlsym(handle, name) + let symbol = dlsym(RTLD_DEFAULT, name) + print("### LOADING: \(name): handle=\(handle) \(symbol)") + //fatalError("### LOADING: \(name): handle=\(handle) \(symbol)") + return unsafeBitCast(symbol, to: T.self) } } #endif -#endif + diff --git a/Tests/SkipSQLTests/SQLContextTestConfiguration.swift b/Tests/SkipSQLTests/SQLContextTestConfiguration.swift index 6bb1975..1c57104 100644 --- a/Tests/SkipSQLTests/SQLContextTestConfiguration.swift +++ b/Tests/SkipSQLTests/SQLContextTestConfiguration.swift @@ -9,9 +9,6 @@ extension SQLiteConfiguration { } func SQLContextTest(path: String? = nil, flags: SQLContext.OpenFlags? = nil) throws -> SQLContext { - #if !canImport(SQLite3) - throw XCTSkip("SQLite is not available on platform") - #endif if let path { return try SQLContext(path: path, flags: flags, configuration: .test) } else { From f1a083568b0e01358deebfbccaf9fa5b9ed691a4 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 10 Sep 2025 00:14:40 -0400 Subject: [PATCH 2/2] Cache dynamically-loaded functions --- Sources/SkipSQL/SQLiteCLibrary.swift | 692 ++++++++++++++++----------- 1 file changed, 405 insertions(+), 287 deletions(-) diff --git a/Sources/SkipSQL/SQLiteCLibrary.swift b/Sources/SkipSQL/SQLiteCLibrary.swift index e8392f9..9af380d 100644 --- a/Sources/SkipSQL/SQLiteCLibrary.swift +++ b/Sources/SkipSQL/SQLiteCLibrary.swift @@ -15,6 +15,7 @@ import SQLite3 #endif /// The vendored SQLite3 library on Darwin platforms. +/// /// The version of this library will vary between OS version, so some features (e.g., JSON support) might not be available. final class SQLiteCLibrary : SQLiteLibrary { static let shared = SQLiteCLibrary() @@ -22,575 +23,692 @@ final class SQLiteCLibrary : SQLiteLibrary { init() { } - func sqlite3_sleep(_ duration: Int32) -> Int32 { - let sqlite3_sleep: (Int32) -> Int32 + private static let _sqlite3_sleep: (Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_sleep = SQLite3.sqlite3_sleep + SQLite3.sqlite3_sleep #else - sqlite3_sleep = loadFunction("sqlite3_sleep") + loadFunction("sqlite3_sleep") #endif - return sqlite3_sleep(duration) + }() + + func sqlite3_sleep(_ duration: Int32) -> Int32 { + return Self._sqlite3_sleep(duration) } - func sqlite3_open(_ filename: String, _ ppDb: sqlite3_openarg?) -> Int32 { - let sqlite3_open: (UnsafePointer?, UnsafeMutablePointer?) -> Int32 + private static let _sqlite3_open: (UnsafePointer?, UnsafeMutablePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_open = SQLite3.sqlite3_open + SQLite3.sqlite3_open #else - sqlite3_open = loadFunction("sqlite3_open") + loadFunction("sqlite3_open") #endif - return sqlite3_open(filename, ppDb) + }() + + func sqlite3_open(_ filename: String, _ ppDb: sqlite3_openarg?) -> Int32 { + return Self._sqlite3_open(filename, ppDb) } - func sqlite3_open_v2(_ filename: String, _ ppDb: sqlite3_openarg?, _ flags: Int32, _ vfs: String?) -> Int32 { - let sqlite3_open_v2: (UnsafePointer?, UnsafeMutablePointer?, Int32, UnsafePointer?) -> Int32 + private static let _sqlite3_open_v2: (UnsafePointer?, UnsafeMutablePointer?, Int32, UnsafePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_open_v2 = SQLite3.sqlite3_open_v2 + SQLite3.sqlite3_open_v2 #else - sqlite3_open_v2 = loadFunction("sqlite3_open_v2") + loadFunction("sqlite3_open_v2") #endif - return sqlite3_open_v2(filename, ppDb, flags, vfs) + }() + + func sqlite3_open_v2(_ filename: String, _ ppDb: sqlite3_openarg?, _ flags: Int32, _ vfs: String?) -> Int32 { + return Self._sqlite3_open_v2(filename, ppDb, flags, vfs) } - func sqlite3_close(_ db: OpaquePointer) -> Int32 { - let sqlite3_close: (OpaquePointer?) -> Int32 + private static let _sqlite3_close: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_close = SQLite3.sqlite3_close + SQLite3.sqlite3_close #else - sqlite3_close = loadFunction("sqlite3_close") + loadFunction("sqlite3_close") #endif - return sqlite3_close(db) + }() + + func sqlite3_close(_ db: OpaquePointer) -> Int32 { + return Self._sqlite3_close(db) } - func sqlite3_errcode(_ db: OpaquePointer) -> Int32 { - let sqlite3_errcode: (OpaquePointer?) -> Int32 + private static let _sqlite3_errcode: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_errcode = SQLite3.sqlite3_errcode + SQLite3.sqlite3_errcode #else - sqlite3_errcode = loadFunction("sqlite3_errcode") + loadFunction("sqlite3_errcode") #endif - return sqlite3_errcode(db) + }() + + func sqlite3_errcode(_ db: OpaquePointer) -> Int32 { + return Self._sqlite3_errcode(db) } - func sqlite3_errmsg(_ db: OpaquePointer) -> sqlite3_cstring_ptr? { - let sqlite3_errmsg: (OpaquePointer?) -> UnsafePointer? + private static let _sqlite3_errmsg: (OpaquePointer?) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_errmsg = SQLite3.sqlite3_errmsg + SQLite3.sqlite3_errmsg #else - sqlite3_errmsg = loadFunction("sqlite3_errmsg") + loadFunction("sqlite3_errmsg") #endif - return sqlite3_errmsg(db) + }() + + func sqlite3_errmsg(_ db: OpaquePointer) -> sqlite3_cstring_ptr? { + return Self._sqlite3_errmsg(db) } - func sqlite3_last_insert_rowid(_ db: OpaquePointer) -> Int64 { - let sqlite3_last_insert_rowid: (OpaquePointer?) -> sqlite3_int64 + private static let _sqlite3_last_insert_rowid: (OpaquePointer?) -> sqlite3_int64 = { #if canImport(SQLite3) - sqlite3_last_insert_rowid = SQLite3.sqlite3_last_insert_rowid + SQLite3.sqlite3_last_insert_rowid #else - sqlite3_last_insert_rowid = loadFunction("sqlite3_last_insert_rowid") + loadFunction("sqlite3_last_insert_rowid") #endif - return sqlite3_last_insert_rowid(db) + }() + + func sqlite3_last_insert_rowid(_ db: OpaquePointer) -> Int64 { + return Self._sqlite3_last_insert_rowid(db) } - func sqlite3_total_changes(_ db: OpaquePointer) -> Int32 { - let sqlite3_total_changes: (OpaquePointer?) -> Int32 + private static let _sqlite3_total_changes: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_total_changes = SQLite3.sqlite3_total_changes + SQLite3.sqlite3_total_changes #else - sqlite3_total_changes = loadFunction("sqlite3_total_changes") + loadFunction("sqlite3_total_changes") #endif - return sqlite3_total_changes(db) + }() + + func sqlite3_total_changes(_ db: OpaquePointer) -> Int32 { + return Self._sqlite3_total_changes(db) } - func sqlite3_changes(_ db: OpaquePointer) -> Int32 { - let sqlite3_changes: (OpaquePointer?) -> Int32 + private static let _sqlite3_changes: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_changes = SQLite3.sqlite3_changes + SQLite3.sqlite3_changes #else - sqlite3_changes = loadFunction("sqlite3_changes") + loadFunction("sqlite3_changes") #endif - return sqlite3_changes(db) + }() + + func sqlite3_changes(_ db: OpaquePointer) -> Int32 { + return Self._sqlite3_changes(db) } - func sqlite3_interrupt(_ db: OpaquePointer) { - let sqlite3_interrupt: (OpaquePointer?) -> Void + private static let _sqlite3_interrupt: (OpaquePointer?) -> Void = { #if canImport(SQLite3) - sqlite3_interrupt = SQLite3.sqlite3_interrupt + SQLite3.sqlite3_interrupt #else - sqlite3_interrupt = loadFunction("sqlite3_interrupt") + loadFunction("sqlite3_interrupt") #endif - return sqlite3_interrupt(db) + }() + + func sqlite3_interrupt(_ db: OpaquePointer) { + return Self._sqlite3_interrupt(db) } - func sqlite3_exec(_ db: OpaquePointer, _ sql: String, _ callback: sqlite3_callback?, _ pArg: UnsafeMutableRawPointer?, _ errmsg: sqlite_error_ptr?) -> Int32 { - let sqlite3_exec: (OpaquePointer?, UnsafePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafeMutablePointer?>?, UnsafeMutablePointer?>?) -> Int32)?, UnsafeMutableRawPointer?, UnsafeMutablePointer?>?) -> Int32 + private static let _sqlite3_exec: (OpaquePointer?, UnsafePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafeMutablePointer?>?, UnsafeMutablePointer?>?) -> Int32)?, UnsafeMutableRawPointer?, UnsafeMutablePointer?>?) -> Int32 = { #if canImport(SQLite3) - sqlite3_exec = SQLite3.sqlite3_exec + SQLite3.sqlite3_exec #else - sqlite3_exec = loadFunction("sqlite3_exec") + loadFunction("sqlite3_exec") #endif - return sqlite3_exec(db, sql, callback, pArg, errmsg) + }() + + func sqlite3_exec(_ db: OpaquePointer, _ sql: String, _ callback: sqlite3_callback?, _ pArg: UnsafeMutableRawPointer?, _ errmsg: sqlite_error_ptr?) -> Int32 { + return Self._sqlite3_exec(db, sql, callback, pArg, errmsg) } - func sqlite3_prepare_v2(_ db: OpaquePointer, _ sql: String, _ nBytes: Int32, _ ppStmt: sqlite3_openarg, _ tail: UnsafeMutablePointer?>?) -> Int32 { - let sqlite3_prepare_v2: (OpaquePointer?, UnsafePointer?, Int32, UnsafeMutablePointer?, UnsafeMutablePointer?>?) -> Int32 + private static let _sqlite3_prepare_v2: (OpaquePointer?, UnsafePointer?, Int32, UnsafeMutablePointer?, UnsafeMutablePointer?>?) -> Int32 = { #if canImport(SQLite3) - sqlite3_prepare_v2 = SQLite3.sqlite3_prepare_v2 + SQLite3.sqlite3_prepare_v2 #else - sqlite3_prepare_v2 = loadFunction("sqlite3_prepare_v2") + loadFunction("sqlite3_prepare_v2") #endif - return sqlite3_prepare_v2(db, sql, nBytes, ppStmt, tail) + }() + + func sqlite3_prepare_v2(_ db: OpaquePointer, _ sql: String, _ nBytes: Int32, _ ppStmt: sqlite3_openarg, _ tail: UnsafeMutablePointer?>?) -> Int32 { + return Self._sqlite3_prepare_v2(db, sql, nBytes, ppStmt, tail) } - func sqlite3_step(_ stmt: OpaquePointer) -> Int32 { - let sqlite3_step: (OpaquePointer?) -> Int32 + private static let _sqlite3_step: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_step = SQLite3.sqlite3_step + SQLite3.sqlite3_step #else - sqlite3_step = loadFunction("sqlite3_step") + loadFunction("sqlite3_step") #endif - return sqlite3_step(stmt) + }() + + func sqlite3_step(_ stmt: OpaquePointer) -> Int32 { + return Self._sqlite3_step(stmt) } - func sqlite3_finalize(_ stmt: OpaquePointer) -> Int32 { - let sqlite3_finalize: (OpaquePointer?) -> Int32 + private static let _sqlite3_finalize: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_finalize = SQLite3.sqlite3_finalize + SQLite3.sqlite3_finalize #else - sqlite3_finalize = loadFunction("sqlite3_finalize") + loadFunction("sqlite3_finalize") #endif - return sqlite3_finalize(stmt) + }() + + func sqlite3_finalize(_ stmt: OpaquePointer) -> Int32 { + return Self._sqlite3_finalize(stmt) } - func sqlite3_reset(_ stmt: OpaquePointer) -> Int32 { - let sqlite3_reset: (OpaquePointer?) -> Int32 + private static let _sqlite3_reset: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_reset = SQLite3.sqlite3_reset + SQLite3.sqlite3_reset #else - sqlite3_reset = loadFunction("sqlite3_reset") + loadFunction("sqlite3_reset") #endif - return sqlite3_reset(stmt) + }() + + func sqlite3_reset(_ stmt: OpaquePointer) -> Int32 { + return Self._sqlite3_reset(stmt) } - func sqlite3_column_count(_ stmt: OpaquePointer) -> Int32 { - let sqlite3_column_count: (OpaquePointer?) -> Int32 + private static let _sqlite3_column_count: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_column_count = SQLite3.sqlite3_column_count + SQLite3.sqlite3_column_count #else - sqlite3_column_count = loadFunction("sqlite3_column_count") + loadFunction("sqlite3_column_count") #endif - return sqlite3_column_count(stmt) + }() + + func sqlite3_column_count(_ stmt: OpaquePointer) -> Int32 { + return Self._sqlite3_column_count(stmt) } - func sqlite3_bind_parameter_count(_ stmnt: OpaquePointer) -> Int32 { - let sqlite3_bind_parameter_count: (OpaquePointer?) -> Int32 + private static let _sqlite3_bind_parameter_count: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_parameter_count = SQLite3.sqlite3_bind_parameter_count + SQLite3.sqlite3_bind_parameter_count #else - sqlite3_bind_parameter_count = loadFunction("sqlite3_bind_parameter_count") + loadFunction("sqlite3_bind_parameter_count") #endif - return sqlite3_bind_parameter_count(stmnt) + }() + + func sqlite3_bind_parameter_count(_ stmnt: OpaquePointer) -> Int32 { + return Self._sqlite3_bind_parameter_count(stmnt) } - func sqlite3_bind_parameter_name(_ stmnt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - let sqlite3_bind_parameter_name: (OpaquePointer?, Int32) -> UnsafePointer? + private static let _sqlite3_bind_parameter_name: (OpaquePointer?, Int32) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_bind_parameter_name = SQLite3.sqlite3_bind_parameter_name + SQLite3.sqlite3_bind_parameter_name #else - sqlite3_bind_parameter_name = loadFunction("sqlite3_bind_parameter_name") + loadFunction("sqlite3_bind_parameter_name") #endif - return sqlite3_bind_parameter_name(stmnt, columnIndex) + }() + + func sqlite3_bind_parameter_name(_ stmnt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { + return Self._sqlite3_bind_parameter_name(stmnt, columnIndex) } - func sqlite3_bind_parameter_index(_ stmnt: OpaquePointer, _ name: String) -> Int32 { - let sqlite3_bind_parameter_index: (OpaquePointer?, UnsafePointer?) -> Int32 + private static let _sqlite3_bind_parameter_index: (OpaquePointer?, UnsafePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_parameter_index = SQLite3.sqlite3_bind_parameter_index + SQLite3.sqlite3_bind_parameter_index #else - sqlite3_bind_parameter_index = loadFunction("sqlite3_bind_parameter_index") + loadFunction("sqlite3_bind_parameter_index") #endif - return sqlite3_bind_parameter_index(stmnt, name) + }() + + func sqlite3_bind_parameter_index(_ stmnt: OpaquePointer, _ name: String) -> Int32 { + return Self._sqlite3_bind_parameter_index(stmnt, name) } - func sqlite3_clear_bindings(_ stmnt: OpaquePointer) -> Int32 { - let sqlite3_clear_bindings: (OpaquePointer?) -> Int32 + private static let _sqlite3_clear_bindings: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_clear_bindings = SQLite3.sqlite3_clear_bindings + SQLite3.sqlite3_clear_bindings #else - sqlite3_clear_bindings = loadFunction("sqlite3_clear_bindings") + loadFunction("sqlite3_clear_bindings") #endif - return sqlite3_clear_bindings(stmnt) + }() + + func sqlite3_clear_bindings(_ stmnt: OpaquePointer) -> Int32 { + return Self._sqlite3_clear_bindings(stmnt) } - func sqlite3_column_name(_ stmt: OpaquePointer!, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - let sqlite3_column_name: (OpaquePointer?, Int32) -> UnsafePointer? + private static let _sqlite3_column_name: (OpaquePointer?, Int32) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_column_name = SQLite3.sqlite3_column_name + SQLite3.sqlite3_column_name #else - sqlite3_column_name = loadFunction("sqlite3_column_name") + loadFunction("sqlite3_column_name") #endif - return sqlite3_column_name(stmt!, columnIndex) + }() + + func sqlite3_column_name(_ stmt: OpaquePointer!, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { + return Self._sqlite3_column_name(stmt!, columnIndex) } - func sqlite3_column_decltype(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { - let sqlite3_column_decltype: (OpaquePointer?, Int32) -> UnsafePointer? + private static let _sqlite3_column_decltype: (OpaquePointer?, Int32) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_column_decltype = SQLite3.sqlite3_column_decltype + SQLite3.sqlite3_column_decltype #else - sqlite3_column_decltype = loadFunction("sqlite3_column_decltype") + loadFunction("sqlite3_column_decltype") #endif - return sqlite3_column_decltype(stmt, columnIndex) + }() + + func sqlite3_column_decltype(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_cstring_ptr? { + return Self._sqlite3_column_decltype(stmt, columnIndex) } - func sqlite3_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_ptr? { - let sqlite3_sql: (OpaquePointer?) -> UnsafePointer? + private static let _sqlite3_sql: (OpaquePointer?) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_sql = SQLite3.sqlite3_sql + SQLite3.sqlite3_sql #else - sqlite3_sql = loadFunction("sqlite3_sql") + loadFunction("sqlite3_sql") #endif - return sqlite3_sql(stmt) + }() + + func sqlite3_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_ptr? { + return Self._sqlite3_sql(stmt) } - func sqlite3_expanded_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_mutptr? { - let sqlite3_expanded_sql: (OpaquePointer?) -> UnsafeMutablePointer? + private static let _sqlite3_expanded_sql: (OpaquePointer?) -> UnsafeMutablePointer? = { #if canImport(SQLite3) - sqlite3_expanded_sql = SQLite3.sqlite3_expanded_sql + SQLite3.sqlite3_expanded_sql #else - sqlite3_expanded_sql = loadFunction("sqlite3_expanded_sql") + loadFunction("sqlite3_expanded_sql") #endif - return sqlite3_expanded_sql(stmt) + }() + + func sqlite3_expanded_sql(_ stmt: OpaquePointer) -> sqlite3_cstring_mutptr? { + return Self._sqlite3_expanded_sql(stmt) } - func sqlite3_db_handle(_ stmt: OpaquePointer) -> OpaquePointer { - let sqlite3_db_handle: (OpaquePointer?) -> OpaquePointer? + private static let _sqlite3_db_handle: (OpaquePointer?) -> OpaquePointer? = { #if canImport(SQLite3) - sqlite3_db_handle = SQLite3.sqlite3_db_handle + SQLite3.sqlite3_db_handle #else - sqlite3_db_handle = loadFunction("sqlite3_db_handle") + loadFunction("sqlite3_db_handle") #endif - return sqlite3_db_handle(stmt)! + }() + + func sqlite3_db_handle(_ stmt: OpaquePointer) -> OpaquePointer { + return Self._sqlite3_db_handle(stmt)! } - func sqlite3_bind_null(_ stmt: OpaquePointer, _ paramIndex: Int32) -> Int32 { - let sqlite3_bind_null: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_bind_null: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_null = SQLite3.sqlite3_bind_null + SQLite3.sqlite3_bind_null #else - sqlite3_bind_null = loadFunction("sqlite3_bind_null") + loadFunction("sqlite3_bind_null") #endif - return sqlite3_bind_null(stmt, paramIndex) + }() + + func sqlite3_bind_null(_ stmt: OpaquePointer, _ paramIndex: Int32) -> Int32 { + return Self._sqlite3_bind_null(stmt, paramIndex) } - func sqlite3_bind_int(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int32) -> Int32 { - let sqlite3_bind_int: (OpaquePointer?, Int32, Int32) -> Int32 + private static let _sqlite3_bind_int: (OpaquePointer?, Int32, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_int = SQLite3.sqlite3_bind_int + SQLite3.sqlite3_bind_int #else - sqlite3_bind_int = loadFunction("sqlite3_bind_int") + loadFunction("sqlite3_bind_int") #endif - return sqlite3_bind_int(stmt, paramIndex, value) + }() + + func sqlite3_bind_int(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int32) -> Int32 { + return Self._sqlite3_bind_int(stmt, paramIndex, value) } - func sqlite3_bind_int64(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int64) -> Int32 { - let sqlite3_bind_int64: (OpaquePointer?, Int32, sqlite3_int64) -> Int32 + private static let _sqlite3_bind_int64: (OpaquePointer?, Int32, sqlite3_int64) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_int64 = SQLite3.sqlite3_bind_int64 + SQLite3.sqlite3_bind_int64 #else - sqlite3_bind_int64 = loadFunction("sqlite3_bind_int64") + loadFunction("sqlite3_bind_int64") #endif - return sqlite3_bind_int64(stmt, paramIndex, value) + }() + + func sqlite3_bind_int64(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Int64) -> Int32 { + return Self._sqlite3_bind_int64(stmt, paramIndex, value) } - func sqlite3_bind_double(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Double) -> Int32 { - let sqlite3_bind_double: (OpaquePointer?, Int32, Double) -> Int32 + private static let _sqlite3_bind_double: (OpaquePointer?, Int32, Double) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_double = SQLite3.sqlite3_bind_double + SQLite3.sqlite3_bind_double #else - sqlite3_bind_double = loadFunction("sqlite3_bind_double") + loadFunction("sqlite3_bind_double") #endif - return sqlite3_bind_double(stmt, paramIndex, value) + }() + + func sqlite3_bind_double(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: Double) -> Int32 { + return Self._sqlite3_bind_double(stmt, paramIndex, value) } - func sqlite3_bind_text(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: String, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { - let sqlite3_bind_text: (OpaquePointer?, Int32, UnsafePointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 + private static let _sqlite3_bind_text: (OpaquePointer?, Int32, UnsafePointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_text = SQLite3.sqlite3_bind_text + SQLite3.sqlite3_bind_text #else - sqlite3_bind_text = loadFunction("sqlite3_bind_text") + loadFunction("sqlite3_bind_text") #endif - return sqlite3_bind_text(stmt, paramIndex, value, length, destructor) + }() + + func sqlite3_bind_text(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: String, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { + return Self._sqlite3_bind_text(stmt, paramIndex, value, length, destructor) } - func sqlite3_bind_blob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: UnsafeRawPointer?, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { - let sqlite3_bind_blob: (OpaquePointer?, Int32, UnsafeRawPointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 + private static let _sqlite3_bind_blob: (OpaquePointer?, Int32, UnsafeRawPointer?, Int32, (@convention(c) (UnsafeMutableRawPointer?) -> Void)?) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_blob = SQLite3.sqlite3_bind_blob + SQLite3.sqlite3_bind_blob #else - sqlite3_bind_blob = loadFunction("sqlite3_bind_blob") + loadFunction("sqlite3_bind_blob") #endif - return sqlite3_bind_blob(stmt, paramIndex, value, length, destructor) + }() + + func sqlite3_bind_blob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ value: UnsafeRawPointer?, _ length: Int32, _ destructor: sqlite3_destructor_type) -> Int32 { + return Self._sqlite3_bind_blob(stmt, paramIndex, value, length, destructor) } - func sqlite3_bind_zeroblob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ length: Int32) -> Int32 { - let sqlite3_bind_zeroblob: (OpaquePointer?, Int32, Int32) -> Int32 + private static let _sqlite3_bind_zeroblob: (OpaquePointer?, Int32, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_bind_zeroblob = SQLite3.sqlite3_bind_zeroblob + SQLite3.sqlite3_bind_zeroblob #else - sqlite3_bind_zeroblob = loadFunction("sqlite3_bind_zeroblob") + loadFunction("sqlite3_bind_zeroblob") #endif - return sqlite3_bind_zeroblob(stmt, paramIndex, length) + }() + + func sqlite3_bind_zeroblob(_ stmt: OpaquePointer, _ paramIndex: Int32, _ length: Int32) -> Int32 { + return Self._sqlite3_bind_zeroblob(stmt, paramIndex, length) } - func sqlite3_column_type(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - let sqlite3_column_type: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_column_type: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_column_type = SQLite3.sqlite3_column_type + SQLite3.sqlite3_column_type #else - sqlite3_column_type = loadFunction("sqlite3_column_type") + loadFunction("sqlite3_column_type") #endif - return sqlite3_column_type(stmt, columnIndex) + }() + + func sqlite3_column_type(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { + return Self._sqlite3_column_type(stmt, columnIndex) } - func sqlite3_column_int(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - let sqlite3_column_int: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_column_int: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_column_int = SQLite3.sqlite3_column_int + SQLite3.sqlite3_column_int #else - sqlite3_column_int = loadFunction("sqlite3_column_int") + loadFunction("sqlite3_column_int") #endif - return sqlite3_column_int(stmt, columnIndex) + }() + + func sqlite3_column_int(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { + return Self._sqlite3_column_int(stmt, columnIndex) } - func sqlite3_column_int64(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int64 { - let sqlite3_column_int64: (OpaquePointer?, Int32) -> sqlite3_int64 + private static let _sqlite3_column_int64: (OpaquePointer?, Int32) -> sqlite3_int64 = { #if canImport(SQLite3) - sqlite3_column_int64 = SQLite3.sqlite3_column_int64 + SQLite3.sqlite3_column_int64 #else - sqlite3_column_int64 = loadFunction("sqlite3_column_int64") + loadFunction("sqlite3_column_int64") #endif - return sqlite3_column_int64(stmt, columnIndex) + }() + + func sqlite3_column_int64(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int64 { + return Self._sqlite3_column_int64(stmt, columnIndex) } - func sqlite3_column_double(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Double { - let sqlite3_column_double: (OpaquePointer?, Int32) -> Double + private static let _sqlite3_column_double: (OpaquePointer?, Int32) -> Double = { #if canImport(SQLite3) - sqlite3_column_double = SQLite3.sqlite3_column_double + SQLite3.sqlite3_column_double #else - sqlite3_column_double = loadFunction("sqlite3_column_double") + loadFunction("sqlite3_column_double") #endif - return sqlite3_column_double(stmt, columnIndex) + }() + + func sqlite3_column_double(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Double { + return Self._sqlite3_column_double(stmt, columnIndex) } - func sqlite3_column_text(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_uint8_ptr? { - let sqlite3_column_text: (OpaquePointer?, Int32) -> UnsafePointer? + private static let _sqlite3_column_text: (OpaquePointer?, Int32) -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_column_text = SQLite3.sqlite3_column_text + SQLite3.sqlite3_column_text #else - sqlite3_column_text = loadFunction("sqlite3_column_text") + loadFunction("sqlite3_column_text") #endif - return sqlite3_column_text(stmt, columnIndex) + }() + + func sqlite3_column_text(_ stmt: OpaquePointer, _ columnIndex: Int32) -> sqlite3_uint8_ptr? { + return Self._sqlite3_column_text(stmt, columnIndex) } - func sqlite3_column_blob(_ stmt: OpaquePointer, _ columnIndex: Int32) -> UnsafeRawPointer? { - let sqlite3_column_blob: (OpaquePointer?, Int32) -> UnsafeRawPointer? + private static let _sqlite3_column_blob: (OpaquePointer?, Int32) -> UnsafeRawPointer? = { #if canImport(SQLite3) - sqlite3_column_blob = SQLite3.sqlite3_column_blob + SQLite3.sqlite3_column_blob #else - sqlite3_column_blob = loadFunction("sqlite3_column_blob") + loadFunction("sqlite3_column_blob") #endif - return sqlite3_column_blob(stmt, columnIndex) + }() + + func sqlite3_column_blob(_ stmt: OpaquePointer, _ columnIndex: Int32) -> UnsafeRawPointer? { + return Self._sqlite3_column_blob(stmt, columnIndex) } - func sqlite3_column_bytes(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { - let sqlite3_column_bytes: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_column_bytes: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_column_bytes = SQLite3.sqlite3_column_bytes + SQLite3.sqlite3_column_bytes #else - sqlite3_column_bytes = loadFunction("sqlite3_column_bytes") + loadFunction("sqlite3_column_bytes") #endif - return sqlite3_column_bytes(stmt, columnIndex) + }() + + func sqlite3_column_bytes(_ stmt: OpaquePointer, _ columnIndex: Int32) -> Int32 { + return Self._sqlite3_column_bytes(stmt, columnIndex) } - func sqlite3_backup_init(_ destDb: OpaquePointer, _ destName: String, _ sourceDb: OpaquePointer?, _ sourceName: String) -> OpaquePointer { - let sqlite3_backup_init: (OpaquePointer?, UnsafePointer?, OpaquePointer?, UnsafePointer?) -> OpaquePointer? + private static let _sqlite3_backup_init: (OpaquePointer?, UnsafePointer?, OpaquePointer?, UnsafePointer?) -> OpaquePointer? = { #if canImport(SQLite3) - sqlite3_backup_init = SQLite3.sqlite3_backup_init + SQLite3.sqlite3_backup_init #else - sqlite3_backup_init = loadFunction("sqlite3_backup_init") + loadFunction("sqlite3_backup_init") #endif - return sqlite3_backup_init(destDb, destName, sourceDb, sourceName)! + }() + + func sqlite3_backup_init(_ destDb: OpaquePointer, _ destName: String, _ sourceDb: OpaquePointer?, _ sourceName: String) -> OpaquePointer { + return Self._sqlite3_backup_init(destDb, destName, sourceDb, sourceName)! } - func sqlite3_backup_step(_ backup: OpaquePointer, _ pages: Int32) -> Int32 { - let sqlite3_backup_step: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_backup_step: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_backup_step = SQLite3.sqlite3_backup_step + SQLite3.sqlite3_backup_step #else - sqlite3_backup_step = loadFunction("sqlite3_backup_step") + loadFunction("sqlite3_backup_step") #endif - return sqlite3_backup_step(backup, pages) + }() + + func sqlite3_backup_step(_ backup: OpaquePointer, _ pages: Int32) -> Int32 { + return Self._sqlite3_backup_step(backup, pages) } - func sqlite3_backup_finish(_ backup: OpaquePointer) -> Int32 { - let sqlite3_backup_finish: (OpaquePointer?) -> Int32 + private static let _sqlite3_backup_finish: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_backup_finish = SQLite3.sqlite3_backup_finish + SQLite3.sqlite3_backup_finish #else - sqlite3_backup_finish = loadFunction("sqlite3_backup_finish") + loadFunction("sqlite3_backup_finish") #endif - return sqlite3_backup_finish(backup) + }() + + func sqlite3_backup_finish(_ backup: OpaquePointer) -> Int32 { + return Self._sqlite3_backup_finish(backup) } - func sqlite3_backup_remaining(_ backup: OpaquePointer) -> Int32 { - let sqlite3_backup_remaining: (OpaquePointer?) -> Int32 + private static let _sqlite3_backup_remaining: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_backup_remaining = SQLite3.sqlite3_backup_remaining + SQLite3.sqlite3_backup_remaining #else - sqlite3_backup_remaining = loadFunction("sqlite3_backup_remaining") + loadFunction("sqlite3_backup_remaining") #endif - return sqlite3_backup_remaining(backup) + }() + + func sqlite3_backup_remaining(_ backup: OpaquePointer) -> Int32 { + return Self._sqlite3_backup_remaining(backup) } - func sqlite3_backup_pagecount(_ backup: OpaquePointer) -> Int32 { - let sqlite3_backup_pagecount: (OpaquePointer?) -> Int32 + private static let _sqlite3_backup_pagecount: (OpaquePointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_backup_pagecount = SQLite3.sqlite3_backup_pagecount + SQLite3.sqlite3_backup_pagecount #else - sqlite3_backup_pagecount = loadFunction("sqlite3_backup_pagecount") + loadFunction("sqlite3_backup_pagecount") #endif - return sqlite3_backup_pagecount(backup) + }() + + func sqlite3_backup_pagecount(_ backup: OpaquePointer) -> Int32 { + return Self._sqlite3_backup_pagecount(backup) } - func sqlite3_initialize() -> Int32 { - let sqlite3_initialize: () -> Int32 + private static let _sqlite3_initialize: () -> Int32 = { #if canImport(SQLite3) - sqlite3_initialize = SQLite3.sqlite3_initialize + SQLite3.sqlite3_initialize #else - sqlite3_initialize = loadFunction("sqlite3_initialize") + loadFunction("sqlite3_initialize") #endif - return sqlite3_initialize() + }() + + func sqlite3_initialize() -> Int32 { + return Self._sqlite3_initialize() } - func sqlite3_shutdown() -> Int32 { - let sqlite3_shutdown: () -> Int32 + private static let _sqlite3_shutdown: () -> Int32 = { #if canImport(SQLite3) - sqlite3_shutdown = SQLite3.sqlite3_shutdown + SQLite3.sqlite3_shutdown #else - sqlite3_shutdown = loadFunction("sqlite3_shutdown") + loadFunction("sqlite3_shutdown") #endif - return sqlite3_shutdown() + }() + + func sqlite3_shutdown() -> Int32 { + return Self._sqlite3_shutdown() } - func sqlite3_libversion() -> sqlite3_cstring_ptr? { - let sqlite3_libversion: () -> UnsafePointer? + private static let _sqlite3_libversion: () -> UnsafePointer? = { #if canImport(SQLite3) - sqlite3_libversion = SQLite3.sqlite3_libversion + SQLite3.sqlite3_libversion #else - sqlite3_libversion = loadFunction("sqlite3_libversion") + loadFunction("sqlite3_libversion") #endif - return sqlite3_libversion() + }() + + func sqlite3_libversion() -> sqlite3_cstring_ptr? { + return Self._sqlite3_libversion() } - func sqlite3_libversion_number() -> Int32 { - let sqlite3_libversion_number: () -> Int32 + private static let _sqlite3_libversion_number: () -> Int32 = { #if canImport(SQLite3) - sqlite3_libversion_number = SQLite3.sqlite3_libversion_number + SQLite3.sqlite3_libversion_number #else - sqlite3_libversion_number = loadFunction("sqlite3_libversion_number") + loadFunction("sqlite3_libversion_number") #endif - return sqlite3_libversion_number() + }() + + func sqlite3_libversion_number() -> Int32 { + return Self._sqlite3_libversion_number() } - func sqlite3_extended_result_codes(_ db: OpaquePointer, _ on: Int32) -> Int32 { - let sqlite3_extended_result_codes: (OpaquePointer?, Int32) -> Int32 + private static let _sqlite3_extended_result_codes: (OpaquePointer?, Int32) -> Int32 = { #if canImport(SQLite3) - sqlite3_extended_result_codes = SQLite3.sqlite3_extended_result_codes + SQLite3.sqlite3_extended_result_codes #else - sqlite3_extended_result_codes = loadFunction("sqlite3_extended_result_codes") + loadFunction("sqlite3_extended_result_codes") #endif - return sqlite3_extended_result_codes(db, on) + }() + + func sqlite3_extended_result_codes(_ db: OpaquePointer, _ on: Int32) -> Int32 { + return Self._sqlite3_extended_result_codes(db, on) } - func sqlite3_free(_ ptr: sqlite3_pointer_type) { - let sqlite3_free: (UnsafeMutableRawPointer?) -> Void + private static let _sqlite3_free: (UnsafeMutableRawPointer?) -> Void = { #if canImport(SQLite3) - sqlite3_free = SQLite3.sqlite3_free + SQLite3.sqlite3_free #else - sqlite3_free = loadFunction("sqlite3_free") + loadFunction("sqlite3_free") #endif - return sqlite3_free(ptr) + }() + + func sqlite3_free(_ ptr: sqlite3_pointer_type) { + return Self._sqlite3_free(ptr) } - func sqlite3_db_mutex(_ db: OpaquePointer?) -> OpaquePointer? { - let sqlite3_db_mutex: (OpaquePointer?) -> OpaquePointer? + private static let _sqlite3_db_mutex: (OpaquePointer?) -> OpaquePointer? = { #if canImport(SQLite3) - sqlite3_db_mutex = SQLite3.sqlite3_db_mutex + SQLite3.sqlite3_db_mutex #else - sqlite3_db_mutex = loadFunction("sqlite3_db_mutex") + loadFunction("sqlite3_db_mutex") #endif - return sqlite3_db_mutex(db) + }() + + func sqlite3_db_mutex(_ db: OpaquePointer?) -> OpaquePointer? { + return Self._sqlite3_db_mutex(db) } - func sqlite3_mutex_free(_ lock: OpaquePointer?) { - let sqlite3_mutex_free: (OpaquePointer?) -> Void + private static let _sqlite3_mutex_free: (OpaquePointer?) -> Void = { #if canImport(SQLite3) - sqlite3_mutex_free = SQLite3.sqlite3_mutex_free + SQLite3.sqlite3_mutex_free #else - sqlite3_mutex_free = loadFunction("sqlite3_mutex_free") + loadFunction("sqlite3_mutex_free") #endif - return sqlite3_mutex_free(lock) + }() + + func sqlite3_mutex_free(_ lock: OpaquePointer?) { + return Self._sqlite3_mutex_free(lock) } - func sqlite3_mutex_enter(_ lock: OpaquePointer?) { - let sqlite3_mutex_enter: (OpaquePointer?) -> Void + private static let _sqlite3_mutex_enter: (OpaquePointer?) -> Void = { #if canImport(SQLite3) - sqlite3_mutex_enter = SQLite3.sqlite3_mutex_enter + SQLite3.sqlite3_mutex_enter #else - sqlite3_mutex_enter = loadFunction("sqlite3_mutex_enter") + loadFunction("sqlite3_mutex_enter") #endif - return sqlite3_mutex_enter(lock) + }() + + func sqlite3_mutex_enter(_ lock: OpaquePointer?) { + return Self._sqlite3_mutex_enter(lock) } - func sqlite3_mutex_leave(_ lock: OpaquePointer?) { - let sqlite3_mutex_leave: (OpaquePointer?) -> Void + private static let _sqlite3_mutex_leave: (OpaquePointer?) -> Void = { #if canImport(SQLite3) - sqlite3_mutex_leave = SQLite3.sqlite3_mutex_leave + SQLite3.sqlite3_mutex_leave #else - sqlite3_mutex_leave = loadFunction("sqlite3_mutex_leave") + loadFunction("sqlite3_mutex_leave") #endif - return sqlite3_mutex_leave(lock) + }() + + func sqlite3_mutex_leave(_ lock: OpaquePointer?) { + return Self._sqlite3_mutex_leave(lock) } - func sqlite3_update_hook(_ db: OpaquePointer?, _ callback: sqlite3_update_hook?, _ pArg: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { - let sqlite3_update_hook: (OpaquePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafePointer?, UnsafePointer?, sqlite3_int64) -> Void)?, UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? + private static let _sqlite3_update_hook: (OpaquePointer?, (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafePointer?, UnsafePointer?, sqlite3_int64) -> Void)?, UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? = { #if canImport(SQLite3) - sqlite3_update_hook = SQLite3.sqlite3_update_hook + SQLite3.sqlite3_update_hook #else - sqlite3_update_hook = loadFunction("sqlite3_update_hook") + loadFunction("sqlite3_update_hook") #endif - return sqlite3_update_hook(db, callback, pArg) + }() + + func sqlite3_update_hook(_ db: OpaquePointer?, _ callback: sqlite3_update_hook?, _ pArg: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { + return Self._sqlite3_update_hook(db, callback, pArg) } - func sqlite3_trace_v2(_ db: OpaquePointer?, _ mask: sqlite3_unsigned, _ callback: sqlite3_trace_hook?, _ pCtx: UnsafeMutableRawPointer?) -> Int32 { - let sqlite3_trace_v2: (OpaquePointer?, UInt32, (@convention(c) (UInt32, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?) -> Int32)?, UnsafeMutableRawPointer?) -> Int32 + private static let _sqlite3_trace_v2: (OpaquePointer?, UInt32, (@convention(c) (UInt32, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?, UnsafeMutableRawPointer?) -> Int32)?, UnsafeMutableRawPointer?) -> Int32 = { #if canImport(SQLite3) - sqlite3_trace_v2 = SQLite3.sqlite3_trace_v2 + SQLite3.sqlite3_trace_v2 #else - sqlite3_trace_v2 = loadFunction("sqlite3_trace_v2") + loadFunction("sqlite3_trace_v2") #endif - return sqlite3_trace_v2(db, mask, callback, pCtx) + }() + + func sqlite3_trace_v2(_ db: OpaquePointer?, _ mask: sqlite3_unsigned, _ callback: sqlite3_trace_hook?, _ pCtx: UnsafeMutableRawPointer?) -> Int32 { + return Self._sqlite3_trace_v2(db, mask, callback, pCtx) } - private func loadFunction(_ name: String) -> T { - //fatalError("### LOADING: \(name)") - //let handle = dlopen(nil, RTLD_NOW) - //let symbol = dlsym(handle, name) + #if !canImport(SQLite3) + private static func loadFunction(_ name: String) -> T { + #if canImport(Darwin) + let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2) + #else + let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: 0) + #endif + let symbol = dlsym(RTLD_DEFAULT, name) - print("### LOADING: \(name): handle=\(handle) \(symbol)") - //fatalError("### LOADING: \(name): handle=\(handle) \(symbol)") + if symbol == nil { + fatalError("SQLiteCLibrary: unable to dlsym \(name)") + } return unsafeBitCast(symbol, to: T.self) } + #endif } #endif -