mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-14 06:16:12 +01:00
WIP
This commit is contained in:
@@ -10,7 +10,7 @@ extension Modern.PokedexDemo {
|
||||
|
||||
// MARK: - Modern.PokedexDemo.Move
|
||||
|
||||
enum PokemonType: String, CaseIterable, FieldStorableType {
|
||||
enum PokemonType: String, CaseIterable, ImportableAttributeType, FieldStorableType {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
|
||||
@@ -808,6 +808,39 @@ extension QueryChainBuilder where O: CoreStoreObject {
|
||||
return self.queryChain(appending: clause(O.meta))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||
|
||||
- parameter keyPath: a key path to group the query results with
|
||||
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
|
||||
*/
|
||||
public func groupBy<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<T>>) -> QueryChainBuilder<O, R> {
|
||||
|
||||
return self.groupBy(GroupBy<O>(keyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||
|
||||
- parameter keyPath: a key path to group the query results with
|
||||
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
|
||||
*/
|
||||
public func groupBy<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>) -> QueryChainBuilder<O, R> {
|
||||
|
||||
return self.groupBy(GroupBy<O>(keyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||
|
||||
- parameter keyPath: a key path to group the query results with
|
||||
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
|
||||
*/
|
||||
public func groupBy<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Coded<T>>) -> QueryChainBuilder<O, R> {
|
||||
|
||||
return self.groupBy(GroupBy<O>(keyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||
|
||||
|
||||
@@ -124,6 +124,36 @@ extension GroupBy where O: NSManagedObject {
|
||||
|
||||
extension GroupBy where O: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
|
||||
- parameter keyPath: a key path to group results with
|
||||
*/
|
||||
public init<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<T>>) {
|
||||
|
||||
self.init([O.meta[keyPath: keyPath].keyPath])
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
|
||||
- parameter keyPath: a key path to group results with
|
||||
*/
|
||||
public init<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>) {
|
||||
|
||||
self.init([O.meta[keyPath: keyPath].keyPath])
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
|
||||
- parameter keyPath: a key path to group results with
|
||||
*/
|
||||
public init<T>(_ keyPath: KeyPath<O, FieldContainer<O>.Coded<T>>) {
|
||||
|
||||
self.init([O.meta[keyPath: keyPath].keyPath])
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
|
||||
|
||||
@@ -419,6 +419,94 @@ import Combine
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension ListPublisher: ObservableObject {}
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension ListPublisher: Publisher {
|
||||
|
||||
// MARK: Publisher
|
||||
|
||||
public typealias Output = ListSnapshot<O>
|
||||
public typealias Failure = Never
|
||||
|
||||
public func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Failure {
|
||||
|
||||
subscriber.receive(
|
||||
subscription: ListSnapshotSubscription(
|
||||
publisher: self,
|
||||
subscriber: subscriber
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ListSnapshotSubscriber
|
||||
|
||||
fileprivate final class ListSnapshotSubscriber: Subscriber {
|
||||
|
||||
// MARK: Subscriber
|
||||
|
||||
typealias Failure = Never
|
||||
|
||||
func receive(subscription: Subscription) {
|
||||
|
||||
subscription.request(.unlimited)
|
||||
}
|
||||
|
||||
func receive(_ input: Output) -> Subscribers.Demand {
|
||||
|
||||
return .unlimited
|
||||
}
|
||||
|
||||
func receive(completion: Subscribers.Completion<Failure>) {}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ListSnapshotSubscription
|
||||
|
||||
fileprivate final class ListSnapshotSubscription<S: Subscriber>: Subscription where S.Input == Output, S.Failure == Never {
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
init(publisher: ListPublisher<O>, subscriber: S) {
|
||||
|
||||
self.publisher = publisher
|
||||
self.subscriber = subscriber
|
||||
}
|
||||
|
||||
|
||||
// MARK: Subscription
|
||||
|
||||
func request(_ demand: Subscribers.Demand) {
|
||||
|
||||
guard demand > 0 else {
|
||||
|
||||
return
|
||||
}
|
||||
self.publisher.addObserver(self) { [weak self] (publisher) in
|
||||
|
||||
guard let self = self, let subscriber = self.subscriber else {
|
||||
|
||||
return
|
||||
}
|
||||
_ = subscriber.receive(publisher.snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Cancellable
|
||||
|
||||
func cancel() {
|
||||
self.publisher.removeObserver(self)
|
||||
self.subscriber = nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let publisher: ListPublisher<O>
|
||||
private var subscriber: S?
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - ListPublisher
|
||||
|
||||
@@ -79,7 +79,7 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
||||
/**
|
||||
Returns the value for the specified property from the object’s private internal storage.
|
||||
|
||||
Accessing this property does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily to implement custom accessor methods that need direct access to the object's private storage.
|
||||
This method is used primarily to implement custom accessor methods that need direct access to the object's private storage.
|
||||
*/
|
||||
public var primitiveValue: V? {
|
||||
|
||||
@@ -95,8 +95,6 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
||||
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
|
||||
Accessing this property triggers the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`).
|
||||
*/
|
||||
public var value: V {
|
||||
|
||||
@@ -147,6 +145,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
||||
}
|
||||
self.setPrimitiveValue = {
|
||||
|
||||
rawObject.willChangeValue(forKey: keyPathString)
|
||||
defer {
|
||||
|
||||
rawObject.didChangeValue(forKey: keyPathString)
|
||||
}
|
||||
rawObject.setPrimitiveValue(
|
||||
$0.cs_toFieldStoredNativeType(),
|
||||
forKey: keyPathString
|
||||
@@ -179,7 +182,7 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
self.setPrimitiveValue = {
|
||||
|
||||
|
||||
rawObject.setPrimitiveValue(
|
||||
$0,
|
||||
forKey: keyPathString
|
||||
@@ -216,7 +219,12 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
||||
}
|
||||
}
|
||||
self.setPrimitiveValue = {
|
||||
|
||||
rawObject.willChangeValue(forKey: keyPathString)
|
||||
defer {
|
||||
|
||||
rawObject.didChangeValue(forKey: keyPathString)
|
||||
}
|
||||
rawObject.setPrimitiveValue(
|
||||
$0,
|
||||
forKey: keyPathString
|
||||
|
||||
@@ -288,6 +288,101 @@ import Combine
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension ObjectPublisher: ObservableObject {}
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension ObjectPublisher: Publisher {
|
||||
|
||||
// MARK: Publisher
|
||||
|
||||
public typealias Output = ObjectSnapshot<O>
|
||||
public typealias Failure = Never
|
||||
|
||||
public func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Failure {
|
||||
|
||||
subscriber.receive(
|
||||
subscription: ObjectSnapshotSubscription(
|
||||
publisher: self,
|
||||
subscriber: subscriber
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ObjectSnapshotSubscriber
|
||||
|
||||
fileprivate final class ObjectSnapshotSubscriber: Subscriber {
|
||||
|
||||
// MARK: Subscriber
|
||||
|
||||
typealias Failure = Never
|
||||
|
||||
func receive(subscription: Subscription) {
|
||||
|
||||
subscription.request(.unlimited)
|
||||
}
|
||||
|
||||
func receive(_ input: Output) -> Subscribers.Demand {
|
||||
|
||||
return .unlimited
|
||||
}
|
||||
|
||||
func receive(completion: Subscribers.Completion<Failure>) {}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ObjectSnapshotSubscription
|
||||
|
||||
fileprivate final class ObjectSnapshotSubscription<S: Subscriber>: Subscription where S.Input == Output, S.Failure == Never {
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
init(publisher: ObjectPublisher<O>, subscriber: S) {
|
||||
|
||||
self.publisher = publisher
|
||||
self.subscriber = subscriber
|
||||
}
|
||||
|
||||
|
||||
// MARK: Subscription
|
||||
|
||||
func request(_ demand: Subscribers.Demand) {
|
||||
|
||||
guard demand > 0 else {
|
||||
|
||||
return
|
||||
}
|
||||
self.publisher.addObserver(self) { [weak self] (publisher) in
|
||||
|
||||
guard let self = self, let subscriber = self.subscriber else {
|
||||
|
||||
return
|
||||
}
|
||||
if let snapshot = publisher.snapshot {
|
||||
|
||||
_ = subscriber.receive(snapshot)
|
||||
}
|
||||
else {
|
||||
|
||||
subscriber.receive(completion: .finished)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Cancellable
|
||||
|
||||
func cancel() {
|
||||
self.publisher.removeObserver(self)
|
||||
self.subscriber = nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let publisher: ObjectPublisher<O>
|
||||
private var subscriber: S?
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - ObjectPublisher
|
||||
|
||||
Reference in New Issue
Block a user