Exemplos de Banco de Dados macOS Swift

Exemplos de banco de dados macOS Swift incluindo conexão SQLite, execução de consultas e processamento de transações

💻 Conexão SQLite swift

🟡 intermediate ⭐⭐⭐

Estabelecer e gerenciar conexões de banco de dados SQLite com configuração e tratamento de erros apropriados

⏱️ 30 min 🏷️ swift, macos, database, sqlite
Prerequisites: Intermediate Swift, SQLite C API, File I/O
// macOS Swift SQLite Connection Examples
// Using SQLite3 C API and wrapper patterns

import Foundation
import SQLite3

// 1. Basic Database Connection
class BasicConnection {

    var db: OpaquePointer?

    func openDatabase(path: String) -> Bool {
        print("\n--- Opening Database ---")

        // Open database
        let result = sqlite3_open(path, &db)

        if result == SQLITE_OK {
            print("Database opened successfully at: \(path)")

            // Get SQLite version
            if let version = sqlite3_libversion() {
                let versionString = String(cString: version)
                print("SQLite version: \(versionString)")
            }

            return true
        } else {
            let error = String(cString: sqlite3_errmsg(db))
            print("Error opening database: \(error)")
            return false
        }
    }

    func closeDatabase() {
        print("\n--- Closing Database ---")

        if db != nil {
            sqlite3_close(db)
            db = nil
            print("Database closed")
        }
    }

    deinit {
        closeDatabase()
    }
}

// 2. Create In-Memory Database
class InMemoryDatabase {

    var db: OpaquePointer?

    func createInMemoryDatabase() -> Bool {
        print("\n--- In-Memory Database ---")

        let result = sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nil)

        if result == SQLITE_OK {
            print("In-memory database created successfully")
            return true
        } else {
            let error = String(cString: sqlite3_errmsg(db))
            print("Error creating in-memory database: \(error)")
            return false
        }
    }

    func getDatabaseInfo() {
        guard let db = db else { return }

        // Get page size
        var pageSize: Int32 = 0
        sqlite3_file_control(db, nil, SQLITE_FCNTL_POWERSAFE_OVERWRITE, &pageSize)

        // Get database status
        var curPage: Int32 = 0, pageSizeResult: Int32 = 0, freePages: Int32 = 0
        sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &curPage, &pageSizeResult, 0)

        print("Database info:")
        print("  Current page cache: \(curPage)")
    }
}

// 3. Connection with Configuration
class ConfiguredConnection {

    var db: OpaquePointer?

    func openWithConfiguration(path: String) -> Bool {
        print("\n--- Opening with Configuration ---")

        // Open with flags
        let flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX
        let result = sqlite3_open_v2(path, &db, flags, nil)

        guard result == SQLITE_OK else {
            let error = String(cString: sqlite3_errmsg(db))
            print("Error opening database: \(error)")
            return false
        }

        print("Database opened with flags")

        // Configure busy timeout (in milliseconds)
        let timeout = 5000 // 5 seconds
        sqlite3_busy_timeout(db, Int32(timeout))
        print("Busy timeout set to \(timeout)ms")

        // Enable foreign keys
        executeSQL("PRAGMA foreign_keys = ON;")
        print("Foreign keys enabled")

        // Set journal mode
        executeSQL("PRAGMA journal_mode = WAL;")
        print("Journal mode set to WAL")

        // Set synchronous mode
        executeSQL("PRAGMA synchronous = NORMAL;")
        print("Synchronous mode set to NORMAL")

        // Set cache size (-2000 = 2MB)
        executeSQL("PRAGMA cache_size = -2000;")
        print("Cache size set to 2MB")

        // Set temp store to memory
        executeSQL("PRAGMA temp_store = MEMORY;")
        print("Temp store set to MEMORY")

        return true
    }

    private func executeSQL(_ sql: String) {
        sqlite3_exec(db, sql, nil, nil, nil)
    }
}

// 4. Connection Pool
class SQLiteConnectionPool {

    private var connections: [OpaquePointer] = []
    private var maxConnections: Int
    private var available: [OpaquePointer] = []
    private let lock = NSLock()

    init(databasePath: String, maxConnections: Int = 5) {
        self.maxConnections = maxConnections

        // Create connections
        for _ in 0..<maxConnections {
            var db: OpaquePointer?
            if sqlite3_open(databasePath, &db) == SQLITE_OK {
                connections.append(db!)
                available.append(db!)
            }
        }

        print("Created connection pool with \(connections.count) connections")
    }

    func getConnection() -> OpaquePointer? {
        lock.lock()
        defer { lock.unlock() }

        if let connection = available.first {
            available.removeFirst()
            return connection
        }

        print("No available connections")
        return nil
    }

    func returnConnection(_ connection: OpaquePointer) {
        lock.lock()
        defer { lock.unlock() }

        available.append(connection)
    }

    func closeAll() {
        for connection in connections {
            sqlite3_close(connection)
        }
        connections.removeAll()
        available.removeAll()
        print("All connections closed")
    }
}

// 5. Database Information
class DatabaseInfo {

    static func getDatabaseInfo(_ db: OpaquePointer?) {
        print("\n--- Database Information ---")

        guard let db = db else {
            print("No database connection")
            return
        }

        // Get filename
        var filename: UnsafeMutablePointer<Int8>?
        sqlite3_file_control(db, "main", SQLITE_FCNTL_FILENAME_POINTER, &filename)
        if let name = filename {
            print("Database file: \(String(cString: name))")
        }

        // Check if read-only
        var readOnly: Int32 = 0
        sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &readOnly, nil, 0)
        print("Read-only status: \(readOnly != 0)")

        // Get page count
        var statement: OpaquePointer?
        if sqlite3_prepare_v2(db, "PRAGMA page_count;", -1, &statement, nil) == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_ROW {
                let pageCount = sqlite3_column_int64(statement, 0)
                print("Page count: \(pageCount)")
            }
            sqlite3_finalize(statement)
        }

        // Get page size
        if sqlite3_prepare_v2(db, "PRAGMA page_size;", -1, &statement, nil) == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_ROW {
                let pageSize = sqlite3_column_int(statement, 0)
                print("Page size: \(pageSize) bytes")
            }
            sqlite3_finalize(statement)
        }

        // Get encoding
        if sqlite3_prepare_v2(db, "PRAGMA encoding;", -1, &statement, nil) == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_ROW {
                let encoding = sqlite3_column_text(statement, 0)
                if let enc = encoding {
                    print("Encoding: \(String(cString: enc))")
                }
            }
            sqlite3_finalize(statement)
        }

        // Get list of tables
        print("\nTables:")
        if sqlite3_prepare_v2(db, "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;", -1, &statement, nil) == SQLITE_OK {
            while sqlite3_step(statement) == SQLITE_ROW {
                let tableName = sqlite3_column_text(statement, 0)
                if let name = tableName {
                    print("  - \(String(cString: name))")
                }
            }
            sqlite3_finalize(statement)
        }
    }
}

// 6. Database File Management
class DatabaseFileManager {

    static func databaseExists(at path: String) -> Bool {
        return FileManager.default.fileExists(atPath: path)
    }

    static func deleteDatabase(at path: String) throws {
        if databaseExists(at: path) {
            try FileManager.default.removeItem(atPath: path)
            print("Database deleted at: \(path)")
        }

        // Delete associated files
        let pathsToDelete = [
            path + "-wal",
            path + "-shm",
            path + "-journal"
        ]

        for walPath in pathsToDelete {
            if FileManager.default.fileExists(atPath: walPath) {
                try FileManager.default.removeItem(atPath: walPath)
                print("Deleted associated file: \(walPath)")
            }
        }
    }

    static func getDatabaseSize(at path: String) -> UInt64? {
        guard let attributes = try? FileManager.default.attributesOfItem(atPath: path),
              let fileSize = attributes[.size] as? UInt64 else {
            return nil
        }

        return fileSize
    }

    static func copyDatabase(from source: String, to destination: String) throws {
        try FileManager.default.copyItem(atPath: source, toPath: destination)
        print("Database copied from \(source) to \(destination)")
    }

    static func backupDatabase(from source: String, to backupPath: String) -> Bool {
        print("\n--- Database Backup ---")

        var sourceDB: OpaquePointer?
        var backupDB: OpaquePointer?

        // Open source database
        guard sqlite3_open(source, &sourceDB) == SQLITE_OK else {
            print("Failed to open source database")
            return false
        }

        // Open backup database
        guard sqlite3_open(backupPath, &backupDB) == SQLITE_OK else {
            print("Failed to open backup database")
            sqlite3_close(sourceDB)
            return false
        }

        // Perform backup
        var backup = sqlite3_backup_init(backupDB, "main", sourceDB, "main")

        if backup == nil {
            print("Failed to initialize backup")
            sqlite3_close(sourceDB)
            sqlite3_close(backupDB)
            return false
        }

        // Copy remaining pages
        while sqlite3_backup_step(backup, -1) == SQLITE_OK {
            // Continue stepping until done
        }

        sqlite3_backup_finish(backup)
        sqlite3_close(sourceDB)
        sqlite3_close(backupDB)

        print("Backup completed to: \(backupPath)")
        return true
    }
}

// 7. Secure Database
class SecureDatabase {

    var db: OpaquePointer?

    func openEncryptedDatabase(path: String, password: String) -> Bool {
        print("\n--- Opening Encrypted Database ---")

        // Open database with key
        let result = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nil)

        guard result == SQLITE_OK else {
            print("Failed to open database")
            return false
        }

        // Set key for encrypted database
        let keyResult = sqlite3_key(db, password, Int32(password.count))

        if keyResult == SQLITE_OK {
            // Try to read from database to verify key
            var statement: OpaquePointer?
            let verifyResult = sqlite3_prepare_v2(db, "SELECT count(*) FROM sqlite_master;", -1, &statement, nil)

            if verifyResult == SQLITE_OK {
                sqlite3_finalize(statement)
                print("Encrypted database opened successfully")
                return true
            } else {
                print("Invalid password or corrupted database")
                sqlite3_close(db)
                db = nil
                return false
            }
        }

        return false
    }

    func changePassword(from oldPassword: String, to newPassword: String) -> Bool {
        print("\n--- Changing Database Password ---")

        // Verify old password
        sqlite3_key(db, oldPassword, Int32(oldPassword.count))

        var statement: OpaquePointer?
        if sqlite3_prepare_v2(db, "SELECT count(*) FROM sqlite_master;", -1, &statement, nil) != SQLITE_OK {
            print("Old password is incorrect")
            return false
        }
        sqlite3_finalize(statement)

        // Change password using rekey
        let result = sqlite3_rekey(db, newPassword, Int32(newPassword.count))

        if result == SQLITE_OK {
            print("Password changed successfully")
            return true
        } else {
            print("Failed to change password")
            return false
        }
    }
}

// 8. Connection Health Check
class ConnectionHealthCheck {

    static func checkConnection(_ db: OpaquePointer?) -> Bool {
        guard let db = db else {
            return false
        }

        // Try to execute a simple query
        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, "SELECT 1;", -1, &statement, nil)

        if result == SQLITE_OK {
            sqlite3_finalize(statement)
            return true
        }

        return false
    }

    static func isDatabaseLocked(_ db: OpaquePointer?) -> Bool {
        guard let db = db else { return false }

        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, "BEGIN IMMEDIATE;", -1, &statement, nil)

        if result == SQLITE_BUSY {
            sqlite3_finalize(statement)
            return true
        }

        if result == SQLITE_OK {
            sqlite3_finalize(statement)
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
        }

        return false
    }

    static func getLastError(_ db: OpaquePointer?) -> String {
        guard let db = db else {
            return "No database connection"
        }

        let error = sqlite3_errmsg(db)
        return String(cString: error)
    }

    static func getExtendedErrorCode(_ db: OpaquePointer?) -> Int32 {
        guard let db = db else { return 0 }

        return sqlite3_extended_errcode(db)
    }
}

// 9. Prepared Statement Cache
class StatementCache {

    private var cache: [String: OpaquePointer] = [:]
    private let db: OpaquePointer?
    private let lock = NSLock()

    init(db: OpaquePointer?) {
        self.db = db
    }

    func getStatement(for sql: String) -> OpaquePointer? {
        lock.lock()
        defer { lock.unlock() }

        // Return cached statement if available
        if let statement = cache[sql] {
            sqlite3_reset(statement)
            sqlite3_clear_bindings(statement)
            return statement
        }

        // Prepare new statement
        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        if result == SQLITE_OK {
            cache[sql] = statement
            return statement
        }

        return nil
    }

    func clearCache() {
        lock.lock()
        defer { lock.unlock() }

        for (_, statement) in cache {
            sqlite3_finalize(statement)
        }
        cache.removeAll()
        print("Statement cache cleared")
    }
}

// 10. Database URI Support
class URIConnection {

    func openWithURI(uri: String) -> OpaquePointer? {
        print("\n--- Opening Database with URI ---")

        var db: OpaquePointer?
        let flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI

        let result = sqlite3_open_v2(uri, &db, flags, nil)

        if result == SQLITE_OK {
            print("Database opened with URI: \(uri)")
            return db
        } else {
            let error = String(cString: sqlite3_errmsg(db))
            print("Error opening with URI: \(error)")
            return nil
        }
    }

    func openWithParameters(path: String, readOnly: Bool = false, mode: String = "rwc") -> OpaquePointer? {
        var components = URLComponents()
        components.scheme = "file"
        components.path = path

        var queryItems = [
            URLQueryItem(name: "mode", value: mode)
        ]

        if readOnly {
            queryItems.append(URLQueryItem(name: "readonly", value: "1"))
        }

        components.queryItems = queryItems

        if let uri = components.url?.absoluteString {
            return openWithURI(uri: uri)
        }

        return nil
    }
}

// Main demonstration
func demonstrateSQLiteConnection() {
    print("=== macOS Swift SQLite Connection Examples ===")

    let dbPath = "/tmp/test_database.db"

    // Remove existing database
    try? DatabaseFileManager.deleteDatabase(at: dbPath)

    // 1. Basic connection
    let basicConn = BasicConnection()
    if basicConn.openDatabase(path: dbPath) {
        DatabaseInfo.getDatabaseInfo(basicConn.db)
    }
    basicConn.closeDatabase()

    // 2. In-memory database
    let memDB = InMemoryDatabase()
    if memDB.createInMemoryDatabase() {
        memDB.getDatabaseInfo()
    }

    // 3. Configured connection
    let configuredConn = ConfiguredConnection()
    if configuredConn.openWithConfiguration(path: dbPath) {
        DatabaseInfo.getDatabaseInfo(configuredConn.db)
    }

    // 4. Connection pool
    let pool = SQLiteConnectionPool(databasePath: dbPath, maxConnections: 3)
    if let conn1 = pool.getConnection() {
        print("Got connection 1")
        pool.returnConnection(conn1)
    }

    // 5. Health check
    if let conn2 = pool.getConnection() {
        print("\nConnection healthy: \(ConnectionHealthCheck.checkConnection(conn2))")
        pool.returnConnection(conn2)
    }

    pool.closeAll()

    // 6. Database size
    if let size = DatabaseFileManager.getDatabaseSize(at: dbPath) {
        print("\nDatabase size: \(size) bytes")
    }

    print("\n=== All SQLite Connection Examples Completed ===")
}

// Run demonstration
demonstrateSQLiteConnection()

💻 Execução de Consultas SQL swift

🟡 intermediate ⭐⭐⭐⭐

Executar consultas SELECT, INSERT, UPDATE, DELETE com vinculação de parâmetros apropriada e tratamento de resultados

⏱️ 35 min 🏷️ swift, macos, database, sql
Prerequisites: Intermediate Swift, SQLite C API, SQL knowledge
// macOS Swift SQL Query Execution Examples
// Using SQLite3 C API

import Foundation
import SQLite3

// 1. Execute SQL Statements
class ExecuteSQL {

    func executeStatement(_ db: OpaquePointer?, sql: String) -> Bool {
        print("\n--- Executing SQL ---")
        print("SQL: \(sql)")

        var errMsg: UnsafeMutablePointer<Int8>?

        let result = sqlite3_exec(db, sql, nil, nil, &errMsg)

        if result == SQLITE_OK {
            print("Statement executed successfully")
            return true
        } else {
            if let error = errMsg {
                print("Error: \(String(cString: error))")
                sqlite3_free(errMsg)
            }
            return false
        }
    }

    func executeMultipleStatements(_ db: OpaquePointer?, sql: String) {
        print("\n--- Executing Multiple Statements ---")

        var errMsg: UnsafeMutablePointer<Int8>?
        let result = sqlite3_exec(db, sql, nil, nil, &errMsg)

        if result != SQLITE_OK {
            if let error = errMsg {
                print("Error: \(String(cString: error))")
                sqlite3_free(errMsg)
            }
        } else {
            print("All statements executed successfully")
        }
    }
}

// 2. Create Table
class TableOperations {

    func createUsersTable(_ db: OpaquePointer?) -> Bool {
        let sql = """
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL UNIQUE,
            email TEXT NOT NULL,
            age INTEGER,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
        );
        """

        print("\n--- Creating Users Table ---")
        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        if result == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_DONE {
                print("Users table created successfully")
                sqlite3_finalize(statement)
                return true
            }
        }

        sqlite3_finalize(statement)
        return false
    }

    func createOrdersTable(_ db: OpaquePointer?) -> Bool {
        let sql = """
        CREATE TABLE IF NOT EXISTS orders (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL,
            product_name TEXT NOT NULL,
            quantity INTEGER DEFAULT 1,
            price REAL NOT NULL,
            order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
        );
        """

        print("\n--- Creating Orders Table ---")
        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        if result == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_DONE {
                print("Orders table created successfully")
                sqlite3_finalize(statement)
                return true
            }
        }

        sqlite3_finalize(statement)
        return false
    }

    func createIndex(_ db: OpaquePointer?) -> Bool {
        let sql = "CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);"

        print("\n--- Creating Index ---")
        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        if result == SQLITE_OK {
            if sqlite3_step(statement) == SQLITE_DONE {
                print("Index created successfully")
                sqlite3_finalize(statement)
                return true
            }
        }

        sqlite3_finalize(statement)
        return false
    }
}

// 3. INSERT Operations
class InsertOperations {

    func insertUser(_ db: OpaquePointer?, username: String, email: String, age: Int) -> Int64? {
        print("\n--- Inserting User ---")

        let sql = "INSERT INTO users (username, email, age) VALUES (?, ?, ?);"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            print("Failed to prepare statement")
            return nil
        }

        // Bind parameters
        sqlite3_bind_text(statement, 1, (username as NSString).utf8String, -1, nil)
        sqlite3_bind_text(statement, 2, (email as NSString).utf8String, -1, nil)
        sqlite3_bind_int(statement, 3, Int32(age))

        // Execute
        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let rowId = sqlite3_last_insert_rowid(db)
            print("User inserted with ID: \(rowId)")
            return rowId
        } else {
            print("Failed to insert user")
            return nil
        }
    }

    func insertUserNamed(_ db: OpaquePointer?, params: [String: Any]) -> Int64? {
        print("\n--- Inserting with Named Parameters ---")

        let sql = "INSERT INTO users (username, email, age) VALUES (:username, :email, :age);"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return nil
        }

        // Bind named parameters
        let usernameIndex = sqlite3_bind_parameter_index(statement, ":username")
        let emailIndex = sqlite3_bind_parameter_index(statement, ":email")
        let ageIndex = sqlite3_bind_parameter_index(statement, ":age")

        if let username = params["username"] as? String {
            sqlite3_bind_text(statement, usernameIndex, (username as NSString).utf8String, -1, nil)
        }
        if let email = params["email"] as? String {
            sqlite3_bind_text(statement, emailIndex, (email as NSString).utf8String, -1, nil)
        }
        if let age = params["age"] as? Int {
            sqlite3_bind_int(statement, ageIndex, Int32(age))
        }

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            return sqlite3_last_insert_rowid(db)
        }

        return nil
    }

    func batchInsert(_ db: OpaquePointer?, users: [(String, String, Int)]) -> Int {
        print("\n--- Batch Insert ---")

        let sql = "INSERT INTO users (username, email, age) VALUES (?, ?, ?);"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return 0
        }

        var insertedCount = 0

        // Begin transaction
        sqlite3_exec(db, "BEGIN TRANSACTION;", nil, nil, nil)

        for (username, email, age) in users {
            sqlite3_bind_text(statement, 1, (username as NSString).utf8String, -1, nil)
            sqlite3_bind_text(statement, 2, (email as NSString).utf8String, -1, nil)
            sqlite3_bind_int(statement, 3, Int32(age))

            if sqlite3_step(statement) == SQLITE_DONE {
                insertedCount += 1
            }

            sqlite3_reset(statement)
        }

        // Commit
        sqlite3_exec(db, "COMMIT;", nil, nil, nil)

        sqlite3_finalize(statement)
        print("Batch inserted \(insertedCount) users")

        return insertedCount
    }
}

// 4. SELECT Operations
class SelectOperations {

    struct User {
        let id: Int64
        let username: String
        let email: String
        let age: Int
        let createdAt: String
    }

    func getAllUsers(_ db: OpaquePointer?) -> [User] {
        print("\n--- Selecting All Users ---")

        let sql = "SELECT id, username, email, age, created_at FROM users;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return []
        }

        var users: [User] = []

        while sqlite3_step(statement) == SQLITE_ROW {
            let id = sqlite3_column_int64(statement, 0)
            let username = sqlite3_column_text(statement, 1)
            let email = sqlite3_column_text(statement, 2)
            let age = sqlite3_column_int(statement, 3)
            let createdAt = sqlite3_column_text(statement, 4)

            let user = User(
                id: id,
                username: String(cString: username!),
                email: String(cString: email!),
                age: Int(age),
                createdAt: String(cString: createdAt!)
            )

            users.append(user)
            print("  Found: \(user.username) (\(user.email))")
        }

        sqlite3_finalize(statement)
        print("Total users: \(users.count)")

        return users
    }

    func getUserById(_ db: OpaquePointer?, userId: Int64) -> User? {
        print("\n--- Selecting User by ID ---")

        let sql = "SELECT id, username, email, age, created_at FROM users WHERE id = ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return nil
        }

        sqlite3_bind_int64(statement, 1, userId)

        guard sqlite3_step(statement) == SQLITE_ROW else {
            sqlite3_finalize(statement)
            print("User not found")
            return nil
        }

        let id = sqlite3_column_int64(statement, 0)
        let username = sqlite3_column_text(statement, 1)
        let email = sqlite3_column_text(statement, 2)
        let age = sqlite3_column_int(statement, 3)
        let createdAt = sqlite3_column_text(statement, 4)

        let user = User(
            id: id,
            username: String(cString: username!),
            email: String(cString: email!),
            age: Int(age),
            createdAt: String(cString: createdAt!)
        )

        sqlite3_finalize(statement)
        print("Found: \(user.username)")

        return user
    }

    func searchUsers(_ db: OpaquePointer?, searchTerm: String) -> [User] {
        print("\n--- Searching Users ---")
        print("Search term: \(searchTerm)")

        let sql = "SELECT id, username, email, age, created_at FROM users WHERE username LIKE ? OR email LIKE ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return []
        }

        let pattern = "%\(searchTerm)%"

        sqlite3_bind_text(statement, 1, (pattern as NSString).utf8String, -1, nil)
        sqlite3_bind_text(statement, 2, (pattern as NSString).utf8String, -1, nil)

        var users: [User] = []

        while sqlite3_step(statement) == SQLITE_ROW {
            let id = sqlite3_column_int64(statement, 0)
            let username = sqlite3_column_text(statement, 1)
            let email = sqlite3_column_text(statement, 2)
            let age = sqlite3_column_int(statement, 3)
            let createdAt = sqlite3_column_text(statement, 4)

            let user = User(
                id: id,
                username: String(cString: username!),
                email: String(cString: email!),
                age: Int(age),
                createdAt: String(cString: createdAt!)
            )

            users.append(user)
        }

        sqlite3_finalize(statement)
        print("Found \(users.count) users")

        return users
    }
}

// 5. UPDATE Operations
class UpdateOperations {

    func updateUserAge(_ db: OpaquePointer?, userId: Int64, newAge: Int) -> Bool {
        print("\n--- Updating User Age ---")

        let sql = "UPDATE users SET age = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return false
        }

        sqlite3_bind_int(statement, 1, Int32(newAge))
        sqlite3_bind_int64(statement, 2, userId)

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Updated \(changes) row(s)")
            return changes > 0
        }

        return false
    }

    func updateUserEmail(_ db: OpaquePointer?, userId: Int64, newEmail: String) -> Bool {
        print("\n--- Updating User Email ---")

        let sql = "UPDATE users SET email = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return false
        }

        sqlite3_bind_text(statement, 1, (newEmail as NSString).utf8String, -1, nil)
        sqlite3_bind_int64(statement, 2, userId)

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Updated \(changes) row(s)")
            return changes > 0
        }

        return false
    }

    func bulkUpdate(_ db: OpaquePointer?, minAge: Int, newAge: Int) -> Int {
        print("\n--- Bulk Update ---")

        let sql = "UPDATE users SET age = ?, updated_at = CURRENT_TIMESTAMP WHERE age < ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return 0
        }

        sqlite3_bind_int(statement, 1, Int32(newAge))
        sqlite3_bind_int(statement, 2, Int32(minAge))

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Updated \(changes) rows")
            return Int(changes)
        }

        return 0
    }
}

