mirror of
https://github.com/immich-app/immich.git
synced 2025-11-18 12:33:29 -05:00
chore(mobile): add table schemas to swift (#23749)
* add schemas * handle json, improve type safety * formatting * sync variants * formatting
This commit is contained in:
parent
6922a92b69
commit
9e2208b8dd
@ -32,6 +32,9 @@
|
|||||||
FEAFA8732E4D42F4001E47FE /* Thumbhash.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEAFA8722E4D42F4001E47FE /* Thumbhash.swift */; };
|
FEAFA8732E4D42F4001E47FE /* Thumbhash.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEAFA8722E4D42F4001E47FE /* Thumbhash.swift */; };
|
||||||
FED3B1962E253E9B0030FD97 /* ThumbnailsImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED3B1942E253E9B0030FD97 /* ThumbnailsImpl.swift */; };
|
FED3B1962E253E9B0030FD97 /* ThumbnailsImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED3B1942E253E9B0030FD97 /* ThumbnailsImpl.swift */; };
|
||||||
FED3B1972E253E9B0030FD97 /* Thumbnails.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED3B1932E253E9B0030FD97 /* Thumbnails.g.swift */; };
|
FED3B1972E253E9B0030FD97 /* Thumbnails.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED3B1932E253E9B0030FD97 /* Thumbnails.g.swift */; };
|
||||||
|
FEE084F82EC172460045228E /* SQLiteData in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084F72EC172460045228E /* SQLiteData */; };
|
||||||
|
FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FA2EC1725A0045228E /* RawStructuredFieldValues */; };
|
||||||
|
FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FC2EC1725A0045228E /* StructuredFieldValues */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -133,15 +136,11 @@
|
|||||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
B231F52D2E93A44A00BC45D1 /* Core */ = {
|
B231F52D2E93A44A00BC45D1 /* Core */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
exceptions = (
|
|
||||||
);
|
|
||||||
path = Core;
|
path = Core;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
B2CF7F8C2DDE4EBB00744BF6 /* Sync */ = {
|
B2CF7F8C2DDE4EBB00744BF6 /* Sync */ = {
|
||||||
isa = PBXFileSystemSynchronizedRootGroup;
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
exceptions = (
|
|
||||||
);
|
|
||||||
path = Sync;
|
path = Sync;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -153,6 +152,11 @@
|
|||||||
path = WidgetExtension;
|
path = WidgetExtension;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
FEE084F22EC172080045228E /* Schemas */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
path = Schemas;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -160,6 +164,9 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
FEE084F82EC172460045228E /* SQLiteData in Frameworks */,
|
||||||
|
FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */,
|
||||||
|
FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */,
|
||||||
D218389C4A4C4693F141F7D1 /* Pods_Runner.framework in Frameworks */,
|
D218389C4A4C4693F141F7D1 /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -254,6 +261,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
FEE084F22EC172080045228E /* Schemas */,
|
||||||
B231F52D2E93A44A00BC45D1 /* Core */,
|
B231F52D2E93A44A00BC45D1 /* Core */,
|
||||||
B25D37792E72CA15008B6CA7 /* Connectivity */,
|
B25D37792E72CA15008B6CA7 /* Connectivity */,
|
||||||
B21E34A62E5AF9760031FDB9 /* Background */,
|
B21E34A62E5AF9760031FDB9 /* Background */,
|
||||||
@ -341,6 +349,7 @@
|
|||||||
fileSystemSynchronizedGroups = (
|
fileSystemSynchronizedGroups = (
|
||||||
B231F52D2E93A44A00BC45D1 /* Core */,
|
B231F52D2E93A44A00BC45D1 /* Core */,
|
||||||
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
B2CF7F8C2DDE4EBB00744BF6 /* Sync */,
|
||||||
|
FEE084F22EC172080045228E /* Schemas */,
|
||||||
);
|
);
|
||||||
name = Runner;
|
name = Runner;
|
||||||
productName = Runner;
|
productName = Runner;
|
||||||
@ -419,6 +428,10 @@
|
|||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = 97C146E51CF9000F007C117D;
|
mainGroup = 97C146E51CF9000F007C117D;
|
||||||
|
packageReferences = (
|
||||||
|
FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */,
|
||||||
|
FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */,
|
||||||
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -530,10 +543,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
@ -562,10 +579,14 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
@ -1201,6 +1222,43 @@
|
|||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/pointfreeco/sqlite-data";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 1.3.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/apple/swift-http-structured-headers.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 1.5.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
FEE084F72EC172460045228E /* SQLiteData */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */;
|
||||||
|
productName = SQLiteData;
|
||||||
|
};
|
||||||
|
FEE084FA2EC1725A0045228E /* RawStructuredFieldValues */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */;
|
||||||
|
productName = RawStructuredFieldValues;
|
||||||
|
};
|
||||||
|
FEE084FC2EC1725A0045228E /* StructuredFieldValues */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */;
|
||||||
|
productName = StructuredFieldValues;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,150 @@
|
|||||||
|
{
|
||||||
|
"originHash" : "9be33bfaa68721646604aefff3cabbdaf9a193da192aae024c265065671f6c49",
|
||||||
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "combine-schedulers",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/combine-schedulers",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "5928286acce13def418ec36d05a001a9641086f2",
|
||||||
|
"version" : "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "grdb.swift",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/groue/GRDB.swift",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "18497b68fdbb3a09528d260a0a0e1e7e61c8c53d",
|
||||||
|
"version" : "7.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "sqlite-data",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/sqlite-data",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b66b894b9a5710f1072c8eb6448a7edfc2d743d9",
|
||||||
|
"version" : "1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-clocks",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-clocks",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "cc46202b53476d64e824e0b6612da09d84ffde8e",
|
||||||
|
"version" : "1.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-collections",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-collections",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e",
|
||||||
|
"version" : "1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-concurrency-extras",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-concurrency-extras",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "5a3825302b1a0d744183200915a47b508c828e6f",
|
||||||
|
"version" : "1.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-custom-dump",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-custom-dump",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1",
|
||||||
|
"version" : "1.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-dependencies",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-dependencies",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "a10f9feeb214bc72b5337b6ef6d5a029360db4cc",
|
||||||
|
"version" : "1.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-http-structured-headers",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-http-structured-headers.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "a9f3c352f4d46afd155e00b3c6e85decae6bcbeb",
|
||||||
|
"version" : "1.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-identified-collections",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-identified-collections",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "322d9ffeeba85c9f7c4984b39422ec7cc3c56597",
|
||||||
|
"version" : "1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-perception",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-perception",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "4f47ebafed5f0b0172cf5c661454fa8e28fb2ac4",
|
||||||
|
"version" : "2.0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-sharing",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-sharing",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "3bfc408cc2d0bee2287c174da6b1c76768377818",
|
||||||
|
"version" : "2.7.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-snapshot-testing",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "a8b7c5e0ed33d8ab8887d1654d9b59f2cbad529b",
|
||||||
|
"version" : "1.18.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-structured-queries",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-structured-queries",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "1447ea20550f6f02c4b48cc80931c3ed40a9c756",
|
||||||
|
"version" : "0.25.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-syntax",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/swiftlang/swift-syntax",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "4799286537280063c85a32f09884cfbca301b1a1",
|
||||||
|
"version" : "602.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "xctest-dynamic-overlay",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "4c27acf5394b645b70d8ba19dc249c0472d5f618",
|
||||||
|
"version" : "1.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version" : 3
|
||||||
|
}
|
||||||
177
mobile/ios/Runner/Schemas/Constants.swift
Normal file
177
mobile/ios/Runner/Schemas/Constants.swift
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
import SQLiteData
|
||||||
|
|
||||||
|
struct Endpoint: Codable {
|
||||||
|
let url: URL
|
||||||
|
let status: Status
|
||||||
|
|
||||||
|
enum Status: String, Codable {
|
||||||
|
case loading, valid, error, unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StoreKey: Int, CaseIterable, QueryBindable {
|
||||||
|
// MARK: - Int
|
||||||
|
case _version = 0
|
||||||
|
static let version = Typed<Int>(rawValue: ._version)
|
||||||
|
case _deviceIdHash = 3
|
||||||
|
static let deviceIdHash = Typed<Int>(rawValue: ._deviceIdHash)
|
||||||
|
case _backupTriggerDelay = 8
|
||||||
|
static let backupTriggerDelay = Typed<Int>(rawValue: ._backupTriggerDelay)
|
||||||
|
case _tilesPerRow = 103
|
||||||
|
static let tilesPerRow = Typed<Int>(rawValue: ._tilesPerRow)
|
||||||
|
case _groupAssetsBy = 105
|
||||||
|
static let groupAssetsBy = Typed<Int>(rawValue: ._groupAssetsBy)
|
||||||
|
case _uploadErrorNotificationGracePeriod = 106
|
||||||
|
static let uploadErrorNotificationGracePeriod = Typed<Int>(rawValue: ._uploadErrorNotificationGracePeriod)
|
||||||
|
case _thumbnailCacheSize = 110
|
||||||
|
static let thumbnailCacheSize = Typed<Int>(rawValue: ._thumbnailCacheSize)
|
||||||
|
case _imageCacheSize = 111
|
||||||
|
static let imageCacheSize = Typed<Int>(rawValue: ._imageCacheSize)
|
||||||
|
case _albumThumbnailCacheSize = 112
|
||||||
|
static let albumThumbnailCacheSize = Typed<Int>(rawValue: ._albumThumbnailCacheSize)
|
||||||
|
case _selectedAlbumSortOrder = 113
|
||||||
|
static let selectedAlbumSortOrder = Typed<Int>(rawValue: ._selectedAlbumSortOrder)
|
||||||
|
case _logLevel = 115
|
||||||
|
static let logLevel = Typed<Int>(rawValue: ._logLevel)
|
||||||
|
case _mapRelativeDate = 119
|
||||||
|
static let mapRelativeDate = Typed<Int>(rawValue: ._mapRelativeDate)
|
||||||
|
case _mapThemeMode = 124
|
||||||
|
static let mapThemeMode = Typed<Int>(rawValue: ._mapThemeMode)
|
||||||
|
|
||||||
|
// MARK: - String
|
||||||
|
case _assetETag = 1
|
||||||
|
static let assetETag = Typed<String>(rawValue: ._assetETag)
|
||||||
|
case _currentUser = 2
|
||||||
|
static let currentUser = Typed<String>(rawValue: ._currentUser)
|
||||||
|
case _deviceId = 4
|
||||||
|
static let deviceId = Typed<String>(rawValue: ._deviceId)
|
||||||
|
case _accessToken = 11
|
||||||
|
static let accessToken = Typed<String>(rawValue: ._accessToken)
|
||||||
|
case _serverEndpoint = 12
|
||||||
|
static let serverEndpoint = Typed<String>(rawValue: ._serverEndpoint)
|
||||||
|
case _sslClientCertData = 15
|
||||||
|
static let sslClientCertData = Typed<String>(rawValue: ._sslClientCertData)
|
||||||
|
case _sslClientPasswd = 16
|
||||||
|
static let sslClientPasswd = Typed<String>(rawValue: ._sslClientPasswd)
|
||||||
|
case _themeMode = 102
|
||||||
|
static let themeMode = Typed<String>(rawValue: ._themeMode)
|
||||||
|
case _customHeaders = 127
|
||||||
|
static let customHeaders = Typed<[String: String]>(rawValue: ._customHeaders)
|
||||||
|
case _primaryColor = 128
|
||||||
|
static let primaryColor = Typed<String>(rawValue: ._primaryColor)
|
||||||
|
case _preferredWifiName = 133
|
||||||
|
static let preferredWifiName = Typed<String>(rawValue: ._preferredWifiName)
|
||||||
|
|
||||||
|
// MARK: - Endpoint
|
||||||
|
case _externalEndpointList = 135
|
||||||
|
static let externalEndpointList = Typed<[Endpoint]>(rawValue: ._externalEndpointList)
|
||||||
|
|
||||||
|
// MARK: - URL
|
||||||
|
case _localEndpoint = 134
|
||||||
|
static let localEndpoint = Typed<URL>(rawValue: ._localEndpoint)
|
||||||
|
case _serverUrl = 10
|
||||||
|
static let serverUrl = Typed<URL>(rawValue: ._serverUrl)
|
||||||
|
|
||||||
|
// MARK: - Date
|
||||||
|
case _backupFailedSince = 5
|
||||||
|
static let backupFailedSince = Typed<Date>(rawValue: ._backupFailedSince)
|
||||||
|
|
||||||
|
// MARK: - Bool
|
||||||
|
case _backupRequireWifi = 6
|
||||||
|
static let backupRequireWifi = Typed<Bool>(rawValue: ._backupRequireWifi)
|
||||||
|
case _backupRequireCharging = 7
|
||||||
|
static let backupRequireCharging = Typed<Bool>(rawValue: ._backupRequireCharging)
|
||||||
|
case _autoBackup = 13
|
||||||
|
static let autoBackup = Typed<Bool>(rawValue: ._autoBackup)
|
||||||
|
case _backgroundBackup = 14
|
||||||
|
static let backgroundBackup = Typed<Bool>(rawValue: ._backgroundBackup)
|
||||||
|
case _loadPreview = 100
|
||||||
|
static let loadPreview = Typed<Bool>(rawValue: ._loadPreview)
|
||||||
|
case _loadOriginal = 101
|
||||||
|
static let loadOriginal = Typed<Bool>(rawValue: ._loadOriginal)
|
||||||
|
case _dynamicLayout = 104
|
||||||
|
static let dynamicLayout = Typed<Bool>(rawValue: ._dynamicLayout)
|
||||||
|
case _backgroundBackupTotalProgress = 107
|
||||||
|
static let backgroundBackupTotalProgress = Typed<Bool>(rawValue: ._backgroundBackupTotalProgress)
|
||||||
|
case _backgroundBackupSingleProgress = 108
|
||||||
|
static let backgroundBackupSingleProgress = Typed<Bool>(rawValue: ._backgroundBackupSingleProgress)
|
||||||
|
case _storageIndicator = 109
|
||||||
|
static let storageIndicator = Typed<Bool>(rawValue: ._storageIndicator)
|
||||||
|
case _advancedTroubleshooting = 114
|
||||||
|
static let advancedTroubleshooting = Typed<Bool>(rawValue: ._advancedTroubleshooting)
|
||||||
|
case _preferRemoteImage = 116
|
||||||
|
static let preferRemoteImage = Typed<Bool>(rawValue: ._preferRemoteImage)
|
||||||
|
case _loopVideo = 117
|
||||||
|
static let loopVideo = Typed<Bool>(rawValue: ._loopVideo)
|
||||||
|
case _mapShowFavoriteOnly = 118
|
||||||
|
static let mapShowFavoriteOnly = Typed<Bool>(rawValue: ._mapShowFavoriteOnly)
|
||||||
|
case _selfSignedCert = 120
|
||||||
|
static let selfSignedCert = Typed<Bool>(rawValue: ._selfSignedCert)
|
||||||
|
case _mapIncludeArchived = 121
|
||||||
|
static let mapIncludeArchived = Typed<Bool>(rawValue: ._mapIncludeArchived)
|
||||||
|
case _ignoreIcloudAssets = 122
|
||||||
|
static let ignoreIcloudAssets = Typed<Bool>(rawValue: ._ignoreIcloudAssets)
|
||||||
|
case _selectedAlbumSortReverse = 123
|
||||||
|
static let selectedAlbumSortReverse = Typed<Bool>(rawValue: ._selectedAlbumSortReverse)
|
||||||
|
case _mapwithPartners = 125
|
||||||
|
static let mapwithPartners = Typed<Bool>(rawValue: ._mapwithPartners)
|
||||||
|
case _enableHapticFeedback = 126
|
||||||
|
static let enableHapticFeedback = Typed<Bool>(rawValue: ._enableHapticFeedback)
|
||||||
|
case _dynamicTheme = 129
|
||||||
|
static let dynamicTheme = Typed<Bool>(rawValue: ._dynamicTheme)
|
||||||
|
case _colorfulInterface = 130
|
||||||
|
static let colorfulInterface = Typed<Bool>(rawValue: ._colorfulInterface)
|
||||||
|
case _syncAlbums = 131
|
||||||
|
static let syncAlbums = Typed<Bool>(rawValue: ._syncAlbums)
|
||||||
|
case _autoEndpointSwitching = 132
|
||||||
|
static let autoEndpointSwitching = Typed<Bool>(rawValue: ._autoEndpointSwitching)
|
||||||
|
case _loadOriginalVideo = 136
|
||||||
|
static let loadOriginalVideo = Typed<Bool>(rawValue: ._loadOriginalVideo)
|
||||||
|
case _manageLocalMediaAndroid = 137
|
||||||
|
static let manageLocalMediaAndroid = Typed<Bool>(rawValue: ._manageLocalMediaAndroid)
|
||||||
|
case _readonlyModeEnabled = 138
|
||||||
|
static let readonlyModeEnabled = Typed<Bool>(rawValue: ._readonlyModeEnabled)
|
||||||
|
case _autoPlayVideo = 139
|
||||||
|
static let autoPlayVideo = Typed<Bool>(rawValue: ._autoPlayVideo)
|
||||||
|
case _photoManagerCustomFilter = 1000
|
||||||
|
static let photoManagerCustomFilter = Typed<Bool>(rawValue: ._photoManagerCustomFilter)
|
||||||
|
case _betaPromptShown = 1001
|
||||||
|
static let betaPromptShown = Typed<Bool>(rawValue: ._betaPromptShown)
|
||||||
|
case _betaTimeline = 1002
|
||||||
|
static let betaTimeline = Typed<Bool>(rawValue: ._betaTimeline)
|
||||||
|
case _enableBackup = 1003
|
||||||
|
static let enableBackup = Typed<Bool>(rawValue: ._enableBackup)
|
||||||
|
case _useWifiForUploadVideos = 1004
|
||||||
|
static let useWifiForUploadVideos = Typed<Bool>(rawValue: ._useWifiForUploadVideos)
|
||||||
|
case _useWifiForUploadPhotos = 1005
|
||||||
|
static let useWifiForUploadPhotos = Typed<Bool>(rawValue: ._useWifiForUploadPhotos)
|
||||||
|
case _needBetaMigration = 1006
|
||||||
|
static let needBetaMigration = Typed<Bool>(rawValue: ._needBetaMigration)
|
||||||
|
case _shouldResetSync = 1007
|
||||||
|
static let shouldResetSync = Typed<Bool>(rawValue: ._shouldResetSync)
|
||||||
|
|
||||||
|
struct Typed<T>: RawRepresentable {
|
||||||
|
let rawValue: StoreKey
|
||||||
|
|
||||||
|
@_transparent
|
||||||
|
init(rawValue value: StoreKey) {
|
||||||
|
self.rawValue = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BackupSelection: Int, QueryBindable {
|
||||||
|
case selected, none, excluded
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AvatarColor: Int, QueryBindable {
|
||||||
|
case primary, pink, red, yellow, blue, green, purple, orange, gray, amber
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AlbumUserRole: Int, QueryBindable {
|
||||||
|
case editor, viewer
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MemoryType: Int, QueryBindable {
|
||||||
|
case onThisDay
|
||||||
|
}
|
||||||
146
mobile/ios/Runner/Schemas/Store.swift
Normal file
146
mobile/ios/Runner/Schemas/Store.swift
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
import SQLiteData
|
||||||
|
|
||||||
|
enum StoreError: Error {
|
||||||
|
case invalidJSON(String)
|
||||||
|
case invalidURL(String)
|
||||||
|
case encodingFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol StoreConvertible {
|
||||||
|
associatedtype StorageType
|
||||||
|
static func fromValue(_ value: StorageType) throws(StoreError) -> Self
|
||||||
|
static func toValue(_ value: Self) throws(StoreError) -> StorageType
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int: StoreConvertible {
|
||||||
|
static func fromValue(_ value: Int) -> Int { value }
|
||||||
|
static func toValue(_ value: Int) -> Int { value }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Bool: StoreConvertible {
|
||||||
|
static func fromValue(_ value: Int) -> Bool { value == 1 }
|
||||||
|
static func toValue(_ value: Bool) -> Int { value ? 1 : 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Date: StoreConvertible {
|
||||||
|
static func fromValue(_ value: Int) -> Date { Date(timeIntervalSince1970: TimeInterval(value) / 1000) }
|
||||||
|
static func toValue(_ value: Date) -> Int { Int(value.timeIntervalSince1970 * 1000) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String: StoreConvertible {
|
||||||
|
static func fromValue(_ value: String) -> String { value }
|
||||||
|
static func toValue(_ value: String) -> String { value }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension URL: StoreConvertible {
|
||||||
|
static func fromValue(_ value: String) throws(StoreError) -> URL {
|
||||||
|
guard let url = URL(string: value) else {
|
||||||
|
throw StoreError.invalidURL(value)
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
static func toValue(_ value: URL) -> String { value.absoluteString }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StoreConvertible where Self: Codable, StorageType == String {
|
||||||
|
static var jsonDecoder: JSONDecoder { JSONDecoder() }
|
||||||
|
static var jsonEncoder: JSONEncoder { JSONEncoder() }
|
||||||
|
|
||||||
|
static func fromValue(_ value: String) throws(StoreError) -> Self {
|
||||||
|
do {
|
||||||
|
return try jsonDecoder.decode(Self.self, from: Data(value.utf8))
|
||||||
|
} catch {
|
||||||
|
throw StoreError.invalidJSON(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func toValue(_ value: Self) throws(StoreError) -> String {
|
||||||
|
let encoded: Data
|
||||||
|
do {
|
||||||
|
encoded = try jsonEncoder.encode(value)
|
||||||
|
} catch {
|
||||||
|
throw StoreError.encodingFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let string = String(data: encoded, encoding: .utf8) else {
|
||||||
|
throw StoreError.encodingFailed
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Array: StoreConvertible where Element: Codable {
|
||||||
|
typealias StorageType = String
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Dictionary: StoreConvertible where Key == String, Value: Codable {
|
||||||
|
typealias StorageType = String
|
||||||
|
}
|
||||||
|
|
||||||
|
class StoreRepository {
|
||||||
|
private let db: DatabasePool
|
||||||
|
|
||||||
|
init(db: DatabasePool) {
|
||||||
|
self.db = db
|
||||||
|
}
|
||||||
|
|
||||||
|
func get<T: StoreConvertible>(_ key: StoreKey.Typed<T>) throws -> T? where T.StorageType == Int {
|
||||||
|
let query = Store.select(\.intValue).where { $0.id.eq(key.rawValue) }
|
||||||
|
if let value = try db.read({ conn in try query.fetchOne(conn) }) ?? nil {
|
||||||
|
return try T.fromValue(value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func get<T: StoreConvertible>(_ key: StoreKey.Typed<T>) throws -> T? where T.StorageType == String {
|
||||||
|
let query = Store.select(\.stringValue).where { $0.id.eq(key.rawValue) }
|
||||||
|
if let value = try db.read({ conn in try query.fetchOne(conn) }) ?? nil {
|
||||||
|
return try T.fromValue(value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func get<T: StoreConvertible>(_ key: StoreKey.Typed<T>) async throws -> T? where T.StorageType == Int {
|
||||||
|
let query = Store.select(\.intValue).where { $0.id.eq(key.rawValue) }
|
||||||
|
if let value = try await db.read({ conn in try query.fetchOne(conn) }) ?? nil {
|
||||||
|
return try T.fromValue(value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func get<T: StoreConvertible>(_ key: StoreKey.Typed<T>) async throws -> T? where T.StorageType == String {
|
||||||
|
let query = Store.select(\.stringValue).where { $0.id.eq(key.rawValue) }
|
||||||
|
if let value = try await db.read({ conn in try query.fetchOne(conn) }) ?? nil {
|
||||||
|
return try T.fromValue(value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func set<T: StoreConvertible>(_ key: StoreKey.Typed<T>, value: T) throws where T.StorageType == Int {
|
||||||
|
let value = try T.toValue(value)
|
||||||
|
try db.write { conn in
|
||||||
|
try Store.upsert { Store(id: key.rawValue, stringValue: nil, intValue: value) }.execute(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func set<T: StoreConvertible>(_ key: StoreKey.Typed<T>, value: T) throws where T.StorageType == String {
|
||||||
|
let value = try T.toValue(value)
|
||||||
|
try db.write { conn in
|
||||||
|
try Store.upsert { Store(id: key.rawValue, stringValue: value, intValue: nil) }.execute(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func set<T: StoreConvertible>(_ key: StoreKey.Typed<T>, value: T) async throws where T.StorageType == Int {
|
||||||
|
let value = try T.toValue(value)
|
||||||
|
try await db.write { conn in
|
||||||
|
try Store.upsert { Store(id: key.rawValue, stringValue: nil, intValue: value) }.execute(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func set<T: StoreConvertible>(_ key: StoreKey.Typed<T>, value: T) async throws where T.StorageType == String {
|
||||||
|
let value = try T.toValue(value)
|
||||||
|
try await db.write { conn in
|
||||||
|
try Store.upsert { Store(id: key.rawValue, stringValue: value, intValue: nil) }.execute(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
237
mobile/ios/Runner/Schemas/Tables.swift
Normal file
237
mobile/ios/Runner/Schemas/Tables.swift
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
import GRDB
|
||||||
|
import SQLiteData
|
||||||
|
|
||||||
|
@Table("asset_face_entity")
|
||||||
|
struct AssetFace {
|
||||||
|
let id: String
|
||||||
|
let assetId: String
|
||||||
|
let personId: String?
|
||||||
|
let imageWidth: Int
|
||||||
|
let imageHeight: Int
|
||||||
|
let boundingBoxX1: Int
|
||||||
|
let boundingBoxY1: Int
|
||||||
|
let boundingBoxX2: Int
|
||||||
|
let boundingBoxY2: Int
|
||||||
|
let sourceType: String
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("auth_user_entity")
|
||||||
|
struct AuthUser {
|
||||||
|
let id: String
|
||||||
|
let name: String
|
||||||
|
let email: String
|
||||||
|
let isAdmin: Bool
|
||||||
|
let hasProfileImage: Bool
|
||||||
|
let profileChangedAt: Date
|
||||||
|
let avatarColor: AvatarColor
|
||||||
|
let quotaSizeInBytes: Int
|
||||||
|
let quotaUsageInBytes: Int
|
||||||
|
let pinCode: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("local_album_entity")
|
||||||
|
struct LocalAlbum {
|
||||||
|
let id: String
|
||||||
|
let backupSelection: BackupSelection
|
||||||
|
let linkedRemoteAlbumId: String?
|
||||||
|
let marker_: Bool?
|
||||||
|
let name: String
|
||||||
|
let isIosSharedAlbum: Bool
|
||||||
|
let updatedAt: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("local_album_asset_entity")
|
||||||
|
struct LocalAlbumAsset {
|
||||||
|
let id: ID
|
||||||
|
let marker_: String?
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let assetId: String
|
||||||
|
let albumId: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("local_asset_entity")
|
||||||
|
struct LocalAsset {
|
||||||
|
let id: String
|
||||||
|
let checksum: String?
|
||||||
|
let createdAt: Date
|
||||||
|
let durationInSeconds: Int?
|
||||||
|
let height: Int?
|
||||||
|
let isFavorite: Bool
|
||||||
|
let name: String
|
||||||
|
let orientation: String
|
||||||
|
let type: Int
|
||||||
|
let updatedAt: Date
|
||||||
|
let width: Int?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("memory_asset_entity")
|
||||||
|
struct MemoryAsset {
|
||||||
|
let id: ID
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let assetId: String
|
||||||
|
let albumId: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("memory_entity")
|
||||||
|
struct Memory {
|
||||||
|
let id: String
|
||||||
|
let createdAt: Date
|
||||||
|
let updatedAt: Date
|
||||||
|
let deletedAt: Date?
|
||||||
|
let ownerId: String
|
||||||
|
let type: MemoryType
|
||||||
|
let data: String
|
||||||
|
let isSaved: Bool
|
||||||
|
let memoryAt: Date
|
||||||
|
let seenAt: Date?
|
||||||
|
let showAt: Date?
|
||||||
|
let hideAt: Date?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("partner_entity")
|
||||||
|
struct Partner {
|
||||||
|
let id: ID
|
||||||
|
let inTimeline: Bool
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let sharedById: String
|
||||||
|
let sharedWithId: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("person_entity")
|
||||||
|
struct Person {
|
||||||
|
let id: String
|
||||||
|
let createdAt: Date
|
||||||
|
let updatedAt: Date
|
||||||
|
let ownerId: String
|
||||||
|
let name: String
|
||||||
|
let faceAssetId: String?
|
||||||
|
let isFavorite: Bool
|
||||||
|
let isHidden: Bool
|
||||||
|
let color: String?
|
||||||
|
let birthDate: Date?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("remote_album_entity")
|
||||||
|
struct RemoteAlbum {
|
||||||
|
let id: String
|
||||||
|
let createdAt: Date
|
||||||
|
let description: String?
|
||||||
|
let isActivityEnabled: Bool
|
||||||
|
let name: String
|
||||||
|
let order: Int
|
||||||
|
let ownerId: String
|
||||||
|
let thumbnailAssetId: String?
|
||||||
|
let updatedAt: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("remote_album_asset_entity")
|
||||||
|
struct RemoteAlbumAsset {
|
||||||
|
let id: ID
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let assetId: String
|
||||||
|
let albumId: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("remote_album_user_entity")
|
||||||
|
struct RemoteAlbumUser {
|
||||||
|
let id: ID
|
||||||
|
let role: AlbumUserRole
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let albumId: String
|
||||||
|
let userId: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("remote_asset_entity")
|
||||||
|
struct RemoteAsset {
|
||||||
|
let id: String
|
||||||
|
let checksum: String?
|
||||||
|
let deletedAt: Date?
|
||||||
|
let isFavorite: Int
|
||||||
|
let libraryId: String?
|
||||||
|
let livePhotoVideoId: String?
|
||||||
|
let localDateTime: Date?
|
||||||
|
let orientation: String
|
||||||
|
let ownerId: String
|
||||||
|
let stackId: String?
|
||||||
|
let visibility: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("remote_exif_entity")
|
||||||
|
struct RemoteExif {
|
||||||
|
@Column(primaryKey: true)
|
||||||
|
let assetId: String
|
||||||
|
let city: String?
|
||||||
|
let state: String?
|
||||||
|
let country: String?
|
||||||
|
let dateTimeOriginal: Date?
|
||||||
|
let description: String?
|
||||||
|
let height: Int?
|
||||||
|
let width: Int?
|
||||||
|
let exposureTime: String?
|
||||||
|
let fNumber: Double?
|
||||||
|
let fileSize: Int?
|
||||||
|
let focalLength: Double?
|
||||||
|
let latitude: Double?
|
||||||
|
let longitude: Double?
|
||||||
|
let iso: Int?
|
||||||
|
let make: String?
|
||||||
|
let model: String?
|
||||||
|
let lens: String?
|
||||||
|
let orientation: String?
|
||||||
|
let timeZone: String?
|
||||||
|
let rating: Int?
|
||||||
|
let projectionType: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("stack_entity")
|
||||||
|
struct Stack {
|
||||||
|
let id: String
|
||||||
|
let createdAt: Date
|
||||||
|
let updatedAt: Date
|
||||||
|
let ownerId: String
|
||||||
|
let primaryAssetId: String
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("store_entity")
|
||||||
|
struct Store {
|
||||||
|
let id: StoreKey
|
||||||
|
let stringValue: String?
|
||||||
|
let intValue: Int?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("user_entity")
|
||||||
|
struct User {
|
||||||
|
let id: String
|
||||||
|
let name: String
|
||||||
|
let email: String
|
||||||
|
let hasProfileImage: Bool
|
||||||
|
let profileChangedAt: Date
|
||||||
|
let avatarColor: AvatarColor
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table("user_metadata_entity")
|
||||||
|
struct UserMetadata {
|
||||||
|
let id: ID
|
||||||
|
let value: Data
|
||||||
|
|
||||||
|
@Selection
|
||||||
|
struct ID {
|
||||||
|
let userId: String
|
||||||
|
let key: Date
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user