Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The SQLite C API is small and powerful, but in Swift it comes with a few pain po
- The default Swift `SQLite3` module does not expose any inline documentation, because SQLite’s comments are not in the format Swift recognizes for doc comments.

LSQLite keeps the *exact* SQLite API surface and behavior, but:
- Wraps raw handles like `sqlite3 *` and `sqlite3_stmt *` into small Swift structs (`Database`, `Statement`, …).
- Wraps raw handles like `sqlite3 *` and `sqlite3_stmt *` into small Swift structs (`Connection`, `Statement`, …).
- Wraps result codes and flags into typed Swift values (`ResultCode`, `OpenFlag`, …).
- Leaves control flow and error handling exactly as in the C API: you still check result codes instead of catching errors.

Expand Down Expand Up @@ -74,8 +74,8 @@ In Xcode, you can also add it via:
import LSQLite

// 1. Open database
var db: Database?
let openResult = Database.open(&db, at: .init(rawValue: databasePath), withOpenFlags: [.readwrite, .create])
var db: Connection?
let openResult = Connection.open(&db, at: .init(rawValue: databasePath), withOpenFlags: [.readwrite, .create])
guard openResult == .ok, let db else {
fatalError("Failed to open database: \(openResult)")
}
Expand Down Expand Up @@ -123,8 +123,8 @@ if rc != SQLITE_OK { /* handle error */ }

```swift
import LSQLite
var db: Database?
let rc = Database.open(&db, at: .init(rawValue: "test.db"), withOpenFlags: [.readwrite, .create])
var db: Connection?
let rc = Connection.open(&db, at: .init(rawValue: "test.db"), withOpenFlags: [.readwrite, .create])
if rc != .ok { /* handle error */ }
```

Expand Down Expand Up @@ -166,7 +166,7 @@ let rawCode: Int32 = db.close().rawValue
From C to LSQLite:

```swift
let db = Database(rawValue: someSQLitePointer)
let db = Connection(rawValue: someSQLitePointer)
let code = ResultCode(rawValue: SQLITE_BUSY)
```

Expand All @@ -188,7 +188,7 @@ It is a low-level, but safer and more readable, Swift presentation of the origin

- **Zero overhead:** Public APIs are `@inlinable` and forward directly to `sqlite3_*` calls. After inlining, your binary contains the same code as if you had called the C API yourself.
- **Better constants:** SQLite `#define` values are exposed as real Swift constants, not computed variables. The compiler can see this at compile time, fold expressions, and better optimize flag checks.
- **Type safety:** Typed wrappers (`Database`, `Statement`, `ResultCode`, `OpenFlag`, etc.) make it harder to pass the wrong pointer or constant.
- **Type safety:** Typed wrappers (`Connection`, `Statement`, `ResultCode`, `OpenFlag`, etc.) make it harder to pass the wrong pointer or constant.

## Contributing

Expand Down
2 changes: 1 addition & 1 deletion Sources/LSQLite/Blob/Blob.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// Wrapper around an open BLOB handle for incremental I/O.
///
/// Create a handle with `Database.openBlob(_:databaseName:tableName:columnName:rowID:flags:)`
/// Create a handle with `Connection.openBlob(_:databaseName:tableName:columnName:rowID:flags:)`
/// and close it when finished. Do not use the handle after closing.
///
/// Related SQLite: `sqlite3_blob`, `sqlite3_blob_open`, `sqlite3_blob_close`, `sqlite3_blob_read`, `sqlite3_blob_write`, `sqlite3_blob_bytes`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Authorization callback invoked while SQL statements are being compiled.
///
/// The callback runs as the compiler considers each operation. Return `.ok` to allow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Indicates whether this connection is currently in autocommit mode (no transaction open).
///
/// Autocommit is enabled by default. It is disabled by explicitly beginning a transaction
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Access flags for incremental BLOB I/O opened via `openBlob(_:databaseName:tableName:columnName:rowID:flags:)`.
///
/// Use `.readonly` for read-only access or `.readwrite` for read/write access. SQLite treats any
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Callback invoked when SQLite reports a busy contention; return a retry decision.
///
/// Related SQLite: `sqlite3_busy_handler`, `sqlite3_busy_timeout`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Number of rows changed by the most recent INSERT, UPDATE, or DELETE on this connection.
///
/// Only changes made directly by the statement are counted; changes from triggers, foreign key
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// WAL checkpoint modes used by `walCheckpoint(_:mode:frameCount:totalFrameCount:)` and auto-checkpointing.
///
/// Related SQLite: `SQLITE_CHECKPOINT_PASSIVE`, `SQLITE_CHECKPOINT_FULL`, `SQLITE_CHECKPOINT_RESTART`, `SQLITE_CHECKPOINT_TRUNCATE`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Closes the connection immediately.
///
/// This call fails with `.busy` if there are unfinalized statements, open BLOB handles,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Comparator used by SQLite to order text for a custom collation.
///
/// Related SQLite: `sqlite3_create_collation_v2`, `sqlite3_create_collation`, `sqlite3_create_collation16`
Expand All @@ -14,7 +14,7 @@ extension Database {
/// Callback used to lazily create missing collations on demand.
///
/// Related SQLite: `sqlite3_collation_needed`, `sqlite3_collation_needed16`
public typealias CollationNeededHandler = @convention(c) (_ userData: UnsafeMutableRawPointer?, _ database: OpaquePointer?, _ collationFlag: Int32, _ name: UnsafePointer<Int8>?) -> Void
public typealias CollationNeededHandler = @convention(c) (_ userData: UnsafeMutableRawPointer?, _ connection: OpaquePointer?, _ collationFlag: Int32, _ name: UnsafePointer<Int8>?) -> Void

/// Text encoding and behavior flags for user-defined collations.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Switch controlling whether extended result codes are reported for this connection.
///
/// Related SQLite: `sqlite3_extended_result_codes`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Row callback invoked by `exec(_:)` when SQL produces result rows.
///
/// The arrays and strings are only valid for the duration of the callback.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Returns the absolute filename for the named database on this connection.
/// - Parameter name: Database name such as `"main"` or `"temp"`.
/// - Returns: Absolute path, or `nil` for in-memory or temporary databases.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// C callback invoked to compute a scalar SQL function result.
///
/// Related SQLite: `sqlite3_create_function_v2`, `sqlite3_user_data`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Commit hook invoked before the transaction is finalized; return nonzero to roll back.
///
/// Related SQLite: `sqlite3_commit_hook`
Expand All @@ -19,7 +19,7 @@ extension Database {
/// WAL hook invoked after a write transaction commits when using WAL mode.
///
/// Related SQLite: `sqlite3_wal_hook`
public typealias WALHookHandler = @convention(c) (_ userData: UnsafeMutableRawPointer?, _ database: OpaquePointer?, _ databaseName: UnsafePointer<Int8>?, _ pageInWALFileCount: Int32) -> Int32
public typealias WALHookHandler = @convention(c) (_ userData: UnsafeMutableRawPointer?, _ connection: OpaquePointer?, _ databaseName: UnsafePointer<Int8>?, _ pageInWALFileCount: Int32) -> Int32

/// Return codes for commit hooks to continue or force a rollback.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Requests that all running statements on this connection abort at their earliest opportunity.
///
/// It is safe to call from a different thread as long as the connection remains open.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Rowid of the most recent successful INSERT on this connection (rowid tables only).
///
/// Rowid is the implicit 64-bit integer key for rowid tables and can be accessed via the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MissedSwiftSQLite

extension Database {
/// Runtime limit categories used with `Database.limit(for:)` and `Database.setLimit(_:for:)`.
extension Connection {
/// Runtime limit categories used with `Connection.limit(for:)` and `Connection.setLimit(_:for:)`.
///
/// Related SQLite: `sqlite3_limit`, `SQLITE_LIMIT_*`
@frozen public struct LimitCategory: Hashable, RawRepresentable, CustomStringConvertible, CustomDebugStringConvertible {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Filename wrapper used when opening a connection.
///
/// For `file:` URIs, pass the full URI string as `rawValue` and include `.uri` in the open flags.
Expand Down Expand Up @@ -275,8 +275,8 @@ extension Database {
/// the file is write-protected. Use `readWriteAccessState(forDatabaseNamed:)` to check the
/// actual access mode.
///
/// On success, `database` is set to a new handle and the result is `.ok`.
/// On failure, `database` may still be set to a handle unless the open fails due to
/// On success, `connection` is set to a new handle and the result is `.ok`.
/// On failure, `connection` may still be set to a handle unless the open fails due to
/// an out-of-memory condition. When a handle is returned, the caller is responsible
/// for closing it to release resources.
///
Expand All @@ -285,16 +285,16 @@ extension Database {
/// case the filename is used only for cache sharing. `FileName.temporary` creates a
/// private on-disk database that is deleted on close.
/// - Parameters:
/// - database: Receives the connection handle; may be set even when the result is an error.
/// - connection: Receives the connection handle; may be set even when the result is an error.
/// - filename: Target database path or special filename like `.memory`.
/// - openFlag: Flags controlling the open mode and options.
/// - Returns: Result code from the open attempt.
///
/// Related SQLite: `sqlite3_open`, `sqlite3_open_v2`, `SQLITE_OPEN_*`, `sqlite3_temp_directory`
@inlinable public static func open(_ database: inout Database?, at filename: FileName, withOpenFlags openFlag: OpenFlag) -> ResultCode {
var databasePointer: OpaquePointer? = nil
let resultCode = sqlite3_open_v2(filename.rawValue, &databasePointer, openFlag.rawValue, nil).resultCode
database = databasePointer.map(Database.init(rawValue:))
@inlinable public static func open(_ connection: inout Connection?, at filename: FileName, withOpenFlags openFlag: OpenFlag) -> ResultCode {
var connectionPointer: OpaquePointer? = nil
let resultCode = sqlite3_open_v2(filename.rawValue, &connectionPointer, openFlag.rawValue, nil).resultCode
connection = connectionPointer.map(Connection.init(rawValue:))
return resultCode
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Callback invoked periodically during virtual machine execution; return a code indicating whether to continue.
///
/// Related SQLite: `sqlite3_progress_handler`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Read/write state values returned by `readWriteAccessState(forDatabaseNamed:)`.
///
/// Related SQLite: `sqlite3_db_readonly`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MissedSwiftSQLite

extension Database {
extension Connection {
/// Returns the next prepared statement on this connection.
/// - Parameter statement: The current statement, or nil to fetch the first.
/// - Returns: The next statement, or nil if none exist.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MissedSwiftSQLite

@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)
extension Database {
extension Connection {
/// Trace callback invoked for subscribed events with event-specific payloads.
///
/// Related SQLite: `sqlite3_trace_v2`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/// Use `rawValue` to access the underlying handle when needed.
///
/// Related SQLite: `sqlite3`, `sqlite3_open`, `sqlite3_open_v2`, `sqlite3_close`, `sqlite3_close_v2`
@frozen public struct Database: RawRepresentable {
@frozen public struct Connection: RawRepresentable {
public let rawValue: OpaquePointer

@inlinable public init(rawValue: OpaquePointer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extension Context {
/// - Returns: Database connection for the function invocation, or `nil` if unavailable.
///
/// Related SQLite: `sqlite3_context_db_handle`, `sqlite3_create_function_v2`
@inlinable public var database: Database? {
return sqlite3_context_db_handle(rawValue).map(Database.init(rawValue:))
@inlinable public var connection: Connection? {
return sqlite3_context_db_handle(rawValue).map(Connection.init(rawValue:))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extension Statement {
/// - Returns: The owning database connection, or nil if unavailable.
///
/// Related SQLite: `sqlite3_db_handle`
@inlinable public var database: Database? {
return sqlite3_db_handle(rawValue).map(Database.init(rawValue:))
@inlinable public var connection: Connection? {
return sqlite3_db_handle(rawValue).map(Connection.init(rawValue:))
}
}
24 changes: 12 additions & 12 deletions Sources/LSQLite/Statement/Statement+Prepare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ extension Statement {
/// - statement: Receives the prepared statement, or nil if the input
/// contains no SQL.
/// - sql: SQL text to compile.
/// - database: Connection used to compile the statement.
/// - connection: Connection used to compile the statement.
/// - Returns: Result code from compilation.
///
/// Related SQLite: `sqlite3_prepare_v2`
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, for database: Database) -> ResultCode {
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, for connection: Connection) -> ResultCode {
var tail: String?
return prepare(&statement, sql: sql, tail: &tail, for: database)
return prepare(&statement, sql: sql, tail: &tail, for: connection)
}

/// Compiles the first statement in a UTF-8 SQL string.
Expand All @@ -87,16 +87,16 @@ extension Statement {
/// contains no SQL.
/// - sql: SQL text to compile.
/// - tail: Receives any remaining SQL text after the first statement.
/// - database: Connection used to compile the statement.
/// - connection: Connection used to compile the statement.
/// - Returns: Result code from compilation.
///
/// Related SQLite: `sqlite3_prepare_v2`
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, tail: inout String?, for database: Database) -> ResultCode {
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, tail: inout String?, for connection: Connection) -> ResultCode {
var statementPointer: OpaquePointer?
var tailString: String?
let resultCode = sql.withCString { cString in
var tailPointer: UnsafePointer<Int8>?
let result = sqlite3_prepare_v2(database.rawValue, cString, -1, &statementPointer, &tailPointer).resultCode
let result = sqlite3_prepare_v2(connection.rawValue, cString, -1, &statementPointer, &tailPointer).resultCode
tailString = tailPointer.map { String(cString: $0) }
return result
}
Expand All @@ -110,15 +110,15 @@ extension Statement {
/// - statement: Receives the prepared statement, or nil if the input
/// contains no SQL.
/// - sql: SQL text to compile.
/// - database: Connection used to compile the statement.
/// - connection: Connection used to compile the statement.
/// - prepareFlag: Options that influence compilation.
/// - Returns: Result code from compilation.
///
/// Related SQLite: `sqlite3_prepare_v3`
@available(iOS 12.0, macOS 10.14, tvOS 12.0, watchOS 5.0, *)
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, for database: Database, prepareFlag: PrepareFlag) -> ResultCode {
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, for connection: Connection, prepareFlag: PrepareFlag) -> ResultCode {
var tail: String?
return prepare(&statement, sql: sql, tail: &tail, for: database, prepareFlag: prepareFlag)
return prepare(&statement, sql: sql, tail: &tail, for: connection, prepareFlag: prepareFlag)
}

/// Compiles the first statement in a UTF-8 SQL string with compilation options.
Expand All @@ -127,18 +127,18 @@ extension Statement {
/// contains no SQL.
/// - sql: SQL text to compile.
/// - tail: Receives any remaining SQL text after the first statement.
/// - database: Connection used to compile the statement.
/// - connection: Connection used to compile the statement.
/// - prepareFlag: Options that influence compilation.
/// - Returns: Result code from compilation.
///
/// Related SQLite: `sqlite3_prepare_v3`
@available(iOS 12.0, macOS 10.14, tvOS 12.0, watchOS 5.0, *)
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, tail: inout String?, for database: Database, prepareFlag: PrepareFlag) -> ResultCode {
@inlinable public static func prepare(_ statement: inout Statement?, sql: String, tail: inout String?, for connection: Connection, prepareFlag: PrepareFlag) -> ResultCode {
var statementPointer: OpaquePointer? = nil
var tailString: String? = nil
let resultCode = sql.withCString { cString in
var tailPointer: UnsafePointer<Int8>? = nil
let result = sqlite3_prepare_v3(database.rawValue, cString, -1, prepareFlag.rawValue, &statementPointer, &tailPointer).resultCode
let result = sqlite3_prepare_v3(connection.rawValue, cString, -1, prepareFlag.rawValue, &statementPointer, &tailPointer).resultCode
tailString = tailPointer.map { String(cString: $0) }
return result
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/LSQLite/Value/Value+Introspect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ extension Value {
///
/// Requires a protected value; using an unprotected value is not thread-safe.
/// Subtypes are preserved for SQL functions registered with
/// `Database.FunctionFlag.subtype`.
/// `Connection.FunctionFlag.subtype`.
/// - Returns: Subtype tag for the value, or 0 if none is set.
///
/// Related SQLite: `sqlite3_value_subtype`
Expand Down
Loading