Skip to content

Commit da1886c

Browse files
authored
- Added ability to delete only some items: Country.destroyAll(matching: withSpanishLanguage) (#6)
- Added ability to delete only some items: `Country.destroyAll(matching: withSpanishLanguage)` - `destroyAll(...)` no longer automatically saves the context - Tests for destroyAll and `countFor(...)` ## Details on `destroyAll(...)`: Removes all objects from Core Data. *Deletes them from the context.* ```swift Drawing.destroyAll(context: viewContext) ``` You can also specify a predicate to only delete some items: ```swift let withSpanishLanguage = Predicate("languages contains %@", es) Country.destroyAll(matching: withSpanishLanguage) ``` Remember to save the context after deleting objects.
1 parent c312150 commit da1886c

File tree

4 files changed

+134
-13
lines changed

4 files changed

+134
-13
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,21 @@ for drawing in results {
142142
### `destroyAll`
143143

144144
Removes all objects from Core Data.
145-
*Deletes them from the context, and saves the context.*
145+
*Deletes them from the context.*
146146

147147
```swift
148148
Drawing.destroyAll(context: viewContext)
149149
```
150150

151151

152+
You can also specify a predicate to only delete some items:
153+
```swift
154+
let withSpanishLanguage = Predicate("languages contains %@", es)
155+
Country.destroyAll(matching: withSpanishLanguage)
156+
```
157+
158+
Remember to save the context after deleting objects.
159+
152160

153161

154162
## Logging

Sources/CoreDataPlus/ManagedObjectDeletable.swift

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,32 @@ import CoreData
22
import Foundation
33

44
public protocol ManagedObjectDeletable {
5-
/// Removes all objects from the context, and saves the context.
5+
/// Removes all objects from the context
66
static func destroyAll(context: NSManagedObjectContext)
7+
/// Removes all objects from the foreground or background context
78
static func destroyAll(using: ContextMode)
9+
/// Removes all objects matching the predicate from the context
10+
static func destroyAll(matching: Predicate?, context: NSManagedObjectContext)
11+
/// Removes all objects matching the predicate from the foreground or background context
12+
static func destroyAll(matching: Predicate?, using: ContextMode)
813
}
914

1015
public extension ManagedObjectDeletable {
1116
static func destroyAll(context: NSManagedObjectContext) {
17+
destroyAll(matching: nil, context: context)
18+
}
19+
static func destroyAll(using: ContextMode = .foreground) {
20+
destroyAll(context: contextModeToNSManagedObjectContext(using))
21+
}
22+
static func destroyAll(matching: Predicate? = nil, using: ContextMode = .foreground) {
23+
destroyAll(matching: matching, context: contextModeToNSManagedObjectContext(using))
24+
}
25+
static func destroyAll(matching: Predicate? = nil, context: NSManagedObjectContext) {
1226
let request = (self as! NSManagedObject.Type).fetchRequest()
1327
request.entity = (self as! NSManagedObject.Type).entity()
14-
28+
29+
request.predicate = matching
30+
1531
var objects: [Any]
1632
do {
1733
objects = try context.fetch(request)
@@ -22,10 +38,7 @@ public extension ManagedObjectDeletable {
2238
context.delete(obj as! NSManagedObject)
2339
}
2440
}
25-
26-
static func destroyAll(using: ContextMode = .foreground) {
27-
let context = contextModeToNSManagedObjectContext(using)
28-
29-
destroyAll(context: context)
30-
}
3141
}
42+
43+
44+

Tests/CoreDataPlusTests/ContextSynchronizationTests.swift

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import CoreData
44

55
final class ContextSynchronizationTests: BaseTestCase {
66

7-
func test1() async throws {
7+
func syncTestBasic() async throws {
88

99
let b = backgroundContext
1010
let c = viewContext
@@ -30,7 +30,7 @@ final class ContextSynchronizationTests: BaseTestCase {
3030
XCTAssertEqual(try c.count(for: Book.fetchRequest()), 4)
3131
}
3232

33-
func test2() async throws {
33+
func syncTestExtended() async throws {
3434

3535
let b = backgroundContext
3636
let c = viewContext
@@ -61,7 +61,7 @@ final class ContextSynchronizationTests: BaseTestCase {
6161
XCTAssertEqual(try c.count(for: City.fetchRequest()), 2)
6262
}
6363

64-
func test3() async throws {
64+
func syncTestEnhanced() async throws {
6565

6666
let b = backgroundContext
6767
let c = viewContext
@@ -98,5 +98,60 @@ final class ContextSynchronizationTests: BaseTestCase {
9898
XCTAssertEqual(Language.findButDoNotCreate(column: "langCode", value: "jp", context: b)!.name, "Japanese 2")
9999
}
100100

101-
101+
func testManagedObjectDeletableAndCountForSynchronization() throws {
102+
let b = backgroundContext
103+
let c = viewContext
104+
105+
b.clearAll()
106+
c.clearAll()
107+
108+
CoreDataPlus.config = nil
109+
CoreDataPlus.setup(viewContext: c, backgroundContext: b, logHandler: { _ in
110+
111+
})
112+
113+
let usa = Country.findOrCreate(id: "1")
114+
let japan = Country.findOrCreate(id: "2")
115+
let mexico = Country.findOrCreate(id: "3")
116+
117+
let nyc = City.findOrCreate(id: "nyc-1", context: c)
118+
let tokyo = City.findOrCreate(id: "japan-1", context: c)
119+
120+
let enUS = Language.findOrCreate(column: "langCode", value: "en-us", context: c)
121+
let jp1 = Language.findOrCreate(column: "langCode", value: "jp", context: c)
122+
let es = Language.findOrCreate(column: "langCode", value: "es", context: c)
123+
124+
nyc.country = usa
125+
tokyo.country = japan
126+
127+
usa.addToLanguages(enUS)
128+
usa.addToLanguages(es)
129+
japan.addToLanguages(jp1)
130+
mexico.addToLanguages(es)
131+
132+
let withSpanishLanguage = Predicate("languages contains %@", es)
133+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 2)
134+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .background), 0)
135+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .foreground), 2)
136+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .custom(nsManagedObjectContext: c)), 2)
137+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .custom(nsManagedObjectContext: b)), 0)
138+
139+
try! c.save()
140+
141+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 2)
142+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .background), 2)
143+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .foreground), 2)
144+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .custom(nsManagedObjectContext: c)), 2)
145+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .custom(nsManagedObjectContext: b)), 2)
146+
147+
Country.destroyAll(matching: withSpanishLanguage)
148+
149+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 0)
150+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .background), 2)
151+
152+
try! c.save()
153+
154+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 0)
155+
XCTAssertEqual(Country.countFor(withSpanishLanguage, using: .background), 0)
156+
}
102157
}

