DataLiteCore swift package

This commit is contained in:
2025-04-24 23:48:46 +03:00
parent b0e52a72b7
commit 6f955b2c43
70 changed files with 7939 additions and 1 deletions

View File

@@ -0,0 +1,82 @@
import Foundation
/// Represents the journal modes available for an SQLite database.
///
/// The journal mode determines how the database handles transactions and how it
/// maintains the journal for rollback and recovery. For more details, refer to
/// [Journal Mode Pragma](https://www.sqlite.org/pragma.html#pragma_journal_mode).
public enum JournalMode: String, SQLiteRawRepresentable {
/// DELETE journal mode.
///
/// This is the default behavior. The rollback journal is deleted at the conclusion
/// of each transaction. The delete operation itself causes the transaction to commit.
/// For more details, refer to the
/// [Atomic Commit In SQLite](https://www.sqlite.org/atomiccommit.html).
case delete
/// TRUNCATE journal mode.
///
/// In this mode, the rollback journal is truncated to zero length at the end of each transaction
/// instead of being deleted. On many systems, truncating a file is much faster than deleting it
/// because truncating does not require modifying the containing directory.
case truncate
/// PERSIST journal mode.
///
/// In this mode, the rollback journal is not deleted at the end of each transaction. Instead,
/// the header of the journal is overwritten with zeros. This prevents other database connections
/// from rolling the journal back. The PERSIST mode is useful as an optimization on platforms
/// where deleting or truncating a file is more expensive than overwriting the first block of a file
/// with zeros. For additional configuration, refer to
/// [journal_size_limit](https://www.sqlite.org/pragma.html#pragma_journal_size_limit).
case persist
/// MEMORY journal mode.
///
/// In this mode, the rollback journal is stored entirely in volatile RAM rather than on disk.
/// This saves disk I/O but at the expense of database safety and integrity. If the application
/// crashes during a transaction, the database file will likely become corrupt.
case memory
/// Write-Ahead Logging (WAL) journal mode.
///
/// This mode uses a write-ahead log instead of a rollback journal to implement transactions.
/// The WAL mode is persistent, meaning it stays in effect across multiple database connections
/// and persists even after closing and reopening the database. For more details, refer to the
/// [Write-Ahead Logging](https://www.sqlite.org/wal.html).
case wal
/// OFF journal mode.
///
/// In this mode, the rollback journal is completely disabled, meaning no rollback journal is ever created.
/// This disables SQLite's atomic commit and rollback capabilities. The `ROLLBACK` command will no longer work
/// and behaves in an undefined way. Applications must avoid using the `ROLLBACK` command when the journal mode is OFF.
/// If the application crashes in the middle of a transaction, the database file will likely become corrupt,
/// as there is no way to unwind partially completed operations. For example, if a duplicate entry causes a
/// `CREATE UNIQUE INDEX` statement to fail halfway through, it will leave behind a partially created index,
/// resulting in a corrupted database state.
case off
public var rawValue: String {
switch self {
case .delete: "DELETE"
case .truncate: "TRUNCATE"
case .persist: "PERSIST"
case .memory: "MEMORY"
case .wal: "WAL"
case .off: "OFF"
}
}
public init?(rawValue: String) {
switch rawValue.uppercased() {
case "DELETE": self = .delete
case "TRUNCATE": self = .truncate
case "PERSIST": self = .persist
case "MEMORY": self = .memory
case "WAL": self = .wal
case "OFF": self = .off
default: return nil
}
}
}

View File

@@ -0,0 +1,40 @@
import Foundation
/// Represents different types of database update actions.
///
/// The `SQLiteAction` enum is used to identify the type of action
/// performed on a database, such as insertion, updating, or deletion.
public enum SQLiteAction {
/// Indicates the insertion of a new row into a table.
///
/// This case is used to represent the action of adding a new
/// row to a specific table in a database.
///
/// - Parameters:
/// - db: The name of the database where the insertion occurred.
/// - table: The name of the table where the insertion occurred.
/// - rowID: The row ID of the newly inserted row.
case insert(db: String, table: String, rowID: Int64)
/// Indicates the modification of an existing row in a table.
///
/// This case is used to represent the action of updating an
/// existing row within a specific table in a database.
///
/// - Parameters:
/// - db: The name of the database where the update occurred.
/// - table: The name of the table where the update occurred.
/// - rowID: The row ID of the updated row.
case update(db: String, table: String, rowID: Int64)
/// Indicates the removal of a row from a table.
///
/// This case is used to represent the action of deleting a
/// row from a specific table in a database.
///
/// - Parameters:
/// - db: The name of the database from which the row was deleted.
/// - table: The name of the table from which the row was deleted.
/// - rowID: The row ID of the deleted row.
case delete(db: String, table: String, rowID: Int64)
}

View File

