diff --git a/Amplify.xcodeproj/project.pbxproj b/Amplify.xcodeproj/project.pbxproj index d2425614a7..8a32141323 100755 --- a/Amplify.xcodeproj/project.pbxproj +++ b/Amplify.xcodeproj/project.pbxproj @@ -415,6 +415,7 @@ B9FAA180238FBB5D009414B4 /* Model+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAA17F238FBB5D009414B4 /* Model+Array.swift */; }; B9FB05F82383740D00DE1FD4 /* DataStoreStatement.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FB05F72383740D00DE1FD4 /* DataStoreStatement.swift */; }; D83C5160248964780091548E /* ModelGraphQLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83C515F248964780091548E /* ModelGraphQLTests.swift */; }; + D84CF107255C5CA8007B96A9 /* CodingKeysTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84CF106255C5CA8007B96A9 /* CodingKeysTests.swift */; }; D8DD7A1D24A1CCCD001C49FD /* QuerySortInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DD7A1C24A1CCCD001C49FD /* QuerySortInput.swift */; }; FA00F68824DA37EE003E8A71 /* AuthCategoryBehavior+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA00F68724DA37EE003E8A71 /* AuthCategoryBehavior+Combine.swift */; }; FA00F68A24DA3A43003E8A71 /* AuthCategoryDeviceBehavior+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA00F68924DA3A43003E8A71 /* AuthCategoryDeviceBehavior+Combine.swift */; }; @@ -1265,6 +1266,7 @@ D5363CAF9EFAA822FED56808 /* Pods_Amplify_AWSPluginsCore_AWSPluginsTestConfigs_AWSPluginsTestCommon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Amplify_AWSPluginsCore_AWSPluginsTestConfigs_AWSPluginsTestCommon.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D5521D5FA66340943C39C451 /* Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSAPICategoryPlugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSAPICategoryPlugin.debug.xcconfig"; path = "Target Support Files/Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSAPICategoryPlugin/Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSAPICategoryPlugin.debug.xcconfig"; sourceTree = ""; }; D83C515F248964780091548E /* ModelGraphQLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelGraphQLTests.swift; sourceTree = ""; }; + D84CF106255C5CA8007B96A9 /* CodingKeysTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodingKeysTests.swift; sourceTree = ""; }; D8DD7A1C24A1CCCD001C49FD /* QuerySortInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuerySortInput.swift; sourceTree = ""; }; DD2486414D63230FF39130C7 /* Pods-Amplify-AWSPluginsCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Amplify-AWSPluginsCore.debug.xcconfig"; path = "Target Support Files/Pods-Amplify-AWSPluginsCore/Pods-Amplify-AWSPluginsCore.debug.xcconfig"; sourceTree = ""; }; DEEB82A328223C60557B75C1 /* Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSPinpointAnalyticsPlugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSPinpointAnalyticsPlugin.release.xcconfig"; path = "Target Support Files/Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSPinpointAnalyticsPlugin/Pods-Amplify-AmplifyAWSPlugins-AWSPluginsCore-AWSPinpointAnalyticsPlugin.release.xcconfig"; sourceTree = ""; }; @@ -3396,6 +3398,7 @@ FAD3937B23820CE200463F5E /* DataStore */ = { isa = PBXGroup; children = ( + D84CF106255C5CA8007B96A9 /* CodingKeysTests.swift */, FAD3937923820CDB00463F5E /* DataStoreCategoryClientAPITests.swift */, FAD3937C23820D0200463F5E /* DataStoreCategoryConfigurationTests.swift */, B4944D51251C141200BF0BFE /* JSONValueHolderTest.swift */, @@ -4818,6 +4821,7 @@ B91A87A423D64B0F0049A12F /* TemporalTests.swift in Sources */, FA00F69024DA3F95003E8A71 /* HubCombineTests.swift in Sources */, FA5D76AF23947E9C00489864 /* Model+CodableTests.swift in Sources */, + D84CF107255C5CA8007B96A9 /* CodingKeysTests.swift in Sources */, FA58456B24DA31370028D65A /* AmplifyInProcessReportingOperationChainedTests.swift in Sources */, FA1B964E24BF5FA70002B90A /* AmplifyOperationCombineTests.swift in Sources */, FAAFAF3323904BA4002CF932 /* AtomicValue+NumericTests.swift in Sources */, diff --git a/Amplify/Categories/DataStore/Query/ModelKey.swift b/Amplify/Categories/DataStore/Query/ModelKey.swift index add03d5d3b..744446e3f2 100644 --- a/Amplify/Categories/DataStore/Query/ModelKey.swift +++ b/Amplify/Categories/DataStore/Query/ModelKey.swift @@ -32,24 +32,43 @@ import Foundation /// post.content != nil /// }) /// ``` -public protocol ModelKey: CodingKey, CaseIterable, QueryFieldOperation {} +public protocol ModelKey: CodingKey, CaseIterable, QueryFieldOperation, DefaultLogger { + var modelName: String { get } +} + +extension ModelKey { + public var modelName: String { "" } +} extension CodingKey where Self: ModelKey { + var columnName: String { + guard let modelSchema: ModelSchema = ModelRegistry.modelSchema(from: modelName) else { + log.warn("Please upgrade to the latest version of Amplify CLI and rerun `amplify codegen models`") + return stringValue + } + switch modelSchema.field(withName: stringValue)?.association { + case .belongsTo(_, let targetName): + return targetName ?? stringValue + default: + return stringValue + } + } + // MARK: - beginsWith public func beginsWith(_ value: String) -> QueryPredicateOperation { - return field(stringValue).beginsWith(value) + return field(columnName).beginsWith(value) } // MARK: - between public func between(start: Persistable, end: Persistable) -> QueryPredicateOperation { - return field(stringValue).between(start: start, end: end) + return field(columnName).between(start: start, end: end) } // MARK: - contains public func contains(_ value: String) -> QueryPredicateOperation { - return field(stringValue).contains(value) + return field(columnName).contains(value) } public static func ~= (key: Self, value: String) -> QueryPredicateOperation { @@ -59,11 +78,11 @@ extension CodingKey where Self: ModelKey { // MARK: - eq public func eq(_ value: Persistable?) -> QueryPredicateOperation { - return field(stringValue).eq(value) + return field(columnName).eq(value) } public func eq(_ value: EnumPersistable) -> QueryPredicateOperation { - return field(stringValue).eq(value) + return field(columnName).eq(value) } public static func == (key: Self, value: Persistable?) -> QueryPredicateOperation { @@ -77,7 +96,7 @@ extension CodingKey where Self: ModelKey { // MARK: - ge public func ge(_ value: Persistable) -> QueryPredicateOperation { - return field(stringValue).ge(value) + return field(columnName).ge(value) } public static func >= (key: Self, value: Persistable) -> QueryPredicateOperation { @@ -87,7 +106,7 @@ extension CodingKey where Self: ModelKey { // MARK: - gt public func gt(_ value: Persistable) -> QueryPredicateOperation { - return field(stringValue).gt(value) + return field(columnName).gt(value) } public static func > (key: Self, value: Persistable) -> QueryPredicateOperation { @@ -97,7 +116,7 @@ extension CodingKey where Self: ModelKey { // MARK: - le public func le(_ value: Persistable) -> QueryPredicateOperation { - return field(stringValue).le(value) + return field(columnName).le(value) } public static func <= (key: Self, value: Persistable) -> QueryPredicateOperation { @@ -107,7 +126,7 @@ extension CodingKey where Self: ModelKey { // MARK: - lt public func lt(_ value: Persistable) -> QueryPredicateOperation { - return field(stringValue).lt(value) + return field(columnName).lt(value) } public static func < (key: Self, value: Persistable) -> QueryPredicateOperation { @@ -117,11 +136,11 @@ extension CodingKey where Self: ModelKey { // MARK: - ne public func ne(_ value: Persistable?) -> QueryPredicateOperation { - return field(stringValue).ne(value) + return field(columnName).ne(value) } public func ne(_ value: EnumPersistable) -> QueryPredicateOperation { - return field(stringValue).ne(value) + return field(columnName).ne(value) } public static func != (key: Self, value: Persistable?) -> QueryPredicateOperation { diff --git a/AmplifyPlugins/Core/AWSPluginsCoreTests/Model/Decorator/AuthRuleDecorator/ModelWithOwnerAuthAndGroupWithGroupClaim.swift b/AmplifyPlugins/Core/AWSPluginsCoreTests/Model/Decorator/AuthRuleDecorator/ModelWithOwnerAuthAndGroupWithGroupClaim.swift index a16ae66e89..4d6416d715 100644 --- a/AmplifyPlugins/Core/AWSPluginsCoreTests/Model/Decorator/AuthRuleDecorator/ModelWithOwnerAuthAndGroupWithGroupClaim.swift +++ b/AmplifyPlugins/Core/AWSPluginsCoreTests/Model/Decorator/AuthRuleDecorator/ModelWithOwnerAuthAndGroupWithGroupClaim.swift @@ -16,9 +16,13 @@ import XCTest @model @auth( rules: [ - { allow: owner, provider: oidc, identityClaim: "sub"}, - { allow: groups, provider: oidc, groups: ["Admins"], - groupClaim: "https://myapp.com/claims/groups"} + { allow: owner, provider: oidc, identityClaim: "sub" } + { + allow: groups + provider: oidc + groups: ["Admins"] + groupClaim: "https://myapp.com/claims/groups" + } ] ) { id: ID! @@ -28,48 +32,48 @@ import XCTest */ public struct OIDCGroupPost: Model { - public let id: String - public var title: String - public var owner: String? - - public init(id: String = UUID().uuidString, - title: String, - owner: String? = nil) { - self.id = id - self.title = title - self.owner = owner - } + public let id: String + public var title: String + public var owner: String? + + public init(id: String = UUID().uuidString, + title: String, + owner: String? = nil) { + self.id = id + self.title = title + self.owner = owner + } // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case title - case owner + public enum CodingKeys: String, ModelKey { + case id + case title + case owner } public static let keys = CodingKeys.self public static let schema = defineSchema { model in - let oIDCGroupPost = OIDCGroupPost.keys - - model.authRules = [ - rule(allow: .owner, - ownerField: "owner", - identityClaim: "sub", - operations: [.create, .update, .delete, .read]), - rule(allow: .groups, - groupClaim: "https://myapp.com/claims/groups", - groups: ["Admins"], - operations: [.create, .update, .delete, .read]) - ] - - model.pluralName = "OIDCGroupPosts" - - model.fields( - .id(), - .field(oIDCGroupPost.title, is: .required, ofType: .string), - .field(oIDCGroupPost.owner, is: .optional, ofType: .string) - ) - } + let oIDCGroupPost = OIDCGroupPost.keys + + model.authRules = [ + rule(allow: .owner, + ownerField: "owner", + identityClaim: "sub", + operations: [.create, .update, .delete, .read]), + rule(allow: .groups, + groupClaim: "https://myapp.com/claims/groups", + groups: ["Admins"], + operations: [.create, .update, .delete, .read]) + ] + + model.pluralName = "OIDCGroupPosts" + + model.fields( + .id(), + .field(oIDCGroupPost.title, is: .required, ofType: .string), + .field(oIDCGroupPost.owner, is: .optional, ofType: .string) + ) + } } class ModelWithOwnerAuthAndGroupWithGroupClaim: XCTestCase { diff --git a/AmplifyPlugins/Core/AWSPluginsTestCommon/MockAWSAuthService.swift b/AmplifyPlugins/Core/AWSPluginsTestCommon/MockAWSAuthService.swift index f7c2d0b020..5730eadb8d 100644 --- a/AmplifyPlugins/Core/AWSPluginsTestCommon/MockAWSAuthService.swift +++ b/AmplifyPlugins/Core/AWSPluginsTestCommon/MockAWSAuthService.swift @@ -16,7 +16,7 @@ public class MockAWSAuthService: AWSAuthServiceBehavior { var getTokenClaimsError: AuthError? var identityId: String? var token: String? - var tokenClaims: [String : AnyObject]? + var tokenClaims: [String: AnyObject]? public func configure() { } @@ -45,10 +45,10 @@ public class MockAWSAuthService: AWSAuthServiceBehavior { return .success(token ?? "token") } - public func getTokenClaims(tokenString: String) -> Result<[String : AnyObject], AuthError> { + public func getTokenClaims(tokenString: String) -> Result<[String: AnyObject], AuthError> { if let error = getTokenClaimsError { return .failure(error) } - return .success(tokenClaims ?? ["":"" as AnyObject]) + return .success(tokenClaims ?? ["": "" as AnyObject]) } } diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLStatementTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLStatementTests.swift index e9978be2ca..158c76b83a 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLStatementTests.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/SQLStatementTests.swift @@ -330,6 +330,31 @@ class SQLStatementTests: XCTestCase { XCTAssertEqual(statement.stringValue, expectedStatement) } + /// - Given: a `Model` type + /// - When: + /// - the model is of type `Comment` + /// - `QueryPredicate` on a connected field is given + /// - Then: + /// - check if the generated SQL statement is valid + /// - check if an inner join is added referencing `Post` + /// - check if a where with columnName `commentPostId` is generated + func testSelectStatementFromModelWhenQueryPredicateIsGiven() { + let statement = SelectStatement(from: Comment.schema, predicate: Comment.keys.post == "commentPostId") + let expectedStatement = """ + select + "root"."id" as "id", "root"."content" as "content", "root"."createdAt" as "createdAt", + "root"."commentPostId" as "commentPostId", "post"."id" as "post.id", "post"."content" as "post.content", + "post"."createdAt" as "post.createdAt", "post"."draft" as "post.draft", "post"."rating" as "post.rating", + "post"."status" as "post.status", "post"."title" as "post.title", "post"."updatedAt" as "post.updatedAt" + from Comment as "root" + inner join Post as "post" + on "post"."id" = "root"."commentPostId" + where 1 = 1 + and "root"."commentPostId" = ? + """ + XCTAssertEqual(statement.stringValue, expectedStatement) + } + // MARK: - Select Statements paginated /// - Given: a `Model` type and a `QueryPaginationInput` diff --git a/AmplifyTestCommon/Models/Associations/BookAuthor+Schema.swift b/AmplifyTestCommon/Models/Associations/BookAuthor+Schema.swift index 515bebf8e1..44322309b2 100644 --- a/AmplifyTestCommon/Models/Associations/BookAuthor+Schema.swift +++ b/AmplifyTestCommon/Models/Associations/BookAuthor+Schema.swift @@ -15,6 +15,10 @@ extension BookAuthor { case id case book case author + + public var modelName: String { + return "BookAuthor" + } } public static let keys = CodingKeys.self diff --git a/AmplifyTestCommon/Models/Associations/UserProfile+Schema.swift b/AmplifyTestCommon/Models/Associations/UserProfile+Schema.swift index d85257acbe..64a80ead26 100644 --- a/AmplifyTestCommon/Models/Associations/UserProfile+Schema.swift +++ b/AmplifyTestCommon/Models/Associations/UserProfile+Schema.swift @@ -14,6 +14,10 @@ extension UserProfile { public enum CodingKeys: String, ModelKey { case id case account + + public var modelName: String { + return "UserProfile" + } } public static let keys = CodingKeys.self diff --git a/AmplifyTestCommon/Models/Comment+Schema.swift b/AmplifyTestCommon/Models/Comment+Schema.swift index bfb397c0f6..db765a70a4 100644 --- a/AmplifyTestCommon/Models/Comment+Schema.swift +++ b/AmplifyTestCommon/Models/Comment+Schema.swift @@ -10,27 +10,31 @@ import Amplify import Foundation extension Comment { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case content - case createdAt - case post - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case content + case createdAt + case post - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public var modelName: String { + return "Comment" + } + } + + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let comment = Comment.keys + public static let schema = defineSchema { model in + let comment = Comment.keys - model.pluralName = "Comments" + model.pluralName = "Comments" - model.fields( - .id(), - .field(comment.content, is: .required, ofType: .string), - .field(comment.createdAt, is: .required, ofType: .dateTime), - .belongsTo(comment.post, is: .required, ofType: Post.self, targetName: "commentPostId") - ) + model.fields( + .id(), + .field(comment.content, is: .required, ofType: .string), + .field(comment.createdAt, is: .required, ofType: .dateTime), + .belongsTo(comment.post, is: .required, ofType: Post.self, targetName: "commentPostId") + ) } } diff --git a/AmplifyTestCommon/Models/Deprecated/DeprecatedTodo.swift b/AmplifyTestCommon/Models/Deprecated/DeprecatedTodo.swift index a1a65d8a89..09e424f73f 100644 --- a/AmplifyTestCommon/Models/Deprecated/DeprecatedTodo.swift +++ b/AmplifyTestCommon/Models/Deprecated/DeprecatedTodo.swift @@ -9,15 +9,15 @@ import Amplify import Foundation /* -The schema used to codegen this model: + The schema used to codegen this model: type DeprecatedTodo @model { - id: ID! - description: String - note: Note + id: ID! + description: String + note: Note } type Note { - name: String! - color: String! + name: String! + color: String! } Amplify CLI version used is less than 4.21.4. `.customType` has since been replaced with `.embedded(type)` and @@ -26,40 +26,40 @@ The schema used to codegen this model: */ public struct DeprecatedTodo: Model { - public let id: String - public var description: String? - public var note: Note? + public let id: String + public var description: String? + public var note: Note? - public init(id: String = UUID().uuidString, - description: String? = nil, - note: Note? = nil) { - self.id = id - self.description = description - self.note = note - } + public init(id: String = UUID().uuidString, + description: String? = nil, + note: Note? = nil) { + self.id = id + self.description = description + self.note = note + } } extension DeprecatedTodo { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case description - case note - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case description + case note + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let deprecatedTodo = DeprecatedTodo.keys + public static let schema = defineSchema { model in + let deprecatedTodo = DeprecatedTodo.keys - model.pluralName = "DeprecatedTodos" + model.pluralName = "DeprecatedTodos" - model.fields( - .id(), - .field(deprecatedTodo.description, is: .optional, ofType: .string), - .field(deprecatedTodo.note, is: .optional, ofType: .customType(Note.self)) - ) + model.fields( + .id(), + .field(deprecatedTodo.description, is: .optional, ofType: .string), + .field(deprecatedTodo.note, is: .optional, ofType: .customType(Note.self)) + ) } } diff --git a/AmplifyTestCommon/Models/NonModel/DynamicModel.swift b/AmplifyTestCommon/Models/NonModel/DynamicModel.swift index b8c7163d83..0ca8f3c27a 100644 --- a/AmplifyTestCommon/Models/NonModel/DynamicModel.swift +++ b/AmplifyTestCommon/Models/NonModel/DynamicModel.swift @@ -71,6 +71,10 @@ extension DynamicModel { public enum CodingKeys: String, ModelKey { case id case values + + public var modelName: String { + return "DynamicModel" + } } public static let keys = CodingKeys.self diff --git a/AmplifyTestCommon/Models/NonModel/Todo+Schema.swift b/AmplifyTestCommon/Models/NonModel/Todo+Schema.swift index 2b16606f8b..d52d61905c 100644 --- a/AmplifyTestCommon/Models/NonModel/Todo+Schema.swift +++ b/AmplifyTestCommon/Models/NonModel/Todo+Schema.swift @@ -10,31 +10,31 @@ import Amplify import Foundation extension Todo { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case name - case description - case categories - case section - case stickies - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case name + case description + case categories + case section + case stickies + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let todo = Todo.keys + public static let schema = defineSchema { model in + let todo = Todo.keys - model.pluralName = "Todos" + model.pluralName = "Todos" - model.fields( - .id(), - .field(todo.name, is: .required, ofType: .string), - .field(todo.description, is: .optional, ofType: .string), - .field(todo.categories, is: .optional, ofType: .embeddedCollection(of: Category.self)), - .field(todo.section, is: .optional, ofType: .embedded(type: Section.self)), - .field(todo.stickies, is: .optional, ofType: .embeddedCollection(of: String.self)) - ) + model.fields( + .id(), + .field(todo.name, is: .required, ofType: .string), + .field(todo.description, is: .optional, ofType: .string), + .field(todo.categories, is: .optional, ofType: .embeddedCollection(of: Category.self)), + .field(todo.section, is: .optional, ofType: .embedded(type: Section.self)), + .field(todo.stickies, is: .optional, ofType: .embeddedCollection(of: String.self)) + ) } } diff --git a/AmplifyTestCommon/Models/OGCScenarioBMGroupPost+Schema.swift b/AmplifyTestCommon/Models/OGCScenarioBMGroupPost+Schema.swift index 234af3f402..b0f8fb7d03 100644 --- a/AmplifyTestCommon/Models/OGCScenarioBMGroupPost+Schema.swift +++ b/AmplifyTestCommon/Models/OGCScenarioBMGroupPost+Schema.swift @@ -10,30 +10,30 @@ import Amplify import Foundation extension OGCScenarioBMGroupPost { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case title - case owner - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case title + case owner + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let oGCScenarioBMGroupPost = OGCScenarioBMGroupPost.keys + public static let schema = defineSchema { model in + let oGCScenarioBMGroupPost = OGCScenarioBMGroupPost.keys - model.authRules = [ - rule(allow: .owner, ownerField: "owner", identityClaim: "cognito:username", operations: [.create, .update, .delete, .read]), - rule(allow: .groups, groupClaim: "cognito:groups", groups: ["Admins", "HR"], operations: [.create, .update, .delete, .read]) - ] + model.authRules = [ + rule(allow: .owner, ownerField: "owner", identityClaim: "cognito:username", operations: [.create, .update, .delete, .read]), + rule(allow: .groups, groupClaim: "cognito:groups", groups: ["Admins", "HR"], operations: [.create, .update, .delete, .read]) + ] - model.pluralName = "OGCScenarioBMGroupPosts" + model.pluralName = "OGCScenarioBMGroupPosts" - model.fields( - .id(), - .field(oGCScenarioBMGroupPost.title, is: .required, ofType: .string), - .field(oGCScenarioBMGroupPost.owner, is: .optional, ofType: .string) - ) + model.fields( + .id(), + .field(oGCScenarioBMGroupPost.title, is: .required, ofType: .string), + .field(oGCScenarioBMGroupPost.owner, is: .optional, ofType: .string) + ) } } diff --git a/AmplifyTestCommon/Models/OGCScenarioBPost+Schema.swift b/AmplifyTestCommon/Models/OGCScenarioBPost+Schema.swift index e37a68e96f..cd2b4623bf 100644 --- a/AmplifyTestCommon/Models/OGCScenarioBPost+Schema.swift +++ b/AmplifyTestCommon/Models/OGCScenarioBPost+Schema.swift @@ -10,30 +10,30 @@ import Amplify import Foundation extension OGCScenarioBPost { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case title - case owner - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case title + case owner + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let oGCScenarioBPost = OGCScenarioBPost.keys + public static let schema = defineSchema { model in + let oGCScenarioBPost = OGCScenarioBPost.keys - model.authRules = [ - rule(allow: .owner, ownerField: "owner", identityClaim: "cognito:username", operations: [.create, .update, .delete, .read]), - rule(allow: .groups, groupClaim: "cognito:groups", groups: ["Admins"], operations: [.create, .update, .delete, .read]) - ] + model.authRules = [ + rule(allow: .owner, ownerField: "owner", identityClaim: "cognito:username", operations: [.create, .update, .delete, .read]), + rule(allow: .groups, groupClaim: "cognito:groups", groups: ["Admins"], operations: [.create, .update, .delete, .read]) + ] - model.pluralName = "OGCScenarioBPosts" + model.pluralName = "OGCScenarioBPosts" - model.fields( - .id(), - .field(oGCScenarioBPost.title, is: .required, ofType: .string), - .field(oGCScenarioBPost.owner, is: .optional, ofType: .string) - ) + model.fields( + .id(), + .field(oGCScenarioBPost.title, is: .required, ofType: .string), + .field(oGCScenarioBPost.owner, is: .optional, ofType: .string) + ) } } diff --git a/AmplifyTestCommon/Models/Post+Schema.swift b/AmplifyTestCommon/Models/Post+Schema.swift index 09532d3b0d..adb8bf765f 100644 --- a/AmplifyTestCommon/Models/Post+Schema.swift +++ b/AmplifyTestCommon/Models/Post+Schema.swift @@ -10,37 +10,37 @@ import Amplify import Foundation extension Post { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case title - case content - case createdAt - case updatedAt - case draft - case rating - case status - case comments - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case title + case content + case createdAt + case updatedAt + case draft + case rating + case status + case comments + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let post = Post.keys + public static let schema = defineSchema { model in + let post = Post.keys - model.pluralName = "Posts" + model.pluralName = "Posts" - model.fields( - .id(), - .field(post.title, is: .required, ofType: .string), - .field(post.content, is: .required, ofType: .string), - .field(post.createdAt, is: .required, ofType: .dateTime), - .field(post.updatedAt, is: .optional, ofType: .dateTime), - .field(post.draft, is: .optional, ofType: .bool), - .field(post.rating, is: .optional, ofType: .double), - .field(post.status, is: .optional, ofType: .enum(type: PostStatus.self)), - .hasMany(post.comments, is: .optional, ofType: Comment.self, associatedWith: Comment.keys.post) - ) + model.fields( + .id(), + .field(post.title, is: .required, ofType: .string), + .field(post.content, is: .required, ofType: .string), + .field(post.createdAt, is: .required, ofType: .dateTime), + .field(post.updatedAt, is: .optional, ofType: .dateTime), + .field(post.draft, is: .optional, ofType: .bool), + .field(post.rating, is: .optional, ofType: .double), + .field(post.status, is: .optional, ofType: .enum(type: PostStatus.self)), + .hasMany(post.comments, is: .optional, ofType: Comment.self, associatedWith: Comment.keys.post) + ) } } diff --git a/AmplifyTestCommon/Models/ScenarioATest6Post+Schema.swift b/AmplifyTestCommon/Models/ScenarioATest6Post+Schema.swift index 4c2168e6e1..ff2d7288d3 100644 --- a/AmplifyTestCommon/Models/ScenarioATest6Post+Schema.swift +++ b/AmplifyTestCommon/Models/ScenarioATest6Post+Schema.swift @@ -10,27 +10,27 @@ import Amplify import Foundation extension ScenarioATest6Post { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case title - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case title + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let scenarioATest6Post = ScenarioATest6Post.keys + public static let schema = defineSchema { model in + let scenarioATest6Post = ScenarioATest6Post.keys - model.authRules = [ - rule(allow: .owner, ownerField: "owner", identityClaim: "sub", operations: [.create, .update, .delete, .read]) - ] + model.authRules = [ + rule(allow: .owner, ownerField: "owner", identityClaim: "sub", operations: [.create, .update, .delete, .read]) + ] - model.pluralName = "ScenarioATest6Posts" + model.pluralName = "ScenarioATest6Posts" - model.fields( - .id(), - .field(scenarioATest6Post.title, is: .required, ofType: .string) - ) + model.fields( + .id(), + .field(scenarioATest6Post.title, is: .required, ofType: .string) + ) } } diff --git a/AmplifyTestCommon/Models/User+Schema.swift b/AmplifyTestCommon/Models/User+Schema.swift index ba7e7fae45..9dded1389e 100644 --- a/AmplifyTestCommon/Models/User+Schema.swift +++ b/AmplifyTestCommon/Models/User+Schema.swift @@ -10,27 +10,27 @@ import Amplify import Foundation extension User { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case name - case following - case followers - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case name + case following + case followers + } - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let user = User.keys + public static let schema = defineSchema { model in + let user = User.keys - model.pluralName = "Users" + model.pluralName = "Users" - model.fields( - .id(), - .field(user.name, is: .required, ofType: .string), - .hasMany(user.following, is: .optional, ofType: UserFollowing.self, associatedWith: UserFollowing.keys.user), - .hasMany(user.followers, is: .optional, ofType: UserFollowers.self, associatedWith: UserFollowers.keys.user) - ) + model.fields( + .id(), + .field(user.name, is: .required, ofType: .string), + .hasMany(user.following, is: .optional, ofType: UserFollowing.self, associatedWith: UserFollowing.keys.user), + .hasMany(user.followers, is: .optional, ofType: UserFollowers.self, associatedWith: UserFollowers.keys.user) + ) } } diff --git a/AmplifyTestCommon/Models/UserFollowers+Schema.swift b/AmplifyTestCommon/Models/UserFollowers+Schema.swift index ad68d9a3e3..4c175d67c5 100644 --- a/AmplifyTestCommon/Models/UserFollowers+Schema.swift +++ b/AmplifyTestCommon/Models/UserFollowers+Schema.swift @@ -10,25 +10,29 @@ import Amplify import Foundation extension UserFollowers { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case user - case followersUser - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case user + case followersUser - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public var modelName: String { + return "UserFollowers" + } + } + + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let userFollowers = UserFollowers.keys + public static let schema = defineSchema { model in + let userFollowers = UserFollowers.keys - model.pluralName = "UserFollowers" + model.pluralName = "UserFollowers" - model.fields( - .id(), - .belongsTo(userFollowers.user, is: .optional, ofType: User.self, targetName: "userFollowersUserId"), - .belongsTo(userFollowers.followersUser, is: .optional, ofType: User.self, targetName: "userFollowersFollowersUserId") - ) + model.fields( + .id(), + .belongsTo(userFollowers.user, is: .optional, ofType: User.self, targetName: "userFollowersUserId"), + .belongsTo(userFollowers.followersUser, is: .optional, ofType: User.self, targetName: "userFollowersFollowersUserId") + ) } } diff --git a/AmplifyTestCommon/Models/UserFollowing+Schema.swift b/AmplifyTestCommon/Models/UserFollowing+Schema.swift index 8e84c88fba..1008e39c4b 100644 --- a/AmplifyTestCommon/Models/UserFollowing+Schema.swift +++ b/AmplifyTestCommon/Models/UserFollowing+Schema.swift @@ -10,25 +10,29 @@ import Amplify import Foundation extension UserFollowing { - // MARK: - CodingKeys - public enum CodingKeys: String, ModelKey { - case id - case user - case followingUser - } + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case user + case followingUser - public static let keys = CodingKeys.self - // MARK: - ModelSchema + public var modelName: String { + return "UserFollowing" + } + } + + public static let keys = CodingKeys.self + // MARK: - ModelSchema - public static let schema = defineSchema { model in - let userFollowing = UserFollowing.keys + public static let schema = defineSchema { model in + let userFollowing = UserFollowing.keys - model.pluralName = "UserFollowings" + model.pluralName = "UserFollowings" - model.fields( - .id(), - .belongsTo(userFollowing.user, is: .optional, ofType: User.self, targetName: "userFollowingUserId"), - .belongsTo(userFollowing.followingUser, is: .optional, ofType: User.self, targetName: "userFollowingFollowingUserId") - ) + model.fields( + .id(), + .belongsTo(userFollowing.user, is: .optional, ofType: User.self, targetName: "userFollowingUserId"), + .belongsTo(userFollowing.followingUser, is: .optional, ofType: User.self, targetName: "userFollowingFollowingUserId") + ) } } diff --git a/AmplifyTests/CategoryTests/DataStore/CodingKeysTests.swift b/AmplifyTests/CategoryTests/DataStore/CodingKeysTests.swift new file mode 100644 index 0000000000..ad0811c02b --- /dev/null +++ b/AmplifyTests/CategoryTests/DataStore/CodingKeysTests.swift @@ -0,0 +1,26 @@ +// +// Copyright 2018-2020 Amazon.com, +// Inc. or its affiliates. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import XCTest +import Amplify +@testable import AmplifyTestCommon + +class CodingKeysTests: XCTestCase { + + func testSchemaHasCorrectColumnName() throws { + ModelRegistry.register(modelType: Comment.self) + let commentQPO: QueryPredicateOperation = Comment.keys.id == "1234" + XCTAssertEqual(commentQPO.field, "id") + } + + func testSchemaWithBelongsToHasCorrectColumnName() throws { + ModelRegistry.register(modelType: Comment.self) + let commentQPO: QueryPredicateOperation = Comment.keys.post == "5678" + XCTAssertEqual(commentQPO.field, "commentPostId") + } + +}