allow querying on relationship attributes (fixes #83)

This commit is contained in:
John Rommel Estropia
2016-07-22 00:29:48 +09:00
parent 3344e42d7c
commit f0cd288657

View File

@@ -715,9 +715,28 @@ internal extension CollectionType where Generator.Element == SelectTerm {
fetchRequest.includesPendingChanges = false fetchRequest.includesPendingChanges = false
fetchRequest.resultType = .DictionaryResultType fetchRequest.resultType = .DictionaryResultType
let entityDescription = fetchRequest.entity! func attributeDescriptionForKeyPath(keyPath: String, inEntity entity: NSEntityDescription) -> NSAttributeDescription? {
let propertiesByName = entityDescription.propertiesByName
let attributesByName = entityDescription.attributesByName let components = keyPath.componentsSeparatedByString(".")
switch components.count {
case 0:
return nil
case 1:
return entity.attributesByName[components[0]]
default:
guard let relationship = entity.relationshipsByName[components[0]] else {
return nil
}
return attributeDescriptionForKeyPath(
components.dropFirst().joinWithSeparator("."),
inEntity: relationship.entity
)
}
}
var propertiesToFetch = [AnyObject]() var propertiesToFetch = [AnyObject]()
for term in self { for term in self {
@@ -725,20 +744,22 @@ internal extension CollectionType where Generator.Element == SelectTerm {
switch term { switch term {
case ._Attribute(let keyPath): case ._Attribute(let keyPath):
if let propertyDescription = propertiesByName[keyPath] { let entityDescription = fetchRequest.entity!
if let attributeDescription = attributeDescriptionForKeyPath(keyPath, inEntity: entityDescription) {
propertiesToFetch.append(propertyDescription) propertiesToFetch.append(attributeDescription)
} }
else { else {
CoreStore.log( CoreStore.log(
.Warning, .Warning,
message: "The property \"\(keyPath)\" does not exist in entity \(cs_typeName(entityDescription.managedObjectClassName)) and will be ignored by \(cs_typeName(owner)) query clause." message: "The key path \"\(keyPath)\" could not be resolved in entity \(cs_typeName(entityDescription.managedObjectClassName)) as an attribute and will be ignored by \(cs_typeName(owner)) query clause."
) )
} }
case ._Aggregate(let function, let keyPath, let alias, let nativeType): case ._Aggregate(let function, let keyPath, let alias, let nativeType):
if let attributeDescription = attributesByName[keyPath] { let entityDescription = fetchRequest.entity!
if let attributeDescription = attributeDescriptionForKeyPath(keyPath, inEntity: entityDescription) {
let expressionDescription = NSExpressionDescription() let expressionDescription = NSExpressionDescription()
expressionDescription.name = alias expressionDescription.name = alias
@@ -754,14 +775,13 @@ internal extension CollectionType where Generator.Element == SelectTerm {
forFunction: function, forFunction: function,
arguments: [NSExpression(forKeyPath: keyPath)] arguments: [NSExpression(forKeyPath: keyPath)]
) )
propertiesToFetch.append(expressionDescription) propertiesToFetch.append(expressionDescription)
} }
else { else {
CoreStore.log( CoreStore.log(
.Warning, .Warning,
message: "The attribute \"\(keyPath)\" does not exist in entity \(cs_typeName(entityDescription.managedObjectClassName)) and will be ignored by \(cs_typeName(owner)) query clause." message: "The key path \"\(keyPath)\" could not be resolved in entity \(cs_typeName(entityDescription.managedObjectClassName)) as an attribute and will be ignored by \(cs_typeName(owner)) query clause."
) )
} }