|
|
@ -3,13 +3,16 @@ package net.aiterp.git.ykonsole2.infrastructure |
|
|
|
import com.zaxxer.hikari.HikariConfig |
|
|
|
import com.zaxxer.hikari.HikariDataSource |
|
|
|
import net.aiterp.git.ykonsole2.InfrastructureException |
|
|
|
import net.aiterp.git.ykonsole2.application.logging.log |
|
|
|
import net.aiterp.git.ykonsole2.domain.models.randomId |
|
|
|
import org.intellij.lang.annotations.Language |
|
|
|
import java.sql.Connection |
|
|
|
import java.sql.PreparedStatement |
|
|
|
import java.sql.ResultSet |
|
|
|
import java.sql.SQLException |
|
|
|
import java.util.concurrent.TimeUnit |
|
|
|
import javax.sql.DataSource |
|
|
|
import kotlin.time.Duration.Companion.minutes |
|
|
|
|
|
|
|
fun makeDataSource( |
|
|
|
url: String, |
|
|
@ -23,16 +26,30 @@ fun makeDataSource( |
|
|
|
cfg.password = password |
|
|
|
cfg.poolName = "ykonsole2-pool-${randomId()}" |
|
|
|
cfg.maximumPoolSize = poolSize |
|
|
|
cfg.maxLifetime = 5.minutes.inWholeMilliseconds |
|
|
|
|
|
|
|
if (driverClassName != null) { |
|
|
|
cfg.driverClassName = driverClassName |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
fun <T : Any?> DataSource.withConnection(func: Connection.() -> T): T = try { |
|
|
|
connection.use(func) |
|
|
|
} catch (e: SQLException) { |
|
|
|
throw InfrastructureException(e) |
|
|
|
fun <T : Any?> DataSource.withConnection(func: Connection.() -> T): T { |
|
|
|
var health = 3 |
|
|
|
|
|
|
|
while (true) { |
|
|
|
try { |
|
|
|
return connection.use(func) |
|
|
|
} catch (e: SQLException) { |
|
|
|
health-- |
|
|
|
log.error("DB error: $e", e) |
|
|
|
|
|
|
|
if (health <= 0) { |
|
|
|
throw InfrastructureException(e) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
log.info("Trying again") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fun <T : Any?> Connection.prepare(@Language("MySQL") sql: String, func: PreparedStatement.() -> T): T = |
|
|
|