Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9217d2a
Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity
Jul 11, 2025
fb0e530
Issue 2693: [BE] Delete unused column audioFileUrl from Resource entity
Jul 11, 2025
7c90506
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
c7dc26b
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
872e360
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
132a25c
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
b6ea21e
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
9c07cec
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
072c5ef
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
e7a01b3
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
51cb2de
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
0376999
Issue 2693: [BE] Delete unused column audioFileUrl from Resource enti…
Jul 11, 2025
21b6338
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
umedvedev Jul 15, 2025
d376608
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
ElenaSpb Jul 15, 2025
d03b01d
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
ElenaSpb Jul 17, 2025
13048eb
Migration fixed by removing duplicates before adding new constraint r…
Jul 18, 2025
a22fb3a
Migration fixed drop index if exists ukt37wptru4xcs8es5ae1huynph, res…
Jul 21, 2025
ed193bb
Migration fix
Jul 21, 2025
b801525
Migration fix 1
Jul 21, 2025
7061d0c
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
umedvedev Jul 21, 2025
96aaedc
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
ElenaSpb Jul 22, 2025
c504bc5
alter table resource drop constraint if exists ukt37wptru4xcs8es5ae1h…
Jul 22, 2025
fa87bda
2693: Migration fixed, remap task resources before dropping column `a…
Aug 26, 2025
3160e27
Merge branch 'master' into ISSUE_2693_del_unused_audiofileurl
umedvedev Aug 26, 2025
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 @@ -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?,
Expand Down
10 changes: 2 additions & 8 deletions src/main/kotlin/com/epam/brn/model/Resource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ 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_word_type_idx", columnList = "word, wordType"),
],
)
class Resource(
@Id
@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 = "",
Expand All @@ -39,7 +36,6 @@ class Resource(
) {
fun toResponse() = ResourceResponse(
id = id,
audioFileUrl = audioFileUrl,
word = word.replace("+", ""),
wordPronounce = word,
pictureFileUrl = pictureFileUrl,
Expand All @@ -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
Expand All @@ -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)
Expand Down
11 changes: 0 additions & 11 deletions src/main/kotlin/com/epam/brn/repo/ResourceRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ interface ResourceRepository : CrudRepository<Resource, Long> {
wordType: String,
): Optional<Resource>

fun findFirstByWordAndAudioFileUrlLike(
word: String,
audioFileUrl: String,
): Optional<Resource>

fun findFirstByWordAndWordTypeAndAudioFileUrlLike(
word: String,
wordType: String,
audioFileUrl: String,
): Optional<Resource>

fun findFirstByWordAndLocaleAndWordType(
word: String,
locale: String,
Expand Down
7 changes: 0 additions & 7 deletions src/main/kotlin/com/epam/brn/service/ResourceService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<Resource> = resourceRepository
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -70,21 +69,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,
),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,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
Expand All @@ -23,7 +21,6 @@ class SeriesPhrasesRecordProcessor(
private val subGroupRepository: SubGroupRepository,
private val resourceRepository: ResourceRepository,
private val exerciseRepository: ExerciseRepository,
private val wordsService: WordsService,
) : RecordProcessor<SeriesPhrasesRecord, Exercise> {
@Value(value = "\${fonAudioPath}")
private lateinit var fonAudioPath: String
Expand Down Expand Up @@ -67,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(" ")
Expand All @@ -84,14 +81,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
Expand All @@ -102,7 +91,6 @@ class SeriesPhrasesRecordProcessor(
locale = locale.locale,
),
)
resource.audioFileUrl = audioPath
resource.wordType = wordType
return resource
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -73,19 +72,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
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -63,14 +62,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())
Expand All @@ -80,7 +71,6 @@ class SeriesWordsKorolevaRecordProcessor(
locale = locale.locale,
),
)
resource.audioFileUrl = audioPath
resource.wordType = WordType.OBJECT.toString()
return resource
}
Expand Down
60 changes: 60 additions & 0 deletions src/main/resources/db/migration/V220250711_2566.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
drop index if exists audio_file_idx;

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 if exists resource_constrain;

alter table resource drop constraint if exists ukt37wptru4xcs8es5ae1huynph;

drop index if exists ukt37wptru4xcs8es5ae1huynph;

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;
8 changes: 5 additions & 3 deletions src/test/kotlin/com/epam/brn/integration/repo/BaseTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -61,11 +63,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))

Expand Down
32 changes: 0 additions & 32 deletions src/test/kotlin/com/epam/brn/service/ResourceServiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading