Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.
Open
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
38 changes: 38 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "Swift",
"image": "swift:6.1",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "false",
"username": "vscode",
// "userUid": "1000",
// "userGid": "1000",
"upgradePackages": "false"
},
"ghcr.io/devcontainers/features/git:1": {
"version": "os-provided",
"ppa": "false"
}
},
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"lldb.library": "/usr/lib/liblldb.so"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["swiftlang.swift-vscode"]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "swift --version",

// Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}
54 changes: 54 additions & 0 deletions Sources/Kuzu/Connection+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// kuzu-swift
// https://github.com/kuzudb/kuzu-swift
//
// Copyright © 2023 - 2025 Kùzu Inc.
// This code is licensed under MIT license (see LICENSE for details)

import cxx_kuzu

@_spi(Typed)
extension Connection {
public func execute_(
_ preparedStatement: PreparedStatement,
_ parameters: [String: any KuzuEncodable]
) throws -> QueryResult {
var cQueryResult = kuzu_query_result()
for (key, value) in parameters {
let kuzuValue = try value.kuzuValue()
let state = kuzu_prepared_statement_bind_value(
&preparedStatement.cPreparedStatement,
key,
kuzuValue.ptr
)
if state != KuzuSuccess {
throw KuzuError.queryExecutionFailed(
"Failed to bind value with status \(state)"
)
}
}
kuzu_connection_execute(
&cConnection,
&preparedStatement.cPreparedStatement,
&cQueryResult
)
if !kuzu_query_result_is_success(&cQueryResult) {
let cErrorMesage: UnsafeMutablePointer<CChar>? =
kuzu_query_result_get_error_message(&cQueryResult)
defer {
kuzu_query_result_destroy(&cQueryResult)
kuzu_destroy_string(cErrorMesage)
}
if cErrorMesage == nil {
throw KuzuError.queryExecutionFailed(
"Query execution failed with an unknown error."
)
} else {
let errorMessage = String(cString: cErrorMesage!)
throw KuzuError.queryExecutionFailed(errorMessage)
}
}
let queryResult = QueryResult(self, cQueryResult)
return queryResult
}
}
2 changes: 1 addition & 1 deletion Sources/Kuzu/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Copyright © 2023 - 2025 Kùzu Inc.
// This code is licensed under MIT license (see LICENSE for details)

@_implementationOnly import cxx_kuzu
import cxx_kuzu

/// Represents a connection to a Kuzu database.
public final class Connection: @unchecked Sendable {
Expand Down
3 changes: 1 addition & 2 deletions Sources/Kuzu/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
// Copyright © 2023 - 2025 Kùzu Inc.
// This code is licensed under MIT license (see LICENSE for details)

import Foundation
@_implementationOnly import cxx_kuzu
import cxx_kuzu

/// A class representing a Kuzu database instance.
public final class Database: @unchecked Sendable {
Expand Down
59 changes: 59 additions & 0 deletions Sources/Kuzu/FlatTuple+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// kuzu-swift
// https://github.com/kuzudb/kuzu-swift
//
// Copyright © 2023 - 2025 Kùzu Inc.
// This code is licensed under MIT license (see LICENSE for details)

import cxx_kuzu

@_spi(Typed)
extension FlatTuple {
private func extractKuzu(
index: Int,
into cValue: inout kuzu_value
) throws -> KuzuValue {
let state = kuzu_flat_tuple_get_value(&cFlatTuple, UInt64(index), &cValue)
let value = KuzuValue(ptr: &cValue)
guard state == KuzuSuccess else {
throw KuzuError.getValueFailed(
"Get value failed with error code: \(state)"
)
}
return value
}

private func checkIndex(_ index: Int) throws {
let count = queryResult.getColumnCount()
guard index < count else {
throw KuzuError.getValueFailed(
"Index overflow on columns count of \(count)"
)
}
}

public subscript<T>(
_ index: Int,
as type: T.Type = T.self
) -> T where T: KuzuDecodable {
get throws {
try checkIndex(index)
var cValue = kuzu_value()
let value = try extractKuzu(index: index, into: &cValue)
return try T.kuzuDecode(from: value)
}
}

// tuples cannot conform to protocols - helper to not have to specify `KuzuMap<T, U>`
public subscript<T, U>(
_ index: Int,
as type: [(T, U)].Type = [(T, U)].self
) -> [(T, U)] where T: KuzuDecodable, U: KuzuDecodable {
get throws {
try checkIndex(index)
var cValue = kuzu_value()
let value = try extractKuzu(index: index, into: &cValue)
return try KuzuMap<T, U>.kuzuDecode(from: value).tuples
}
}
}
3 changes: 1 addition & 2 deletions Sources/Kuzu/FlatTuple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
// Copyright © 2023 - 2025 Kùzu Inc.
// This code is licensed under MIT license (see LICENSE for details)

import Foundation
@_implementationOnly import cxx_kuzu
import cxx_kuzu

/// A class representing a row in the result set of a query.
/// FlatTuple provides access to the values in a query result row and methods to convert them to different formats.
Expand Down
Loading