Skip to content

Commit

Permalink
fixup! fixup! Fix remaining tests
Browse files Browse the repository at this point in the history
  • Loading branch information
e5l committed Sep 8, 2023
1 parent 7d4d4f5 commit 6792bd3
Show file tree
Hide file tree
Showing 27 changed files with 1,204 additions and 1,031 deletions.
2 changes: 1 addition & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repositories {

dependencies {
gradleApi()
implementation("org.jetbrains.kotlin.jvm", "org.jetbrains.kotlin.jvm.gradle.plugin", "1.9.0")
implementation("org.jetbrains.kotlin.jvm", "org.jetbrains.kotlin.jvm.gradle.plugin", "1.9.10")
implementation("com.avast.gradle", "gradle-docker-compose-plugin", "0.17.4")
implementation("io.gitlab.arturbosch.detekt", "detekt-gradle-plugin", "1.21.0")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ fun Project.testDb(name: String, block: TestDb.() -> Unit) {
systemProperties["exposed.test.container"] = if (db.withContainer) db.container else "none"
systemProperties["exposed.test.dialects"] = db.dialects.joinToString(",") { it.toUpperCase() }
outputs.cacheIf { false }
ignoreFailures = true

if (!db.withContainer) return@register
dependsOn(rootProject.tasks.getByName("${db.container}ComposeUp"))
finalizedBy(rootProject.tasks.getByName("${db.container}ComposeDown"))
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.jetbrains.exposed.gradle

object Versions {
const val kotlin = "1.9.0"
const val kotlinCoroutines = "1.7.3"
const val kotlinxSerialization = "1.5.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.nio.ByteBuffer
import java.sql.Blob
import java.sql.Clob
import java.sql.ResultSet
import java.sql.SQLException
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
Expand Down Expand Up @@ -467,7 +468,7 @@ class DecimalColumnType(
is BigDecimal -> value
is Double -> {
if (value.isNaN()) {
error("Unexpected value of type Double: NaN of ${value::class.qualifiedName}")
throw SQLException("Unexpected value of type Double: NaN of ${value::class.qualifiedName}")
} else {
value.toBigDecimal()
}
Expand Down
17 changes: 15 additions & 2 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class Database private constructor(
@TestOnly
set

override fun toString(): String =
"ExposedDatabase[${hashCode()}]($resolvedVendor${config.explicitDialect?.let { ", dialect=$it" } ?: ""})"

internal fun <T> metadata(body: ExposedDatabaseMetadata.() -> T): T {
val transaction = TransactionManager.currentOrNull()
return if (transaction == null) {
Expand Down Expand Up @@ -52,7 +55,9 @@ class Database private constructor(

fun isVersionCovers(version: BigDecimal) = this.version >= version

val supportsAlterTableWithAddColumn by lazy(LazyThreadSafetyMode.NONE) { metadata { supportsAlterTableWithAddColumn } }
val supportsAlterTableWithAddColumn by lazy(
LazyThreadSafetyMode.NONE
) { metadata { supportsAlterTableWithAddColumn } }
val supportsMultipleResultSets by lazy(LazyThreadSafetyMode.NONE) { metadata { supportsMultipleResultSets } }

val identifierManager by lazy { metadata { identifierManager } }
Expand Down Expand Up @@ -183,7 +188,15 @@ class Database private constructor(
): Database {
Class.forName(driver).getDeclaredConstructor().newInstance()
val dialectName = getDialectName(url) ?: error("Can't resolve dialect for connection: $url")
return doConnect(dialectName, databaseConfig, { DriverManager.getConnection(url, user, password) }, setupConnection, manager)
return doConnect(
dialectName,
databaseConfig,
{
DriverManager.getConnection(url, user, password)
},
setupConnection,
manager
)
}

fun getDefaultIsolationLevel(db: Database): Int =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:Suppress("PackageDirectoryMismatch", "InvalidPackageDeclaration")

package org.jetbrains.exposed.exceptions

import org.jetbrains.exposed.sql.AbstractQuery
Expand All @@ -9,7 +10,11 @@ import org.jetbrains.exposed.sql.statements.expandArgs
import org.jetbrains.exposed.sql.vendors.DatabaseDialect
import java.sql.SQLException

class ExposedSQLException(cause: Throwable?, val contexts: List<StatementContext>, private val transaction: Transaction) : SQLException(cause) {
class ExposedSQLException(
cause: Throwable?,
val contexts: List<StatementContext>,
private val transaction: Transaction
) : SQLException(cause) {
fun causedByQueries(): List<String> = contexts.map {
try {
if (transaction.debug) {
Expand All @@ -36,7 +41,9 @@ class ExposedSQLException(cause: Throwable?, val contexts: List<StatementContext
}

@Suppress("MaximumLineLength")
class UnsupportedByDialectException(baseMessage: String, val dialect: DatabaseDialect) : UnsupportedOperationException(baseMessage + ", dialect: ${dialect.name}.")
class UnsupportedByDialectException(baseMessage: String, val dialect: DatabaseDialect) : UnsupportedOperationException(
baseMessage + ", dialect: ${dialect.name}."
)

/**
* DuplicateColumnException is thrown :
Expand All @@ -47,7 +54,9 @@ class UnsupportedByDialectException(baseMessage: String, val dialect: DatabaseDi
* @param columnName the duplicated column name
*/
@Suppress("MaximumLineLength")
class DuplicateColumnException(columnName: String, tableName: String) : ExceptionInInitializerError("Duplicate column name \"$columnName\" in table \"$tableName\"")
class DuplicateColumnException(columnName: String, tableName: String) : ExceptionInInitializerError(
"Duplicate column name \"$columnName\" in table \"$tableName\""
)

/**
* LongQueryException is thrown:
Expand All @@ -58,4 +67,7 @@ class DuplicateColumnException(columnName: String, tableName: String) : Exceptio
*/
class LongQueryException : RuntimeException("Long query was executed")

internal fun Transaction.throwUnsupportedException(message: String): Nothing = throw UnsupportedByDialectException(message, db.dialect)
internal fun Transaction.throwUnsupportedException(message: String): Nothing = throw UnsupportedByDialectException(
message,
db.dialect
)
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ThreadLocalTransactionManager(
}
return field
}

@Deprecated("Use DatabaseConfig to define the defaultIsolationLevel")
@TestOnly
set
Expand All @@ -51,6 +52,10 @@ class ThreadLocalTransactionManager(

val threadLocal = ThreadLocal<Transaction>()

override fun toString(): String {
return "ThreadLocalTransactionManager[${hashCode()}](db=$db)"
}

override fun newTransaction(isolation: Int, readOnly: Boolean, outerTransaction: Transaction?): Transaction {
val transaction = outerTransaction?.takeIf { !db.useNestedTransactions } ?: Transaction(
ThreadLocalTransaction(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.jetbrains.exposed.sql.vendors

/**
* Represents metadata information about a specific column.
*/
data class ColumnMetadata(
/** Name of the column. */
val name: String,
/**
* Type of the column.
*
* @see java.sql.Types
*/
val type: Int,
/** Whether the column if nullable or not. */
val nullable: Boolean,
/** Optional size of the column. */
val size: Int?,
/** Is the column auto increment */
val autoIncrement: Boolean,
/** Default value */
val defaultDbValue: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package org.jetbrains.exposed.sql.vendors

import org.jetbrains.exposed.exceptions.UnsupportedByDialectException
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.Function
import java.nio.ByteBuffer
import java.util.*

/**
* Provides definitions for all the supported SQL data types.
* By default, definitions from the SQL standard are provided but if a vendor doesn't support a specific type, or it is
* implemented differently, the corresponding function should be overridden.
*/
abstract class DataTypeProvider {
// Numeric types

/** Numeric type for storing 1-byte integers. */
open fun byteType(): String = "TINYINT"

/** Numeric type for storing 1-byte unsigned integers.
*
* **Note:** If the database being used is not MySQL, MariaDB, or SQL Server, this will represent the 2-byte
* integer type.
*/
open fun ubyteType(): String = "SMALLINT"

/** Numeric type for storing 2-byte integers. */
open fun shortType(): String = "SMALLINT"

/** Numeric type for storing 2-byte unsigned integers.
*
* **Note:** If the database being used is not MySQL or MariaDB, this will represent the 4-byte integer type.
*/
open fun ushortType(): String = "INT"

/** Numeric type for storing 4-byte integers. */
open fun integerType(): String = "INT"

/** Numeric type for storing 4-byte unsigned integers.
*
* **Note:** If the database being used is not MySQL or MariaDB, this will represent the 8-byte integer type.
*/
open fun uintegerType(): String = "BIGINT"

/** Numeric type for storing 4-byte integers, marked as auto-increment. */
open fun integerAutoincType(): String = "INT AUTO_INCREMENT"

/** Numeric type for storing 8-byte integers. */
open fun longType(): String = "BIGINT"

/** Numeric type for storing 8-byte unsigned integers. */
open fun ulongType(): String = "BIGINT"

/** Numeric type for storing 8-byte integers, and marked as auto-increment. */
open fun longAutoincType(): String = "BIGINT AUTO_INCREMENT"

/** Numeric type for storing 4-byte (single precision) floating-point numbers. */
open fun floatType(): String = "FLOAT"

/** Numeric type for storing 8-byte (double precision) floating-point numbers. */
open fun doubleType(): String = "DOUBLE PRECISION"

// Character types

/** Character type for storing strings of variable length up to a maximum. */
open fun varcharType(colLength: Int): String = "VARCHAR($colLength)"

/** Character type for storing strings of variable length.
* Some database (postgresql) use the same data type name to provide virtually _unlimited_ length. */
open fun textType(): String = "TEXT"

/** Character type for storing strings of _medium_ length. */
open fun mediumTextType(): String = "TEXT"

/** Character type for storing strings of variable and _large_ length. */
open fun largeTextType(): String = "TEXT"

// Binary data types

/** Binary type for storing binary strings of variable and _unlimited_ length. */
abstract fun binaryType(): String

/** Binary type for storing binary strings of a specific [length]. */
open fun binaryType(length: Int): String = if (length == Int.MAX_VALUE) "VARBINARY(MAX)" else "VARBINARY($length)"

/** Binary type for storing BLOBs. */
open fun blobType(): String = "BLOB"

/** Binary type for storing [UUID]. */
open fun uuidType(): String = "BINARY(16)"

@Suppress("MagicNumber")
open fun uuidToDB(value: UUID): Any =
ByteBuffer.allocate(16).putLong(value.mostSignificantBits).putLong(value.leastSignificantBits).array()

// Date/Time types

/** Data type for storing both date and time without a time zone. */
open fun dateTimeType(): String = "DATETIME"

/** Data type for storing both date and time with a time zone. */
open fun timestampWithTimeZoneType(): String = "TIMESTAMP WITH TIME ZONE"

/** Time type for storing time without a time zone. */
open fun timeType(): String = "TIME"

/** Data type for storing date without time or a time zone. */
open fun dateType(): String = "DATE"

// Boolean type

/** Data type for storing boolean values. */
open fun booleanType(): String = "BOOLEAN"

/** Returns the SQL representation of the specified [bool] value. */
open fun booleanToStatementString(bool: Boolean): String = bool.toString().uppercase()

/** Returns the boolean value of the specified SQL [value]. */
open fun booleanFromStringToBoolean(value: String): Boolean = value.toBoolean()

// JSON types

/** Data type for storing JSON in a non-binary text format. */
open fun jsonType(): String = "JSON"

/** Data type for storing JSON in a decomposed binary format. */
open fun jsonBType(): String =
throw UnsupportedByDialectException("This vendor does not support binary JSON data type", currentDialect)

// Misc.

/** Returns the SQL representation of the specified expression, for it to be used as a column default value. */
open fun processForDefaultValue(e: Expression<*>): String = when {
e is LiteralOp<*> && e.columnType is JsonColumnMarker -> if (currentDialect is H2Dialect) {
"$e".substringAfter("JSON ")
} else {
"'$e'"
}

e is LiteralOp<*> -> "$e"
e is Function<*> -> "$e"
currentDialect is MysqlDialect -> "$e"
currentDialect is SQLServerDialect -> "$e"
else -> "($e)"
}

open fun precessOrderByClause(queryBuilder: QueryBuilder, expression: Expression<*>, sortOrder: SortOrder) {
queryBuilder.append((expression as? ExpressionAlias<*>)?.alias ?: expression, " ", sortOrder.code)
}

/** Returns the hex-encoded value to be inserted into the database. */
abstract fun hexToDb(hexString: String): String
}
Loading

0 comments on commit 6792bd3

Please sign in to comment.