Skip to content

Conversation

@lawmicha
Copy link
Contributor

@lawmicha lawmicha commented Feb 6, 2023

Issue #

Description

When there is no metadata to create a ModelProvider, the lazy reference will be instantiated with nil identifiers with a DefaultModelProvider. When this happens, try await on the computed property should simply return nil on get() and throw on require().

General Checklist

  • Added new tests to cover change, if needed
  • Build succeeds with all target using Swift Package Manager
  • All unit tests pass
  • All integration tests pass
  • Security oriented best practices and standards are followed (e.g. using input sanitization, principle of least privilege, etc)
  • Documentation update for the change if required
  • PR title conforms to conventional commit style
  • New or updated tests include Given When Then inline code documentation and are named accordingly testThing_condition_expectation()
  • If breaking change, documentation/changelog update with migration instructions

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@lawmicha lawmicha requested review from a team as code owners February 6, 2023 22:42
switch loadedState {
case .notLoaded:
throw CoreError.clientValidation("DefaultModelProvider does not provide loading capabilities", "")
return nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main functional change. If the default model provider is called from a not loaded state, it should simply return nil. The caller (LazyReference) is responsible for returning nil on get() or throwing if require() is called.

Comment on lines +57 to +58
let nilParent = try await savedChild.parent
XCTAssertNil(nilParent)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was what triggered the implementation change in the PR, the child without a parent should be query-able and can be traversed to the parent, even if the parent is nil. Previously, this call was throwing due to the default model provider throwing. Since the parent is an optional association, LazyReference gets nil back from the default model provider, and returns nil on get().

.hasMany(compositePKParent.implicitChildren, is: .optional, ofType: ImplicitChild.self, associatedWith: ImplicitChild.keys.parent),
.hasMany(compositePKParent.strangeChildren, is: .optional, ofType: StrangeExplicitChild.self, associatedWith: StrangeExplicitChild.keys.parent),
.hasMany(compositePKParent.childrenSansBelongsTo, is: .optional, ofType: ChildSansBelongsTo.self, associatedWith: ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToCustomId),
.hasMany(compositePKParent.childrenSansBelongsTo, is: .optional, ofType: ChildSansBelongsTo.self, associatedFields: [ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToCustomId, ChildSansBelongsTo.keys.compositePKParentChildrenSansBelongsToContent]),
Copy link
Contributor Author

@lawmicha lawmicha Feb 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this use case is the uni-directional has-many changes. childrenSansBelongsTo doesn't have a belongs to reference to the parent, and the parent (this schema) has a has-many field to the childrenSansBelongsTo child. With the CPK feature, it should have associatedFields of the CPK fields of the parent on the child.

self.updatedAt = updatedAt
}
public mutating func setParent(parent: CompositePKParent? = nil) {
public mutating func setParent(_ parent: CompositePKParent? = nil) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what should be codegenerated (see https://github.com/aws-amplify/amplify-codegen/pull/504/files#r1098000791) and is updated here manually.

// query child and load the parent - CompositePKChild
let queriedCompositePKChild = try await query(for: savedCompositePKChild)
assertLazyReference(queriedCompositePKChild._parent,
state: .notLoaded(identifiers: [.init(name: "@@primaryKey", value: savedParent.identifier)]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the belongsTo in #2737, the identifiers will be an array of LazyReferenceIdentifier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, i'll rebase 2737 with data-dev-preview and re-run/fix the integration tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants