From 9217d2a3f5f1b5d67d34fb59098a60d0792da8ca Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 15:01:57 +0200 Subject: [PATCH 01/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity --- .../epam/brn/dto/response/ResourceResponse.kt | 1 - .../kotlin/com/epam/brn/model/Resource.kt | 10 ++---- .../com/epam/brn/repo/ResourceRepository.kt | 11 ------- .../com/epam/brn/service/ResourceService.kt | 7 ---- .../LopotkoRecordProcessor.kt | 11 +------ .../SeriesMatrixRecordProcessor.kt | 10 ------ .../SeriesPhrasesRecordProcessor.kt | 9 ------ .../seriesWords/SeriesWordsRecordProcessor.kt | 9 ------ .../SeriesWordsKorolevaRecordProcessor.kt | 9 ------ .../com/epam/brn/integration/repo/BaseTest.kt | 6 ++-- .../epam/brn/service/ResourceServiceTest.kt | 32 ------------------- 11 files changed, 6 insertions(+), 109 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/dto/response/ResourceResponse.kt b/src/main/kotlin/com/epam/brn/dto/response/ResourceResponse.kt index d261149d7..941c5de92 100644 --- a/src/main/kotlin/com/epam/brn/dto/response/ResourceResponse.kt +++ b/src/main/kotlin/com/epam/brn/dto/response/ResourceResponse.kt @@ -4,7 +4,6 @@ import com.epam.brn.enums.WordType data class ResourceResponse( var id: Long? = null, - var audioFileUrl: String? = "", val word: String? = "", val wordPronounce: String? = "", val wordType: WordType?, diff --git a/src/main/kotlin/com/epam/brn/model/Resource.kt b/src/main/kotlin/com/epam/brn/model/Resource.kt index 0ee81c1d6..a7dd82f72 100644 --- a/src/main/kotlin/com/epam/brn/model/Resource.kt +++ b/src/main/kotlin/com/epam/brn/model/Resource.kt @@ -15,10 +15,9 @@ import javax.persistence.UniqueConstraint @Entity @Table( - uniqueConstraints = [UniqueConstraint(columnNames = ["word", "audioFileUrl", "wordType"])], + uniqueConstraints = [UniqueConstraint(columnNames = ["word", "wordType"])], indexes = [ - Index(name = "word_audio_file_idx", columnList = "word, audioFileUrl, wordType"), - Index(name = "audio_file_idx", columnList = "audioFileUrl"), + Index(name = "word_audio_file_idx", columnList = "word, wordType") ], ) class Resource( @@ -26,8 +25,6 @@ class Resource( @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long? = null, @Column(nullable = false) - var audioFileUrl: String? = "", - @Column(nullable = false) var word: String = "", var wordType: String = "", var locale: String = "", @@ -39,7 +36,6 @@ class Resource( ) { fun toResponse() = ResourceResponse( id = id, - audioFileUrl = audioFileUrl, word = word.replace("+", ""), wordPronounce = word, pictureFileUrl = pictureFileUrl, @@ -54,7 +50,6 @@ class Resource( other as Resource if (id != other.id) return false - if (audioFileUrl != other.audioFileUrl) return false if (word != other.word) return false if (wordType != other.wordType) return false if (pictureFileUrl != other.pictureFileUrl) return false @@ -66,7 +61,6 @@ class Resource( override fun hashCode(): Int { var result = id?.hashCode() ?: 0 - result = 31 * result + (audioFileUrl?.hashCode() ?: 0) result = 31 * result + (word.hashCode()) result = 31 * result + wordType.hashCode() result = 31 * result + (pictureFileUrl?.hashCode() ?: 0) diff --git a/src/main/kotlin/com/epam/brn/repo/ResourceRepository.kt b/src/main/kotlin/com/epam/brn/repo/ResourceRepository.kt index 1c6af02d6..b39ea856a 100644 --- a/src/main/kotlin/com/epam/brn/repo/ResourceRepository.kt +++ b/src/main/kotlin/com/epam/brn/repo/ResourceRepository.kt @@ -18,17 +18,6 @@ interface ResourceRepository : CrudRepository { wordType: String, ): Optional - fun findFirstByWordAndAudioFileUrlLike( - word: String, - audioFileUrl: String, - ): Optional - - fun findFirstByWordAndWordTypeAndAudioFileUrlLike( - word: String, - wordType: String, - audioFileUrl: String, - ): Optional - fun findFirstByWordAndLocaleAndWordType( word: String, locale: String, diff --git a/src/main/kotlin/com/epam/brn/service/ResourceService.kt b/src/main/kotlin/com/epam/brn/service/ResourceService.kt index 8c8dcffd6..bd9f5a14c 100644 --- a/src/main/kotlin/com/epam/brn/service/ResourceService.kt +++ b/src/main/kotlin/com/epam/brn/service/ResourceService.kt @@ -20,13 +20,6 @@ class ResourceService( return if (resources.isNotEmpty()) resources.first() else null } - fun findFirstByWordAndAudioFileUrlLike( - word: String, - audioFileName: String, - ): Resource? = resourceRepository - .findFirstByWordAndAudioFileUrlLike(word, audioFileName) - .orElse(null) - fun save(resource: Resource): Resource = resourceRepository.save(resource) fun findAll(): List = resourceRepository diff --git a/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt index 3d3f20980..d0a2c8b91 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt @@ -70,21 +70,12 @@ class LopotkoRecordProcessor( val hashWord = DigestUtils.md5Hex(word) mapHashWord[word] = hashWord val wordType = WordType.AUDIOMETRY_WORD.toString() - val audioFileUrl = - wordsService.getSubFilePathForWord( - AudioFileMetaData( - word, - locale.locale, - wordsService.getDefaultManVoiceForLocale(locale.locale), - ), - ) val resource = resourceRepository - .findFirstByWordAndWordTypeAndAudioFileUrlLike(word, wordType, audioFileUrl) + .findFirstByWordAndWordType(word, wordType) .orElse( Resource( word = word, - audioFileUrl = audioFileUrl, locale = locale.locale, ), ) diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesMatrix/SeriesMatrixRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesMatrix/SeriesMatrixRecordProcessor.kt index 494bfeaa7..418d91573 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesMatrix/SeriesMatrixRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesMatrix/SeriesMatrixRecordProcessor.kt @@ -1,6 +1,5 @@ package com.epam.brn.upload.csv.seriesMatrix -import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.enums.BrnLocale import com.epam.brn.enums.WordType import com.epam.brn.exception.EntityNotFoundException @@ -79,19 +78,10 @@ class SeriesMatrixRecordProcessor( wordType: WordType, locale: BrnLocale, ): Resource { - val audioPath = - wordsService.getSubFilePathForWord( - AudioFileMetaData( - word, - locale.locale, - wordsService.getDefaultManVoiceForLocale(locale.locale), - ), - ) val resource = resourceRepository .findFirstByWordAndLocaleAndWordType(word, locale.locale, wordType.name) .orElse(Resource(word = word, locale = locale.locale)) - resource.audioFileUrl = audioPath resource.wordType = wordType.name return resource } diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt index c5d029f66..73292e929 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt @@ -84,14 +84,6 @@ class SeriesPhrasesRecordProcessor( phrase: String, locale: BrnLocale, ): Resource { - val audioPath = - wordsService.getSubFilePathForWord( - AudioFileMetaData( - phrase, - locale.locale, - wordsService.getDefaultManVoiceForLocale(locale.locale), - ), - ) val wordType = WordType.PHRASE.toString() val resource = resourceRepository @@ -102,7 +94,6 @@ class SeriesPhrasesRecordProcessor( locale = locale.locale, ), ) - resource.audioFileUrl = audioPath resource.wordType = wordType return resource } diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt index 5469530ce..6fb59289c 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt @@ -73,19 +73,10 @@ class SeriesWordsRecordProcessor( word: String, locale: BrnLocale, ): Resource { - val audioPath = - wordsService.getSubFilePathForWord( - AudioFileMetaData( - word, - locale.locale, - wordsService.getDefaultManVoiceForLocale(locale.locale), - ), - ) val resource = resourceRepository .findFirstByWordAndLocaleAndWordType(word, locale.locale, WordType.OBJECT.toString()) .orElse(Resource(word = word, locale = locale.locale)) - resource.audioFileUrl = audioPath resource.wordType = WordType.OBJECT.toString() return resource } diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt index 9daab76e0..53bd796de 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt @@ -63,14 +63,6 @@ class SeriesWordsKorolevaRecordProcessor( word: String, locale: BrnLocale, ): Resource { - val audioPath = - wordsService.getSubFilePathForWord( - AudioFileMetaData( - word, - locale.locale, - wordsService.getDefaultWomanVoiceForLocale(locale.locale), - ), - ) val resource = resourceRepository .findFirstByWordAndLocaleAndWordType(word, locale.locale, WordType.OBJECT.toString()) @@ -80,7 +72,6 @@ class SeriesWordsKorolevaRecordProcessor( locale = locale.locale, ), ) - resource.audioFileUrl = audioPath resource.wordType = WordType.OBJECT.toString() return resource } diff --git a/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt b/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt index 9bf1b0f1b..72e8a32e4 100644 --- a/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt +++ b/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt @@ -61,11 +61,11 @@ abstract class BaseTest { subGroup1.exercises.addAll(listOf(exercise1, exercise2)) val firstResource = - Resource(audioFileUrl = "audio_f", word = listOfWords[0], pictureFileUrl = "picture_f", soundsCount = 0) + Resource(word = listOfWords[0], pictureFileUrl = "picture_f", soundsCount = 0) val secondResource = - Resource(audioFileUrl = "audio_s", word = listOfWords[1], pictureFileUrl = "picture_s", soundsCount = 0) + Resource(word = listOfWords[1], pictureFileUrl = "picture_s", soundsCount = 0) val thirdResource = - Resource(audioFileUrl = "audio_t", word = listOfWords[2], pictureFileUrl = "picture_t", soundsCount = 0) + Resource(word = listOfWords[2], pictureFileUrl = "picture_t", soundsCount = 0) resourceRepository.saveAll(listOf(firstResource, secondResource, thirdResource)) diff --git a/src/test/kotlin/com/epam/brn/service/ResourceServiceTest.kt b/src/test/kotlin/com/epam/brn/service/ResourceServiceTest.kt index 6157607d6..d6b7d3023 100644 --- a/src/test/kotlin/com/epam/brn/service/ResourceServiceTest.kt +++ b/src/test/kotlin/com/epam/brn/service/ResourceServiceTest.kt @@ -14,7 +14,6 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith import org.springframework.data.repository.findByIdOrNull -import java.util.Optional @ExtendWith(MockKExtension::class) internal class ResourceServiceTest { @@ -56,37 +55,6 @@ internal class ResourceServiceTest { foundFirstResource shouldBe null } - @Test - fun `should return resource by word and audio file url`() { - // GIVEN - val word = "word" - val audioFileName = "audioFileName" - every { resourceRepositoryMock.findFirstByWordAndAudioFileUrlLike(word, audioFileName) } returns - Optional.of( - resourceMock, - ) - - // WHEN - val foundResource = resourceService.findFirstByWordAndAudioFileUrlLike(word, audioFileName) - - // THEN - foundResource shouldBe resourceMock - } - - @Test - fun `should return null if word and audio file url is not found`() { - // GIVEN - val word = "word" - val audioFileName = "audioFileName" - every { resourceRepositoryMock.findFirstByWordAndAudioFileUrlLike(word, audioFileName) } returns Optional.empty() - - // WHEN - val foundResource = resourceService.findFirstByWordAndAudioFileUrlLike(word, audioFileName) - - // THEN - foundResource shouldBe null - } - @Test fun `should save resource`() { // GIVEN From fb0e5309ae70878dbcc0278324dd9ee17289010a Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 15:14:38 +0200 Subject: [PATCH 02/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity --- .../brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt | 1 - .../upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt | 1 - .../brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt | 1 - .../seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt | 1 - src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt | 2 ++ 5 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt index d0a2c8b91..97ee02fa8 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessor.kt @@ -1,6 +1,5 @@ package com.epam.brn.upload.csv.audiometrySpeech -import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.enums.AudiometryType import com.epam.brn.enums.BrnLocale import com.epam.brn.enums.WordType diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt index 73292e929..6ed0f39ad 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt @@ -1,6 +1,5 @@ package com.epam.brn.upload.csv.seriesPhrases -import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.enums.BrnLocale import com.epam.brn.enums.WordType import com.epam.brn.exception.EntityNotFoundException diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt index 6fb59289c..50b3456f0 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessor.kt @@ -1,6 +1,5 @@ package com.epam.brn.upload.csv.seriesWords -import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.enums.BrnLocale import com.epam.brn.enums.WordType import com.epam.brn.exception.EntityNotFoundException diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt index 53bd796de..d2dc95a3f 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessor.kt @@ -1,6 +1,5 @@ package com.epam.brn.upload.csv.seriesWordsKoroleva -import com.epam.brn.dto.AudioFileMetaData import com.epam.brn.enums.BrnLocale import com.epam.brn.enums.WordType import com.epam.brn.exception.EntityNotFoundException diff --git a/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt b/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt index 72e8a32e4..535762c3e 100644 --- a/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt +++ b/src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt @@ -10,8 +10,10 @@ import com.epam.brn.repo.ExerciseGroupRepository import com.epam.brn.repo.ResourceRepository import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired +@TestInstance(TestInstance.Lifecycle.PER_CLASS) abstract class BaseTest { @Autowired lateinit var exerciseGroupRepository: ExerciseGroupRepository From 7c90506c56079d2e0436526d84d0ef9a2f08d952 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 16:06:09 +0200 Subject: [PATCH 03/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (migration) --- src/main/resources/db/migration/V220250711_2566.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/resources/db/migration/V220250711_2566.sql diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql new file mode 100644 index 000000000..4748109e2 --- /dev/null +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -0,0 +1,11 @@ +drop index if exists audio_file_idx; + +drop index if exists word_audio_file_idx; + +create index word_audio_file_idx on resource (word, wordType); + +alter table resource drop constraint resource_constrain; + +alter table resource add constraint resource_constrain unique (word, word_type); + +alter table resource drop column audio_file_url; \ No newline at end of file From c7dc26b44d3c9b2a78308fa6801ee339767b68dc Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 16:25:55 +0200 Subject: [PATCH 04/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (linter) --- src/main/kotlin/com/epam/brn/model/Resource.kt | 2 +- src/main/resources/db/migration/V220250711_2566.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/model/Resource.kt b/src/main/kotlin/com/epam/brn/model/Resource.kt index a7dd82f72..640275706 100644 --- a/src/main/kotlin/com/epam/brn/model/Resource.kt +++ b/src/main/kotlin/com/epam/brn/model/Resource.kt @@ -17,7 +17,7 @@ import javax.persistence.UniqueConstraint @Table( uniqueConstraints = [UniqueConstraint(columnNames = ["word", "wordType"])], indexes = [ - Index(name = "word_audio_file_idx", columnList = "word, wordType") + Index(name = "word_audio_file_idx", columnList = "word, wordType"), ], ) class Resource( diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 4748109e2..a9655d868 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -8,4 +8,4 @@ alter table resource drop constraint resource_constrain; alter table resource add constraint resource_constrain unique (word, word_type); -alter table resource drop column audio_file_url; \ No newline at end of file +alter table resource drop column audio_file_url; From 872e360d6310feae24691ce63efb863fd960de96 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 16:48:21 +0200 Subject: [PATCH 05/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (linter 1) --- .../LopotkoRecordProcessorTest.kt | 17 +---------------- .../SeriesWordsRecordProcessorTest.kt | 6 ------ .../SeriesWordsKorolevaRecordProcessorTest.kt | 6 ------ 3 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/test/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessorTest.kt b/src/test/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessorTest.kt index 486ddc75e..058c56623 100644 --- a/src/test/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessorTest.kt +++ b/src/test/kotlin/com/epam/brn/upload/csv/audiometrySpeech/LopotkoRecordProcessorTest.kt @@ -45,14 +45,6 @@ internal class LopotkoRecordProcessorTest { private val audiometry = Audiometry(name = "Audiometry", audiometryType = AudiometryType.SPEECH.name, locale = BrnLocale.RU.locale) - private val audiometryTask = - AudiometryTask( - level = 1, - audiometryGroup = "A", - frequencyZone = FrequencyZone.LOW.name, - minFrequency = 200, - maxFrequency = 400, - ) private val savedAudiometryTask = AudiometryTask( id = 1, @@ -93,8 +85,7 @@ internal class LopotkoRecordProcessorTest { ) } returns audiometry every { - resourceRepositoryMock.findFirstByWordAndWordTypeAndAudioFileUrlLike( - ofType(String::class), + resourceRepositoryMock.findFirstByWordAndWordType( ofType(String::class), ofType(String::class), ) @@ -166,42 +157,36 @@ internal class LopotkoRecordProcessorTest { private fun resource_бал(): Resource = Resource( word = "бал", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/518d3c4523afcd59e2feae1093870f5f.ogg", pictureFileUrl = "pictures/бал.jpg", ) private fun resource_бум(): Resource = Resource( word = "бум", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/8e3cba18a3a6a3aa51e160a3d1e1ebcc.ogg", pictureFileUrl = "pictures/бум.jpg", ) private fun resource_быль(): Resource = Resource( word = "быль", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/4df3cdbbe2abf27f91f673032c95141e.ogg", pictureFileUrl = "pictures/быль.jpg", ) private fun resource_вить(): Resource = Resource( word = "вить", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/77ebaea90791bb15d4f758191aae5930.ogg", pictureFileUrl = "pictures/вить.jpg", ) private fun resource_гад(): Resource = Resource( word = "гад", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/2e0b56e224fe469866e1aaa81caaafcc.ogg", pictureFileUrl = "pictures/гад.jpg", ) private fun resource_дуб(): Resource = Resource( word = "дуб", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/audio/filipp/494d676049e14da7fd3a9182955287ab.ogg", pictureFileUrl = "pictures/дуб.jpg", ) } diff --git a/src/test/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessorTest.kt b/src/test/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessorTest.kt index 4e5ec14de..520e849fe 100644 --- a/src/test/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessorTest.kt +++ b/src/test/kotlin/com/epam/brn/upload/csv/seriesWords/SeriesWordsRecordProcessorTest.kt @@ -287,36 +287,30 @@ internal class SeriesWordsRecordProcessorTest { private fun resource_бал(): Resource = Resource( word = "бал", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/бал.ogg", ) private fun resource_бум(): Resource = Resource( word = "бум", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/бум.ogg", ) private fun resource_быль(): Resource = Resource( word = "быль", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/быль.ogg", ) private fun resource_вить(): Resource = Resource( word = "вить", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/вить.ogg", ) private fun resource_гад(): Resource = Resource( word = "гад", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/гад.ogg", ) private fun resource_дуб(): Resource = Resource( word = "дуб", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/дуб.ogg", ) } diff --git a/src/test/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessorTest.kt b/src/test/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessorTest.kt index c262ce7db..510850108 100644 --- a/src/test/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessorTest.kt +++ b/src/test/kotlin/com/epam/brn/upload/csv/seriesWordsKoroleva/SeriesWordsKorolevaRecordProcessorTest.kt @@ -315,36 +315,30 @@ internal class SeriesWordsKorolevaRecordProcessorTest { private fun resource_бал(): Resource = Resource( word = "бал", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/бал.ogg", ) private fun resource_бум(): Resource = Resource( word = "бум", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/бум.ogg", ) private fun resource_быль(): Resource = Resource( word = "быль", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/быль.ogg", ) private fun resource_вить(): Resource = Resource( word = "вить", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/вить.ogg", ) private fun resource_гад(): Resource = Resource( word = "гад", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/гад.ogg", ) private fun resource_дуб(): Resource = Resource( word = "дуб", wordType = WordType.OBJECT.toString(), - audioFileUrl = "/test/дуб.ogg", ) } From 132a25c7c45205777b9d9649aad20e86b1b70deb Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 16:57:45 +0200 Subject: [PATCH 06/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (test) --- .../seriesPhrases/SeriesPhrasesRecordProcessorTest.kt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/test/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessorTest.kt b/src/test/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessorTest.kt index dc70761b2..980d9396d 100644 --- a/src/test/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessorTest.kt +++ b/src/test/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessorTest.kt @@ -1,7 +1,6 @@ package com.epam.brn.upload.csv.seriesPhrases import com.epam.brn.enums.BrnLocale -import com.epam.brn.enums.Voice import com.epam.brn.exception.EntityNotFoundException import com.epam.brn.model.Exercise import com.epam.brn.model.Resource @@ -9,7 +8,6 @@ import com.epam.brn.model.SubGroup import com.epam.brn.repo.ExerciseRepository import com.epam.brn.repo.ResourceRepository import com.epam.brn.repo.SubGroupRepository -import com.epam.brn.service.WordsService import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldHaveSize @@ -39,9 +37,6 @@ internal class SeriesPhrasesRecordProcessorTest { @MockK private lateinit var resourceRepository: ResourceRepository - @MockK - private lateinit var wordsService: WordsService - @Test fun `should create correct exercise`() { // GIVEN @@ -58,8 +53,6 @@ internal class SeriesPhrasesRecordProcessorTest { val exercise = mockk() every { exerciseRepository.findExerciseByNameAndLevel(any(), any()) } returns Optional.empty() every { subGroupRepository.findByCodeAndLocale(any(), any()) } returns subGroup - every { wordsService.getDefaultManVoiceForLocale(any()) } returns Voice.FILIPP.name - every { wordsService.getSubFilePathForWord(any()) } returns "" every { resourceRepository.findFirstByWordAndLocaleAndWordType(any(), any(), any()) } returns Optional.empty() every { resourceRepository.saveAll(any>()) } returns emptyList() every { exerciseRepository.save(any()) } returns exercise @@ -70,8 +63,6 @@ internal class SeriesPhrasesRecordProcessorTest { // THEN verify(exactly = 1) { exerciseRepository.findExerciseByNameAndLevel(any(), any()) } verify(exactly = 1) { subGroupRepository.findByCodeAndLocale(any(), any()) } - verify(exactly = 2) { wordsService.getDefaultManVoiceForLocale(any()) } - verify(exactly = 2) { wordsService.getSubFilePathForWord(any()) } verify(exactly = 2) { resourceRepository.findFirstByWordAndLocaleAndWordType(any(), any(), any()) } verify(exactly = 1) { resourceRepository.saveAll(any>()) } verify(exactly = 1) { exerciseRepository.save(any()) } From b6ea21e42b98187879f2cee5c948a5dc7cefb05a Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 17:08:36 +0200 Subject: [PATCH 07/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (test 1) --- .../csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt index 6ed0f39ad..b6579c133 100644 --- a/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt +++ b/src/main/kotlin/com/epam/brn/upload/csv/seriesPhrases/SeriesPhrasesRecordProcessor.kt @@ -10,7 +10,6 @@ import com.epam.brn.model.Task import com.epam.brn.repo.ExerciseRepository import com.epam.brn.repo.ResourceRepository import com.epam.brn.repo.SubGroupRepository -import com.epam.brn.service.WordsService import com.epam.brn.upload.csv.RecordProcessor import com.epam.brn.upload.toStringWithoutBraces import org.springframework.beans.factory.annotation.Value @@ -22,7 +21,6 @@ class SeriesPhrasesRecordProcessor( private val subGroupRepository: SubGroupRepository, private val resourceRepository: ResourceRepository, private val exerciseRepository: ExerciseRepository, - private val wordsService: WordsService, ) : RecordProcessor { @Value(value = "\${fonAudioPath}") private lateinit var fonAudioPath: String @@ -66,12 +64,12 @@ class SeriesPhrasesRecordProcessor( .map { it.toStringWithoutBraces() } .toMutableList() val lastWordOnFirstPhrase = words.find { w -> w.contains(".") } - var phraseFirst = + val phraseFirst = words .subList(0, words.indexOf(lastWordOnFirstPhrase) + 1) .joinToString(" ") .replace(".", "") - var phraseSecond = + val phraseSecond = words .subList(words.indexOf(lastWordOnFirstPhrase) + 1, words.size) .joinToString(" ") From 9c07cec11ae8f4ac99932c02fcf0d3f0250022a0 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 17:38:57 +0200 Subject: [PATCH 08/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (migration fix) --- src/main/resources/db/migration/V220250711_2566.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index a9655d868..67341e406 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -6,6 +6,6 @@ create index word_audio_file_idx on resource (word, wordType); alter table resource drop constraint resource_constrain; -alter table resource add constraint resource_constrain unique (word, word_type); +alter table resource add constraint resource_constrain unique (word, wordType); alter table resource drop column audio_file_url; From 072c5ef86cc35cc8e9988a1f42141a89f2358f30 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 17:58:38 +0200 Subject: [PATCH 09/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (migration fix 1) --- src/main/kotlin/com/epam/brn/model/Resource.kt | 2 +- src/main/resources/db/migration/V220250711_2566.sql | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/model/Resource.kt b/src/main/kotlin/com/epam/brn/model/Resource.kt index 640275706..dd18431d5 100644 --- a/src/main/kotlin/com/epam/brn/model/Resource.kt +++ b/src/main/kotlin/com/epam/brn/model/Resource.kt @@ -17,7 +17,7 @@ import javax.persistence.UniqueConstraint @Table( uniqueConstraints = [UniqueConstraint(columnNames = ["word", "wordType"])], indexes = [ - Index(name = "word_audio_file_idx", columnList = "word, wordType"), + Index(name = "word_wordtype_idx", columnList = "word, wordType"), ], ) class Resource( diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 67341e406..b39561ba1 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -2,10 +2,10 @@ drop index if exists audio_file_idx; drop index if exists word_audio_file_idx; -create index word_audio_file_idx on resource (word, wordType); +create index word_word_type_idx on resource (word, word_type); alter table resource drop constraint resource_constrain; -alter table resource add constraint resource_constrain unique (word, wordType); +alter table resource add constraint resource_constrain unique (word, word_type); alter table resource drop column audio_file_url; From e7a01b3360a112d6f663f70fe231b61f13bab4bc Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 18:00:44 +0200 Subject: [PATCH 10/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (migration fix 2) --- src/main/kotlin/com/epam/brn/model/Resource.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/model/Resource.kt b/src/main/kotlin/com/epam/brn/model/Resource.kt index dd18431d5..98df8ecef 100644 --- a/src/main/kotlin/com/epam/brn/model/Resource.kt +++ b/src/main/kotlin/com/epam/brn/model/Resource.kt @@ -15,9 +15,9 @@ import javax.persistence.UniqueConstraint @Entity @Table( - uniqueConstraints = [UniqueConstraint(columnNames = ["word", "wordType"])], + uniqueConstraints = [UniqueConstraint(columnNames = ["word", "word_type"])], indexes = [ - Index(name = "word_wordtype_idx", columnList = "word, wordType"), + Index(name = "word_word_type_idx", columnList = "word, word_type"), ], ) class Resource( From 51cb2de6f985e44df70a20f097456061468cd54f Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 18:15:10 +0200 Subject: [PATCH 11/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (entity fix 3) --- src/main/kotlin/com/epam/brn/model/Resource.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/epam/brn/model/Resource.kt b/src/main/kotlin/com/epam/brn/model/Resource.kt index 98df8ecef..9f5d0b14f 100644 --- a/src/main/kotlin/com/epam/brn/model/Resource.kt +++ b/src/main/kotlin/com/epam/brn/model/Resource.kt @@ -15,9 +15,9 @@ import javax.persistence.UniqueConstraint @Entity @Table( - uniqueConstraints = [UniqueConstraint(columnNames = ["word", "word_type"])], + uniqueConstraints = [UniqueConstraint(columnNames = ["word", "wordType"])], indexes = [ - Index(name = "word_word_type_idx", columnList = "word, word_type"), + Index(name = "word_word_type_idx", columnList = "word, wordType"), ], ) class Resource( From 0376999a1937e85b6087617f6de67a8390f7e70a Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 11 Jul 2025 18:16:12 +0200 Subject: [PATCH 12/18] Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity (migration 4) --- src/main/resources/db/migration/V220250711_2566.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index b39561ba1..b5ce3de4d 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -2,7 +2,7 @@ drop index if exists audio_file_idx; drop index if exists word_audio_file_idx; -create index word_word_type_idx on resource (word, word_type); +create index if not exists word_word_type_idx on resource (word, word_type); alter table resource drop constraint resource_constrain; From 13048ebb1e072d247534cc323ba189f084522397 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Fri, 18 Jul 2025 17:07:02 +0200 Subject: [PATCH 13/18] Migration fixed by removing duplicates before adding new constraint resource.resource_constrain --- src/main/resources/db/migration/V220250711_2566.sql | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index b5ce3de4d..9f7e8c673 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -6,6 +6,13 @@ create index if not exists word_word_type_idx on resource (word, word_type); alter table resource drop constraint resource_constrain; +DELETE FROM resource +WHERE id NOT IN ( + SELECT MIN(id) + FROM resource + GROUP BY word, word_type +); + alter table resource add constraint resource_constrain unique (word, word_type); alter table resource drop column audio_file_url; From a22fb3ace31ed5cb524d449a1890b9dcef0ff06d Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Mon, 21 Jul 2025 12:47:58 +0200 Subject: [PATCH 14/18] Migration fixed drop index if exists ukt37wptru4xcs8es5ae1huynph, resource drop if exists constraint resource_constrain --- src/main/resources/db/migration/V220250711_2566.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 9f7e8c673..9df1092c1 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -4,7 +4,9 @@ drop index if exists word_audio_file_idx; create index if not exists word_word_type_idx on resource (word, word_type); -alter table resource drop constraint resource_constrain; +drop index if exists ukt37wptru4xcs8es5ae1huynph; + +alter table resource drop if exists constraint resource_constrain; DELETE FROM resource WHERE id NOT IN ( From ed193bbc77aae66448a0b3f1c01dc002655e5921 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Mon, 21 Jul 2025 15:01:18 +0200 Subject: [PATCH 15/18] Migration fix --- src/main/resources/db/migration/V220250711_2566.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 9df1092c1..50b8c8d74 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -6,7 +6,7 @@ create index if not exists word_word_type_idx on resource (word, word_type); drop index if exists ukt37wptru4xcs8es5ae1huynph; -alter table resource drop if exists constraint resource_constrain; +alter table resource drop constraint if exists resource_constrain; DELETE FROM resource WHERE id NOT IN ( From b8015250e3f11db0b20aea965b589b63f2ebe1e7 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Mon, 21 Jul 2025 16:12:41 +0200 Subject: [PATCH 16/18] Migration fix 1 --- src/main/resources/db/migration/V220250711_2566.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 50b8c8d74..1010c32c4 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -4,10 +4,10 @@ drop index if exists word_audio_file_idx; create index if not exists word_word_type_idx on resource (word, word_type); -drop index if exists ukt37wptru4xcs8es5ae1huynph; - alter table resource drop constraint if exists resource_constrain; +drop index if exists ukt37wptru4xcs8es5ae1huynph; + DELETE FROM resource WHERE id NOT IN ( SELECT MIN(id) From c504bc56f695d762aa286d27d000e48d12b61958 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Tue, 22 Jul 2025 14:12:16 +0200 Subject: [PATCH 17/18] alter table resource drop constraint if exists ukt37wptru4xcs8es5ae1huynph was added --- src/main/resources/db/migration/V220250711_2566.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index 1010c32c4..d00b89a57 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -6,6 +6,8 @@ create index if not exists word_word_type_idx on resource (word, word_type); alter table resource drop constraint if exists resource_constrain; +alter table resource drop constraint if exists ukt37wptru4xcs8es5ae1huynph; + drop index if exists ukt37wptru4xcs8es5ae1huynph; DELETE FROM resource From fa87bda87a50b92f76d499ba9949706e59c67b72 Mon Sep 17 00:00:00 2001 From: yevgeniy_medvedev Date: Tue, 26 Aug 2025 17:49:08 +0200 Subject: [PATCH 18/18] 2693: Migration fixed, remap task resources before dropping column `audio_file_url` --- .../db/migration/V220250711_2566.sql | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/main/resources/db/migration/V220250711_2566.sql b/src/main/resources/db/migration/V220250711_2566.sql index d00b89a57..af623fa4b 100644 --- a/src/main/resources/db/migration/V220250711_2566.sql +++ b/src/main/resources/db/migration/V220250711_2566.sql @@ -10,13 +10,51 @@ alter table resource drop constraint if exists ukt37wptru4xcs8es5ae1huynph; drop index if exists ukt37wptru4xcs8es5ae1huynph; -DELETE FROM resource -WHERE id NOT IN ( - SELECT MIN(id) - FROM resource - GROUP BY word, word_type +CREATE TABLE temp_resource_mapping ( + old_id bigint, + new_id bigint ); +WITH duplicates AS ( + SELECT + word, + word_type, + array_agg(id) AS ids, + min(id) AS keep_id + FROM + resource + GROUP BY + word, word_type + HAVING + count(*) > 1 +) INSERT INTO temp_resource_mapping (old_id, new_id) + SELECT + r.id, + d.keep_id + FROM + resource r + JOIN + duplicates d ON r.word = d.word AND + (r.word_type = d.word_type OR (r.word_type IS NULL AND d.word_type IS NULL)) + WHERE + r.id != d.keep_id AND + r.id = ANY(d.ids); + +UPDATE task +SET resource_id = tm.new_id +FROM temp_resource_mapping tm +WHERE task.resource_id = tm.old_id; + +UPDATE task_resources +SET resource_id = tm.new_id +FROM temp_resource_mapping tm +WHERE task_resources.resource_id = tm.old_id; + +DELETE FROM resource +WHERE id IN (SELECT old_id FROM temp_resource_mapping); + +DROP TABLE temp_resource_mapping; + alter table resource add constraint resource_constrain unique (word, word_type); alter table resource drop column audio_file_url;