Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import org.springframework.data.domain.SliceImpl
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Component
import java.math.BigInteger
import java.text.SimpleDateFormat
import java.util.HashMap
import javax.persistence.EntityManager
import org.springframework.transaction.annotation.Transactional
import kotlin.system.measureTimeMillis

@Component
Expand All @@ -44,9 +46,106 @@ class PostgresOfferRepositoryImpl(

return result
}

@Transactional
override fun saveAll(offers: List<Offer>): List<Offer> {
val result = repository.saveAll(offers).toList()
var result: List<Offer> = listOf()
val values = offers.map {
val isoPattern = "yyyy-MM-dd'T'HH:mm:ss'Z'"
val updatedAt = SimpleDateFormat(isoPattern).format(it.updatedAt)
val createdAt = SimpleDateFormat(isoPattern).format(it.createdAt)
val id = if (it.id == 0L) "nextval('offer_id_seq')" else it.id.toString()

"($id, " +
"'${it.title.replace("'", "''")}'," +
" '${it.description.replace("'", "''")}'," +
" '${it.owner.replace("'", "''")}', " +
"'${it.imageUrl}', '${it.worth}', '$createdAt', '$updatedAt')"
}
if (values.isNotEmpty()) {
val insertOffers = "INSERT INTO offer " +
"(id, title, description, owner, image_url, worth, created_at, updated_at) VALUES \n"
val insertOffersQuery = insertOffers + values.joinToString(",\n") +
"\n ON CONFLICT (id) DO UPDATE SET\n" +
" title = EXCLUDED.title,\n" +
" description = EXCLUDED.description,\n" +
" owner = EXCLUDED.owner,\n" +
" image_url = EXCLUDED.image_url,\n" +
" worth = EXCLUDED.worth,\n" +
" updated_at = EXCLUDED.updated_at\n" +
"RETURNING id;"

@Suppress("UNCHECKED_CAST")
val insertedOfferIds: List<Long> = entityManager
.createNativeQuery(insertOffersQuery)
.resultList as List<Long>

// cleanup tags for the all offers in the request
val offerInByIds = insertedOfferIds.joinToString(", ")
val cleanUpTagsQuery = "DELETE FROM offer_tags\n" +
"WHERE offer_tags.offer_id IN ($offerInByIds);"
entityManager.createNativeQuery(cleanUpTagsQuery).executeUpdate()

val insertTags = "INSERT INTO offer_tags (offer_id, tags, tags_key) VALUES \n"
val insertedOfferTagsValues = offers.mapIndexed { index, offer ->
offer.tags.map { "( ${insertedOfferIds[index]}, " +
"'${it.value.replace("'", "''")}', " +
"'${it.key.replace("'", "''")}' )" }
}.flatten().joinToString(",\n")
if (insertedOfferTagsValues.isNotEmpty()) {
val ifConflictPartTagsQuery = "\nON CONFLICT ON CONSTRAINT offer_tags_pkey DO UPDATE SET\n" +
" tags_key = EXCLUDED.tags_key,\n" +
" tags = EXCLUDED.tags"
val insertOfferTagsQuery = insertTags + insertedOfferTagsValues + ifConflictPartTagsQuery
entityManager.createNativeQuery(insertOfferTagsQuery).executeUpdate()
}

// cleanup compare for the all offers in the request
val cleanUpCompareQuery = "DELETE FROM offer_compare\n" +
"WHERE offer_compare.offer_id IN ($offerInByIds);"
entityManager.createNativeQuery(cleanUpCompareQuery).executeUpdate()

val insertCompare = "INSERT INTO offer_compare (offer_id, compare, compare_key) VALUES \n"
val insertedOfferCompareValues = offers.mapIndexed { index, offer ->
offer.compare.map { "( ${insertedOfferIds[index]}, " +
"'${it.value.replace("'", "''")}', " +
"'${it.key.replace("'", "''")}' )" }
}.flatten().joinToString(",\n")
if (insertedOfferCompareValues.isNotEmpty()) {
val ifConflictOfferCompare = "\n ON CONFLICT ON CONSTRAINT offer_compare_pkey " +
"DO UPDATE SET\n" +
" compare = EXCLUDED.compare,\n" +
" compare_key = EXCLUDED.compare_key"
val offerCompareQuery = insertCompare + insertedOfferCompareValues + ifConflictOfferCompare
entityManager.createNativeQuery(offerCompareQuery).executeUpdate()
}

// cleanup rules for the all offers in the request
val cleanUpRulesQuery = "DELETE FROM offer_rules\n" +
"WHERE offer_rules.offer_id IN ($offerInByIds);"
entityManager.createNativeQuery(cleanUpRulesQuery).executeUpdate()

val insertRules = "INSERT INTO offer_rules (offer_id, rules, rules_key) VALUES \n"
val insertedOfferRulesValues = offers.mapIndexed { index, offer ->
offer.rules.map { "( ${insertedOfferIds[index]}, ${it.value.ordinal}, " +
"'${it.key.replace("'", "''")}' )" }
}.flatten().joinToString(",\n")
if (insertedOfferRulesValues.isNotEmpty()) {
val ifConflictOfferRules = "\n ON CONFLICT ON CONSTRAINT offer_rules_pkey " +
"DO UPDATE SET\n" +
" rules = EXCLUDED.rules,\n" +
" rules_key = EXCLUDED.rules_key"
val insertOfferRulesQuery = insertRules + insertedOfferRulesValues + ifConflictOfferRules
entityManager.createNativeQuery(insertOfferRulesQuery).executeUpdate()
}

// for proper return data purpose only
val ids = insertedOfferIds.joinToString(", ")
val query = "SELECT * FROM offer WHERE offer.id IN ($ids)"
@Suppress("UNCHECKED_CAST")
val wrongSortedResult = entityManager.createNativeQuery(query, Offer::class.java).resultList as List<Offer>
val wrongSortedResultAsMap = wrongSortedResult.map { it.id to it }.toMap()
result = insertedOfferIds.map { wrongSortedResultAsMap[it] ?: error("was not find bt ids") }
}
return syncElementCollections(result)
}

