letsourceAttributes=sourceEntity.cs_resolvedAttributeRenamingIdentities()letdestinationAttributes=destinationEntity.cs_resolvedAttributeRenamingIdentities()varattributeMappings:[NSPropertyMapping]=[]for(renamingIdentifier,destination)indestinationAttributes{// 👇 The part goes down!letsourceAttribute=sourceAttributes[renamingIdentifier]!.attributeletdestinationAttribute=destination.attributeletpropertyMapping=NSPropertyMapping()propertyMapping.name=destinationAttribute.namepropertyMapping.valueExpression=NSExpression(format:"FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceAttribute.name)\")")attributeMappings.append(propertyMapping)}returnattributeMappings
The call above to cs_resolvedAttributeRenamingIdentities() returns source attributes dictionary organized by renaming id when they are present, or by name otherwise, but really should return them organized by attribute name only. In other words, instead of resolving renaming source attributes for v2 as ["newFoo": …] it returns them as ["oldFoo": …], but "oldFoo" isn't available in source entity v2.
Originally created by @iby on GitHub (Jan 13, 2019).
I'm coming across a case with custom mapping provider that fails due to use of renaming identifiers in source attributes. A simplified scenario:
- Migration from v1 to v2 to v3.
- v1 has `oldFoo` attribute.
- v2 has `newFoo` attribute with `fooOld` renaming id for lightweight migration from v1.
- Migration from v2 to v3 fails because explicitly unwrapped source attribute doesn't exist…
I believe it narrows down to [CustomSchemaMappingProvider.swift#L425](https://github.com/JohnEstropia/CoreStore/blob/45e110755dd5ac3af201b9d8ff16f2af909f6539/Sources/CustomSchemaMappingProvider.swift#L425) line:
```swift
let sourceAttributes = sourceEntity.cs_resolvedAttributeRenamingIdentities()
let destinationAttributes = destinationEntity.cs_resolvedAttributeRenamingIdentities()
var attributeMappings: [NSPropertyMapping] = []
for (renamingIdentifier, destination) in destinationAttributes {
// 👇 The part goes down!
let sourceAttribute = sourceAttributes[renamingIdentifier]!.attribute
let destinationAttribute = destination.attribute
let propertyMapping = NSPropertyMapping()
propertyMapping.name = destinationAttribute.name
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceAttribute.name)\")")
attributeMappings.append(propertyMapping)
}
return attributeMappings
```
The call above to `cs_resolvedAttributeRenamingIdentities()` returns source attributes dictionary organized by renaming id when they are present, or by name otherwise, but really should return them organized by attribute name only. In other words, instead of resolving renaming source attributes for v2 as `["newFoo": …]` it returns them as `["oldFoo": …]`, but `"oldFoo"` isn't available in source entity v2.
This also applies to .transformEntity. The #301 PR addresses both cases. The current workaround is to use manual .transformEntity with the following transformation block:
@iby commented on GitHub (Jan 13, 2019):
This also applies to `.transformEntity`. The #301 PR addresses both cases. The current workaround is to use manual `.transformEntity` with the following transformation block:
```swift
.transformEntity(sourceEntity: "…", destinationEntity: "…", transformer: { (sourceObject: UnsafeSourceObject, createDestinationObject: () -> UnsafeDestinationObject) in
let destinationObject: UnsafeDestinationObject = createDestinationObject()
destinationObject.enumerateAttributes({ (destinationAttribute, sourceAttribute) in
destinationObject[destinationAttribute] = sourceObject[sourceAttribute ?? destinationAttribute]
})
})
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @iby on GitHub (Jan 13, 2019).
I'm coming across a case with custom mapping provider that fails due to use of renaming identifiers in source attributes. A simplified scenario:
oldFooattribute.newFooattribute withfooOldrenaming id for lightweight migration from v1.I believe it narrows down to CustomSchemaMappingProvider.swift#L425 line:
The call above to
cs_resolvedAttributeRenamingIdentities()returns source attributes dictionary organized by renaming id when they are present, or by name otherwise, but really should return them organized by attribute name only. In other words, instead of resolving renaming source attributes for v2 as["newFoo": …]it returns them as["oldFoo": …], but"oldFoo"isn't available in source entity v2.@iby commented on GitHub (Jan 13, 2019):
This also applies to
.transformEntity. The #301 PR addresses both cases. The current workaround is to use manual.transformEntitywith the following transformation block:@JohnEstropia commented on GitHub (Jan 15, 2019):
I'll comment on #301 if there's anything that comes up. Thanks again!