mirror of
https://github.com/Dannecron/spring-boot-demo.git
synced 2025-12-25 16:22:35 +03:00
create city repository and service
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package com.example.demo
|
||||
|
||||
import com.example.demo.provider.CityRepository
|
||||
import com.example.demo.provider.MockedShopProvider
|
||||
import com.example.demo.provider.ProductRepository
|
||||
import com.example.demo.provider.ShopProvider
|
||||
import com.example.demo.services.CityService
|
||||
import com.example.demo.services.CityServiceImpl
|
||||
import com.example.demo.services.ProductService
|
||||
import com.example.demo.services.ProductServiceImpl
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
@@ -17,7 +20,8 @@ class AppConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun productService(@Autowired productRepository: ProductRepository): ProductService {
|
||||
return ProductServiceImpl(productRepository = productRepository)
|
||||
}
|
||||
fun productService(@Autowired productRepository: ProductRepository): ProductService = ProductServiceImpl(productRepository)
|
||||
|
||||
@Bean
|
||||
fun cityService(@Autowired cityRepository: CityRepository): CityService = CityServiceImpl(cityRepository)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package com.example.demo.models
|
||||
|
||||
import com.example.demo.models.serializables.OffsetDateTimeSerialization
|
||||
import com.example.demo.models.serializables.UuidSerialization
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.springframework.data.annotation.Id
|
||||
import org.springframework.data.relational.core.mapping.Column
|
||||
import org.springframework.data.relational.core.mapping.Table
|
||||
import java.time.OffsetDateTime
|
||||
import java.util.*
|
||||
|
||||
@Table("city")
|
||||
@Serializable
|
||||
data class City(
|
||||
@Id
|
||||
val id: Long?,
|
||||
@Serializable(with = UuidSerialization::class)
|
||||
val guid: UUID,
|
||||
val name: String,
|
||||
@Serializable(with = OffsetDateTimeSerialization::class)
|
||||
@@ -21,4 +26,6 @@ data class City(
|
||||
@Serializable(with = OffsetDateTimeSerialization::class)
|
||||
@Column(value = "deleted_at")
|
||||
val deletedAt: OffsetDateTime?,
|
||||
)
|
||||
) {
|
||||
fun isDeleted(): Boolean = deletedAt != null
|
||||
}
|
||||
17
src/main/kotlin/com/example/demo/provider/CityRepository.kt
Normal file
17
src/main/kotlin/com/example/demo/provider/CityRepository.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.example.demo.provider
|
||||
|
||||
import com.example.demo.models.City
|
||||
import org.springframework.data.jdbc.repository.query.Query
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import org.springframework.data.repository.query.Param
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.time.OffsetDateTime
|
||||
import java.util.*
|
||||
|
||||
@Repository
|
||||
interface CityRepository: CrudRepository<City, Long> {
|
||||
fun findByGuid(guid: UUID): City?
|
||||
|
||||
@Query(value = "UPDATE City SET deleted_at = :deletedAt WHERE guid = :guid RETURNING *")
|
||||
fun softDelete(@Param("guid") guid: UUID, @Param("deletedAt") deletedAt: OffsetDateTime): City?
|
||||
}
|
||||
17
src/main/kotlin/com/example/demo/services/CityService.kt
Normal file
17
src/main/kotlin/com/example/demo/services/CityService.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.example.demo.services
|
||||
|
||||
import com.example.demo.exceptions.NotFoundException
|
||||
import com.example.demo.exceptions.UnprocessableException
|
||||
import com.example.demo.models.City
|
||||
import org.springframework.stereotype.Service
|
||||
import java.util.*
|
||||
|
||||
@Service
|
||||
interface CityService {
|
||||
fun findByGuid(guid: UUID): City?
|
||||
|
||||
fun create(name: String): City?
|
||||
|
||||
@Throws(NotFoundException::class, UnprocessableException::class)
|
||||
fun delete(guid: UUID): City?
|
||||
}
|
||||
46
src/main/kotlin/com/example/demo/services/CityServiceImpl.kt
Normal file
46
src/main/kotlin/com/example/demo/services/CityServiceImpl.kt
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.example.demo.services
|
||||
|
||||
import com.example.demo.exceptions.NotFoundException
|
||||
import com.example.demo.exceptions.UnprocessableException
|
||||
import com.example.demo.models.City
|
||||
import com.example.demo.provider.CityRepository
|
||||
import java.time.OffsetDateTime
|
||||
import java.util.*
|
||||
|
||||
class CityServiceImpl(
|
||||
private val cityRepository: CityRepository
|
||||
): CityService {
|
||||
override fun findByGuid(guid: UUID): City? = cityRepository.findByGuid(guid)
|
||||
|
||||
override fun create(name: String): City? {
|
||||
val city = City(
|
||||
id = null,
|
||||
guid = UUID.randomUUID(),
|
||||
name = name,
|
||||
createdAt = OffsetDateTime.now(),
|
||||
updatedAt = null,
|
||||
deletedAt = null,
|
||||
)
|
||||
|
||||
return cityRepository.save(city)
|
||||
}
|
||||
|
||||
override fun delete(guid: UUID): City? {
|
||||
val city = findByGuid(guid) ?: throw NotFoundException()
|
||||
|
||||
if (city.isDeleted()) {
|
||||
throw UnprocessableException("city already deleted")
|
||||
}
|
||||
|
||||
val deletedCity = city.copy(
|
||||
id = city.id!!,
|
||||
guid = city.guid,
|
||||
name = city.name,
|
||||
createdAt = city.createdAt,
|
||||
updatedAt = city.updatedAt,
|
||||
deletedAt = OffsetDateTime.now(),
|
||||
)
|
||||
|
||||
return cityRepository.save(deletedCity)
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,9 @@ import com.example.demo.provider.ProductRepository
|
||||
import java.time.OffsetDateTime
|
||||
import java.util.*
|
||||
|
||||
class ProductServiceImpl(private val productRepository: ProductRepository): ProductService {
|
||||
class ProductServiceImpl(
|
||||
private val productRepository: ProductRepository,
|
||||
): ProductService {
|
||||
override fun findByGuid(guid: UUID): Product? = productRepository.findByGuid(guid)
|
||||
|
||||
override fun create(name: String, price: Long, description: String?): Product {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.example.demo.services
|
||||
|
||||
import com.example.demo.BaseFeatureTest
|
||||
import com.example.demo.models.City
|
||||
import com.example.demo.provider.CityRepository
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import kotlin.test.*
|
||||
|
||||
@ContextConfiguration(classes = [CityRepository::class, CityServiceImpl::class])
|
||||
class CityServiceImplTest: BaseFeatureTest() {
|
||||
@Autowired
|
||||
private lateinit var cityRepository: CityRepository
|
||||
@Autowired
|
||||
private lateinit var cityServiceImpl: CityServiceImpl
|
||||
|
||||
@Test
|
||||
fun createFindDelete_success() {
|
||||
val name = "Some city"
|
||||
var city: City? = null
|
||||
|
||||
try {
|
||||
city = cityServiceImpl.create(name = name)
|
||||
assertNotNull(city)
|
||||
assertNotNull(city.id)
|
||||
assertEquals(name, city.name)
|
||||
|
||||
val dbCity = cityServiceImpl.findByGuid(city.guid)
|
||||
assertNotNull(dbCity)
|
||||
assertEquals(city.id, dbCity.id)
|
||||
assertFalse(dbCity.isDeleted())
|
||||
|
||||
val deletedCity = cityServiceImpl.delete(city.guid)
|
||||
assertNotNull(deletedCity)
|
||||
assertEquals(city.id, deletedCity.id)
|
||||
assertNotNull(deletedCity.deletedAt)
|
||||
assertTrue(deletedCity.isDeleted())
|
||||
} finally {
|
||||
val id = city?.id
|
||||
if (id != null) {
|
||||
cityRepository.deleteById(id)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user