// 6. DELETE Operations
class DeleteOperations {

    func deleteUserById(_ db: OpaquePointer?, userId: Int64) -> Bool {
        print("\n--- Deleting User by ID ---")

        let sql = "DELETE FROM users WHERE id = ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return false
        }

        sqlite3_bind_int64(statement, 1, userId)

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Deleted \(changes) row(s)")
            return changes > 0
        }

        return false
    }

    func deleteUsersByAge(_ db: OpaquePointer?, maxAge: Int) -> Int {
        print("\n--- Deleting Users by Age ---")

        let sql = "DELETE FROM users WHERE age > ?;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return 0
        }

        sqlite3_bind_int(statement, 1, Int32(maxAge))

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Deleted \(changes) rows")
            return Int(changes)
        }

        return 0
    }

    func deleteAllUsers(_ db: OpaquePointer?) -> Bool {
        print("\n--- Deleting All Users ---")

        let sql = "DELETE FROM users;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return false
        }

        let result = sqlite3_step(statement)
        sqlite3_finalize(statement)

        if result == SQLITE_DONE {
            let changes = sqlite3_changes(db)
            print("Deleted \(changes) row(s)")
            return true
        }

        return false
    }
}

// 7. Aggregate Queries
class AggregateQueries {

    func getUserCount(_ db: OpaquePointer?) -> Int {
        print("\n--- Getting User Count ---")

        let sql = "SELECT COUNT(*) FROM users;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return 0
        }

        guard sqlite3_step(statement) == SQLITE_ROW else {
            sqlite3_finalize(statement)
            return 0
        }

        let count = sqlite3_column_int(statement, 0)
        sqlite3_finalize(statement)

        print("Total users: \(count)")
        return Int(count)
    }

    func getAverageAge(_ db: OpaquePointer?) -> Double {
        print("\n--- Getting Average Age ---")

        let sql = "SELECT AVG(age) FROM users;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return 0
        }

        guard sqlite3_step(statement) == SQLITE_ROW else {
            sqlite3_finalize(statement)
            return 0
        }

        let avgAge = sqlite3_column_double(statement, 0)
        sqlite3_finalize(statement)

        print("Average age: \(avgAge)")
        return avgAge
    }

    func getAgeStats(_ db: OpaquePointer?) -> (min: Int, max: Int, avg: Double)? {
        print("\n--- Getting Age Statistics ---")

        let sql = "SELECT MIN(age), MAX(age), AVG(age) FROM users;"
        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return nil
        }

        guard sqlite3_step(statement) == SQLITE_ROW else {
            sqlite3_finalize(statement)
            return nil
        }

        let minAge = sqlite3_column_int(statement, 0)
        let maxAge = sqlite3_column_int(statement, 1)
        let avgAge = sqlite3_column_double(statement, 2)

        sqlite3_finalize(statement)

        print("Age stats - Min: \(minAge), Max: \(maxAge), Avg: \(avgAge)")

        return (Int(minAge), Int(maxAge), avgAge)
    }
}

// 8. JOIN Queries
class JoinQueries {

    func getUsersWithOrders(_ db: OpaquePointer?) {
        print("\n--- Users with Orders ---")

        let sql = """
        SELECT u.username, u.email, COUNT(o.id) as order_count
        FROM users u
        LEFT JOIN orders o ON u.id = o.user_id
        GROUP BY u.id;
        """

        var statement: OpaquePointer?

        guard sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK else {
            return
        }

        print("Users and their order counts:")
        while sqlite3_step(statement) == SQLITE_ROW {
            let username = sqlite3_column_text(statement, 0)
            let email = sqlite3_column_text(statement, 1)
            let orderCount = sqlite3_column_int(statement, 2)

            print("  \(String(cString: username!)): \(orderCount) orders")
        }

        sqlite3_finalize(statement)
    }
}

// 9. Parameter Binding
class ParameterBinding {

    func demonstrateBinding(_ db: OpaquePointer?) {
        print("\n--- Parameter Binding Examples ---")

        // TEXT binding
        var statement: OpaquePointer?
        let textSQL = "SELECT * FROM users WHERE username = ?;"
        sqlite3_prepare_v2(db, textSQL, -1, &statement, nil)

        // Bind TEXT with explicit length
        let username = "john_doe"
        sqlite3_bind_text(statement, 1, (username as NSString).utf8String, -1, nil)
        print("Bound TEXT: \(username)")

        // INTEGER binding
        let intSQL = "SELECT * FROM users WHERE age = ?;"
        sqlite3_prepare_v2(db, intSQL, -1, &statement, nil)
        sqlite3_bind_int(statement, 1, 25)
        print("Bound INTEGER: 25")

        // REAL binding
        let realSQL = "SELECT * FROM orders WHERE price > ?;"
        sqlite3_prepare_v2(db, realSQL, -1, &statement, nil)
        sqlite3_bind_double(statement, 1, 99.99)
        print("Bound REAL: 99.99")

        // BLOB binding
        let blobSQL = "INSERT INTO files (name, data) VALUES (?, ?);"
        sqlite3_prepare_v2(db, blobSQL, -1, &statement, nil)

        let data = "Hello World".data(using: .utf8)!
        data.withUnsafeBytes { bytes in
            sqlite3_bind_blob(statement, 2, bytes.baseAddress, Int32(data.count), nil)
        }
        print("Bound BLOB: \(data.count) bytes")

        // NULL binding
        sqlite3_bind_null(statement, 1)
        print("Bound NULL")

        sqlite3_finalize(statement)
    }
}

// 10. Error Handling
class ErrorHandling {

    func executeWithErrorHandling(_ db: OpaquePointer?, sql: String) {
        print("\n--- Executing with Error Handling ---")

        var statement: OpaquePointer?
        let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        if result != SQLITE_OK {
            let error = String(cString: sqlite3_errmsg(db))
            let extendedCode = sqlite3_extended_errcode(db)
            print("Error (\(extendedCode)): \(error)")
            return
        }

        // Execute and check for errors
        let stepResult = sqlite3_step(statement)

        if stepResult != SQLITE_ROW && stepResult != SQLITE_DONE {
            let error = String(cString: sqlite3_errmsg(db))
            print("Step error: \(error)")
        }

        sqlite3_finalize(statement)
        print("Statement executed successfully")
    }

