abstract db connection
This commit is contained in:
parent
ca62140e6f
commit
e2cf9c04b5
@ -2,11 +2,39 @@ package dev.mduchene.bolts.persistence
|
|||||||
|
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.DriverManager
|
import java.sql.DriverManager
|
||||||
|
import java.sql.PreparedStatement
|
||||||
|
import java.sql.ResultSet
|
||||||
|
|
||||||
class Database(private val config: DatabaseConfig) {
|
class Database(private val config: DatabaseConfig) {
|
||||||
fun getConnection(): Connection =
|
fun getConnection(): Connection =
|
||||||
DriverManager.getConnection(config.url, config.username, config.password)
|
DriverManager.getConnection(config.url, config.username, config.password)
|
||||||
|
|
||||||
|
fun executeUpdate(
|
||||||
|
sql: String,
|
||||||
|
bind: PreparedStatement.() -> Unit = {},
|
||||||
|
): Int = withPreparedStatement(sql) {
|
||||||
|
bind()
|
||||||
|
executeUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> queryOne(
|
||||||
|
sql: String,
|
||||||
|
bind: PreparedStatement.() -> Unit = {},
|
||||||
|
map: ResultSet.() -> T,
|
||||||
|
): T? = query(sql, bind) {
|
||||||
|
if (next()) map() else null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> queryList(
|
||||||
|
sql: String,
|
||||||
|
bind: PreparedStatement.() -> Unit = {},
|
||||||
|
map: ResultSet.() -> T,
|
||||||
|
): List<T> = query(sql, bind) {
|
||||||
|
buildList {
|
||||||
|
while (next()) add(map())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
getConnection().use { connection ->
|
getConnection().use { connection ->
|
||||||
connection.createStatement().use { statement ->
|
connection.createStatement().use { statement ->
|
||||||
@ -17,6 +45,22 @@ class Database(private val config: DatabaseConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> query(
|
||||||
|
sql: String,
|
||||||
|
bind: PreparedStatement.() -> Unit,
|
||||||
|
read: ResultSet.() -> T,
|
||||||
|
): T = withPreparedStatement(sql) {
|
||||||
|
bind()
|
||||||
|
executeQuery().use { result -> result.read() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> withPreparedStatement(
|
||||||
|
sql: String,
|
||||||
|
action: PreparedStatement.() -> T,
|
||||||
|
): T = getConnection().use { connection ->
|
||||||
|
connection.prepareStatement(sql).use { statement -> statement.action() }
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val CREATE_USERS_TABLE = """
|
const val CREATE_USERS_TABLE = """
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
|||||||
@ -1,18 +1,14 @@
|
|||||||
package dev.mduchene.bolts.user
|
package dev.mduchene.bolts.user
|
||||||
|
|
||||||
import dev.mduchene.bolts.persistence.Database
|
import dev.mduchene.bolts.persistence.Database
|
||||||
import java.sql.ResultSet
|
|
||||||
|
|
||||||
class SessionRepository(private val database: Database) {
|
class SessionRepository(private val database: Database) {
|
||||||
fun create(token: String, userId: Long) {
|
fun create(token: String, userId: Long) {
|
||||||
val sql = "INSERT INTO sessions (token, user_id) VALUES (?, ?)"
|
val sql = "INSERT INTO sessions (token, user_id) VALUES (?, ?)"
|
||||||
|
|
||||||
database.getConnection().use { connection ->
|
database.executeUpdate(sql) {
|
||||||
connection.prepareStatement(sql).use { statement ->
|
setString(1, token)
|
||||||
statement.setString(1, token)
|
setLong(2, userId)
|
||||||
statement.setLong(2, userId)
|
|
||||||
statement.executeUpdate()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,20 +20,10 @@ class SessionRepository(private val database: Database) {
|
|||||||
WHERE sessions.token = ?
|
WHERE sessions.token = ?
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
database.getConnection().use { connection ->
|
return database.queryOne(
|
||||||
connection.prepareStatement(sql).use { statement ->
|
sql,
|
||||||
statement.setString(1, token)
|
bind = { setString(1, token) },
|
||||||
statement.executeQuery().use { result ->
|
map = { toUser() },
|
||||||
return if (result.next()) result.toUser() else null
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ResultSet.toUser() = User(
|
|
||||||
id = getLong("id"),
|
|
||||||
username = getString("username"),
|
|
||||||
passwordHash = getString("password_hash"),
|
|
||||||
role = getString("role"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,17 +11,17 @@ class UserRepository(private val database: Database) {
|
|||||||
RETURNING id, username, password_hash, role
|
RETURNING id, username, password_hash, role
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
database.getConnection().use { connection ->
|
return checkNotNull(
|
||||||
connection.prepareStatement(sql).use { statement ->
|
database.queryOne(
|
||||||
statement.setString(1, username)
|
sql,
|
||||||
statement.setString(2, passwordHash)
|
bind = {
|
||||||
statement.setString(3, role)
|
setString(1, username)
|
||||||
statement.executeQuery().use { result ->
|
setString(2, passwordHash)
|
||||||
check(result.next()) { "User insert returned no row" }
|
setString(3, role)
|
||||||
return result.toUser()
|
},
|
||||||
}
|
map = ResultSet::toUser,
|
||||||
}
|
),
|
||||||
}
|
) { "User insert returned no row" }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findByUsername(username: String): User? {
|
fun findByUsername(username: String): User? {
|
||||||
@ -31,45 +31,32 @@ class UserRepository(private val database: Database) {
|
|||||||
WHERE username = ?
|
WHERE username = ?
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
database.getConnection().use { connection ->
|
return database.queryOne(
|
||||||
connection.prepareStatement(sql).use { statement ->
|
sql,
|
||||||
statement.setString(1, username)
|
bind = { setString(1, username) },
|
||||||
statement.executeQuery().use { result ->
|
map = ResultSet::toUser,
|
||||||
return if (result.next()) result.toUser() else null
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAll(): List<User> {
|
fun findAll(): List<User> {
|
||||||
val sql = "SELECT id, username, password_hash, role FROM users ORDER BY username"
|
val sql = "SELECT id, username, password_hash, role FROM users ORDER BY username"
|
||||||
|
|
||||||
database.getConnection().use { connection ->
|
return database.queryList(sql, map = ResultSet::toUser)
|
||||||
connection.prepareStatement(sql).use { statement ->
|
|
||||||
statement.executeQuery().use { result ->
|
|
||||||
return buildList {
|
|
||||||
while (result.next()) add(result.toUser())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateRole(id: Long, role: String) {
|
fun updateRole(id: Long, role: String) {
|
||||||
val sql = "UPDATE users SET role = ? WHERE id = ?"
|
val sql = "UPDATE users SET role = ? WHERE id = ?"
|
||||||
database.getConnection().use { connection ->
|
database.executeUpdate(sql) {
|
||||||
connection.prepareStatement(sql).use { statement ->
|
setString(1, role)
|
||||||
statement.setString(1, role)
|
setLong(2, id)
|
||||||
statement.setLong(2, id)
|
|
||||||
statement.executeUpdate()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ResultSet.toUser() = User(
|
|
||||||
id = getLong("id"),
|
|
||||||
username = getString("username"),
|
|
||||||
passwordHash = getString("password_hash"),
|
|
||||||
role = getString("role"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun ResultSet.toUser() = User(
|
||||||
|
id = getLong("id"),
|
||||||
|
username = getString("username"),
|
||||||
|
passwordHash = getString("password_hash"),
|
||||||
|
role = getString("role"),
|
||||||
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user