Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
490 changes: 312 additions & 178 deletions Sources/CoreDataRepository/CoreDataRepository+Aggregate.swift

Large diffs are not rendered by default.

94 changes: 24 additions & 70 deletions Sources/CoreDataRepository/Internal/AggregateSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,48 +48,25 @@ final class AggregateSubscription<Value: Numeric & Sendable>: Subscription<Value
attributeDesc: NSAttributeDescription,
groupBy: NSAttributeDescription? = nil,
continuation: AsyncStream<Result<Value, CoreDataError>>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
guard entityDesc == attributeDesc.entity else {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
guard let entityName = entityDesc.name ?? entityDesc.managedObjectClassName else {
fail(.propertyDoesNotMatchEntity(description: nil))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: nil)
}
guard let attributeEntityName = attributeDesc.entity.name ?? attributeDesc.entity.managedObjectClassName
else {
fail(.propertyDoesNotMatchEntity(description: entityName))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: entityName)
}
fail(
.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
throw CoreDataError.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
return
}
self.init(request: request, context: context, continuation: continuation)
}
Expand All @@ -104,48 +81,25 @@ final class AggregateSubscription<Value: Numeric & Sendable>: Subscription<Value
attributeDesc: NSAttributeDescription,
groupBy: NSAttributeDescription? = nil,
continuation: AsyncStream<Result<Value, CoreDataError>>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
guard entityDesc == attributeDesc.entity else {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
guard let entityName = entityDesc.name ?? entityDesc.managedObjectClassName else {
fail(.propertyDoesNotMatchEntity(description: nil))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: nil)
}
guard let attributeEntityName = attributeDesc.entity.name ?? attributeDesc.entity.managedObjectClassName
else {
fail(.propertyDoesNotMatchEntity(description: entityName))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: entityName)
}
fail(
.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
throw CoreDataError.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
return
}
self.init(
fetchRequest: request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,48 +52,25 @@ final class AggregateThrowingSubscription<Value: Numeric & Sendable>: ThrowingSu
attributeDesc: NSAttributeDescription,
groupBy: NSAttributeDescription? = nil,
continuation: AsyncThrowingStream<Value, any Error>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
guard entityDesc == attributeDesc.entity else {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
guard let entityName = entityDesc.name ?? entityDesc.managedObjectClassName else {
fail(.propertyDoesNotMatchEntity(description: nil))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: nil)
}
guard let attributeEntityName = attributeDesc.entity.name ?? attributeDesc.entity.managedObjectClassName
else {
fail(.propertyDoesNotMatchEntity(description: entityName))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: entityName)
}
fail(
.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
throw CoreDataError.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
return
}
self.init(request: request, context: context, continuation: continuation)
}
Expand All @@ -108,48 +85,25 @@ final class AggregateThrowingSubscription<Value: Numeric & Sendable>: ThrowingSu
attributeDesc: NSAttributeDescription,
groupBy: NSAttributeDescription? = nil,
continuation: AsyncThrowingStream<Value, any Error>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.request(
function: function,
predicate: predicate,
entityDesc: entityDesc,
attributeDesc: attributeDesc,
groupBy: groupBy
)
guard entityDesc == attributeDesc.entity else {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
guard let entityName = entityDesc.name ?? entityDesc.managedObjectClassName else {
fail(.propertyDoesNotMatchEntity(description: nil))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: nil)
}
guard let attributeEntityName = attributeDesc.entity.name ?? attributeDesc.entity.managedObjectClassName
else {
fail(.propertyDoesNotMatchEntity(description: entityName))
return
throw CoreDataError.propertyDoesNotMatchEntity(description: entityName)
}
fail(
.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
throw CoreDataError.propertyDoesNotMatchEntity(
description: "\(entityName) != \(attributeDesc.name).\(attributeEntityName)"
)
return
}
self.init(
fetchRequest: request,
Expand Down
8 changes: 8 additions & 0 deletions Sources/CoreDataRepository/Internal/BaseSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ class BaseSubscription<
fetchResultControllerRequest: NSFetchRequest<ControllerResult>,
context: NSManagedObjectContext
) {
if fetchRequest.sortDescriptors == nil {
// if `sortDescriptors` is `nil`, an exception is raised and causes a runtime crash
fetchRequest.sortDescriptors = []
}
if fetchResultControllerRequest.sortDescriptors == nil {
// if `sortDescriptors` is `nil`, an exception is raised and causes a runtime crash
fetchResultControllerRequest.sortDescriptors = []
}
request = fetchRequest
frc = NSFetchedResultsController(
fetchRequest: fetchResultControllerRequest,
Expand Down
41 changes: 10 additions & 31 deletions Sources/CoreDataRepository/Internal/CountSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,11 @@ final class CountSubscription<Value: Numeric & Sendable>: Subscription<Value, NS
predicate: NSPredicate,
entityDesc: NSEntityDescription,
continuation: AsyncStream<Result<Value, CoreDataError>>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
self.init(request: request, context: context, continuation: continuation)
}

Expand All @@ -62,20 +50,11 @@ final class CountSubscription<Value: Numeric & Sendable>: Subscription<Value, NS
changeTrackingRequest: NSFetchRequest<NSManagedObject>,
entityDesc: NSEntityDescription,
continuation: AsyncStream<Result<Value, CoreDataError>>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.countRequest(predicate: predicate, entityDesc: entityDesc)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
self.init(
fetchRequest: request,
fetchResultControllerRequest: changeTrackingRequest,
Expand Down
44 changes: 10 additions & 34 deletions Sources/CoreDataRepository/Internal/CountThrowingSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,11 @@ final class CountThrowingSubscription<Value: Numeric & Sendable>: ThrowingSubscr
predicate: NSPredicate,
entityDesc: NSEntityDescription,
continuation: AsyncThrowingStream<Value, any Error>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
self.init(request: request, context: context, continuation: continuation)
}

Expand All @@ -66,23 +54,11 @@ final class CountThrowingSubscription<Value: Numeric & Sendable>: ThrowingSubscr
changeTrackingRequest: NSFetchRequest<NSManagedObject>,
entityDesc: NSEntityDescription,
continuation: AsyncThrowingStream<Value, any Error>.Continuation
) {
let request: NSFetchRequest<NSDictionary>
do {
request = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
} catch {
self.init(
fetchRequest: NSFetchRequest(),
fetchResultControllerRequest: NSFetchRequest(),
context: context,
continuation: continuation
)
fail(error)
return
}
) throws(CoreDataError) {
let request: NSFetchRequest<NSDictionary> = try NSFetchRequest.countRequest(
predicate: predicate,
entityDesc: entityDesc
)
self.init(
fetchRequest: request,
fetchResultControllerRequest: changeTrackingRequest,
Expand Down
Loading
Loading