Home > Blockchain >  SQLite statement Sendable
SQLite statement Sendable

Time:10-31

I'm writing my own SQLite wrapper in Swift and I was wondering if the SQLite statement can be made Sendable or whether it would be better to make it an actor.

import SQLite

struct Statement: Sendable {
    private(set) var handle: OpaquePointer?

    init(sql: String, connection: OpaquePointer) {
        sqlite3_prepare_v2(connection, sql, -1, &handle, nil)
    }

    public func finalize() {
        guard let handle else { return }
        sqlite3_finalize(handle)
    }
}

// Resulting in
let connection: OpaquePointer = ...
let statement = Statement(sql: "", connection: connection)
statement.finalize()

Or using an actor implementation

import SQLite3

actor Statement {
    private(set) var handle: OpaquePointer?

    init(sql: String, connection: OpaquePointer) {
        sqlite3_prepare_v2(connection, sql, -1, &handle, nil)
    }

    public func finalize() {
        guard let handle else { return }
        sqlite3_finalize(handle)
    }
}

// Resulting in
let connection: OpaquePointer = ...
let statement = Statement(sql: "", connection: connection)
await statement.finalize()

I'm mostly curious as to how Sendable affects the OpaquePointer, if it does, and whether an actor implementation might solve potential issues with the OpaquePointer. The SQLite syntax makes me believe it's pass by reference, even though I'd assume a statement could or should be made pass by value, hence my struct Statement: Sendable protocol. I'm just not sure if that will work.

CodePudding user response:

An OpaquePointer is, by definition, a reference type (as it is a C pointer).

Regarding providing synchronization via an actor, SQLite has three threading modes, and the iOS default is that it is safe to use database connection from multiple threads, but not simultaneously. So, yes, you would want to use an actor.

  • Related