Skip to content

Commit

Permalink
Operation block supports throwing
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Piñera Buendía committed Apr 5, 2016
1 parent ef6dc3e commit 5dc069b
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 92 deletions.
54 changes: 37 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,31 @@ Although `Context`s offer `insertion` and `deletion` methods that you can use it
- **Save**: All the changes you apply to that context are in a memory state unless you call the `save()` method. That method will persist the changes to your store and propagate them across all the available contexts.

```swift
db.operation { (context, save) -> Void in
// Do your operations here
save()
do {
db.operation { (context, save) throws -> Void in
// Do your operations here
save()
}
}
catch {
// There was an error in the operation
}
```

##### New model
You can use the context `new()` method to initialize a model **without inserting it in the context**:

```swift
db.operation { (context, save) -> Void in
let newTask: Track = try! context.new()
newTask.name = "Make CoreData easier!"
try! context.insert(newTask)
save()
do {
db.operation { (context, save) throws -> Void in
let newTask: Track = try! context.new()
newTask.name = "Make CoreData easier!"
try! context.insert(newTask)
save()
}
}
catch {
// There was an error in the operation
}
```
> In order to insert the model into the context you use the insert() method.
Expand All @@ -152,24 +162,34 @@ db.operation { (context, save) -> Void in
You can use the `create()` for initializing and inserting in the context in the same operation:

```swift
db.operation { (context, save) -> Void in
let newTask: Track = try! context.create()
newTask.name = "Make CoreData easier!"
save()
do {
db.operation { (context, save) throws -> Void in
let newTask: Track = try! context.create()
newTask.name = "Make CoreData easier!"
save()
}
}
catch {
// There was an error in the operation
}
```

##### Delete a model
In a similar way you can use the `remove()` method from the context passing the objects you want to remove from the database:

```swift
db.operation { (context, save) -> Void in
let john: User? = try! context.request(User.self).filteredWith("id", equalTo: "1234").fetch().first
if let john = john {
try! context.remove([john])
save()
do {
db.operation { (context, save) -> Void in
let john: User? = try! context.request(User.self).filteredWith("id", equalTo: "1234").fetch().first
if let john = john {
try! context.remove([john])
save()
}
}
}
catch {
// There was an error in the operation
}
```

### Reactive Interface
Expand Down
46 changes: 26 additions & 20 deletions SugarRecord/Source/CoreData/Storages/CoreDataDefaultStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,36 @@ public class CoreDataDefaultStorage: Storage {
return _context
}

public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: NSManagedObjectContext = self.saveContext as! NSManagedObjectContext
var _error: ErrorType!
context.performBlockAndWait {
operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait({
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
})
}
})
do {
try operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait({
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
})
}
})
} catch {
_error = error
}
}
if let error = _error {
throw error
}
if let error = _error { throw error }
}

public func removeStore() throws {
Expand Down
39 changes: 22 additions & 17 deletions SugarRecord/Source/CoreData/Storages/CoreDataiCloudStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,33 @@ public class CoreDataiCloudStorage: Storage {
}
}

public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: NSManagedObjectContext = (self.saveContext as? NSManagedObjectContext)!
var _error: ErrorType!
context.performBlockAndWait {
operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait {
do {
try self.rootSavingContext.save()
}
catch {
_error = error
do {
try operation(context: context, save: { () -> Void in
do {
try context.save()
}
catch {
_error = error
}
if self.rootSavingContext.hasChanges {
self.rootSavingContext.performBlockAndWait {
do {
try self.rootSavingContext.save()
}
catch {
_error = error
}
}
}
}
})
})
}
catch {
_error = error
}
}
if let error = _error {
throw error
Expand Down
2 changes: 1 addition & 1 deletion SugarRecord/Source/Foundation/Entities/Storage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public protocol Storage: CustomStringConvertible, Requestable {
var saveContext: Context! { get }
var memoryContext: Context! { get }
func removeStore() throws
func operation(operation: (context: Context, save: () -> Void) -> Void) throws
func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws
func fetch<T: Entity>(request: Request<T>) throws -> [T]

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: {
do {
try saver()
}
catch {
observer.sendFailed(Error.Store(error))
}
saver()
})
observer.sendCompleted()
}
Expand All @@ -41,12 +36,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: {
do {
try saver()
}
catch {
observer.sendFailed(Error.Store(error))
}
saver()
})
observer.sendCompleted()
}
Expand Down
14 changes: 2 additions & 12 deletions SugarRecord/Source/Reactive/Rx/ReactiveStorage+Rx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ public extension Storage {
do {
try self.operation { (context, saver) -> Void in
op(context: context, save: { () -> Void in
do {
try saver()
}
catch {
observer.onError(error)
}
saver()
})
observer.onCompleted()
}
Expand All @@ -37,12 +32,7 @@ public extension Storage {
do {
try self.operation { (context, saver) in
op(context: context, save: { () -> Void in
do {
try saver()
}
catch {
observer.onError(error)
}
saver()
})
observer.onCompleted()
}
Expand Down
31 changes: 18 additions & 13 deletions SugarRecord/Source/Realm/Storages/RealmDefaultStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,28 @@ public class RealmDefaultStorage: Storage {
try NSFileManager.defaultManager().removeItemAtPath(Realm().path)
}

public func operation(operation: (context: Context, save: () -> Void) -> Void) throws {
public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
let context: Realm = self.saveContext as! Realm
context.beginWrite()
var save: Bool = false
var _error: ErrorType!
operation(context: context, save: { () -> Void in
defer {
save = true
}
do {
try context.commitWrite()
}
catch {
context.cancelWrite()
_error = error
}
})
do {
try operation(context: context, save: { () -> Void in
defer {
save = true
}
do {
try context.commitWrite()
}
catch {
context.cancelWrite()
_error = error
}
})
}
catch {
_error = error
}
if !save {
context.cancelWrite()
}
Expand Down

0 comments on commit 5dc069b

Please sign in to comment.