swift package
parent
193fdc202b
commit
10136ed9d7
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2022, The Cozo Project Authors.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
* If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import SwiftyJSON
|
||||
|
||||
public enum CozoError: Error {
|
||||
case system(String)
|
||||
case query(JSON)
|
||||
}
|
||||
|
||||
public class RowHeaders {
|
||||
public let headers: [String]
|
||||
init(headers: [String]) {
|
||||
self.headers = headers
|
||||
}
|
||||
lazy var invertedKeys: [String:Int] = {
|
||||
var ret: [String:Int] = [:]
|
||||
for i in 0..<self.headers.count {
|
||||
ret[self.headers[i]] = i
|
||||
}
|
||||
return ret
|
||||
}()
|
||||
}
|
||||
|
||||
public struct NamedRow {
|
||||
public let headers: RowHeaders
|
||||
public let fields: [JSON]
|
||||
|
||||
public func get(idx: Int) -> JSON {
|
||||
return self.fields[idx]
|
||||
}
|
||||
public func get(key: String) -> JSON? {
|
||||
if let idx = self.headers.invertedKeys[key] {
|
||||
return self.fields[idx]
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension [NamedRow] {
|
||||
public func toString() -> String {
|
||||
var ret = "["
|
||||
var isFirst = true
|
||||
for field in self {
|
||||
if !isFirst {
|
||||
ret += ", "
|
||||
} else {
|
||||
isFirst = false
|
||||
}
|
||||
ret += field.toString()
|
||||
}
|
||||
ret += "]"
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
extension NamedRow {
|
||||
public func toString() -> String {
|
||||
var ret = "{"
|
||||
for i in 0..<self.headers.headers.count {
|
||||
if i != 0 {
|
||||
ret += ", "
|
||||
}
|
||||
ret += self.headers.headers[i]
|
||||
ret += ": "
|
||||
ret += self.fields[i].rawString(.utf8, options: .init(rawValue: 0))!
|
||||
}
|
||||
ret += "}"
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
public class CozoDB {
|
||||
public let db: DbInstance
|
||||
|
||||
public init() {
|
||||
let db = new_cozo_db("mem", "", "")!
|
||||
self.db = db
|
||||
}
|
||||
public init(kind: String, path: String) throws {
|
||||
if let db = new_cozo_db(kind, path, "") {
|
||||
self.db = db
|
||||
} else {
|
||||
throw CozoError.system("Cannot create database")
|
||||
}
|
||||
}
|
||||
public func run(_ query: String, params: JSON) throws -> [NamedRow] {
|
||||
let payload = params.rawString(.utf8, options: .init(rawValue: 0))!
|
||||
return try self.run(query, stringParams: payload)
|
||||
}
|
||||
public func run(_ query: String) throws -> [NamedRow] {
|
||||
return try self.run(query, stringParams: "")
|
||||
}
|
||||
func run(_ query: String, stringParams: String) throws -> [NamedRow] {
|
||||
let resStr = self.db.run_script_str(query, stringParams).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
if json["ok"].boolValue {
|
||||
let jHeaders = json["headers"].arrayValue.map{(j) -> String in
|
||||
return j.stringValue
|
||||
}
|
||||
let headers = RowHeaders(headers: jHeaders)
|
||||
return json["rows"].arrayValue.map{(j) -> NamedRow in
|
||||
let fields = j.arrayValue
|
||||
return NamedRow(headers: headers, fields: fields)
|
||||
}
|
||||
} else {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
public func exportRelations(relations: [String]) throws -> JSON {
|
||||
let payload = JSON(["relations": relations]).rawString(.utf8, options: .init(rawValue: 0))!
|
||||
let resStr = self.db.export_relations_str(payload).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
if json["ok"].boolValue {
|
||||
return json["data"]
|
||||
} else {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
public func importRelations(data: JSON) throws {
|
||||
let payload = data.rawString(.utf8, options: .init(rawValue: 0))!
|
||||
let resStr = self.db.import_relations_str(payload).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
if !json["ok"].boolValue {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
public func backup(path: String) throws {
|
||||
let resStr = self.db.backup_db_str(path).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
|
||||
if !json["ok"].boolValue {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
public func restore(path: String) throws {
|
||||
let resStr = self.db.restore_backup_str(path).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
|
||||
if !json["ok"].boolValue {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
public func importRelationsFromBackup(path: String, relations: [String]) throws {
|
||||
let payload = JSON(["relations": relations, "path": path]).rawString(.utf8, options: .init(rawValue: 0))!
|
||||
let resStr = self.db.import_relations_str(payload).toString()
|
||||
let dataFromString = resStr.data(using: .utf8, allowLossyConversion: false)!
|
||||
let json = JSON(dataFromString);
|
||||
if !json["ok"].boolValue {
|
||||
throw CozoError.query(json)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "CozoSwiftBridge"
|
||||
spec.version = "0.2.1"
|
||||
spec.summary = "CozoDB for Swift"
|
||||
spec.description = "This library allows you to use CozoDB embedded in your Swift application"
|
||||
spec.homepage = "https://github.com/cozodb/cozo/"
|
||||
spec.license = "MPL-2.0"
|
||||
spec.author = { "Ziyang Hu" => "hu.ziyang@cantab.net" }
|
||||
spec.source = { :http => "http://127.0.0.1:3000/CozoSwiftBridge.tgz" }
|
||||
spec.source_files = "Sources/CozoSwiftBridge/*"
|
||||
spec.vendored_frameworks = "RustXcframework.xcframework"
|
||||
spec.requires_arc = true
|
||||
spec.swift_version = "5.0"
|
||||
spec.osx.deployment_target = "10.9"
|
||||
spec.ios.deployment_target = "9.0"
|
||||
spec.dependency "SwiftyJSON", "~> 4.0"
|
||||
end
|
@ -0,0 +1,23 @@
|
||||
// swift-tools-version:5.5.0
|
||||
import PackageDescription
|
||||
let package = Package(
|
||||
name: "CozoSwiftBridge",
|
||||
products: [
|
||||
.library(
|
||||
name: "CozoSwiftBridge",
|
||||
targets: ["CozoSwiftBridge"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.binaryTarget(
|
||||
name: "RustXcframework",
|
||||
path: "RustXcframework.xcframework"
|
||||
),
|
||||
.target(
|
||||
name: "CozoSwiftBridge",
|
||||
dependencies: ["RustXcframework", "SwiftyJSON"])
|
||||
]
|
||||
)
|
||||
|
Loading…
Reference in New Issue