swift package

main
Ziyang Hu 2 years ago
parent 193fdc202b
commit 10136ed9d7

@ -1,4 +1,10 @@
/* Copyright 2022, The Cozo Project Authors. Licensed under MIT/Apache-2.0/BSD-3-Clause. */
/*
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/.
*/
#ifndef COZO_C_H
#define COZO_C_H

@ -72,9 +72,8 @@ class CozoDb {
* Export several relations
*
* @param relations: names of relations to export, in an array.
* @param as_objects: defaults to `false`, changes the return format.
*/
async exportRelations(relations: Array<string>, as_objects: boolean): object;
async exportRelations(relations: Array<string>): object;
/**
* Import several relations

@ -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"])
]
)

@ -14,6 +14,18 @@ see the Building section below.
## Installation
### CocoaPods
```ruby
target 'YourApp' do
use_frameworks!
pod 'CozoSwiftBridge', '~> 0.2.1'
end
```
### Swift Package Manager (SPM)
The package is published as an archive containing a Swift package.
Download it from the [release page] (look for `CozoSwiftBridge-<VERSION>.tgz`).
Uncompress.
@ -131,14 +143,3 @@ click the plus sign, search for `libc++`, then add `libc++.tbd` found under Appl
Similar same process goes if you want to enable other features. Note that building the
RocksDB engine for mobile is a very demanding task!
## Calling for help
We are no experts on Swift/iOS development. In fact, we learned Swift just enough to produce
this package. Everything from packaging, distribution to the ergonomics of the Swift API is
far from ideal, but is as good as we can produce now. If you like Cozo and you can improve
its user experience on Swift, feel free to open an issue for discussion, or file a pull request.
By the way, the reason that we did not publish the Swift package directly to a GitHub repo is
that the package contains very large binary artefacts, and GitHub will not like it if we put it
directly in the repo.

@ -32,4 +32,16 @@ swift-bridge-cli create-package \
--ios ../target/aarch64-apple-ios/release/libcozo_swift.a \
--simulator ../target/universal-ios/release/libcozo_swift.a \
--macos ../target/universal-macos/release/libcozo_swift.a \
--name CozoSwiftBridge
--name CozoSwiftBridge
cp CozoDB.swift CozoSwiftBridge/Sources/CozoSwiftBridge
cp Package.swift CozoSwiftBridge/
cp CozoSwiftBridge.podspec CozoSwiftBridge/
VERSION=$(cat ../VERSION)
cd CozoSwiftBridge
tar cvzf ../../release/CozoSwiftBridge-$VERSION.tgz .
cd ..

@ -14,10 +14,6 @@ done
cd ..
cd cozo-lib-swift
tar cvzf ../release/CozoSwiftBridge-$VERSION.tgz CozoSwiftBridge
cd ..
gzip release/*.a release/*.so release/*.dylib release/*-darwin release/*-gnu release/*-musl
mkdir -p cozo-lib-nodejs/build/stage/$VERSION/

Loading…
Cancel
Save