SimpleNotes/persistence/src/extensions/KtormExtensions.kt

78 lines
2.5 KiB
Kotlin

package be.simplenotes.persistence.extensions
import org.ktorm.database.Database
import org.ktorm.expression.*
import org.ktorm.schema.*
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.Types
internal class VarcharArraySqlType : SqlType<List<String>>(Types.ARRAY, typeName = "varchar[]") {
override fun doGetResult(rs: ResultSet, index: Int): List<String>? {
return when (val array = rs.getObject(index)) {
null -> null
is Array<*> -> array.map { it.toString() }
else -> error("")
}
}
override fun doSetParameter(ps: PreparedStatement, index: Int, parameter: List<String>) {
throw UnsupportedOperationException()
}
}
internal fun <E : Any> BaseTable<E>.varcharArray(name: String) = registerColumn(name, VarcharArraySqlType())
data class ArrayContainsExpression(
val left: ScalarExpression<*>,
val right: ScalarExpression<*>,
override val sqlType: SqlType<Boolean> = BooleanSqlType,
override val isLeafNode: Boolean = false
) : ScalarExpression<Boolean>() {
override val extraProperties: Map<String, Any> get() = emptyMap()
}
infix fun ColumnDeclaring<*>.arrayContains(arguments: String): ArrayContainsExpression {
return ArrayContainsExpression(asExpression(), ArgumentExpression(arguments, VarcharSqlType))
}
class CustomSqlFormatter(database: Database, beautifySql: Boolean, indentSize: Int) :
SqlFormatter(database, beautifySql, indentSize) {
override fun visitUnknown(expr: SqlExpression): SqlExpression {
return if (expr is ArrayContainsExpression) {
write("ARRAY_CONTAINS(")
if (expr.left.removeBrackets) {
visit(expr.left)
} else {
write("(")
visit(expr.left)
removeLastBlank()
write(") ")
}
write(", ")
if (expr.right.removeBrackets) {
visit(expr.right)
} else {
write("(")
visit(expr.right)
removeLastBlank()
write(") ")
}
write(")")
return expr
} else super.visitUnknown(expr)
}
override fun writePagination(expr: QueryExpression) {
newLine(Indentation.SAME)
writeKeyword("limit ?, ? ")
_parameters += ArgumentExpression(expr.offset ?: 0, IntSqlType)
_parameters += ArgumentExpression(expr.limit ?: Int.MAX_VALUE, IntSqlType)
}
}