mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-04-01 15:13:06 +02:00
WIP
This commit is contained in:
@@ -10,7 +10,7 @@ extension Modern.PokedexDemo {
|
|||||||
|
|
||||||
// MARK: - Modern.PokedexDemo.Move
|
// MARK: - Modern.PokedexDemo.Move
|
||||||
|
|
||||||
enum PokemonType: String, CaseIterable, FieldStorableType {
|
enum PokemonType: String, CaseIterable, ImportableAttributeType, FieldStorableType {
|
||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
|
|||||||
@@ -808,6 +808,39 @@ extension QueryChainBuilder where O: CoreStoreObject {
|
|||||||
return self.queryChain(appending: clause(O.meta))
|
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`
|
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,36 @@ extension GroupBy where O: NSManagedObject {
|
|||||||
|
|
||||||
extension GroupBy where O: CoreStoreObject {
|
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
|
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, *)
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||||
extension ListPublisher: ObservableObject {}
|
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
|
#endif
|
||||||
|
|
||||||
// MARK: - ListPublisher
|
// 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.
|
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? {
|
public var primitiveValue: V? {
|
||||||
|
|
||||||
@@ -95,8 +95,6 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the value for the property identified by a given key.
|
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 {
|
public var value: V {
|
||||||
|
|
||||||
@@ -147,6 +145,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
}
|
}
|
||||||
self.setPrimitiveValue = {
|
self.setPrimitiveValue = {
|
||||||
|
|
||||||
|
rawObject.willChangeValue(forKey: keyPathString)
|
||||||
|
defer {
|
||||||
|
|
||||||
|
rawObject.didChangeValue(forKey: keyPathString)
|
||||||
|
}
|
||||||
rawObject.setPrimitiveValue(
|
rawObject.setPrimitiveValue(
|
||||||
$0.cs_toFieldStoredNativeType(),
|
$0.cs_toFieldStoredNativeType(),
|
||||||
forKey: keyPathString
|
forKey: keyPathString
|
||||||
@@ -217,6 +220,11 @@ public struct ObjectProxy<O: CoreStoreObject> {
|
|||||||
}
|
}
|
||||||
self.setPrimitiveValue = {
|
self.setPrimitiveValue = {
|
||||||
|
|
||||||
|
rawObject.willChangeValue(forKey: keyPathString)
|
||||||
|
defer {
|
||||||
|
|
||||||
|
rawObject.didChangeValue(forKey: keyPathString)
|
||||||
|
}
|
||||||
rawObject.setPrimitiveValue(
|
rawObject.setPrimitiveValue(
|
||||||
$0,
|
$0,
|
||||||
forKey: keyPathString
|
forKey: keyPathString
|
||||||
|
|||||||
@@ -288,6 +288,101 @@ import Combine
|
|||||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||||
extension ObjectPublisher: ObservableObject {}
|
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
|
#endif
|
||||||
|
|
||||||
// MARK: - ObjectPublisher
|
// MARK: - ObjectPublisher
|
||||||
|
|||||||
Reference in New Issue
Block a user