Split up CustomerService.upsert in example app

This commit is contained in:
Michael Bull 2018-01-11 19:27:27 +00:00
parent d2723009df
commit e8581976c3
1 changed files with 23 additions and 25 deletions

View File

@ -25,41 +25,39 @@ object CustomerService {
} }
fun getById(id: CustomerId): Result<Customer, DomainMessage> { fun getById(id: CustomerId): Result<Customer, DomainMessage> {
return getAll().andThen { it.findCustomer(id) } return getAll().andThen { findCustomer(it, id) }
} }
fun upsert(customer: Customer): Result<DomainMessage?, DomainMessage> { fun upsert(customer: Customer): Result<DomainMessage?, DomainMessage> {
val entity = CustomerEntity.from(customer) val entity = CustomerEntity.from(customer)
return getById(customer.id).mapBoth( return getById(customer.id).mapBoth(
success = { existing -> { existing -> updateCustomer(entity, existing, customer) },
Result.of { repository.update(entity) } { createCustomer(entity) }
.mapError(this::exceptionToDomainMessage)
.map {
if (customer.email != existing.email) {
DomainMessage.EmailAddressChanged(existing.email.address, customer.email.address)
} else {
null
}
}
},
failure = {
Result.of { repository.insert(entity) }
.mapError(this::exceptionToDomainMessage)
.map { DomainMessage.CustomerCreated }
}
) )
} }
private fun Collection<Customer>.findCustomer(id: CustomerId): Result<Customer, DomainMessage.CustomerNotFound> { private fun updateCustomer(entity: CustomerEntity, old: Customer, new: Customer) =
val customer = find { it.id == id } Result.of { repository.update(entity) }
.map { differenceBetween(old, new) }
.mapError(this::exceptionToDomainMessage)
private fun createCustomer(entity: CustomerEntity) =
Result.of { repository.insert(entity) }
.mapError(this::exceptionToDomainMessage)
.map { DomainMessage.CustomerCreated }
private fun findCustomer(customers: Collection<Customer>, id: CustomerId): Result<Customer, DomainMessage.CustomerNotFound> {
val customer = customers.find { it.id == id }
return if (customer != null) Ok(customer) else Err(DomainMessage.CustomerNotFound) return if (customer != null) Ok(customer) else Err(DomainMessage.CustomerNotFound)
} }
private fun exceptionToDomainMessage(it: Throwable): DomainMessage { private fun differenceBetween(old: Customer, new: Customer) = when {
return when (it) { new.email != old.email -> DomainMessage.EmailAddressChanged(old.email.address, new.email.address)
is SQLTimeoutException -> DomainMessage.DatabaseTimeout else -> null
else -> DomainMessage.DatabaseError(it.message) }
}
private fun exceptionToDomainMessage(t: Throwable) = when (t) {
is SQLTimeoutException -> DomainMessage.DatabaseTimeout
else -> DomainMessage.DatabaseError(t.message)
} }
} }