Hi everyone, I'm very new to backend development, ...
# ktor
y
Hi everyone, I'm very new to backend development, Ktor, and the Exposed framework. I'm working on a project and trying to migrate my database connection from the standard JDBC (with HikariCP) to R2DBC to learn more about reactive programming. Since I couldn't find many direct examples online for this specific setup, I used an AI assistant to help generate the code. Now, I'm not sure if the result is correct or follows best practices. I'd be really grateful if someone with more experience could take a look and give me some feedback. For context, I've posted the 'before' and 'after' versions of my code below for you to check.
Before: Working JDBC + HikariCP Setup
Copy code
// DatabaseFactory.kt
 object DatabaseFactory {
     fun init() {
         val database = Database.connect(hikari())
         transaction(database) {
             // Create tables if they don't exist
             SchemaUtils.create(
                 UsersTable,
                 ChatsTable,
                 GeneratedImagesTable,
                 ChatMessagesTable
             )
         }
     }
     private fun hikari(): HikariDataSource {
         val config = HikariConfig().apply {
             driverClassName = "org.postgresql.Driver"
             jdbcUrl = System.getenv("DATABASE_URL") ?: "jdbc:<postgresql://localhost:5432/your_db_name|postgresql://localhost:5432/your_db_name>"
             username = System.getenv("DATABASE_USER") ?: "postgres"
             password = System.getenv("DATABASE_PASSWORD") ?: "password"
             maximumPoolSize = 3
             isAutoCommit = false
             transactionIsolation = "TRANSACTION_REPEATABLE_READ"
             validate()
         }
         return HikariDataSource(config)
     }
     suspend fun <T> dbQuery(block: suspend () -> T): T =
         newSuspendedTransaction(<http://Dispatchers.IO|Dispatchers.IO>) { block() }
} After: My Attempt at an R2DBC Setup
Copy code
// DatabaseFactory.kt
 object DatabaseFactory {
     private val database: R2dbcDatabase by lazy {
         val r2dbcUrl = buildR2dbcUrl()
         R2dbcDatabase.connect(
             url = r2dbcUrl,
             user = System.getenv("DATABASE_USER") ?: "postgres",
             password = System.getenv("DATABASE_PASSWORD") ?: "password"
         )
     }
 
     suspend fun init() {
         // Schema creation in a suspended transaction
         suspendTransaction(<http://Dispatchers.IO|Dispatchers.IO>, db = database) {
             SchemaUtils.create(
                 UsersTable,
                 ChatsTable,
                 GeneratedImagesTable,
                 ChatMessagesTable
             )
         }
     }
 
     private fun buildR2dbcUrl(): String {
         val jdbcUrl = System.getenv("DATABASE_URL") ?: "jdbc:<postgresql://localhost:5432/your_db_name|postgresql://localhost:5432/your_db_name>"
         // Handle different JDBC URL formats
         return if (jdbcUrl.startsWith("jdbc:postgresql://")) {
             jdbcUrl.replace("jdbc:postgresql://", "r2dbc:postgresql://")
         } else {
             // Fallback to default R2DBC URL
             "r2dbc:<postgresql://localhost:5432/your_db_name|postgresql://localhost:5432/your_db_name>"
         }
     }
 
     suspend fun <T> dbQuery(block: suspend () -> T): T =
         suspendTransaction(<http://Dispatchers.IO|Dispatchers.IO>, db = database) { block() }
 }
a
You'd better ask this question in the #C0CG7E0A1 channel.
👍 1