diff --git a/.gitignore b/.gitignore index 07102c19..1e284e6e 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,28 @@ pom.xml.asc /fixtures/*.db-shm /fixtures/*.db-wal /query-parser/out/ +## Build generated +build/ +DerivedData +build.xcarchive + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +/sdks/swift/Mentat/*.xcodeproj/project.xcworkspace/xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa \ No newline at end of file diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index cd872585..d7b5451f 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -3,6 +3,10 @@ name = "mentat_ffi" version = "0.1.0" authors = ["Emily Toop "] +[lib] +name = "mentat" +crate-type = ["staticlib", "cdylib"] + [dependencies] libc = "0.2" diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/project.pbxproj b/sdks/swift/Mentat/Mentat.xcodeproj/project.pbxproj new file mode 100644 index 00000000..537d2b4f --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/project.pbxproj @@ -0,0 +1,573 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 7BDB96942077C299009D0651 /* Mentat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDB968A2077C299009D0651 /* Mentat.framework */; }; + 7BDB96992077C299009D0651 /* MentatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96982077C299009D0651 /* MentatTests.swift */; }; + 7BDB969B2077C299009D0651 /* Mentat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BDB968D2077C299009D0651 /* Mentat.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BDB96AF2077C38E009D0651 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96A62077C38D009D0651 /* Query.swift */; }; + 7BDB96B02077C38E009D0651 /* Mentat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96A72077C38D009D0651 /* Mentat.swift */; }; + 7BDB96B12077C38E009D0651 /* store.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BDB96A82077C38E009D0651 /* store.h */; }; + 7BDB96B22077C38E009D0651 /* RelResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96A92077C38E009D0651 /* RelResult.swift */; }; + 7BDB96B32077C38E009D0651 /* RustObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96AA2077C38E009D0651 /* RustObject.swift */; }; + 7BDB96B42077C38E009D0651 /* OptionalRustObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96AB2077C38E009D0651 /* OptionalRustObject.swift */; }; + 7BDB96B52077C38E009D0651 /* TupleResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96AC2077C38E009D0651 /* TupleResult.swift */; }; + 7BDB96B62077C38E009D0651 /* TxReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96AD2077C38E009D0651 /* TxReport.swift */; }; + 7BDB96B72077C38E009D0651 /* TypedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96AE2077C38E009D0651 /* TypedValue.swift */; }; + 7BDB96C02077CD7A009D0651 /* libmentat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDB96BF2077CD7A009D0651 /* libmentat.a */; }; + 7BDB96C22077CD98009D0651 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BDB96C12077CD98009D0651 /* libresolv.tbd */; }; + 7BDB96C62077D347009D0651 /* Date+Int64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB96C52077D346009D0651 /* Date+Int64.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 7BDB96952077C299009D0651 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7BDB96812077C299009D0651 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7BDB96892077C299009D0651; + remoteInfo = Mentat; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 7BDB968A2077C299009D0651 /* Mentat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Mentat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDB968D2077C299009D0651 /* Mentat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Mentat.h; sourceTree = ""; }; + 7BDB968E2077C299009D0651 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7BDB96932077C299009D0651 /* MentatTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MentatTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BDB96982077C299009D0651 /* MentatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentatTests.swift; sourceTree = ""; }; + 7BDB969A2077C299009D0651 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7BDB96A62077C38D009D0651 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = ""; }; + 7BDB96A72077C38D009D0651 /* Mentat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mentat.swift; sourceTree = ""; }; + 7BDB96A82077C38E009D0651 /* store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = store.h; sourceTree = ""; }; + 7BDB96A92077C38E009D0651 /* RelResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelResult.swift; sourceTree = ""; }; + 7BDB96AA2077C38E009D0651 /* RustObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RustObject.swift; sourceTree = ""; }; + 7BDB96AB2077C38E009D0651 /* OptionalRustObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalRustObject.swift; sourceTree = ""; }; + 7BDB96AC2077C38E009D0651 /* TupleResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TupleResult.swift; sourceTree = ""; }; + 7BDB96AD2077C38E009D0651 /* TxReport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TxReport.swift; sourceTree = ""; }; + 7BDB96AE2077C38E009D0651 /* TypedValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypedValue.swift; sourceTree = ""; }; + 7BDB96BF2077CD7A009D0651 /* libmentat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmentat.a; path = ../../../target/universal/release/libmentat.a; sourceTree = ""; }; + 7BDB96C12077CD98009D0651 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; }; + 7BDB96C32077D090009D0651 /* module.map */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.map; sourceTree = ""; }; + 7BDB96C52077D346009D0651 /* Date+Int64.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Int64.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7BDB96862077C299009D0651 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDB96C22077CD98009D0651 /* libresolv.tbd in Frameworks */, + 7BDB96C02077CD7A009D0651 /* libmentat.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7BDB96902077C299009D0651 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDB96942077C299009D0651 /* Mentat.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7BDB96802077C299009D0651 = { + isa = PBXGroup; + children = ( + 7BDB968C2077C299009D0651 /* Mentat */, + 7BDB96972077C299009D0651 /* MentatTests */, + 7BDB968B2077C299009D0651 /* Products */, + 7BDB96BE2077CD7A009D0651 /* Frameworks */, + ); + sourceTree = ""; + }; + 7BDB968B2077C299009D0651 /* Products */ = { + isa = PBXGroup; + children = ( + 7BDB968A2077C299009D0651 /* Mentat.framework */, + 7BDB96932077C299009D0651 /* MentatTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 7BDB968C2077C299009D0651 /* Mentat */ = { + isa = PBXGroup; + children = ( + 7BDB96C42077D346009D0651 /* Extensions */, + 7BDB96BA2077C42B009D0651 /* Core */, + 7BDB96B92077C403009D0651 /* Rust */, + 7BDB96A82077C38E009D0651 /* store.h */, + 7BDB96A72077C38D009D0651 /* Mentat.swift */, + 7BDB96A42077C301009D0651 /* Query */, + 7BDB96B82077C3B2009D0651 /* Transact */, + 7BDB968D2077C299009D0651 /* Mentat.h */, + 7BDB968E2077C299009D0651 /* Info.plist */, + 7BDB96C32077D090009D0651 /* module.map */, + ); + path = Mentat; + sourceTree = ""; + }; + 7BDB96972077C299009D0651 /* MentatTests */ = { + isa = PBXGroup; + children = ( + 7BDB96982077C299009D0651 /* MentatTests.swift */, + 7BDB969A2077C299009D0651 /* Info.plist */, + ); + path = MentatTests; + sourceTree = ""; + }; + 7BDB96A42077C301009D0651 /* Query */ = { + isa = PBXGroup; + children = ( + 7BDB96A62077C38D009D0651 /* Query.swift */, + 7BDB96A92077C38E009D0651 /* RelResult.swift */, + 7BDB96AC2077C38E009D0651 /* TupleResult.swift */, + ); + path = Query; + sourceTree = ""; + }; + 7BDB96B82077C3B2009D0651 /* Transact */ = { + isa = PBXGroup; + children = ( + 7BDB96AD2077C38E009D0651 /* TxReport.swift */, + ); + path = Transact; + sourceTree = ""; + }; + 7BDB96B92077C403009D0651 /* Rust */ = { + isa = PBXGroup; + children = ( + 7BDB96AB2077C38E009D0651 /* OptionalRustObject.swift */, + 7BDB96AA2077C38E009D0651 /* RustObject.swift */, + ); + path = Rust; + sourceTree = ""; + }; + 7BDB96BA2077C42B009D0651 /* Core */ = { + isa = PBXGroup; + children = ( + 7BDB96AE2077C38E009D0651 /* TypedValue.swift */, + ); + path = Core; + sourceTree = ""; + }; + 7BDB96BE2077CD7A009D0651 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7BDB96C12077CD98009D0651 /* libresolv.tbd */, + 7BDB96BF2077CD7A009D0651 /* libmentat.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7BDB96C42077D346009D0651 /* Extensions */ = { + isa = PBXGroup; + children = ( + 7BDB96C52077D346009D0651 /* Date+Int64.swift */, + ); + path = Extensions; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 7BDB96872077C299009D0651 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDB96B12077C38E009D0651 /* store.h in Headers */, + 7BDB969B2077C299009D0651 /* Mentat.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 7BDB96892077C299009D0651 /* Mentat */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BDB969E2077C299009D0651 /* Build configuration list for PBXNativeTarget "Mentat" */; + buildPhases = ( + 7BDB96852077C299009D0651 /* Sources */, + 7BDB96862077C299009D0651 /* Frameworks */, + 7BDB96872077C299009D0651 /* Headers */, + 7BDB96882077C299009D0651 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Mentat; + productName = Mentat; + productReference = 7BDB968A2077C299009D0651 /* Mentat.framework */; + productType = "com.apple.product-type.framework"; + }; + 7BDB96922077C299009D0651 /* MentatTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BDB96A12077C299009D0651 /* Build configuration list for PBXNativeTarget "MentatTests" */; + buildPhases = ( + 7BDB968F2077C299009D0651 /* Sources */, + 7BDB96902077C299009D0651 /* Frameworks */, + 7BDB96912077C299009D0651 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7BDB96962077C299009D0651 /* PBXTargetDependency */, + ); + name = MentatTests; + productName = MentatTests; + productReference = 7BDB96932077C299009D0651 /* MentatTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7BDB96812077C299009D0651 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = Mozilla; + TargetAttributes = { + 7BDB96892077C299009D0651 = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 0930; + }; + 7BDB96922077C299009D0651 = { + CreatedOnToolsVersion = 9.3; + }; + }; + }; + buildConfigurationList = 7BDB96842077C299009D0651 /* Build configuration list for PBXProject "Mentat" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7BDB96802077C299009D0651; + productRefGroup = 7BDB968B2077C299009D0651 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7BDB96892077C299009D0651 /* Mentat */, + 7BDB96922077C299009D0651 /* MentatTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7BDB96882077C299009D0651 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7BDB96912077C299009D0651 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7BDB96852077C299009D0651 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDB96B32077C38E009D0651 /* RustObject.swift in Sources */, + 7BDB96B62077C38E009D0651 /* TxReport.swift in Sources */, + 7BDB96C62077D347009D0651 /* Date+Int64.swift in Sources */, + 7BDB96B42077C38E009D0651 /* OptionalRustObject.swift in Sources */, + 7BDB96B22077C38E009D0651 /* RelResult.swift in Sources */, + 7BDB96AF2077C38E009D0651 /* Query.swift in Sources */, + 7BDB96B02077C38E009D0651 /* Mentat.swift in Sources */, + 7BDB96B72077C38E009D0651 /* TypedValue.swift in Sources */, + 7BDB96B52077C38E009D0651 /* TupleResult.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7BDB968F2077C299009D0651 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDB96992077C299009D0651 /* MentatTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 7BDB96962077C299009D0651 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7BDB96892077C299009D0651 /* Mentat */; + targetProxy = 7BDB96952077C299009D0651 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 7BDB969C2077C299009D0651 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Mentat"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7BDB969D2077C299009D0651 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Mentat"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 7BDB969F2077C299009D0651 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 8BHJ767F4Y; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Mentat/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../../../target/universal/release"; + PRODUCT_BUNDLE_IDENTIFIER = com.mozilla.Mentat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Mentat"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7BDB96A02077C299009D0651 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 8BHJ767F4Y; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_TESTABILITY = NO; + INFOPLIST_FILE = Mentat/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../../../target/universal/release"; + PRODUCT_BUNDLE_IDENTIFIER = com.mozilla.Mentat; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/Mentat"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 7BDB96A22077C299009D0651 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8BHJ767F4Y; + INFOPLIST_FILE = MentatTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.mozilla.MentatTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7BDB96A32077C299009D0651 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8BHJ767F4Y; + INFOPLIST_FILE = MentatTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.mozilla.MentatTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7BDB96842077C299009D0651 /* Build configuration list for PBXProject "Mentat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BDB969C2077C299009D0651 /* Debug */, + 7BDB969D2077C299009D0651 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7BDB969E2077C299009D0651 /* Build configuration list for PBXNativeTarget "Mentat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BDB969F2077C299009D0651 /* Debug */, + 7BDB96A02077C299009D0651 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7BDB96A12077C299009D0651 /* Build configuration list for PBXNativeTarget "MentatTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BDB96A22077C299009D0651 /* Debug */, + 7BDB96A32077C299009D0651 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7BDB96812077C299009D0651 /* Project object */; +} diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..8f0c7f34 --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat Debug.xcscheme b/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat Debug.xcscheme new file mode 100644 index 00000000..589794d4 --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat Debug.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat.xcscheme b/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat.xcscheme new file mode 100644 index 00000000..c03b16b0 --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/xcshareddata/xcschemes/Mentat.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdks/swift/Mentat/Mentat.xcodeproj/xcuserdata/emilytoop.xcuserdatad/xcschemes/xcschememanagement.plist b/sdks/swift/Mentat/Mentat.xcodeproj/xcuserdata/emilytoop.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..a1cba08f --- /dev/null +++ b/sdks/swift/Mentat/Mentat.xcodeproj/xcuserdata/emilytoop.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + Mentat Debug.xcscheme_^#shared#^_ + + orderHint + 0 + + Mentat.xcscheme_^#shared#^_ + + orderHint + 1 + + + SuppressBuildableAutocreation + + 7BDB96892077C299009D0651 + + primary + + + 7BDB96922077C299009D0651 + + primary + + + + + diff --git a/sdks/swift/Mentat/Mentat/Core/TypedValue.swift b/sdks/swift/Mentat/Mentat/Core/TypedValue.swift new file mode 100644 index 00000000..cac861c2 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Core/TypedValue.swift @@ -0,0 +1,70 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +class TypedValue: OptionalRustObject { + + func asLong() -> Int64 { + defer { + self.raw = nil + } + return typed_value_as_long(self.raw!) + } + + func asEntid() -> Int64 { + defer { + self.raw = nil + } + return typed_value_as_entid(self.raw!) + } + + func asKeyword() -> String { + defer { + self.raw = nil + } + return String(cString: typed_value_as_kw(self.raw!)) + } + + func asBool() -> Bool { + defer { + self.raw = nil + } + return typed_value_as_boolean(self.raw!) == 0 ? false : true + } + + func asDouble() -> Double { + defer { + self.raw = nil + } + return typed_value_as_double(self.raw!) + } + + func asDate() -> Date { + defer { + self.raw = nil + } + let timestamp = typed_value_as_timestamp(self.raw!) + return Date(timeIntervalSince1970: TimeInterval(timestamp)) + } + + func asString() -> String { + defer { + self.raw = nil + } + return String(cString: typed_value_as_string(self.raw!)) + } + + func asUUID() -> UUID? { + defer { + self.raw = nil + } + return UUID(uuidString: String(cString: typed_value_as_uuid(self.raw!))) + } + + override func cleanup(pointer: OpaquePointer) { + typed_value_destroy(pointer) + } +} diff --git a/sdks/swift/Mentat/Mentat/Extensions/Date+Int64.swift b/sdks/swift/Mentat/Mentat/Extensions/Date+Int64.swift new file mode 100644 index 00000000..cdcf2458 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Extensions/Date+Int64.swift @@ -0,0 +1,11 @@ +///* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation + +extension Date { + func toMicroseconds() -> Int64 { + return Int64(self.timeIntervalSince1970 * 1_000_000) + } +} diff --git a/sdks/swift/Mentat/Mentat/Info.plist b/sdks/swift/Mentat/Mentat/Info.plist new file mode 100644 index 00000000..1007fd9d --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/sdks/swift/Mentat/Mentat/Mentat.h b/sdks/swift/Mentat/Mentat/Mentat.h new file mode 100644 index 00000000..ab54076b --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Mentat.h @@ -0,0 +1,14 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +#import + +//! Project version number for Mentat. +FOUNDATION_EXPORT double MentatVersionNumber; + +//! Project version string for Mentat. +FOUNDATION_EXPORT const unsigned char MentatVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + diff --git a/sdks/swift/Mentat/Mentat/Mentat.swift b/sdks/swift/Mentat/Mentat/Mentat.swift new file mode 100644 index 00000000..4b89cc73 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Mentat.swift @@ -0,0 +1,107 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation + +import Mentatlib + +protocol Observing { + // define functions for store observation + func transactionDidOccur(key: String, reports: [TxReport]) +} + +protocol Observable { + func register(key: String, observer: Observing, attributes: [String]) + func unregister(key: String) +} + +class Mentat: RustObject { + fileprivate static var observers = [String: Observing]() + + required override init(raw: OpaquePointer) { + super.init(raw: raw) + } + + convenience init(storeURI: String = "") { + self.init(raw: store_open(storeURI)) + } + + + func entidForAttribute(attribute: String) -> Int64 { + return Int64(store_entid_for_attribute(self.raw, attribute)) + } + + func sync_now() -> Bool { + let err = store_sync(self.raw, "00000000-0000-0000-0000-000000000117", "http://mentat.dev.lcip.org/mentatsync/0.1") + if let error = err.pointee.err { + let str = String(cString: error) + print("Sync error \(str)") + return false + } + + return true + } + + func query(query: String) -> Query { + return Query(raw: store_query(self.raw, query)) + } + + func value(forAttribute attribute: String, ofEntity entid: Int64) -> TypedValue? { + let result = store_value_for_attribute(self.raw, entid, attribute).pointee + guard let success = result.ok else { + if let error = result.err { + let str = String(cString: error) + print("Error: \(str)") + } + return nil + } + return TypedValue(raw: success) + } + + override func cleanup(pointer: OpaquePointer) { + store_destroy(pointer) + } +} + +extension Mentat: Observable { + func register(key: String, observer: Observing, attributes: [String]) { + let attrEntIds = attributes.map({ (kw) -> Int64 in + let entid = Int64(self.entidForAttribute(attribute: kw)); + return entid + }) + + let ptr = UnsafeMutablePointer.allocate(capacity: attrEntIds.count) + let entidPointer = UnsafeMutableBufferPointer(start: ptr, count: attrEntIds.count) + var _ = entidPointer.initialize(from: attrEntIds) + + guard let firstElement = entidPointer.baseAddress else { + return + } + Mentat.observers[key] = observer + store_register_observer(self.raw, key, firstElement, Int64(attributes.count), transactionObserverCallback) + + } + + func unregister(key: String) { + store_unregister_observer(self.raw, key) + } +} + +private func transactionObserverCallback(key: UnsafePointer, reports: UnsafePointer) { + // needs to be done in the same thread as the calling thread otherwise the TxReportList might be released before + // we can reference it. + let key = String(cString: key) + guard let observer = Mentat.observers[key] else { return } + + let len = Int(reports.pointee.len) + var txReports = [TxReport]() + for i in 0.. { + case error(Error) + case success(T) +} + +class Query: OptionalRustObject { + + func bind(varName: String, toInt value: Int32) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_int(r, varName, value) + } + + func bind(varName: String, toLong value: Int64) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_long(r, varName, value) + } + + func bind(varName: String, toReference value: Int64) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_ref(r, varName, value) + } + + func bind(varName: String, toReference value: String) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_ref_kw(r, varName, value) + } + + func bind(varName: String, toKeyword value: String) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_kw(r, varName, value) + } + + func bind(varName: String, toBoolean value: Bool) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_boolean(r, varName, value ? 1 : 0) + } + + func bind(varName: String, toDouble value: Double) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_double(r, varName, value) + } + + func bind(varName: String, toDate value: Date) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_timestamp(r, varName, value.toMicroseconds()) + } + + func bind(varName: String, toString value: String) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_string(r, varName, value) + } + + func bind(varName: String, toUuid value: UUID) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + query_builder_bind_uuid(r, varName, value.uuidString) + } + + func executeMap(map: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + map(QueryResult.error(QueryError.executionFailed(message: message))) + return + } + guard let rowsPtr = result.pointee.ok else { + return + } + let rows = RelResult(raw: rowsPtr) + for row in rows { + map(QueryResult.success(row)) + } + } + } + + func execute(callback: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + callback(QueryResult.error(QueryError.executionFailed(message: message))) + return + } + guard let results = result.pointee.ok else { + callback(QueryResult.success(nil)) + return + } + callback(QueryResult.success(RelResult(raw: results))) + } + } + + func executeScalar(callback: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute_scalar(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + callback(QueryResult.error(QueryError.executionFailed(message: message))) + } + guard let results = result.pointee.ok else { + callback(QueryResult.success(nil)) + return + } + callback(QueryResult.success(TypedValue(raw: OpaquePointer(results)))) + } + } + + func executeColl(callback: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute_coll(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + callback(QueryResult.error(QueryError.executionFailed(message: message))) + } + guard let results = result.pointee.ok else { + callback(QueryResult.success(nil)) + return + } + callback(QueryResult.success(ColResult(raw: results))) + } + } + + func executeCollMap(map: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + map(QueryResult.error(QueryError.executionFailed(message: message))) + return + } + guard let cols = result.pointee.ok else { + return + } + let rowList = ColResult(raw: cols) + for row in rowList { + map(QueryResult.success(row)) + } + } + } + + func executeTuple(callback: @escaping (QueryResult) -> Void) throws { + guard let r = self.raw else { + throw QueryError.builderConsumed + } + + DispatchQueue.global(qos: .background).async { + let result = query_builder_execute_tuple(r) + self.raw = nil + + if let err = result.pointee.err { + let message = String(cString: err) + callback(QueryResult.error(QueryError.executionFailed(message: message))) + } + guard let results = result.pointee.ok else { + callback(QueryResult.success(nil)) + return + } + callback(QueryResult.success(TupleResult(raw: OpaquePointer(results)))) + } + } + + override func cleanup(pointer: OpaquePointer) { + query_builder_destroy(pointer) + } +} diff --git a/sdks/swift/Mentat/Mentat/Query/RelResult.swift b/sdks/swift/Mentat/Mentat/Query/RelResult.swift new file mode 100644 index 00000000..4802963f --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Query/RelResult.swift @@ -0,0 +1,62 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +enum QueryResultError: Error { + case resultsConsumed +} + +class RelResult: OptionalRustObject { + private func getRaw() throws -> OpaquePointer { + guard let r = self.raw else { + throw QueryResultError.resultsConsumed + } + return r + } + + func row(index: Int32) throws -> TupleResult? { + guard let row = row_at_index(try self.getRaw(), index) else { + return nil + } + return TupleResult(raw: row) + } + + override func cleanup(pointer: OpaquePointer) { + destroy(UnsafeMutableRawPointer(pointer)) + } +} + +class RelResultIterator: OptionalRustObject, IteratorProtocol { + typealias Element = TupleResult + + init(iter: OpaquePointer?) { + super.init(raw: iter) + } + + func next() -> Element? { + guard let iter = self.raw, + let rowPtr = rows_iter_next(iter) else { + return nil + } + return TupleResult(raw: rowPtr) + } + + override func cleanup(pointer: OpaquePointer) { + typed_value_result_set_iter_destroy(pointer) + } +} + +extension RelResult: Sequence { + func makeIterator() -> RelResultIterator { + do { + let rowIter = rows_iter(try self.getRaw()) + self.raw = nil + return RelResultIterator(iter: rowIter) + } catch { + return RelResultIterator(iter: nil) + } + } +} diff --git a/sdks/swift/Mentat/Mentat/Query/TupleResult.swift b/sdks/swift/Mentat/Mentat/Query/TupleResult.swift new file mode 100644 index 00000000..66cef7aa --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Query/TupleResult.swift @@ -0,0 +1,83 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +class TupleResult: OptionalRustObject { + + func get(index: Int32) -> TypedValue { + return TypedValue(raw: value_at_index(self.raw!, index)) + } + + func asLong(index: Int32) -> Int64 { + return value_at_index_as_long(self.raw!, index) + } + + func asEntid(index: Int32) -> Int64 { + return value_at_index_as_entid(self.raw!, index) + } + + func asKeyword(index: Int32) -> String { + return String(cString: value_at_index_as_kw(self.raw!, index)) + } + + func asBool(index: Int32) -> Bool { + return value_at_index_as_boolean(self.raw!, index) == 0 ? false : true + } + + func asDouble(index: Int32) -> Double { + return value_at_index_as_double(self.raw!, index) + } + + func asDate(index: Int32) -> Date { + return Date(timeIntervalSince1970: TimeInterval(value_at_index_as_timestamp(self.raw!, index))) + } + + func asString(index: Int32) -> String { + return String(cString: value_at_index_as_string(self.raw!, index)) + } + + func asUUID(index: Int32) -> UUID? { + return UUID(uuidString: String(cString: value_at_index_as_uuid(self.raw!, index))) + } + + override func cleanup(pointer: OpaquePointer) { + typed_value_list_destroy(pointer) + } +} + +class ColResult: TupleResult { +} + +class ColResultIterator: OptionalRustObject, IteratorProtocol { + typealias Element = TypedValue + + init(iter: OpaquePointer?) { + super.init(raw: iter) + } + + func next() -> Element? { + guard let iter = self.raw, + let rowPtr = values_iter_next(iter) else { + return nil + } + return TypedValue(raw: rowPtr) + } + + override func cleanup(pointer: OpaquePointer) { + typed_value_list_iter_destroy(pointer) + } +} + +extension ColResult: Sequence { + func makeIterator() -> ColResultIterator { + guard let raw = self.raw else { + print("list pointer destroyed") + return ColResultIterator(iter: nil) + } + let rowIter = values_iter(raw) + return ColResultIterator(iter: rowIter) + } +} diff --git a/sdks/swift/Mentat/Mentat/Rust/OptionalRustObject.swift b/sdks/swift/Mentat/Mentat/Rust/OptionalRustObject.swift new file mode 100644 index 00000000..52d97717 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Rust/OptionalRustObject.swift @@ -0,0 +1,35 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +class OptionalRustObject: Destroyable { + var raw: OpaquePointer? + lazy var uniqueId: ObjectIdentifier = { + ObjectIdentifier(self) + }() + + init(raw: UnsafeMutableRawPointer) { + self.raw = OpaquePointer(raw) + } + + init(raw: OpaquePointer?) { + self.raw = raw + } + + func intoRaw() -> OpaquePointer? { + return self.raw + } + + deinit { + guard let raw = self.raw else { return } + self.cleanup(pointer: raw) + } + + func cleanup(pointer: OpaquePointer) { + fatalError("\(cleanup) is not implemented.") + } +} + diff --git a/sdks/swift/Mentat/Mentat/Rust/RustObject.swift b/sdks/swift/Mentat/Mentat/Rust/RustObject.swift new file mode 100644 index 00000000..ad3a0b45 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Rust/RustObject.swift @@ -0,0 +1,45 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +protocol Destroyable { + func cleanup(pointer: OpaquePointer) +} + +class RustObject: Destroyable { + var raw: OpaquePointer + + lazy var uniqueId: ObjectIdentifier = { + ObjectIdentifier(self) + }() + + init(raw: OpaquePointer) { + self.raw = raw + } + + init(raw: UnsafeMutableRawPointer) { + self.raw = OpaquePointer(raw) + } + + init?(raw: OpaquePointer?) { + guard let r = raw else { + return nil + } + self.raw = r + } + + func intoRaw() -> OpaquePointer { + return self.raw + } + + deinit { + self.cleanup(pointer: self.raw) + } + + func cleanup(pointer: OpaquePointer) { + fatalError("\(cleanup) is not implemented.") + } +} diff --git a/sdks/swift/Mentat/Mentat/Transact/TxReport.swift b/sdks/swift/Mentat/Mentat/Transact/TxReport.swift new file mode 100644 index 00000000..0bb6708c --- /dev/null +++ b/sdks/swift/Mentat/Mentat/Transact/TxReport.swift @@ -0,0 +1,22 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import Foundation +import Mentatlib + +class TxReport { + var raw: UnsafePointer + + required init(raw: UnsafePointer) { + self.raw = raw + } + + func intoRaw() -> UnsafePointer { + return self.raw + } + + deinit { + destroy(UnsafeMutableRawPointer(mutating: raw)) + } +} diff --git a/sdks/swift/Mentat/Mentat/module.map b/sdks/swift/Mentat/Mentat/module.map new file mode 100644 index 00000000..07f846ff --- /dev/null +++ b/sdks/swift/Mentat/Mentat/module.map @@ -0,0 +1,4 @@ +module Mentatlib [system][extern_c] { + header "store.h" + export * +} diff --git a/sdks/swift/Mentat/Mentat/store.h b/sdks/swift/Mentat/Mentat/store.h new file mode 100644 index 00000000..48fce304 --- /dev/null +++ b/sdks/swift/Mentat/Mentat/store.h @@ -0,0 +1,131 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +#ifndef store_h +#define store_h +#include + +struct ExternTxReport { + int64_t txid; + int64_t*_Nonnull* _Nonnull changes; + uint64_t len; +}; + +struct Result { + void* _Nullable ok; + char* _Nullable err; +}; +typedef struct Result Result; + +struct Option { + void* _Nullable value; +}; +typedef struct Option Option; + +struct Store; + +struct TxReportList { + struct ExternTxReport*_Nonnull* _Nonnull reports; + uint64_t len; +}; +typedef struct TxReportList TxReportList; + +struct Query; +struct TypedValue; +struct QueryResultRow; +struct QueryResultRows; +struct QueryRowsIterator; +struct QueryRowIterator; + +// Store +struct Store*_Nonnull store_open(const char*_Nonnull uri); + +void destroy(void* _Nullable obj); +void query_builder_destroy(struct Query* _Nullable obj); +void store_destroy(struct Store* _Nonnull obj); +void typed_value_destroy(struct TypedValue* _Nullable obj); +void typed_value_list_destroy(struct QueryResultRow* _Nullable obj); +void typed_value_list_iter_destroy(struct QueryRowIterator* _Nullable obj); +void typed_value_result_set_destroy(struct QueryResultRows* _Nullable obj); +void typed_value_result_set_iter_destroy(struct QueryRowsIterator* _Nullable obj); + +// Sync +struct Result*_Nonnull store_sync(struct Store*_Nonnull store, const char* _Nonnull user_uuid, const char* _Nonnull server_uri); + +// Observers +void store_register_observer(struct Store*_Nonnull store, const char* _Nonnull key, const int64_t* _Nonnull attributes, const int64_t len, void (*_Nonnull callback_fn)(const char* _Nonnull key, const struct TxReportList* _Nonnull reports)); +void store_unregister_observer(struct Store*_Nonnull store, const char* _Nonnull key); +int64_t store_entid_for_attribute(struct Store*_Nonnull store, const char*_Nonnull attr); +const struct int64_t changelist_entry_at(const struct ExternTxReport* _Nonnull report, size_t index); + +// Query +struct Query*_Nonnull store_query(struct Store*_Nonnull store, const char* _Nonnull query); +struct Result*_Nonnull store_value_for_attribute(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute); + +// Query Variable Binding +void query_builder_bind_int(struct Store*_Nonnull store, const char* _Nonnull var, const int32_t value); +void query_builder_bind_long(struct Query*_Nonnull query, const char* _Nonnull var, const int64_t value); +void query_builder_bind_ref(struct Query*_Nonnull query, const char* _Nonnull var, const int64_t value); +void query_builder_bind_ref_kw(struct Query*_Nonnull query, const char* _Nonnull var, const char* _Nonnull value); +void query_builder_bind_kw(struct Query*_Nonnull query, const char* _Nonnull var, const char* _Nonnull value); +void query_builder_bind_boolean(struct Query*_Nonnull query, const char* _Nonnull var, const int32_t value); +void query_builder_bind_double(struct Query*_Nonnull query, const char* _Nonnull var, const double value); +void query_builder_bind_timestamp(struct Query*_Nonnull query, const char* _Nonnull var, const int64_t value); +void query_builder_bind_string(struct Query*_Nonnull query, const char* _Nonnull var, const char* _Nonnull value); +void query_builder_bind_uuid(struct Query*_Nonnull query, const char* _Nonnull var, const char* _Nonnull value); + +// Query execution +struct Result*_Nonnull query_builder_execute(struct Query*_Nonnull query); +struct Result*_Nonnull query_builder_execute_scalar(struct Query*_Nonnull query); +struct Result*_Nonnull query_builder_execute_coll(struct Query*_Nonnull query); +struct Result*_Nonnull query_builder_execute_tuple(struct Query*_Nonnull query); + +// Query Result Processing +int64_t typed_value_as_long(struct TypedValue*_Nonnull value); +int64_t typed_value_as_entid(struct TypedValue*_Nonnull value); +const char* _Nonnull typed_value_as_kw(struct TypedValue*_Nonnull value); +int32_t typed_value_as_boolean(struct TypedValue*_Nonnull value); +double typed_value_as_double(struct TypedValue*_Nonnull value); +int64_t typed_value_as_timestamp(struct TypedValue*_Nonnull value); +const char* _Nonnull typed_value_as_string(struct TypedValue*_Nonnull value); +const char* _Nonnull typed_value_as_uuid(struct TypedValue*_Nonnull value); + +struct QueryResultRow* _Nullable row_at_index(struct QueryResultRows* _Nonnull rows, const int32_t index); +struct QueryRowsIterator* _Nonnull rows_iter(struct QueryResultRows* _Nonnull rows); +struct QueryResultRow* _Nullable rows_iter_next(struct QueryRowsIterator* _Nonnull iter); +struct QueryRowIterator* _Nonnull values_iter(struct QueryResultRow* _Nonnull row); +struct TypedValue* _Nullable values_iter_next(struct QueryRowIterator* _Nonnull iter); +const int64_t* _Nullable values_iter_next_as_long(struct QueryRowIterator* _Nonnull iter); +const int64_t* _Nullable values_iter_next_as_entid(struct QueryRowIterator* _Nonnull iter); +const char* _Nullable values_iter_next_as_kw(struct QueryRowIterator* _Nonnull iter); +const int32_t* _Nullable values_iter_next_as_boolean(struct QueryRowIterator* _Nonnull iter); +const double* _Nullable values_iter_next_as_double(struct QueryRowIterator* _Nonnull iter); +const int64_t* _Nullable values_iter_next_as_timestamp(struct QueryRowIterator* _Nonnull iter); +const char* _Nullable values_iter_next_as_string(struct QueryRowIterator* _Nonnull iter); +const char* _Nullable values_iter_next_as_uuid(struct QueryRowIterator* _Nonnull iter); + +struct TypedValue* _Nonnull value_at_index(struct QueryResultRow* _Nonnull row, const int32_t index); +int64_t value_at_index_as_long(struct QueryResultRow* _Nonnull row, const int32_t index); +int64_t value_at_index_as_entid(struct QueryResultRow* _Nonnull row, const int32_t index); +const char* _Nonnull value_at_index_as_kw(struct QueryResultRow* _Nonnull row, const int32_t index); +int32_t value_at_index_as_boolean(struct QueryResultRow* _Nonnull row, const int32_t index); +double value_at_index_as_double(struct QueryResultRow* _Nonnull row, const int32_t index); +int64_t value_at_index_as_timestamp(struct QueryResultRow* _Nonnull row, const int32_t index); +const char* _Nonnull value_at_index_as_string(struct QueryResultRow* _Nonnull row, const int32_t index); +const char* _Nonnull value_at_index_as_uuid(struct QueryResultRow* _Nonnull row, const int32_t index); + +// Set single values +struct Result*_Nonnull store_set_long_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const int64_t value); +struct Result*_Nonnull store_set_entid_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const int64_t value); +struct Result*_Nonnull store_set_kw_ref_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const char* _Nonnull value); +struct Result*_Nonnull store_set_boolean_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const int32_t value); +struct Result*_Nonnull store_set_double_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const double value); +struct Result*_Nonnull store_set_timestamp_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const int64_t value); +struct Result*_Nonnull store_set_string_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const char* _Nonnull value); +struct Result*_Nonnull store_set_uuid_for_attribute_on_entid(struct Store*_Nonnull store, const int64_t entid, const char* _Nonnull attribute, const char* _Nonnull value); + +// TxReports +const struct ExternTxReport* _Nullable tx_report_list_entry_at(const struct TxReportList* _Nonnull list, size_t index); + +#endif /* store_h */ diff --git a/sdks/swift/Mentat/MentatTests/Info.plist b/sdks/swift/Mentat/MentatTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/sdks/swift/Mentat/MentatTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/sdks/swift/Mentat/MentatTests/MentatTests.swift b/sdks/swift/Mentat/MentatTests/MentatTests.swift new file mode 100644 index 00000000..86860db3 --- /dev/null +++ b/sdks/swift/Mentat/MentatTests/MentatTests.swift @@ -0,0 +1,32 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +import XCTest +@testable import Mentat + +class MentatTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + // test that a store can be opened in memory + func testOpenInMemoryStore() { + XCTAssertNotNil(Mentat().intoRaw()) + } + + // test that a store can be opened in a specific location + func testOpenStoreInLocation() { + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) + let documentsURL = paths[0] + let storeURI = documentsURL.appendingPathComponent("test.db", isDirectory: false).absoluteString + XCTAssertNotNil(Mentat(storeURI: storeURI).intoRaw()) + } +}