@@ -0,0 +1,75 @@
import Foundation
import DataLiteC
/// Represents different types of columns in an SQLite database.
///
/// The `SQLiteRawType` enum encapsulates the various data types that SQLite supports for columns.
/// Each case in the enum corresponds to a specific SQLite data type, providing a way to work with these
/// types in a type-safe manner. This enum allows for easier handling of SQLite column types by abstracting
/// their raw representations and offering more readable code.
/// For more details, refer to [Datatypes In SQLite](https://www.sqlite.org/datatype3.html).
///
/// ## Topics
///
/// ### Enumeration Cases
///
/// - ``int``
/// - ``real``
/// - ``text``
/// - ``blob``
/// - ``null``
///
/// ### Instance Properties
///
/// - ``rawValue``
///
/// ### Initializers
///
/// - ``init(rawValue:)``
public enum SQLiteRawType: Int32 {
/// The data type of an integer column.
case int
/// The data type of a real (floating point) column.
case real
/// The data type of a text (string) column.
case text
/// The data type of a blob (binary large object) column.
case blob
/// The data type of a NULL column.
case null
/// Returns the raw SQLite data type value corresponding to the column type.
///
/// This computed property provides the raw integer value used by SQLite to represent each column type.
///
/// - Returns: An `Int32` representing the SQLite data type constant.
public var rawValue: Int32 {
switch self {
case .int: return SQLITE_INTEGER
case .real: return SQLITE_FLOAT
case .text: return SQLITE_TEXT
case .blob: return SQLITE_BLOB
case .null: return SQLITE_NULL
}
}
/// Initializes a `SQLiteRawType` enum case from its raw value.
///
/// This initializer maps a raw `Int32` value (SQLite constant) to the corresponding enum case.
///
/// - Parameter rawValue: The raw value representing the column type as defined by SQLite.
public init?(rawValue: Int32) {
switch rawValue {
case SQLITE_INTEGER: self = .int
case SQLITE_FLOAT: self = .real
case SQLITE_TEXT: self = .text
case SQLITE_BLOB: self = .blob
case SQLITE_NULL: self = .null
default: return nil
}
}
}

View File

@@ -0,0 +1,99 @@
import Foundation
/// An enumeration that represents the different types of raw values in an SQLite database.
///
/// This type is used to store values retrieved from or stored in an SQLite database. It supports
/// various data types such as integers, floating-point numbers, text, binary data, and null values.
/// For more details, refer to [Datatypes In SQLite](https://www.sqlite.org/datatype3.html).
///
/// ## Example
///
/// ```swift
/// let integerValue: SQLiteRawValue = .int(42)
/// let realValue: SQLiteRawValue = .real(3.14)
/// let textValue: SQLiteRawValue = .text("Hello, SQLite")
/// let blobValue: SQLiteRawValue = .blob(Data([0x01, 0x02, 0x03]))
/// let nullValue: SQLiteRawValue = .null
/// ```
///
/// ## Topics
///
/// ### Enumeration Cases
///
/// - ``int(_:)``
/// - ``real(_:)``
/// - ``text(_:)``
/// - ``blob(_:)``
/// - ``null``
public enum SQLiteRawValue: Equatable {
/// Represents a 64-bit integer value.
case int(Int64)
/// Represents a floating-point number.
case real(Double)
/// Represents a text string.
case text(String)
/// Represents binary large objects (BLOBs).
case blob(Data)
/// Represents a SQL `NULL` value.
case null
}
extension SQLiteRawValue: SQLiteLiteralable {
/// Returns a string representation of the value suitable for use in SQL queries.
///
/// This method converts the `SQLiteRawValue` into a format that is directly usable in SQL statements:
/// - For `.int`: Converts the integer to its string representation.
/// - For `.real`: Converts the floating-point number to its string representation.
/// - For `.text`: Escapes single quotes within the string and wraps the result in single quotes.
/// - For `.blob`: Converts the binary data to a hexadecimal string representation, formatted as `X'...'`.
/// - For `.null`: Returns the SQL literal `"NULL"`.
///
/// The resulting string is formatted for inclusion in SQL queries, ensuring proper handling of the value
/// according to SQL syntax.
///
/// - Returns: A string representation of the value, formatted for use in SQL queries.
public var sqliteLiteral: String {
switch self {
case .int(let int): return "\(int)"
case .real(let real): return "\(real)"
case .text(let text): return "'\(text.replacingOccurrences(of: "'", with: "''"))'"
case .blob(let data): return "X'\(data.hex)'"
case .null: return "NULL"
}
}
}
extension SQLiteRawValue: CustomStringConvertible {
/// A textual representation of the `SQLiteRawValue`.
///
/// This property returns the string representation of the `SQLiteRawValue` as defined by the `sqliteLiteral` method.
/// It provides a clear and readable format of the value, useful for debugging and logging purposes.
///
/// - Returns: A string that represents the `SQLiteRawValue` in a format suitable for display.
public var description: String {
return sqliteLiteral
}
}
extension Data {
/// Converts the data to a hexadecimal string representation.
///
/// This method converts each byte of the `Data` instance into its two-digit hexadecimal representation.
/// The hexadecimal values are concatenated into a single string. This is useful for representing binary data
/// in a human-readable format, particularly for SQL BLOB literals.
///
/// ## Example
/// ```swift
/// let data = Data([0x01, 0x02, 0x03])
/// print(data.hex) // Output: "010203"
/// ```
///
/// - Returns: A hexadecimal string representation of the data.
var hex: String {
return map { String(format: "%02hhX", $0) }.joined()
}
}

