Skip to content

Commit 1a02860

Browse files
committed
feat: implemented new SQLiteCloudVM (virtual machine)
feat: added new SQLiteCloudProvider protocol
1 parent c284743 commit 1a02860

File tree

8 files changed

+1210
-18
lines changed

8 files changed

+1210
-18
lines changed

Sources/SQLiteCloud/Core/SQLiteCloud.swift

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import Darwin
5151
/// - SeeAlso: `SQLiteCloudConfig` for configuring the SQLite Cloud connection.
5252
/// - SeeAlso: `SQLiteCloudCommand` for representing SQL commands and queries.
5353
/// - SeeAlso: `SQLiteCloudResult` for representing the result of database operations.
54-
public final actor SQLiteCloud {
54+
public final actor SQLiteCloud: SQLiteCloudProvider {
5555
/// The sqlcloud connection opaque pointer.
5656
///
5757
/// This property represents an opaque pointer to the SQLite Cloud connection.
@@ -1144,3 +1144,51 @@ public extension SQLiteCloud {
11441144
}
11451145
}
11461146
}
1147+
1148+
// MARK: - VM API
1149+
1150+
public extension SQLiteCloud {
1151+
/// Compiles an SQL query into a byte-code virtual machine (VM). This method creates a
1152+
/// `SQLiteCloudVM` instance that you can use to execute the compiled SQL statement.
1153+
///
1154+
/// - Parameters:
1155+
/// - query: The SQL query to compile.
1156+
///
1157+
/// - Throws:
1158+
/// - `SQLiteCloudError.connectionFailure`: If the connection to the SQLite Cloud
1159+
/// backend has failed. More details can be found in the associated value
1160+
/// `SQLiteCloudError.ConnectionContext`.
1161+
///
1162+
/// - `SQLiteCloudError.handleError`: If an error occurs while handling the SQLite
1163+
/// Cloud operation.
1164+
///
1165+
/// - Returns:
1166+
/// A `SQLiteCloudVM` instance representing the compiled virtual machine for the SQL
1167+
/// query. You can use this VM to execute the SQL statement.
1168+
///
1169+
/// Example usage:
1170+
///
1171+
/// ```swift
1172+
/// let query = "SELECT * FROM your_table"
1173+
/// let vm = try await sqliteCloud.compile(query: query)
1174+
/// try await vm.step()
1175+
/// ```
1176+
func compile(query: String) async throws -> SQLiteCloudVM {
1177+
// Checks if connection is open and valid.
1178+
let conn = try getConnection()
1179+
1180+
// Compile an SQL statement into a byte-code virtual machine.
1181+
// This function resembles the sqlite3_prepare SQLite API.
1182+
let vm = SQCloudVMCompile(conn, query, -1, nil)
1183+
1184+
// Checks if compile is failed.
1185+
guard let vm = vm else {
1186+
let error = SQLiteCloudError.handleError(connection: conn)
1187+
logError(category: "VIRTUAL MACHINE", message: "🚨 VM compile failed: \(error)")
1188+
throw error
1189+
}
1190+
1191+
logInfo(category: "VIRTUAL MACHINE", message: "🚀 '\(query)' virtual machine created succesfully")
1192+
return SQLiteCloudVM(vm: vm)
1193+
}
1194+
}

Sources/SQLiteCloud/Core/SQLiteCloudError+Internal.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,15 @@ extension SQLiteCloudError.ExecutionContext {
3939
extension SQLiteCloudError.TaskError {
4040
static let urlHandlerFailed = SQLiteCloudError.TaskError(code: -5, message: "Cannot create URL Handler")
4141
static let cannotCreateOutputFile = SQLiteCloudError.TaskError(code: -6, message: "Cannot create output file")
42-
static let invalidNumberOfRows = SQLiteCloudError.TaskError(code: -6, message: "Invalid number of rows.")
43-
static let invalidBlobSizeRead = SQLiteCloudError.TaskError(code: -7, message: "Invalid blob size read.")
44-
static let errorWritingBlob = SQLiteCloudError.TaskError(code: -8, message: "Error writing blob.")
42+
static let invalidNumberOfRows = SQLiteCloudError.TaskError(code: -7, message: "Invalid number of rows.")
43+
static let invalidBlobSizeRead = SQLiteCloudError.TaskError(code: -8, message: "Invalid blob size read.")
44+
static let errorWritingBlob = SQLiteCloudError.TaskError(code: -9, message: "Error writing blob.")
45+
}
46+
47+
extension SQLiteCloudError.VMContext {
48+
static func invalidParameterIndex(index: Int) -> SQLiteCloudError.VMContext {
49+
SQLiteCloudError.VMContext(code: -10, message: "Invalid parameter index [\(index)].")
50+
}
4551
}
4652

4753
extension SQLiteCloudError {
@@ -63,4 +69,12 @@ extension SQLiteCloudError {
6369

6470
return SQLiteCloudError.unhandledError
6571
}
72+
73+
static func handleVMError(vm: OpaquePointer?) -> SQLiteCloudError {
74+
let code = Int(SQCloudVMErrorCode(vm))
75+
let message = String(SQCloudVMErrorMsg(vm))
76+
77+
let context = SQLiteCloudError.VMContext(code: code, message: message)
78+
return SQLiteCloudError.virtualMachineFailure(context)
79+
}
6680
}

Sources/SQLiteCloud/Core/SQLiteCloudError.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public enum SQLiteCloudError: Error, Sendable {
4949
/// An indication that a upload or download task error has occurred.
5050
/// More detailt can be found in the associated value `SQLiteCloudError.TaskError`
5151
case taskError(SQLiteCloudError.TaskError)
52+
53+
/// An indication that the virtual machine has failed.
54+
/// The reasons can be of various types.
55+
/// More details can be found in the associated value `SQLiteCloudError.VMContext`.
56+
case virtualMachineFailure(SQLiteCloudError.VMContext)
5257
}
5358

5459
public extension SQLiteCloudError {
@@ -93,4 +98,13 @@ public extension SQLiteCloudError {
9398
/// The errore message.
9499
public let message: String
95100
}
101+
102+
/// The context in which the virtual machine error occurred.
103+
struct VMContext: Sendable {
104+
/// The error code.
105+
public let code: Int
106+
107+
/// The errore message.
108+
public let message: String
109+
}
96110
}

0 commit comments

Comments
 (0)