Skip to content

Commit

Permalink
Use more refined array column types and pass arrays instead of lists/…
Browse files Browse the repository at this point in the history
…iterables, getting `testEqAny` (for an array of strings) to work on PostgreSQL (`postgres` and `postgresNG`)
  • Loading branch information
ShreckYe committed Nov 15, 2023
1 parent 6aeed36 commit 7dd846b
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 45 deletions.
32 changes: 12 additions & 20 deletions exposed-core/api/exposed-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,6 @@ public final class org/jetbrains/exposed/sql/AndOp : org/jetbrains/exposed/sql/C
public fun <init> (Ljava/util/List;)V
}

public final class org/jetbrains/exposed/sql/ArrayColumnType : org/jetbrains/exposed/sql/ColumnType {
public fun <init> ()V
public fun sqlType ()Ljava/lang/String;
}

public final class org/jetbrains/exposed/sql/AutoIncColumnType : org/jetbrains/exposed/sql/IColumnType {
public fun <init> (Lorg/jetbrains/exposed/sql/ColumnType;Ljava/lang/String;Ljava/lang/String;)V
public fun equals (Ljava/lang/Object;)Z
Expand Down Expand Up @@ -1446,6 +1441,12 @@ public class org/jetbrains/exposed/sql/OffsetWindowFrameBound : org/jetbrains/ex
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
}

public final class org/jetbrains/exposed/sql/OneDimArrayColumnType : org/jetbrains/exposed/sql/ColumnType {
public fun <init> (Lorg/jetbrains/exposed/sql/IColumnType;)V
public final fun getElementType ()Lorg/jetbrains/exposed/sql/IColumnType;
public fun sqlType ()Ljava/lang/String;
}

