Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions documentation-website/Writerside/topics/Breaking-Changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Breaking Changes

## 1.0.0-beta-5

* Migration of kotlinx-datetime from version 6 to version 7. The only package affected is `exposed-kotlin-datetime`. `KotlinInstantColumnType`, and
`Table.timestamp(name: String)` are parametrized with `kotlin.time.Instant` class now. If you need to use `kotlinx.datetime.Instant` with Exposed, you have to
replace usages of `KotlinInstantColumnType` and `Table.timestamp(name: String)` with `XKotlinInstantColumnType` and `Table.xTimestamp(name: String)` respectively.

## 1.0.0-beta-4

* `ThreadLocalMap` has been restricted to internal use, based on its current limited usage in already internal classes.
Expand Down
51 changes: 47 additions & 4 deletions exposed-kotlin-datetime/api/exposed-kotlin-datetime.api
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public final class org/jetbrains/exposed/v1/datetime/KotlinDateColumnTypeKt {
public static final fun time (Lorg/jetbrains/exposed/v1/core/Table;Ljava/lang/String;)Lorg/jetbrains/exposed/v1/core/Column;
public static final fun timestamp (Lorg/jetbrains/exposed/v1/core/Table;Ljava/lang/String;)Lorg/jetbrains/exposed/v1/core/Column;
public static final fun timestampWithTimeZone (Lorg/jetbrains/exposed/v1/core/Table;Ljava/lang/String;)Lorg/jetbrains/exposed/v1/core/Column;
public static final fun xTimestamp (Lorg/jetbrains/exposed/v1/core/Table;Ljava/lang/String;)Lorg/jetbrains/exposed/v1/core/Column;
}

