Skip to content

Commit

Permalink
feat(store): Add parameter for store to update entity (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjechris committed Jun 30, 2023
1 parent 28739ad commit 0e13841
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
32 changes: 28 additions & 4 deletions Sources/CohesionKit/Identity/IdentityStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 26,22 @@ public class IdentityMap {
/// - Parameter entity: the element to store in the identity map
/// - Parameter named: an alias to reference the entity and retrieve it using it
/// - Parameter modifiedAt: if entity was already stored it will be used to determine if the update should be applied or discarded
/// - Parameter ifPresent: applies the closure before storing it if it's already been stored. In this case this is similar as
/// calling `update`
/// - Returns: an object to observe changes on the entity
public func store<T: Identifiable>(entity: T, named: AliasKey<T>? = nil, modifiedAt: Stamp = Date().stamp)
-> EntityObserver<T> {
public func store<T: Identifiable>(
entity: T,
named: AliasKey<T>? = nil,
modifiedAt: Stamp = Date().stamp,
ifPresent update: Update<T>? = nil
) -> EntityObserver<T> {
identityQueue.sync(flags: .barrier) {
var entity = entity

if storage[entity] != nil {
update?(&entity)
}

let node = nodeStore(entity: entity, modifiedAt: modifiedAt)

if let alias = named {
Expand All @@ -46,10 58,22 @@ public class IdentityMap {
/// - Parameter entity: the aggregate to store in the identity map
/// - Parameter named: an alias to reference the aggregate and retrieve it using it
/// - Parameter modifiedAt: if aggregate was already stored it will be used to determine if the update should be applied or discarded
/// - Parameter ifPresent: applies the closure before storing it if it's already been stored. In this case this is similar as
/// calling `update`
/// - Returns: an object to observe changes on the entity
public func store<T: Aggregate>(entity: T, named: AliasKey<T>? = nil, modifiedAt: Stamp = Date().stamp)
-> EntityObserver<T> {
public func store<T: Aggregate>(
entity: T,
named: AliasKey<T>? = nil,
modifiedAt: Stamp = Date().stamp,
ifPresent update: Update<T>? = nil
) -> EntityObserver<T> {
identityQueue.sync(flags: .barrier) {
var entity = entity

if storage[entity] != nil {
update?(&entity)
}

let node = nodeStore(entity: entity, modifiedAt: modifiedAt)

if let alias = named {
Expand Down
14 changes: 14 additions & 0 deletions Tests/CohesionKitTests/IdentityMapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 68,20 @@ class IdentityMapTests: XCTestCase {

wait(for: [expectation], timeout: 0.5)
}

func test_storeIdentifiable_entityIsAlreadyStore_updateIsCalled() {
let root = SingleNodeFixture(id: 1)
let identityMap = IdentityMap()
let expectation = XCTestExpectation()

_ = withExtendedLifetime(identityMap.store(entity: root)) {
_ = identityMap.store(entity: root, ifPresent: { _ in
expectation.fulfill()
})
}

wait(for: [expectation], timeout: 0)
}
}

// MARK: Find
Expand Down

0 comments on commit 0e13841

Please sign in to comment.