public abstract class org/jetbrains/exposed/sql/Op : org/jetbrains/exposed/sql/Expression {
public static final field Companion Lorg/jetbrains/exposed/sql/Op$Companion;
public fun <init> ()V
Expand Down Expand Up @@ -1502,6 +1503,7 @@ public final class org/jetbrains/exposed/sql/OpKt {
public static final fun shortParam (S)Lorg/jetbrains/exposed/sql/Expression;
public static final fun stringLiteral (Ljava/lang/String;)Lorg/jetbrains/exposed/sql/LiteralOp;
public static final fun stringParam (Ljava/lang/String;)Lorg/jetbrains/exposed/sql/Expression;
public static final fun toColumnType (Lkotlin/reflect/KClass;)Lorg/jetbrains/exposed/sql/IColumnType;
public static final fun ubyteLiteral-7apg3OU (B)Lorg/jetbrains/exposed/sql/LiteralOp;
public static final fun ubyteParam-7apg3OU (B)Lorg/jetbrains/exposed/sql/Expression;
public static final fun uintLiteral-WZ4Q5Ns (I)Lorg/jetbrains/exposed/sql/LiteralOp;
Expand Down Expand Up @@ -1724,8 +1726,6 @@ public final class org/jetbrains/exposed/sql/RowNumber : org/jetbrains/exposed/s
public final class org/jetbrains/exposed/sql/SQLExpressionBuilderKt {
public static final fun CustomLongFunction (Ljava/lang/String;[Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/CustomFunction;
public static final fun CustomStringFunction (Ljava/lang/String;[Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/CustomFunction;
public static final fun allOp (Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/AllOp;
public static final fun anyOp (Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/AnyOp;
public static final fun avg (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;I)Lorg/jetbrains/exposed/sql/Avg;
public static synthetic fun avg$default (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;IILjava/lang/Object;)Lorg/jetbrains/exposed/sql/Avg;
public static final fun castTo (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/IColumnType;)Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;
Expand Down Expand Up @@ -2559,10 +2559,12 @@ public final class org/jetbrains/exposed/sql/functions/math/TanFunction : org/je
public fun <init> (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)V
}

public abstract class org/jetbrains/exposed/sql/ops/AllAnyOp : org/jetbrains/exposed/sql/Op {
public fun <init> (Ljava/lang/Iterable;)V
public final class org/jetbrains/exposed/sql/ops/AllAnyOp : org/jetbrains/exposed/sql/Op {
public fun <init> (Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;Lorg/jetbrains/exposed/sql/IColumnType;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)V
public final fun getElementType ()Lorg/jetbrains/exposed/sql/IColumnType;
public final fun getList ()Ljava/lang/Iterable;
public abstract fun isAllOrAny ()Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;
public final fun getOpType ()Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;
public final fun getToTypedArray ()Lkotlin/jvm/functions/Function1;
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
}

Expand All @@ -2573,16 +2575,6 @@ public final class org/jetbrains/exposed/sql/ops/AllAnyOp$OpType : java/lang/Enu
public static fun values ()[Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;
}

public final class org/jetbrains/exposed/sql/ops/AllOp : org/jetbrains/exposed/sql/ops/AllAnyOp {
public fun <init> (Ljava/lang/Iterable;)V
public fun isAllOrAny ()Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;
}

public final class org/jetbrains/exposed/sql/ops/AnyOp : org/jetbrains/exposed/sql/ops/AllAnyOp {
public fun <init> (Ljava/lang/Iterable;)V
public fun isAllOrAny ()Lorg/jetbrains/exposed/sql/ops/AllAnyOp$OpType;
}

public abstract class org/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp : org/jetbrains/exposed/sql/Op, org/jetbrains/exposed/sql/ComplexExpression {
public fun <init> (Ljava/lang/Object;Ljava/lang/Iterable;Z)V
public synthetic fun <init> (Ljava/lang/Object;Ljava/lang/Iterable;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -985,10 +985,10 @@ class CustomEnumerationColumnType<T : Enum<T>>(
override fun nonNullValueToString(value: Any): String = super.nonNullValueToString(notNullValueToDB(value))
}

class ArrayColumnType<T> : ColumnType() {
class OneDimArrayColumnType(val elementType: IColumnType) : ColumnType() {
override fun sqlType(): String =
//currentDialect.dataTypeProvider.arrayType()
"ARRAY" // TODO
// currentDialect.dataTypeProvider.arrayType()
"${elementType.sqlType()}[]" // TODO
}

// Date/Time columns
Expand Down
20 changes: 20 additions & 0 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.wrap
import org.jetbrains.exposed.sql.statements.api.ExposedBlob
import org.jetbrains.exposed.sql.vendors.*
import java.math.BigDecimal
import kotlin.reflect.KClass

/**
* Represents an SQL operator.
Expand Down Expand Up @@ -732,6 +733,25 @@ fun blobParam(value: ExposedBlob): Expression<ExposedBlob> = QueryParameter(valu

// Misc.

/** Adapted from [ISqlExpressionBuilder.wrap]. */
fun <T : Any> KClass<T>.toColumnType(): IColumnType = when (this) {
Boolean::class -> BooleanColumnType.INSTANCE
Byte::class -> ByteColumnType()
UByte::class -> UByteColumnType()
Short::class -> ShortColumnType()
UShort::class -> UShortColumnType()
Int::class -> IntegerColumnType()
UInt::class -> UIntegerColumnType()
Long::class -> LongColumnType()
ULong::class -> ULongColumnType()
Float::class -> FloatColumnType()
Double::class -> DoubleColumnType()
String::class -> TextColumnType() // TODO
// added
BigDecimal::class -> DecimalColumnType(TODO(), TODO())
else -> TODO("$this")
}

/**
* Represents an SQL operator that doesn't perform any operation.
* This is mainly used to change between column types.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ package org.jetbrains.exposed.sql
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.EntityIDFunctionProvider
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.sql.ops.AllOp
import org.jetbrains.exposed.sql.ops.AnyOp
import org.jetbrains.exposed.sql.ops.InListOrNotInListBaseOp
import org.jetbrains.exposed.sql.ops.PairInListOp
import org.jetbrains.exposed.sql.ops.SingleValueInListOp
import org.jetbrains.exposed.sql.ops.TripleInListOp
import org.jetbrains.exposed.sql.ops.*
import org.jetbrains.exposed.sql.vendors.FunctionProvider
import org.jetbrains.exposed.sql.vendors.currentDialect
import java.math.BigDecimal
Expand Down Expand Up @@ -98,8 +93,8 @@ fun <T : Any?> ExpressionWithColumnType<T>.varPop(scale: Int = 2): VarPop<T> = V
*/
fun <T : Any?> ExpressionWithColumnType<T>.varSamp(scale: Int = 2): VarSamp<T> = VarSamp(this, scale)

fun <T> Iterable<T>.allOp() = AllOp(this)
fun <T> Iterable<T>.anyOp() = AnyOp(this)
inline fun <reified T> Iterable<T>.allOp() = AllAnyOp(AllAnyOp.OpType.All, this)
inline fun <reified T> Iterable<T>.anyOp() = AllAnyOp(AllAnyOp.OpType.Any, this)

// Sequence Manipulation Functions

Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
package org.jetbrains.exposed.sql.ops

import org.jetbrains.exposed.sql.ArrayColumnType
import org.jetbrains.exposed.sql.IColumnType
import org.jetbrains.exposed.sql.OneDimArrayColumnType
import org.jetbrains.exposed.sql.Op
import org.jetbrains.exposed.sql.QueryBuilder
import org.jetbrains.exposed.sql.toColumnType
import kotlin.reflect.KClass

class AllAnyOp<T>(val opType: OpType, val elementType: IColumnType, val list: Iterable<T>, val toTypedArray: List<T>.() -> Any) : Op<T>() {
// TODO remove
/*
init {
require(list.any())
val type = list.asSequence().filter { it !== null }::class
require(list.all { it === null || it!!::class == type })
}
*/

abstract class AllAnyOp<T>(val list: Iterable<T>) : Op<T>() {
enum class OpType {
All, Any
}

abstract fun isAllOrAny(): OpType

override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder {
+when (isAllOrAny()) {
+when (opType) {
OpType.All -> "ALL"
OpType.Any -> "ANY"
}
+'('
//+"ARRAY[" // This syntax is for PostgresSQL.
registerArgument(ArrayColumnType<T>(), list)
//+"]"
// +"ARRAY[" // This syntax is for PostgresSQL.
val array = list.toList().toTypedArray()
registerArgument(OneDimArrayColumnType(elementType), array)
// +"]"
+')'
}
}

class AllOp<T>(list: Iterable<T>) : AllAnyOp<T>(list) {
override fun isAllOrAny(): OpType = OpType.All
}
// TODO remove
/*
inline fun <reified T> AllAnyOp(opType: AllAnyOp.OpType, list: Iterable<T>) =
AllAnyOp(opType, (T::class as KClass<*>).toColumnType(), list)
*/

class AnyOp<T>(list: Iterable<T>) : AllAnyOp<T>(list) {
override fun isAllOrAny(): OpType = OpType.Any
}
inline fun <reified T> AllAnyOp(opType: AllAnyOp.OpType, list: Iterable<T>) =
AllAnyOp(opType, (T::class as KClass<*>).toColumnType(), list) { this.toTypedArray() }

0 comments on commit 7dd846b

Please sign in to comment.