View File

@@ -0,0 +1,45 @@
import Foundation
/// Represents different synchronous modes available for an SQLite database.
///
/// The synchronous mode determines how SQLite handles data synchronization with the database.
/// For more details, refer to [Synchronous Pragma](https://www.sqlite.org/pragma.html#pragma_synchronous).
public enum Synchronous: UInt8, SQLiteRawRepresentable {
/// Synchronous mode off. Disables synchronization for maximum performance.
///
/// With synchronous OFF, SQLite continues without syncing as soon as it has handed data off
/// to the operating system. If the application running SQLite crashes, the data will be safe,
/// but the database might become corrupted if the operating system crashes or the computer loses
/// power before the data is written to the disk surface. On the other hand, commits can be orders
/// of magnitude faster with synchronous OFF.
case off = 0
/// Normal synchronous mode.
///
/// The SQLite database engine syncs at the most critical moments, but less frequently
/// than in FULL mode. While there is a very small chance of corruption in
/// `journal_mode=DELETE` on older filesystems during a power failure, WAL
/// mode is safe from corruption with synchronous=NORMAL. Modern filesystems
/// likely make DELETE mode safe too. However, WAL mode in synchronous=NORMAL
/// loses some durability, as a transaction committed in WAL mode might roll back
/// after a power loss or system crash. Transactions are still durable across application
/// crashes regardless of the synchronous setting or journal mode. This setting is a
/// good choice for most applications running in WAL mode.
case normal = 1
/// Full synchronous mode.
///
/// Uses the xSync method of the VFS to ensure that all content is safely written
/// to the disk surface prior to continuing. This ensures that an operating system
/// crash or power failure will not corrupt the database. FULL synchronous is very
/// safe but also slower. It is the most commonly used synchronous setting when
/// not in WAL mode.
case full = 2
/// Extra synchronous mode.
///
/// Similar to FULL mode, but ensures the directory containing the rollback journal
/// is synced after the journal is unlinked, providing additional durability in case of
/// power loss shortly after a commit.
case extra = 3
}

View File

@@ -0,0 +1,40 @@
import Foundation
/// An enumeration representing different types of SQLite transactions.
///
/// SQLite transactions determine how the database engine handles concurrency and locking
/// during a transaction. The default transaction behavior is DEFERRED. For more detailed information
/// about SQLite transactions, refer to the [SQLite documentation](https://www.sqlite.org/lang_transaction.html).
public enum TransactionType: String, CustomStringConvertible {
/// A deferred transaction.
///
/// A deferred transaction does not start until the database is first accessed. Internally,
/// the `BEGIN DEFERRED` statement merely sets a flag on the database connection to prevent
/// the automatic commit that normally occurs when the last statement finishes. If the first
/// statement after `BEGIN DEFERRED` is a `SELECT`, a read transaction begins. If it is a write
/// statement, a write transaction starts. Subsequent write operations may upgrade the transaction
/// to a write transaction if possible, or return `SQLITE_BUSY`. The transaction persists until
/// an explicit `COMMIT` or `ROLLBACK` or until a rollback is provoked by an error or an `ON CONFLICT ROLLBACK` clause.
case deferred = "DEFERRED"
/// An immediate transaction.
///
/// An immediate transaction starts a new write immediately, without waiting for the first
/// write statement. The `BEGIN IMMEDIATE` statement may fail with `SQLITE_BUSY` if another
/// write transaction is active on a different database connection.
case immediate = "IMMEDIATE"
/// An exclusive transaction.
///
/// Similar to `IMMEDIATE`, an exclusive transaction starts a write immediately. However,
/// in non-WAL modes, `EXCLUSIVE` prevents other database connections from reading the database
/// while the transaction is in progress. In WAL mode, `EXCLUSIVE` behaves the same as `IMMEDIATE`.
case exclusive = "EXCLUSIVE"
/// A textual representation of the transaction type.
///
/// Returns the raw value of the transaction type (e.g., "DEFERRED", "IMMEDIATE", "EXCLUSIVE").
public var description: String {
rawValue
}
}