mirror of
https://github.com/Dannecron/spring-boot-demo.git
synced 2025-12-26 00:32:34 +03:00
create city repository and service
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
package com.example.demo
|
package com.example.demo
|
||||||
|
|
||||||
|
import com.example.demo.provider.CityRepository
|
||||||
import com.example.demo.provider.MockedShopProvider
|
import com.example.demo.provider.MockedShopProvider
|
||||||
import com.example.demo.provider.ProductRepository
|
import com.example.demo.provider.ProductRepository
|
||||||
import com.example.demo.provider.ShopProvider
|
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.ProductService
|
||||||
import com.example.demo.services.ProductServiceImpl
|
import com.example.demo.services.ProductServiceImpl
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
@@ -17,7 +20,8 @@ class AppConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun productService(@Autowired productRepository: ProductRepository): ProductService {
|
fun productService(@Autowired productRepository: ProductRepository): ProductService = ProductServiceImpl(productRepository)
|
||||||
return ProductServiceImpl(productRepository = productRepository)
|
|
||||||
}
|
@Bean
|
||||||
|
fun cityService(@Autowired cityRepository: CityRepository): CityService = CityServiceImpl(cityRepository)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package com.example.demo.models
|
package com.example.demo.models
|
||||||
|
|
||||||
import com.example.demo.models.serializables.OffsetDateTimeSerialization
|
import com.example.demo.models.serializables.OffsetDateTimeSerialization
|
||||||
|
import com.example.demo.models.serializables.UuidSerialization
|
||||||
import kotlinx.serialization.Serializable
|
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.Column
|
||||||
import org.springframework.data.relational.core.mapping.Table
|
import org.springframework.data.relational.core.mapping.Table
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@Table("city")
|
@Table("city")
|
||||||
|
@Serializable
|
||||||
data class City(
|
data class City(
|
||||||
|
@Id
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
@Serializable(with = UuidSerialization::class)
|
||||||
val guid: UUID,
|
val guid: UUID,
|
||||||
val name: String,
|
val name: String,
|
||||||
@Serializable(with = OffsetDateTimeSerialization::class)
|
@Serializable(with = OffsetDateTimeSerialization::class)
|
||||||
@@ -21,4 +26,6 @@ data class City(
|
|||||||
@Serializable(with = OffsetDateTimeSerialization::class)
|
@Serializable(with = OffsetDateTimeSerialization::class)
|
||||||
@Column(value = "deleted_at")
|
@Column(value = "deleted_at")
|
||||||
val deletedAt: OffsetDateTime?,
|
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.time.OffsetDateTime
|
||||||
import java.util.*
|
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 findByGuid(guid: UUID): Product? = productRepository.findByGuid(guid)
|
||||||
|
|
||||||
override fun create(name: String, price: Long, description: String?): Product {
|
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