diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 7d0e6702a0..427f98686b 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -921,38 +921,13 @@ interface ISqlExpressionBuilder { /** Returns the specified [value] as a query parameter of type [T]. */ @Suppress("UNCHECKED_CAST") - fun ExpressionWithColumnType.wrap(value: T): QueryParameter = when (value) { - is Boolean -> booleanParam(value) - is Byte -> byteParam(value) - is UByte -> ubyteParam(value) - is Short -> shortParam(value) - is UShort -> ushortParam(value) - is Int -> intParam(value) - is UInt -> uintParam(value) - is Long -> longParam(value) - is ULong -> ulongParam(value) - is Float -> floatParam(value) - is Double -> doubleParam(value) - is String -> QueryParameter(value, columnType as IColumnType) // String value should inherit from column - else -> QueryParameter(value, columnType as IColumnType) - } as QueryParameter + fun ExpressionWithColumnType.wrap(value: T): QueryParameter = + QueryParameter(value, columnType as IColumnType) /** Returns the specified [value] as a literal of type [T]. */ @Suppress("UNCHECKED_CAST", "ComplexMethod") - fun ExpressionWithColumnType.asLiteral(value: T): LiteralOp = when (value) { - is Boolean -> booleanLiteral(value) - is Byte -> byteLiteral(value) - is UByte -> ubyteLiteral(value) - is Short -> shortLiteral(value) - is UShort -> ushortLiteral(value) - is Int -> intLiteral(value) - is UInt -> uintLiteral(value) - is Long -> longLiteral(value) - is ULong -> ulongLiteral(value) - is Float -> floatLiteral(value) - is Double -> doubleLiteral(value) - is String -> stringLiteral(value) - is ByteArray -> stringLiteral(value.toString(Charsets.UTF_8)) + fun ExpressionWithColumnType.asLiteral(value: T): LiteralOp = when { + value is ByteArray && columnType is BasicBinaryColumnType -> stringLiteral(value.toString(Charsets.UTF_8)) else -> LiteralOp(columnType as IColumnType, value) } as LiteralOp diff --git a/exposed-json/src/main/kotlin/org/jetbrains/exposed/sql/json/JsonConditions.kt b/exposed-json/src/main/kotlin/org/jetbrains/exposed/sql/json/JsonConditions.kt index 1b1442ff00..bab311efd4 100644 --- a/exposed-json/src/main/kotlin/org/jetbrains/exposed/sql/json/JsonConditions.kt +++ b/exposed-json/src/main/kotlin/org/jetbrains/exposed/sql/json/JsonConditions.kt @@ -1,13 +1,7 @@ package org.jetbrains.exposed.sql.json -import org.jetbrains.exposed.sql.ComplexExpression -import org.jetbrains.exposed.sql.Expression -import org.jetbrains.exposed.sql.ExpressionWithColumnType -import org.jetbrains.exposed.sql.IColumnType -import org.jetbrains.exposed.sql.Op -import org.jetbrains.exposed.sql.QueryBuilder +import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.asLiteral -import org.jetbrains.exposed.sql.stringLiteral import org.jetbrains.exposed.sql.vendors.currentDialect // Operator Classes @@ -69,6 +63,7 @@ fun ExpressionWithColumnType<*>.contains(candidate: Expression<*>, path: String? */ fun ExpressionWithColumnType<*>.contains(candidate: T, path: String? = null): Contains = when (candidate) { is Iterable<*>, is Array<*> -> Contains(this, stringLiteral(asLiteral(candidate).toString()), path, columnType) + is String -> Contains(this, stringLiteral(candidate), path, columnType) else -> Contains(this, asLiteral(candidate), path, columnType) } diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/BooleanColumnTypeTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/BooleanColumnTypeTests.kt index ef46ddac73..d021c52c56 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/BooleanColumnTypeTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/types/BooleanColumnTypeTests.kt @@ -49,4 +49,60 @@ class BooleanColumnTypeTests : DatabaseTestsBase() { assertEquals(idTrue, resultTrue?.get(BooleanTable.id)) } } + + @Test + fun testCustomCharBooleanColumnType() { + val tester = object : Table("tester") { + val charBooleanColumn = charBoolean("charBooleanColumn") + val charBooleanColumnWithDefault = charBoolean("charBooleanColumnWithDefault") + .default(false) + } + + withDb { + try { + SchemaUtils.create(tester) + + tester.insert { + it[charBooleanColumn] = true + } + + assertEquals( + 1, + tester.select(tester.charBooleanColumn) + .where { tester.charBooleanColumn eq true } + .andWhere { tester.charBooleanColumnWithDefault eq false } + .count() + ) + } finally { + SchemaUtils.drop(tester) + } + } + } + + class CharBooleanColumnType( + private val characterColumnType: VarCharColumnType = VarCharColumnType(1), + ) : ColumnType() { + override fun sqlType(): String = characterColumnType.preciseType() + + override fun valueFromDB(value: Any): Boolean = + when (characterColumnType.valueFromDB(value)) { + "Y" -> true + else -> false + } + + override fun valueToDB(value: Boolean?): Any? = + characterColumnType.valueToDB(value.toChar().toString()) + + override fun nonNullValueToString(value: Boolean): String = + characterColumnType.nonNullValueToString(value.toChar().toString()) + + private fun Boolean?.toChar() = when (this) { + true -> 'Y' + false -> 'N' + else -> ' ' + } + } + + fun Table.charBoolean(name: String): Column = + registerColumn(name, CharBooleanColumnType()) }