Merge branch 'master' into minIOS11

# Conflicts:
#	Sources/ListSnapshot.swift
This commit is contained in:
John Estropia
2020-11-11 13:44:58 +09:00
8 changed files with 190 additions and 23 deletions

View File

@@ -217,7 +217,8 @@ extension CoreStoreObject {
guard
let object = context.fetchExisting(id) as CoreStoreObject?,
let rawObject = object.rawObject
let rawObject = object.rawObject,
!rawObject.isDeleted
else {
return nil

View File

@@ -78,7 +78,7 @@ extension Internals {
var numberOfItems: Int {
return self.structure.allItemIDs.count
return self.structure.allItemsCount
}
var numberOfSections: Int {
@@ -106,6 +106,59 @@ extension Internals {
return self.itemIdentifiers(inSection: identifier).count
}
func itemIdentifier(atAllItemsIndex index: Int) -> NSManagedObjectID? {
guard index >= 0 else {
return nil
}
var remainingIndex = index
for section in self.structure.sections {
let elements = section.elements
let sectionCount = elements.count
if remainingIndex < sectionCount {
return elements[remainingIndex].differenceIdentifier
}
remainingIndex -= sectionCount
}
return nil
}
func itemIdentifiers(atAllItemsBounds bounds: Range<Int>) -> [NSManagedObjectID] {
var remainingIndex = bounds.lowerBound
var itemIdentifiers: [NSManagedObjectID] = []
for section in self.structure.sections {
let elements = section.elements
let sectionCount = elements.count
if remainingIndex < sectionCount {
itemIdentifiers.append(
contentsOf: elements[remainingIndex..<min(sectionCount, bounds.count)]
.map({ $0.differenceIdentifier })
)
}
else if !itemIdentifiers.isEmpty {
itemIdentifiers.append(
contentsOf: elements.prefix(bounds.count - itemIdentifiers.count)
.map({ $0.differenceIdentifier })
)
}
if itemIdentifiers.count >= bounds.count {
return itemIdentifiers
}
remainingIndex -= sectionCount
}
return itemIdentifiers
}
func itemIdentifiers(inSection identifier: String) -> [NSManagedObjectID] {
return self.structure.items(in: identifier)
@@ -332,6 +385,14 @@ extension Internals {
return self.sections.map({ $0.differenceIdentifier })
}
var allItemsCount: Int {
return self.sections.reduce(into: 0) { (result, section) in
result += section.elements.count
}
}
var allItemIDs: [NSManagedObjectID] {
return self.sections.lazy.flatMap({ $0.elements }).map({ $0.differenceIdentifier })

View File

@@ -267,6 +267,17 @@ public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
```
*/
public func == <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: O) -> Where<O> where O.ObjectType: NSManagedObject {
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object.cs_id())
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
@@ -278,6 +289,17 @@ public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
```
*/
public func != <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: O) -> Where<O> where O.ObjectType: NSManagedObject {
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object.cs_id())
}
/**
Creates a `Where` clause by checking if a sequence contains a value of a property
```
@@ -303,6 +325,17 @@ public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Op
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
```
*/
public func == <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: O?) -> Where<O> where O.ObjectType: NSManagedObject {
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object?.cs_toRaw())
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
@@ -314,6 +347,17 @@ public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Op
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
```
*/
public func != <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: O?) -> Where<O> where O.ObjectType: NSManagedObject {
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object?.cs_toRaw())
}
/**
Creates a `Where` clause by checking if a sequence contains a value of a property
```
@@ -690,6 +734,17 @@ public func == <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldCon
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
}
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
```
*/
public func == <O, D: FieldRelationshipToOneType, R: ObjectRepresentation>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: R?) -> Where<O> where D.DestinationObjectType == R.ObjectType {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object?.objectID())
}
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
@@ -723,6 +778,17 @@ public func != <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldCon
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
```
*/
public func != <O, D: FieldRelationshipToOneType, R: ObjectRepresentation>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: R?) -> Where<O> where D.DestinationObjectType == R.ObjectType {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object?.objectID())
}
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```

View File

@@ -71,7 +71,7 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
public subscript(index: Index) -> ObjectPublisher<O> {
let context = self.context!
let itemID = self.diffableSnapshot.itemIdentifiers[index]
let itemID = self.diffableSnapshot.itemIdentifier(atAllItemsIndex: index)!
return context.objectPublisher(objectID: itemID)
}
@@ -83,16 +83,13 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
*/
public subscript(safeIndex index: Index) -> ObjectPublisher<O>? {
guard let context = self.context else {
guard
let context = self.context,
let itemID = self.diffableSnapshot.itemIdentifier(atAllItemsIndex: index)
else {
return nil
}
let itemIDs = self.diffableSnapshot.itemIdentifiers
guard itemIDs.indices.contains(index) else {
return nil
}
let itemID = itemIDs[index]
return context.objectPublisher(objectID: itemID)
}
@@ -610,19 +607,61 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
return self.diffableSnapshot.numberOfItems
}
public func index(after i: Index) -> Index {
return i + 1
}
public func formIndex(after i: inout Index) {
return i += 1
}
public func index(before i: Index) -> Index {
return i - 1
}
public func formIndex(before i: inout Index) {
return i -= 1
}
// MARK: BidirectionalCollection
public func index(_ i: Int, offsetBy distance: Int) -> Int {
public func index(_ i: Index, offsetBy distance: Int) -> Index {
return i + distance
}
public func distance(from start: Int, to end: Int) -> Int {
public func index(_ i: Index, offsetBy distance: Int, limitedBy limit: Int) -> Index? {
let length = limit - i
if distance > 0
? length >= 0 && length < distance
: length <= 0 && length > distance {
return nil
}
return i + distance
}
public func distance(from start: Index, to end: Index) -> Int {
return end - start
}
public subscript(bounds: Range<Index>) -> ArraySlice<Element> {
guard let context = self.context else {
return .init()
}
let itemIDs = self.diffableSnapshot.itemIdentifiers(atAllItemsBounds: bounds)
return ArraySlice(itemIDs.map(context.objectPublisher(objectID:)))
}
// MARK: Sequence