public final class org/jetbrains/exposed/v1/datetime/KotlinDateFunctionsKt {
Expand Down Expand Up @@ -100,6 +101,23 @@ public final class org/jetbrains/exposed/v1/datetime/KotlinDateFunctionsKt {
public static final fun OffsetDateTimeTimeFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun OffsetDateTimeYearExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun OffsetDateTimeYearFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XCustomTimeStampFunction (Ljava/lang/String;[Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/CustomFunction;
public static final fun XInstantDateExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantDateFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantDayExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantDayFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantHourExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantHourFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantMinuteExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantMinuteFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantMonthExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantMonthFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantSecondExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantSecondFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantTimeExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantTimeFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantYearExt (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun XInstantYearFunction (Lorg/jetbrains/exposed/v1/core/Expression;)Lorg/jetbrains/exposed/v1/core/Function;
public static final fun dateLiteral (Lkotlinx/datetime/LocalDate;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
public static final fun dateParam (Lkotlinx/datetime/LocalDate;)Lorg/jetbrains/exposed/v1/core/Expression;
public static final fun dateTimeLiteral (Lkotlinx/datetime/LocalDateTime;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
Expand All @@ -108,7 +126,9 @@ public final class org/jetbrains/exposed/v1/datetime/KotlinDateFunctionsKt {
public static final fun durationParam-LRDsOJo (J)Lorg/jetbrains/exposed/v1/core/Expression;
public static final fun timeLiteral (Lkotlinx/datetime/LocalTime;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
public static final fun timeParam (Lkotlinx/datetime/LocalTime;)Lorg/jetbrains/exposed/v1/core/Expression;
public static final fun timestampLiteral (Lkotlin/time/Instant;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
public static final fun timestampLiteral (Lkotlinx/datetime/Instant;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
public static final fun timestampParam (Lkotlin/time/Instant;)Lorg/jetbrains/exposed/v1/core/Expression;
public static final fun timestampParam (Lkotlinx/datetime/Instant;)Lorg/jetbrains/exposed/v1/core/Expression;
public static final fun timestampWithTimeZoneLiteral (Ljava/time/OffsetDateTime;)Lorg/jetbrains/exposed/v1/core/LiteralOp;
public static final fun timestampWithTimeZoneParam (Ljava/time/OffsetDateTime;)Lorg/jetbrains/exposed/v1/core/Expression;
Expand All @@ -134,15 +154,15 @@ public final class org/jetbrains/exposed/v1/datetime/KotlinInstantColumnType : o
public fun <init> ()V
public fun getHasTimePart ()Z
public synthetic fun nonNullValueAsDefaultString (Ljava/lang/Object;)Ljava/lang/String;
public fun nonNullValueAsDefaultString (Lkotlinx/datetime/Instant;)Ljava/lang/String;
public fun nonNullValueAsDefaultString (Lkotlin/time/Instant;)Ljava/lang/String;
public synthetic fun nonNullValueToString (Ljava/lang/Object;)Ljava/lang/String;
public fun nonNullValueToString (Lkotlinx/datetime/Instant;)Ljava/lang/String;
public fun nonNullValueToString (Lkotlin/time/Instant;)Ljava/lang/String;
public synthetic fun notNullValueToDB (Ljava/lang/Object;)Ljava/lang/Object;
public fun notNullValueToDB (Lkotlinx/datetime/Instant;)Ljava/lang/Object;
public fun notNullValueToDB (Lkotlin/time/Instant;)Ljava/lang/Object;
public fun readObject (Lorg/jetbrains/exposed/v1/core/statements/api/RowApi;I)Ljava/lang/Object;
public fun sqlType ()Ljava/lang/String;
public synthetic fun valueFromDB (Ljava/lang/Object;)Ljava/lang/Object;
public fun valueFromDB (Ljava/lang/Object;)Lkotlinx/datetime/Instant;
public fun valueFromDB (Ljava/lang/Object;)Lkotlin/time/Instant;
}

public final class org/jetbrains/exposed/v1/datetime/KotlinInstantColumnType$Companion {
Expand Down Expand Up @@ -224,6 +244,29 @@ public final class org/jetbrains/exposed/v1/datetime/KotlinOffsetDateTimeColumnT
public final class org/jetbrains/exposed/v1/datetime/KotlinOffsetDateTimeColumnType$Companion {
}

public final class org/jetbrains/exposed/v1/datetime/XCurrentTimestamp : org/jetbrains/exposed/v1/datetime/CurrentTimestampBase {
public static final field INSTANCE Lorg/jetbrains/exposed/v1/datetime/XCurrentTimestamp;
}

public final class org/jetbrains/exposed/v1/datetime/XKotlinInstantColumnType : org/jetbrains/exposed/v1/core/ColumnType, org/jetbrains/exposed/v1/core/IDateColumnType {
public static final field Companion Lorg/jetbrains/exposed/v1/datetime/XKotlinInstantColumnType$Companion;
public fun <init> ()V
public fun getHasTimePart ()Z
public synthetic fun nonNullValueAsDefaultString (Ljava/lang/Object;)Ljava/lang/String;
public fun nonNullValueAsDefaultString (Lkotlinx/datetime/Instant;)Ljava/lang/String;
public synthetic fun nonNullValueToString (Ljava/lang/Object;)Ljava/lang/String;
public fun nonNullValueToString (Lkotlinx/datetime/Instant;)Ljava/lang/String;
public synthetic fun notNullValueToDB (Ljava/lang/Object;)Ljava/lang/Object;
public fun notNullValueToDB (Lkotlinx/datetime/Instant;)Ljava/lang/Object;
public fun readObject (Lorg/jetbrains/exposed/v1/core/statements/api/RowApi;I)Ljava/lang/Object;
public fun sqlType ()Ljava/lang/String;
public synthetic fun valueFromDB (Ljava/lang/Object;)Ljava/lang/Object;
public fun valueFromDB (Ljava/lang/Object;)Lkotlinx/datetime/Instant;
}

public final class org/jetbrains/exposed/v1/datetime/XKotlinInstantColumnType$Companion {
}

public final class org/jetbrains/exposed/v1/datetime/YearInternal : org/jetbrains/exposed/v1/core/Function {
public fun <init> (Lorg/jetbrains/exposed/v1/core/Expression;)V
public final fun getExpr ()Lorg/jetbrains/exposed/v1/core/Expression;
Expand Down
4 changes: 4 additions & 0 deletions exposed-kotlin-datetime/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ repositories {

kotlin {
jvmToolchain(8)

compilerOptions {
optIn.add("kotlin.time.ExperimentalTime")
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import java.time.temporal.ChronoField
import java.util.*
import kotlin.time.Duration
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.Instant
import kotlin.time.toJavaInstant
import kotlin.time.toKotlinInstant
import kotlinx.datetime.Instant as xInstant

private const val MILLIS_IN_SECOND = 1000

Expand Down Expand Up @@ -393,10 +397,84 @@ class KotlinLocalTimeColumnType : ColumnType<LocalTime>(), IDateColumnType {
}

/**
* Column for storing dates and times without time zone, as [Instant].
* Column for storing dates and times without time zone, as [kotlinx.datetime.Instant].
*
* @sample timestamp
*/
class XKotlinInstantColumnType : ColumnType<xInstant>(), IDateColumnType {
override val hasTimePart: Boolean = true

override fun sqlType(): String = currentDialect.dataTypeProvider.timestampType()

override fun nonNullValueToString(value: xInstant): String {
val instant = value.toStdlibInstant().toJavaInstant()

return when (val dialect = currentDialect) {
is MysqlDialect -> {
val formatter = if (dialect.isFractionDateTimeSupported()) MYSQL_FRACTION_TIMESTAMP_STRING_FORMATTER else MYSQL_TIMESTAMP_STRING_FORMATTER
"'${formatter.format(instant)}'"
}

is SQLiteDialect ->
"'${SQLITE_AND_ORACLE_TIMESTAMP_STRING_FORMATTER.format(instant)}'"

is OracleDialect -> oracleTimestampLiteral(value.toStdlibInstant())

else -> "'${DEFAULT_TIMESTAMP_STRING_FORMATTER.format(instant)}'"
}
}

override fun valueFromDB(value: Any): xInstant = when (value) {
is java.sql.Timestamp -> value.toInstant().toKotlinInstant().toDeprecatedInstant()
is String -> xInstant.parse(value)
is java.time.LocalDateTime -> value.atZone(ZoneId.systemDefault()).toInstant().toKotlinInstant().toDeprecatedInstant()
else -> valueFromDB(value.toString())
}

override fun readObject(rs: RowApi, index: Int): Any? {
return rs.getObject(index, java.sql.Timestamp::class.java, this)
}

@Suppress("MagicNumber")
override fun notNullValueToDB(value: xInstant): Any {
val dialect = currentDialect
@OptIn(InternalApi::class)
return when {
dialect is SQLiteDialect ->
SQLITE_AND_ORACLE_TIMESTAMP_STRING_FORMATTER.format(value.toStdlibInstant().toJavaInstant())
dialect is MysqlDialect && dialect !is MariaDBDialect && !CoreTransactionManager.currentTransaction().db.version.covers(8, 0) -> {
val formatter = if (dialect.isFractionDateTimeSupported()) MYSQL_FRACTION_TIMESTAMP_STRING_FORMATTER else MYSQL_TIMESTAMP_STRING_FORMATTER
formatter.format(value.toStdlibInstant().toJavaInstant())
}
else -> java.sql.Timestamp.from(value.toStdlibInstant().toJavaInstant())
}
}

override fun nonNullValueAsDefaultString(value: xInstant): String {
val dialect = currentDialect
return when {
dialect is PostgreSQLDialect ->
"'${
SQLITE_AND_ORACLE_TIMESTAMP_STRING_FORMATTER.format(value.toStdlibInstant().toJavaInstant()).trimEnd('0').trimEnd('.')
}'::timestamp without time zone"

dialect.h2Mode == H2Dialect.H2CompatibilityMode.Oracle ->
"'${SQLITE_AND_ORACLE_TIMESTAMP_STRING_FORMATTER.format(value.toStdlibInstant().toJavaInstant()).trimEnd('0').trimEnd('.')}'"

else -> super.nonNullValueAsDefaultString(value)
}
}

companion object {
internal val INSTANCE = XKotlinInstantColumnType()
}
}

/**
* Column for storing dates and times without time zone, as [kotlin.time.Instant].
*
* @sample Timestamp
*/
class KotlinInstantColumnType : ColumnType<Instant>(), IDateColumnType {
override val hasTimePart: Boolean = true

Expand Down Expand Up @@ -583,6 +661,17 @@ fun Table.datetime(name: String): Column<LocalDateTime> = registerColumn(name, K
*/
fun Table.time(name: String): Column<LocalTime> = registerColumn(name, KotlinLocalTimeColumnType())

/**
* A timestamp column to store both a date and a time without time zone.
*
* @param name The column name
*/
@Deprecated(
"Deprecated due to usage of old kotlinx.datetime.Instant",
replaceWith = ReplaceWith("timestamp")
)
fun Table.xTimestamp(name: String): Column<xInstant> = registerColumn(name, XKotlinInstantColumnType())

/**
* A timestamp column to store both a date and a time without time zone.
*
Expand Down
Loading
Loading