    func checkForErrors(_ db: OpaquePointer?) {
        print("\n--- Checking for Errors ---")

        let result = sqlite3_errcode(db)

        if result != SQLITE_OK {
            let error = String(cString: sqlite3_errmsg(db))
            let extendedResult = sqlite3_extended_errcode(db)

            print("Last error code: \(result)")
            print("Extended error code: \(extendedResult)")
            print("Error message: \(error)")
        } else {
            print("No errors")
        }
    }
}

// Main demonstration
func demonstrateSQLQueryExecution() {
    print("=== macOS Swift SQL Query Execution Examples ===")

    let dbPath = "/tmp/test_queries.db"

    // Open database
    var db: OpaquePointer?
    if sqlite3_open(dbPath, &db) == SQLITE_OK {
        print("Database opened")

        // Create tables
        let tableOps = TableOperations()
        tableOps.createUsersTable(db)
        tableOps.createOrdersTable(db)
        tableOps.createIndex(db)

        // Insert users
        let insertOps = InsertOperations()
        _ = insertOps.insertUser(db, username: "john_doe", email: "[email protected]", age: 30)
        _ = insertOps.insertUser(db, username: "jane_smith", email: "[email protected]", age: 25)
        _ = insertOps.insertUser(db, username: "bob_wilson", email: "[email protected]", age: 35)

        // Batch insert
        let batchUsers = [
            ("user1", "[email protected]", 20),
            ("user2", "[email protected]", 22),
            ("user3", "[email protected]", 28)
        ]
        insertOps.batchInsert(db, users: batchUsers)

        // Select operations
        let selectOps = SelectOperations()
        _ = selectOps.getAllUsers(db)
        _ = selectOps.getUserById(db, userId: 1)
        _ = selectOps.searchUsers(db, searchTerm: "john")

        // Update operations
        let updateOps = UpdateOperations()
        updateOps.updateUserAge(db, userId: 1, newAge: 31)
        updateOps.bulkUpdate(db, minAge: 25, newAge: 26)

        // Aggregate queries
        let aggOps = AggregateQueries()
        _ = aggOps.getUserCount(db)
        _ = aggOps.getAverageAge(db)
        _ = aggOps.getAgeStats(db)

        // Delete operations
        let deleteOps = DeleteOperations()
        deleteOps.deleteUserById(db, userId: 3)

        // Cleanup
        sqlite3_close(db)
        print("\nDatabase closed")
    }

    print("\n=== All SQL Query Execution Examples Completed ===")
}

// Run demonstration
demonstrateSQLQueryExecution()

💻 Processamento de Transações swift

🔴 complex ⭐⭐⭐⭐

Gerenciar transações de banco de dados com operações BEGIN, COMMIT e ROLLBACK

⏱️ 40 min 🏷️ swift, macos, database, transactions
Prerequisites: Advanced Swift, SQLite C API, Transaction concepts
// macOS Swift Transaction Processing Examples
// Using SQLite3 C API

import Foundation
import SQLite3

// 1. Basic Transaction
class BasicTransaction {

    func executeInTransaction(_ db: OpaquePointer?, operations: () -> Bool) -> Bool {
        print("\n--- Basic Transaction ---")

        // Begin transaction
        if sqlite3_exec(db, "BEGIN TRANSACTION;", nil, nil, nil) != SQLITE_OK {
            print("Failed to begin transaction")
            return false
        }

        print("Transaction started")

        // Execute operations
        let success = operations()

        if success {
            // Commit
            if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                print("Transaction committed")
                return true
            } else {
                print("Failed to commit transaction")
                return false
            }
        } else {
            // Rollback
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Transaction rolled back")
            return false
        }
    }
}

// 2. Immediate Transaction
class ImmediateTransaction {

    func executeImmediate(_ db: OpaquePointer?, operations: () -> Bool) -> Bool {
        print("\n--- Immediate Transaction ---")

        // BEGIN IMMEDIATE acquires reserved lock immediately
        if sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil) != SQLITE_OK {
            print("Failed to begin immediate transaction")
            return false
        }

        print("Immediate transaction started (reserved lock acquired)")

        let success = operations()

        if success {
            if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                print("Transaction committed")
                return true
            }
        } else {
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Transaction rolled back")
        }

        return false
    }
}

// 3. Exclusive Transaction
class ExclusiveTransaction {

    func executeExclusive(_ db: OpaquePointer?, operations: () -> Bool) -> Bool {
        print("\n--- Exclusive Transaction ---")

        // BEGIN EXCLUSIVE acquires exclusive lock immediately
        if sqlite3_exec(db, "BEGIN EXCLUSIVE;", nil, nil, nil) != SQLITE_OK {
            print("Failed to begin exclusive transaction")
            return false
        }

        print("Exclusive transaction started (exclusive lock acquired)")

        let success = operations()

        if success {
            if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                print("Transaction committed")
                return true
            }
        } else {
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Transaction rolled back")
        }

        return false
    }
}

// 4. Transaction with Savepoints
class SavepointTransaction {

    func executeWithSavepoints(_ db: OpaquePointer?) {
        print("\n--- Transaction with Savepoints ---")

        // Start transaction
        sqlite3_exec(db, "BEGIN;", nil, nil, nil)

        // First savepoint
        print("Creating savepoint 'update_users'")
        sqlite3_exec(db, "SAVEPOINT update_users;", nil, nil, nil)

        // Perform some operations
        // ... (simulated operations)

        // Second savepoint
        print("Creating savepoint 'update_orders'")
        sqlite3_exec(db, "SAVEPOINT update_orders;", nil, nil, nil)

        // More operations
        // ...

        // Release second savepoint
        sqlite3_exec(db, "RELEASE update_orders;", nil, nil, nil)
        print("Released savepoint 'update_orders'")

        // Rollback first savepoint
        sqlite3_exec(db, "ROLLBACK TO update_users;", nil, nil, nil)
        sqlite3_exec(db, "RELEASE update_users;", nil, nil, nil)
        print("Rolled back to 'update_users'")

        // Commit transaction
        sqlite3_exec(db, "COMMIT;", nil, nil, nil)
        print("Transaction committed")
    }
}

// 5. Nested Transactions
class NestedTransactions {