Expand All @@ -68,7 +167,7 @@ class PostgresOfferRepositoryImpl(
override fun deleteOffers(owner: String): Int {
val deletedOffers = repository.deleteByOwner(owner)
deletedOffers.forEach {
wsService.sendEvent(OfferEvent.OnDelete, it.id)
// wsService.sendEvent(OfferEvent.OnDelete, it.id)
}

return deletedOffers.size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ import com.bitclave.node.repository.priceRule.OfferPriceRulesCrudRepository
import com.bitclave.node.services.errors.DataNotSavedException
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional

@Component
@Qualifier("postgres")
class PostgresOfferPriceRepositoryImpl(
val repository: OfferPriceCrudRepository,
val rulesRepository: OfferPriceRulesCrudRepository
) : OfferPriceRepository {

@Transactional
override fun saveAllPrices(prices: List<OfferPrice>): List<OfferPrice> {

val savedPrices = repository.saveAll(prices)

val rules = savedPrices.mapIndexed { index, offerPrice ->
Expand Down
7 changes: 4 additions & 3 deletions src/main/kotlin/com/bitclave/node/services/v1/OfferService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class OfferService(
val saveAllTiming = measureTimeMillis {
result = offerRepository.changeStrategy(strategy).saveAll(readyForSaveOffers)
}
// logger.debug(" - save all timing $saveAllTiming")
// Logger.debug(" - save all timing $saveAllTiming")

val prices = result.mapIndexed { index, offer ->
readyForSaveOffers[index].offerPrices.map { offerPrice ->
Expand All @@ -152,17 +152,18 @@ class OfferService(
}.flatten()

val saveAllPricesTiming = measureTimeMillis {
val ids = result.map { it.id }
offerPriceRepository.changeStrategy(strategy).saveAllPrices(prices)
}
// logger.debug(" - save all prices timing $saveAllPricesTiming")
// Logger.debug(" - save all prices timing $saveAllPricesTiming")

val offersIdsForCleanupOfferSearches = offers.filter { it.id != 0L }.map { it.id }
val deleteOfferSearchTiming = measureTimeMillis {
if (offersIdsForCleanupOfferSearches.isNotEmpty()) {
offerSearchService.deleteByOfferIds(offersIdsForCleanupOfferSearches, strategy)
}
}
// logger.debug(" - delete all offer searches by offerId timing $deleteOfferSearchTiming")
// Logger.debug(" - delete all offer searches by offerId timing $deleteOfferSearchTiming")

result.map { it.id }
})
Expand Down