Tests/CoreDataPlusTests/CoreTests.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,51 @@ final class CoreTests: BaseTestCase {
168168
XCTAssertEqual(sort3, sort4)
169169
}
170170

171+
172+
173+
174+
175+
func testManagedObjectDeletableAndCountFor() throws {
176+
let b = backgroundContext
177+
let c = viewContext
178+
179+
b.clearAll()
180+
c.clearAll()
181+
182+
CoreDataPlus.config = nil
183+
CoreDataPlus.setup(viewContext: c, backgroundContext: b, logHandler: { _ in
184+
185+
})
186+
187+
let usa = Country.findOrCreate(id: "1")
188+
let japan = Country.findOrCreate(id: "2")
189+
let mexico = Country.findOrCreate(id: "3")
190+
191+
let nyc = City.findOrCreate(id: "nyc-1", context: c)
192+
let tokyo = City.findOrCreate(id: "japan-1", context: c)
193+
194+
let enUS = Language.findOrCreate(column: "langCode", value: "en-us", context: c)
195+
let jp1 = Language.findOrCreate(column: "langCode", value: "jp", context: c)
196+
let es = Language.findOrCreate(column: "langCode", value: "es", context: c)
197+
198+
nyc.country = usa
199+
tokyo.country = japan
200+
201+
usa.addToLanguages(enUS)
202+
usa.addToLanguages(es)
203+
japan.addToLanguages(jp1)
204+
mexico.addToLanguages(es)
205+
206+
let withSpanishLanguage = Predicate("languages contains %@", es)
207+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 2)
208+
209+
Country.destroyAll(matching: withSpanishLanguage)
210+
211+
XCTAssertEqual(Country.countFor(withSpanishLanguage), 0)
212+
213+
}
214+
215+
171216
func testManagedObjectSearchable() throws {
172217
let b = backgroundContext
173218
let c = viewContext

0 commit comments

Comments
 (0)