    func executeNestedTransactions(_ db: OpaquePointer?) {
        print("\n--- Nested Transactions ---")

        // Outer transaction
        sqlite3_exec(db, "BEGIN;", nil, nil, nil)
        print("Outer transaction started")

        // Inner transaction using savepoint
        sqlite3_exec(db, "SAVEPOINT inner_trans;", nil, nil, nil)
        print("Inner transaction (savepoint) started")

        // Perform operations
        // ...

        // Commit inner
        sqlite3_exec(db, "RELEASE inner_trans;", nil, nil, nil)
        print("Inner transaction committed")

        // More outer operations
        // ...

        // Commit outer
        sqlite3_exec(db, "COMMIT;", nil, nil, nil)
        print("Outer transaction committed")
    }
}

// 6. Transaction with Retry
class TransactionWithRetry {

    func executeWithRetry(_ db: OpaquePointer?, operations: () -> Bool, maxRetries: Int = 3) -> Bool {
        print("\n--- Transaction with Retry ---")

        for attempt in 1...maxRetries {
            print("Attempt \(attempt)")

            // Begin transaction
            if sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil) != SQLITE_OK {
                let error = String(cString: sqlite3_errmsg(db))
                print("Failed to begin: \(error)")

                if attempt < maxRetries {
                    print("Retrying in 100ms...")
                    Thread.sleep(forTimeInterval: 0.1)
                }
                continue
            }

            // Execute operations
            let success = operations()

            if success {
                if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                    print("Transaction committed successfully")
                    return true
                }
            } else {
                sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
                print("Transaction failed, rolled back")
            }

            if attempt < maxRetries {
                print("Retrying in 100ms...")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        print("Transaction failed after \(maxRetries) attempts")
        return false
    }
}

// 7. Batch Operations in Transaction
class BatchTransaction {

    func batchInsert(_ db: OpaquePointer?, records: [[String: Any]], tableName: String) -> Int {
        print("\n--- Batch Insert in Transaction ---")

        // Begin transaction
        sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil)

        var insertedCount = 0
        var statement: OpaquePointer?

        // Prepare statement
        let sql = "INSERT INTO \(tableName) (username, email, age) VALUES (?, ?, ?);"
        sqlite3_prepare_v2(db, sql, -1, &statement, nil)

        for record in records {
            // Clear previous bindings
            sqlite3_clear_bindings(statement)
            sqlite3_reset(statement)

            // Bind parameters
            if let username = record["username"] as? String {
                sqlite3_bind_text(statement, 1, (username as NSString).utf8String, -1, nil)
            }
            if let email = record["email"] as? String {
                sqlite3_bind_text(statement, 2, (email as NSString).utf8String, -1, nil)
            }
            if let age = record["age"] as? Int {
                sqlite3_bind_int(statement, 3, Int32(age))
            }

            // Execute
            if sqlite3_step(statement) == SQLITE_DONE {
                insertedCount += 1
            }
        }

        sqlite3_finalize(statement)

        // Commit if at least one record inserted
        if insertedCount > 0 {
            sqlite3_exec(db, "COMMIT;", nil, nil, nil)
            print("Batch insert completed: \(insertedCount) records")
        } else {
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Batch insert failed, rolled back")
        }

        return insertedCount
    }
}

// 8. Transaction Isolation Levels
class IsolationLevels {

    func setReadUncommitted(_ db: OpaquePointer?) {
        print("\n--- Setting Read Uncommitted ---")
        sqlite3_exec(db, "PRAGMA read_uncommitted = true;", nil, nil, nil)
        print("Read uncommitted enabled (dirty reads allowed)")
    }

    func setIsolationLevel(_ db: OpaquePointer?, level: String) {
        print("\n--- Setting Isolation Level ---")

        let levels = [
            "DEFERRED",
            "IMMEDIATE",
            "EXCLUSIVE"
        ]

        if levels.contains(level.uppercased()) {
            let sql = "BEGIN \(level.uppercased()) TRANSACTION;"
            sqlite3_exec(db, sql, nil, nil, nil)
            print("Isolation level set to: \(level.uppercased())")
        }
    }
}

// 9. Transaction Timeout
class TransactionTimeout {

    func executeWithTimeout(_ db: OpaquePointer?, timeout: TimeInterval, operations: @escaping () -> Bool) -> Bool {
        print("\n--- Transaction with Timeout ---")

        // Set busy timeout
        sqlite3_busy_timeout(db, Int32(timeout * 1000))

        // Try to begin transaction
        let startTime = Date()

        while Date().timeIntervalSince(startTime) < timeout {
            if sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil) == SQLITE_OK {
                print("Transaction started")

                let success = operations()

                if success {
                    if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                        print("Transaction committed")
                        return true
                    }
                } else {
                    sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
                }

                return false
            }

            Thread.sleep(forTimeInterval: 0.1)
        }

        print("Transaction timeout after \(timeout) seconds")
        return false
    }
}

// 10. Transaction Monitoring
class TransactionMonitor {

    func getTransactionStatus(_ db: OpaquePointer?) -> Bool {
        print("\n--- Transaction Status ---")

        var statement: OpaquePointer?
        let sql = "SELECT COUNT(*) FROM sqlite_master WHERE name = 'sqlite_sequence';"

        if sqlite3_prepare_v2(db, sql, -1, &statement, nil) == SQLITE_OK {
            sqlite3_step(statement)
            sqlite3_finalize(statement)
        }

        // Check if in transaction by attempting a rollback
        // Note: This is a simplified check
        let inTransaction = sqlite3_get_autocommit(db) == 0

        print("In transaction: \(inTransaction)")

        return inTransaction
    }

    func monitorTransaction(_ db: OpaquePointer?) {
        print("\n--- Monitoring Transaction ---")

        var changesBefore = sqlite3_total_changes(db)

        // Begin transaction
        sqlite3_exec(db, "BEGIN;", nil, nil, nil)

        // Perform operations
        // ... (simulated)
        sqlite3_exec(db, "INSERT INTO users (username, email, age) VALUES ('test', '[email protected]', 25);", nil, nil, nil)

        var changesDuring = sqlite3_total_changes(db)

        // Commit
        sqlite3_exec(db, "COMMIT;", nil, nil, nil)

        var changesAfter = sqlite3_total_changes(db)

        print("Changes before transaction: \(changesBefore)")
        print("Changes during transaction: \(changesDuring)")
        print("Changes after transaction: \(changesAfter)")
    }
}

// 11. ACID Properties Demo
class ACIDDemo {

