aboutsummaryrefslogtreecommitdiff
path: root/database
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-01-25 19:22:29 +0100
committerLinnea Gräf <nea@nea.moe>2025-01-25 19:22:29 +0100
commit518c02396eff3c8e86d9bca371b097e0c7e6da3b (patch)
tree7abeafe5b953d75c51017780d6d06ca388e87c63 /database
parent5a49c878ede9df81417c79e98d226c941551f3c0 (diff)
downloadLocalTransactionLedger-518c02396eff3c8e86d9bca371b097e0c7e6da3b.tar.gz
LocalTransactionLedger-518c02396eff3c8e86d9bca371b097e0c7e6da3b.tar.bz2
LocalTransactionLedger-518c02396eff3c8e86d9bca371b097e0c7e6da3b.zip
feat(server): More SQL refactoring
Diffstat (limited to 'database')
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/ClauseBuilder.kt5
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/ColumnOperand.kt2
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListClause.kt8
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListExpression.kt22
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/SQLQueryComponent.kt19
-rw-r--r--database/core/src/main/kotlin/moe/nea/ledger/database/sql/TypedOperand.kt4
6 files changed, 57 insertions, 3 deletions
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ClauseBuilder.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ClauseBuilder.kt
index aae8456..cb0ddfc 100644
--- a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ClauseBuilder.kt
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ClauseBuilder.kt
@@ -4,6 +4,7 @@ import moe.nea.ledger.database.Column
import moe.nea.ledger.database.DBType
class ClauseBuilder {
+ // TODO: should we match on T AND R? maybe allow explicit upcasting
fun <T, R> column(column: Column<T, R>): ColumnOperand<T, R> = ColumnOperand(column)
fun string(string: String): StringOperand = StringOperand(string)
fun <T, R> value(dbType: DBType<T, R>, value: T): Operand<T, R> = ValuedOperand(dbType, value)
@@ -15,6 +16,10 @@ class ClauseBuilder {
infix fun <T> Operand<*, T>.le(op: Operand<*, T>): BooleanExpression = LessThanEqualsExpression(this, op)
infix fun <T> Operand<*, T>.gt(op: Operand<*, T>): BooleanExpression = op lt this
infix fun <T> Operand<*, T>.ge(op: Operand<*, T>): BooleanExpression = op le this
+ infix fun <T> Operand<*, T>.inList(list: ListExpression<*, T>): Clause = ListClause(this, list)
+ infix fun <T, R> TypedOperand<T, R>.inList(list: List<T>): Clause = this inList list(dbType, list)
+ fun <T, R> list(dbType: DBType<T, R>, vararg values: T): ListExpression<T, R> = list(dbType, values.toList())
+ fun <T, R> list(dbType: DBType<T, R>, values: List<T>): ListExpression<T, R> = ListExpression(values, dbType)
infix fun BooleanExpression.and(clause: BooleanExpression): BooleanExpression = ANDExpression(listOf(this, clause))
infix fun BooleanExpression.or(clause: BooleanExpression): BooleanExpression = ORExpression(listOf(this, clause))
} \ No newline at end of file
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ColumnOperand.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ColumnOperand.kt
index 710c577..430d592 100644
--- a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ColumnOperand.kt
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ColumnOperand.kt
@@ -4,7 +4,7 @@ import moe.nea.ledger.database.Column
import moe.nea.ledger.database.DBType
import java.sql.PreparedStatement
-data class ColumnOperand<T, Raw>(val column: Column<T, Raw>) : TypedOperand<T, Raw>() {
+data class ColumnOperand<T, Raw>(val column: Column<T, Raw>) : TypedOperand<T, Raw> {
override val dbType: DBType<T, Raw>
get() = column.type
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListClause.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListClause.kt
new file mode 100644
index 0000000..d240472
--- /dev/null
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListClause.kt
@@ -0,0 +1,8 @@
+package moe.nea.ledger.database.sql
+
+class ListClause<R>(
+ val lhs: Operand<*, R>,
+ val list: ListExpression<*, R>,
+) : Clause, SQLQueryComponent by SQLQueryComponent.composite(
+ lhs, SQLQueryComponent.standalone("IN"), list
+) \ No newline at end of file
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListExpression.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListExpression.kt
new file mode 100644
index 0000000..e1522d0
--- /dev/null
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/ListExpression.kt
@@ -0,0 +1,22 @@
+package moe.nea.ledger.database.sql
+
+import moe.nea.ledger.database.DBType
+import java.sql.PreparedStatement
+
+data class ListExpression<T, R>(
+ val elements: List<T>,
+ val dbType: DBType<T, R>
+) : Operand<List<T>, List<R>> {
+ override fun asSql(): String {
+ return elements.joinToString(prefix = "(", postfix = ")") { "?" }
+ }
+
+ override fun appendToStatement(stmt: PreparedStatement, startIndex: Int): Int {
+ var index = startIndex
+ for (element in elements) {
+ dbType.set(stmt, index, element)
+ index++
+ }
+ return index
+ }
+}
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/SQLQueryComponent.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/SQLQueryComponent.kt
index 10b2be6..77d63d3 100644
--- a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/SQLQueryComponent.kt
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/SQLQueryComponent.kt
@@ -11,6 +11,25 @@ interface SQLQueryComponent {
fun appendToStatement(stmt: PreparedStatement, startIndex: Int): Int
companion object {
+ fun composite(vararg elements: SQLQueryComponent): SQLQueryComponent {
+ return object : SQLQueryComponent {
+ override fun asSql(): String {
+ return elements.joinToString(" ") { it.asSql() }
+ }
+
+ override fun appendToStatement(stmt: PreparedStatement, startIndex: Int): Int {
+ var index = startIndex
+ for (element in elements) {
+ val lastIndex = index
+ index = element.appendToStatement(stmt, index)
+ require(lastIndex <= index) { "$element just tried to go back in time $index < $lastIndex" }
+ }
+ return index
+
+ }
+ }
+ }
+
fun standalone(sql: String): SQLQueryComponent {
return object : SQLQueryComponent {
override fun asSql(): String {
diff --git a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/TypedOperand.kt b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/TypedOperand.kt
index 57efe58..8a1f723 100644
--- a/database/core/src/main/kotlin/moe/nea/ledger/database/sql/TypedOperand.kt
+++ b/database/core/src/main/kotlin/moe/nea/ledger/database/sql/TypedOperand.kt
@@ -2,6 +2,6 @@ package moe.nea.ledger.database.sql
import moe.nea.ledger.database.DBType
-abstract class TypedOperand<T, Raw> : Operand<T, Raw> {
- abstract val dbType: DBType<T, Raw>
+interface TypedOperand<T, Raw> : Operand<T, Raw> {
+ val dbType: DBType<T, Raw>
}