package com.android.trisolarisserver.config import org.slf4j.LoggerFactory import org.springframework.boot.ApplicationArguments import org.springframework.boot.ApplicationRunner import org.springframework.jdbc.core.JdbcTemplate import org.springframework.stereotype.Component @Component class IssuedCardSchemaFix( private val jdbcTemplate: JdbcTemplate ) : ApplicationRunner { private val logger = LoggerFactory.getLogger(IssuedCardSchemaFix::class.java) override fun run(args: ApplicationArguments) { val version = jdbcTemplate.queryForObject("select version()", String::class.java) ?: return if (!version.contains("PostgreSQL", ignoreCase = true)) { return } val isNullable = jdbcTemplate.queryForObject( """ select count(*) from information_schema.columns where table_name = 'issued_card' and column_name = 'room_stay_id' and is_nullable = 'YES' """.trimIndent(), Int::class.java ) ?: 0 if (isNullable == 0) { logger.info("Dropping NOT NULL on issued_card.room_stay_id") jdbcTemplate.execute("alter table issued_card alter column room_stay_id drop not null") } val uniqueIndexExists = jdbcTemplate.queryForObject( """ select count(*) from pg_indexes where schemaname = 'public' and tablename = 'issued_card' and indexname = 'idx_issued_card_property_card_id_unique' """.trimIndent(), Int::class.java ) ?: 0 if (uniqueIndexExists == 0) { logger.info("Removing duplicate issued_card rows by property_id + card_id") jdbcTemplate.execute( """ with ranked as ( select id, row_number() over ( partition by property_id, lower(card_id) order by issued_at desc, id desc ) as rn from issued_card where card_id is not null ) delete from issued_card where id in (select id from ranked where rn > 1) """.trimIndent() ) logger.info("Creating unique index on issued_card(property_id, lower(card_id))") jdbcTemplate.execute( "create unique index if not exists idx_issued_card_property_card_id_unique on issued_card (property_id, lower(card_id))" ) } } }