    func demonstrateAtomicity(_ db: OpaquePointer?) {
        print("\n--- Demonstrating Atomicity ---")

        sqlite3_exec(db, "BEGIN;", nil, nil, nil)

        let insertSQL1 = "INSERT INTO users (username, email, age) VALUES ('test1', '[email protected]', 25);"
        let insertSQL2 = "INSERT INTO users (username, email, age) VALUES ('test2', '[email protected]', 30);"

        var success1 = sqlite3_exec(db, insertSQL1, nil, nil, nil) == SQLITE_OK
        var success2 = sqlite3_exec(db, insertSQL2, nil, nil, nil) == SQLITE_OK

        if success1 && success2 {
            sqlite3_exec(db, "COMMIT;", nil, nil, nil)
            print("Both inserts committed (atomic)")
        } else {
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("One or more inserts failed, rolled back (atomic)")
        }
    }

    func demonstrateConsistency(_ db: OpaquePointer?) {
        print("\n--- Demonstrating Consistency ---")

        sqlite3_exec(db, "BEGIN;", nil, nil, nil)

        // Insert valid data
        let validSQL = "INSERT INTO users (username, email, age) VALUES ('valid', '[email protected]', 25);"
        sqlite3_exec(db, validSQL, nil, nil, nil)

        // Try to insert invalid data (violates constraint)
        let invalidSQL = "INSERT INTO users (username, email, age) VALUES ('valid', '[email protected]', 30);"

        if sqlite3_exec(db, invalidSQL, nil, nil, nil) == SQLITE_OK {
            sqlite3_exec(db, "COMMIT;", nil, nil, nil)
        } else {
            print("Constraint violation detected")
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Transaction rolled back (consistency maintained)")
        }
    }

    func demonstrateIsolation(_ db: OpaquePointer?) {
        print("\n--- Demonstrating Isolation ---")

        // This would require two separate database connections to fully demonstrate
        // Simplified example showing transaction isolation

        sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil)

        let selectSQL = "SELECT COUNT(*) FROM users;"
        var statement: OpaquePointer?

        sqlite3_prepare_v2(db, selectSQL, -1, &statement, nil)
        sqlite3_step(statement)
        let count = sqlite3_column_int(statement, 0)
        sqlite3_finalize(statement)

        print("Count in transaction: \(count)")

        sqlite3_exec(db, "COMMIT;", nil, nil, nil)
    }

    func demonstrateDurability(_ db: OpaquePointer?) {
        print("\n--- Demonstrating Durability ---")

        // Sync mode ensures durability
        sqlite3_exec(db, "PRAGMA synchronous = FULL;", nil, nil, nil)

        sqlite3_exec(db, "BEGIN;", nil, nil, nil)

        let insertSQL = "INSERT INTO users (username, email, age) VALUES ('durable', '[email protected]', 25);"
        sqlite3_exec(db, insertSQL, nil, nil, nil)

        if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
            print("Data committed to disk (durable)")

            // Force flush
            sqlite3_exec(db, "PRAGMA wal_checkpoint(TRUNCATE);", nil, nil, nil)
        }
    }
}

// 12. Error Recovery Transaction
class ErrorRecoveryTransaction {

    func executeWithErrorRecovery(_ db: OpaquePointer?, operations: () -> Bool) -> Bool {
        print("\n--- Transaction with Error Recovery ---")

        // Start with IMMEDIATE to reserve locks
        guard sqlite3_exec(db, "BEGIN IMMEDIATE;", nil, nil, nil) == SQLITE_OK else {
            // If busy, try deferred
            print("IMMEDIATE failed, trying DEFERRED...")
            guard sqlite3_exec(db, "BEGIN DEFERRED;", nil, nil, nil) == SQLITE_OK else {
                print("Failed to begin transaction")
                return false
            }
        }

        print("Transaction started")

        let success = operations()

        if success {
            if sqlite3_exec(db, "COMMIT;", nil, nil, nil) == SQLITE_OK {
                print("Transaction committed")
                return true
            } else {
                // Commit failed, try rollback
                print("Commit failed, rolling back...")
                sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
                return false
            }
        } else {
            sqlite3_exec(db, "ROLLBACK;", nil, nil, nil)
            print("Operations failed, rolled back")
            return false
        }
    }
}

// Main demonstration
func demonstrateTransactionProcessing() {
    print("=== macOS Swift Transaction Processing Examples ===")

    let dbPath = "/tmp/test_transactions.db"

    // Open database
    var db: OpaquePointer?
    if sqlite3_open(dbPath, &db) == SQLITE_OK {
        // Create table
        let createSQL = """
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL UNIQUE,
            email TEXT NOT NULL,
            age INTEGER
        );
        """
        sqlite3_exec(db, createSQL, nil, nil, nil)

        // 1. Basic transaction
        let basicTrans = BasicTransaction()
        basicTrans.executeInTransaction(db) {
            // Insert user
            var statement: OpaquePointer?
            let sql = "INSERT INTO users (username, email, age) VALUES ('john', '[email protected]', 30);"

            let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)
            if result == SQLITE_OK {
                let stepResult = sqlite3_step(statement)
                sqlite3_finalize(statement)
                return stepResult == SQLITE_DONE
            }
            return false
        }

        // 2. Immediate transaction
        let immediateTrans = ImmediateTransaction()
        immediateTrans.executeImmediate(db) {
            var statement: OpaquePointer?
            let sql = "INSERT INTO users (username, email, age) VALUES ('jane', '[email protected]', 25);"

            let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)
            if result == SQLITE_OK {
                let stepResult = sqlite3_step(statement)
                sqlite3_finalize(statement)
                return stepResult == SQLITE_DONE
            }
            return false
        }

        // 3. Savepoints
        let savepointTrans = SavepointTransaction()
        savepointTrans.executeWithSavepoints(db)

        // 4. ACID demo
        let acidDemo = ACIDDemo()
        acidDemo.demonstrateAtomicity(db)
        acidDemo.demonstrateConsistency(db)
        acidDemo.demonstrateIsolation(db)
        acidDemo.demonstrateDurability(db)

        // 5. Batch transaction
        let batchTrans = BatchTransaction()
        let records = [
            ["username": "user1", "email": "[email protected]", "age": 20],
            ["username": "user2", "email": "[email protected]", "age": 22],
            ["username": "user3", "email": "[email protected]", "age": 28]
        ]
        batchTrans.batchInsert(db, records: records, tableName: "users")

        // Cleanup
        sqlite3_close(db)
        print("\nDatabase closed")
    }

    print("\n=== All Transaction Processing Examples Completed ===")
}

// Run demonstration
demonstrateTransactionProcessing()