Skip to content
Snippets Groups Projects
Commit 119b224c authored by Aidan's avatar Aidan
Browse files

dasdad

parent 8384d8de
No related branches found
No related tags found
No related merge requests found
......@@ -16,6 +16,8 @@
50ADFFA42020D75100D50D53 /* Capacitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFFA52020D75100D50D53 /* Capacitor.framework */; };
50ADFFA82020EE4F00D50D53 /* MobileLevelPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFFA72020EE4F00D50D53 /* MobileLevelPlugin.m */; };
50E1A94820377CB70090CE1A /* MobileLevelPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E1A94720377CB70090CE1A /* MobileLevelPlugin.swift */; };
DD4A07632BE01E4A00E234FA /* Foo.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD4A07622BE01E4A00E234FA /* Foo.mm */; };
DD4A07652BE0202400E234FA /* Foo.h in Headers */ = {isa = PBXBuildFile; fileRef = DD4A07642BE0202400E234FA /* Foo.h */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -43,6 +45,8 @@
5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig"; sourceTree = "<group>"; };
91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.release.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig"; sourceTree = "<group>"; };
96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig"; sourceTree = "<group>"; };
DD4A07622BE01E4A00E234FA /* Foo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Foo.mm; sourceTree = "<group>"; };
DD4A07642BE0202400E234FA /* Foo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Foo.h; sourceTree = "<group>"; };
F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig"; sourceTree = "<group>"; };
F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PluginTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
......@@ -97,6 +101,8 @@
50ADFF8B201F53D600D50D53 /* MobileLevelPlugin.h */,
50ADFFA72020EE4F00D50D53 /* MobileLevelPlugin.m */,
50ADFF8C201F53D600D50D53 /* Info.plist */,
DD4A07622BE01E4A00E234FA /* Foo.mm */,
DD4A07642BE0202400E234FA /* Foo.h */,
);
path = Plugin;
sourceTree = "<group>";
......@@ -139,6 +145,7 @@
buildActionMask = 2147483647;
files = (
50ADFF99201F53D600D50D53 /* MobileLevelPlugin.h in Headers */,
DD4A07652BE0202400E234FA /* Foo.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -270,11 +277,13 @@
"${PODS_ROOT}/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Capacitor/Capacitor.framework",
"${BUILT_PRODUCTS_DIR}/CapacitorCordova/Cordova.framework",
"${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capacitor.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cordova.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
......@@ -306,6 +315,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DD4A07632BE01E4A00E234FA /* Foo.mm in Sources */,
50E1A94820377CB70090CE1A /* MobileLevelPlugin.swift in Sources */,
2F98D68224C9AAE500613A4C /* MobileLevel.swift in Sources */,
50ADFFA82020EE4F00D50D53 /* MobileLevelPlugin.m in Sources */,
......
//
// Foo.h
// Plugin
//
// Created by Aidan Dunlap on 4/29/24.
// Copyright © 2024 Max Lynch. All rights reserved.
//
#ifndef Foo_h
#define Foo_h
#import <Foundation/Foundation.h>
// Forward declaration of C++ class
namespace leveldb {
class DB;
class Options;
class ReadOptions;
class WriteOptions;
}
@interface MobileLevel2 : CAPPlugin {
leveldb::DB* db;
}
- (instancetype)init;
- (void)Open:(CAPPluginCall *)path;
//- (void)Get:(CAPPluginCall *)key;
//- (void)Put:(CAPPluginCall *)value;
//- (void)Delete:(CAPPluginCall *)key;
//- (void)Close;
@end
#endif /* Foo_h */
#import "Foo.h"
#import <leveldb/db.h>
#import <leveldb/options.h>
#import <leveldb/write_batch.h>
@implementation MobileLevel2
- (void) Open:(CAPPluginCall *)params {
options = new leveldb::Options();
options->create_if_missing = true;
NSString *path = [params getString:@"path"];
leveldb::Status status = leveldb::DB::Open(options, path, &db);
if (!status.ok()) {
if (error != NULL) {
*error = [NSError errorWithDomain:@"MobileLevelErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithUTF8String:status.ToString().c_str()]}];
}
}}
@end
import Foundation
import leveldb
let DBOptions = leveldb_options_create()
let ReadOptions = leveldb_readoptions_create()
let WriteOptions = leveldb_writeoptions_create()
// TODO? Manually free these?
@objc public class MobileLevel: NSObject {
@objc public func echo(_ value: String) -> String {
print(value)
return value
private var db: OpaquePointer?
func leveldbErrorToSwiftString(_ error: UnsafePointer<UnsafeMutablePointer<Int8>?>?) -> String? {
/*
From LevelDB's C API documentation:
(3) Errors are represented by a null-terminated c string. NULL
means no error. All operations that can raise an error are passed
a "char** errptr" as the last argument. One of the following must
be true on entry:
*errptr == NULL
*errptr points to a malloc()ed null-terminated error message
(On Windows, *errptr must have been malloc()-ed by this library.)
On success, a leveldb routine leaves *errptr unchanged.
On failure, leveldb frees the old value of *errptr and
set *errptr to a malloc()ed error message.
*/
if let error = error, let errorPointee = error.pointee {
let errorMessage = String(cString: errorPointee)
leveldb_free(errorPointee)
return errorMessage
}
}
@objc func open(path: String) throws {
// Assuming leveldb_open is a function to open a database
leveldb_options_set_create_if_missing(DBOptions, 1)
var error: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?
self.db = leveldb_open(DBOptions, path, error)
// if let errorMessage = leveldbErrorToSwiftString(error) {
// throw MobileLevelError.open(errorMessage)
// }
}
@objc func get(key: String, callback: @escaping (String?, Error?) -> Void) {
var error: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?
var vallen = UnsafeMutablePointer<Int>.allocate(capacity: 1)
var string: String?
defer {
if let error = error, let errorPointee = error.pointee {
let errorMessage = String(cString: errorPointee)
print("Error getting: \(errorMessage)")
leveldb_free(errorPointee)
} else {
callback(string, nil)
}
vallen.deallocate()
}
key.withCString { cKey in
let length = key.lengthOfBytes(using: String.Encoding.utf8)
let levelDBResult = leveldb_get(self.db, ReadOptions, cKey, length, vallen, error)
if let validPointer = levelDBResult {
string = String(bytesNoCopy: validPointer, length: vallen.pointee, encoding: .ascii, freeWhenDone: true)
}
}
}
@objc func put(key: String, value: String, callback: @escaping (Error?) -> Void) {
var error: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?
defer {
if let error = error {
print("Error putting: \(error)")
leveldb_free(error)
}
}
key.withCString { cKey in
let cKeyLength = key.lengthOfBytes(using: String.Encoding.utf8)
value.withCString { cValue in
let cValueLength = value.lengthOfBytes(using: String.Encoding.ascii)
leveldb_put(self.db, WriteOptions, cKey, cKeyLength, cValue, cValueLength, error)
}
}
}
@objc func delete(key: String, options: [String: Any], callback: @escaping (Error?) -> Void) {
var error: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?
defer {
if let error = error {
print("Error deleting: \(error)")
leveldb_free(error)
}
}
key.withCString { cKey in
let cKeyLength = key.lengthOfBytes(using: String.Encoding.utf8)
leveldb_delete(self.db, WriteOptions, cKey, cKeyLength, error)
}
}
@objc func close(callback: @escaping (Error?) -> Void) {
leveldb_close(self.db)
callback(nil)
}
// Additional methods like _batch, _clear, etc., would be similarly implemented.
}
......@@ -3,6 +3,6 @@
// Define the plugin using the CAP_PLUGIN Macro, and
// each method the plugin supports using the CAP_PLUGIN_METHOD macro.
CAP_PLUGIN(MobileLevelPlugin, "MobileLevel",
CAP_PLUGIN_METHOD(echo, CAPPluginReturnPromise);
CAP_PLUGIN(MobileLevel2, "MobileLevel",
CAP_PLUGIN_METHOD(Open, CAPPluginReturnPromise);
)
import Foundation
import Capacitor
import JavaScriptCore
/**
* Please read the Capacitor iOS Plugin Development Guide
......@@ -9,10 +10,71 @@ import Capacitor
public class MobileLevelPlugin: CAPPlugin {
private let implementation = MobileLevel()
@objc func echo(_ call: CAPPluginCall) {
let value = call.getString("value") ?? ""
call.resolve([
"value": implementation.echo(value)
])
@objc func open(_ call: CAPPluginCall) {
guard let path = call.getString("path") else {
call.reject("Missing path parameter")
return
}
implementation.open(path: path) { error in
if let error = error {
call.reject("Failed to open database: \(error)")
} else {
call.resolve()
}
}
}
@objc func get(_ call: CAPPluginCall) {
guard let key = call.getString("key") else {
call.reject("Missing key parameter")
return
}
implementation.get(key: key) { result, error in
if let error = error {
call.reject("Failed to get value: \(error.localizedDescription)")
} else if let result = result {
call.resolve(["value": result])
} else {
call.reject("Key not found")
}
}
}
@objc func put(_ call: CAPPluginCall) {
guard let key = call.getString("key"), let value = call.getString("value") else {
call.reject("Missing key or value parameter")
return
}
implementation.put(key: key, value: value) { error in
if let error = error {
call.reject("Failed to put value: \(error.localizedDescription)")
} else {
call.resolve()
}
}
}
@objc func delete(_ call: CAPPluginCall) {
guard let key = call.getString("key") else {
call.reject("Missing key parameter")
return
}
implementation.delete(key: key, options: [:]) { error in
if let error = error {
call.reject("Failed to delete key: \(error.localizedDescription)")
} else {
call.resolve()
}
}
}
@objc func close(_ call: CAPPluginCall) {
implementation.close { error in
if let error = error {
call.reject("Failed to close database: \(error.localizedDescription)")
} else {
call.resolve()
}
}
}
}
......@@ -17,9 +17,10 @@ class MobileLevelTests: XCTestCase {
// Use XCTAssert and related functions to verify your tests produce the correct results.
let implementation = MobileLevel()
let value = "Hello, World!"
let result = implementation.echo(value)
// let value = "Hello, World!"
// let result =
implementation.open(path: "hello", callback: <#T##(String?) -> Void#>)
XCTAssertEqual(value, result)
XCTAssertEqual(true, true)
}
}
......@@ -5,6 +5,7 @@ def capacitor_pods
use_frameworks!
pod 'Capacitor', :path => '../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios'
pod 'leveldb-library', '~> 1.22.5'
end
target 'Plugin' do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment