Skip to content

Instantly share code, notes, and snippets.

@Tapac
Created May 7, 2020 10:52
Show Gist options
  • Save Tapac/a5dfa1f37b4a584898dae3e123b88500 to your computer and use it in GitHub Desktop.
Save Tapac/a5dfa1f37b4a584898dae3e123b88500 to your computer and use it in GitHub Desktop.
Exposed PR #857 patch
Index: exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ResultRow.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ResultRow.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/ResultRow.kt (date 1588795290614)
@@ -26,7 +26,7 @@
}
operator fun <T> set(c: Expression<out T>, value: T) {
- if (c is CompositeColumn) {
+ if (c is CompositeColumn<*>) {
(c as CompositeColumn<Any>).getRealColumnsWithVales(value as Any).forEach { (column, itsValue) -> set(column, itsValue) }
} else {
val index = fieldIndex[c] ?: error("$c is not in record set")
@@ -55,7 +55,7 @@
@Suppress("UNCHECKED_CAST")
private fun <T> getRaw(c: Expression<T>): T? {
if (c is CompositeColumn<T>) {
- val rawParts = c.getRealColumns().map { getRaw(it) }
+ val rawParts = c.getRealColumns().associateWith { getRaw(it) }
return c.restoreValueFromParts(rawParts)
}
Index: exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt (date 1588785711078)
@@ -352,7 +352,7 @@
/** Adds a column of the specified [type] and with the specified [name] to the table. */
fun <T> registerColumn(name: String, type: IColumnType): Column<T> = Column<T>(this, name, type).also { _columns.addColumn(it) }
- fun <T : CompositeColumn<*>> registerColumn(type: CompositeColumnType<T>, vararg names: String): T = type.buildCompositeColumn(*names)
+ fun <T : CompositeColumn<*>> registerCompositeColumn(column: T) : T = column.apply { getRealColumns().forEach { _columns.addColumn(it) } }
/**
* Replaces the specified [oldColumn] with the specified [newColumn] in the table.
Index: exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt (date 1588794937564)
@@ -79,8 +79,14 @@
val refValue = value?.run { reference.referee<REF>()!!.getValue(this, desc) }
reference.setValue(o, desc, refValue)
}
+
operator fun <T> Column<T>.getValue(o: Entity<ID>, desc: KProperty<*>): T = lookup()
+ operator fun <T> CompositeColumn<T>.getValue(o: Entity<ID>, desc: KProperty<*>): T {
+ val values = this.getRealColumns().associateWith { it.lookup() }
+ return this.restoreValueFromParts(values)
+ }
+
@Suppress("UNCHECKED_CAST")
fun <T, R:Any> Column<T>.lookupInReadValues(found: (T?) -> R?, notFound: () -> R?): R? =
if (_readValues?.hasValue(this) == true)
Index: exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumn.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumn.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumn.kt (date 1588795290603)
@@ -6,14 +6,14 @@
* @author Vladislav Kisel
*/
// TODO to be discussed - extending Column class
-abstract class CompositeColumn<T>(table: Table, name: String, columnType: IColumnType) : Column<T>(table, name, columnType) {
+abstract class CompositeColumn<T> : Expression<T>() {
/**
* Parse values from [compositeValue] and return list of real columns with its values
*
* @return key - real column, value - its parsed value
*/
- abstract fun getRealColumnsWithVales(compositeValue : T) : Map<Column<Any?>, Any?>
+ abstract fun getRealColumnsWithVales(compositeValue : T) : Map<Column<*>, Any?>
/**
* Return list of real columns, wrapped by this composite column
@@ -23,6 +23,31 @@
/**
* Restore the composite value from its parts loaded from the DB
*/
- abstract fun restoreValueFromParts(parts : List<Any?>) : T
+ abstract fun restoreValueFromParts(parts : Map<Column<*>, Any?>) : T
+
+ override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder {
+ getRealColumns().appendTo { +it }
+ }
}
+
+
+abstract class BiCompositeColumn<C1, C2, T>(
+ val column1: Column<C1>,
+ val column2: Column<C2>,
+ val transformFromValue : (T) -> Pair<C1, C2>,
+ val transformToValue: (C1, C2) -> T
+) : CompositeColumn<T>() {
+ override fun getRealColumns(): List<Column<*>> = listOf(column1, column2)
+ override fun getRealColumnsWithVales(compositeValue: T): Map<Column<*>, Any?> {
+ val (v1, v2) = transformFromValue(compositeValue)
+ return mapOf(column1 to v1, column2 to v2)
+ }
+
+ override fun restoreValueFromParts(parts: Map<Column<*>, Any?>): T {
+ val v1 = parts[column1] as C1
+ val v2 = parts[column2] as C2
+ return transformToValue(v1, v2)
+ }
+}
+
Index: exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumnType.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumnType.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/CompositeColumnType.kt (date 1588785711065)
@@ -5,7 +5,7 @@
*
* @author Vladislav Kisel
*/
-abstract class CompositeColumnType<T : CompositeColumn<*>> : ColumnType() {
+abstract class CompositeColumnType<T> : ColumnType() {
/**
* Build an instance of [CompositeColumn]
Index: exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumnType.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumnType.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumnType.kt (date 1588786078769)
@@ -1,33 +1,18 @@
package org.jetbrains.exposed.sql.money
+import org.jetbrains.exposed.sql.Column
import org.jetbrains.exposed.sql.CompositeColumnType
import org.jetbrains.exposed.sql.Table
-
-/**
- * Represents amount of money and currency using Java Money API. Data are stored using two composite columns.
- *
- * @author Vladislav Kisel
- */
-class CompositeMoneyColumnType(
- /** Total count of digits in the whole number and its fractional part. */
- val precision: Int,
- val scale: Int,
- private val table: Table
-) : CompositeColumnType<CompositeMoneyColumn>() {
-
- override fun buildCompositeColumn(vararg names: String): CompositeMoneyColumn {
- check(names.size == 2) {
- "CompositeMoneyColumnType requires two column names!"
- }
-
- return CompositeMoneyColumn(this, names[0], names[1], table)
- }
-
- override fun sqlType(): String {
- TODO("Not yet implemented")
- }
-
-}
+import java.math.BigDecimal
fun Table.compositeMoney(precision: Int, scale: Int, amountName: String, currencyName: String = amountName + "_C"): CompositeMoneyColumn =
- registerColumn(CompositeMoneyColumnType(precision, scale, this), amountName, currencyName)
+ registerCompositeColumn(CompositeMoneyColumn(this, precision, scale, amountName, currencyName))
+
+
+fun Table.compositeMoney(amountColumn: Column<BigDecimal>, currencyColumn: Column<String>): CompositeMoneyColumn {
+ return CompositeMoneyColumn(amountColumn, currencyColumn).also {
+ if (amountColumn !in columns && currencyColumn !in columns) {
+ registerCompositeColumn(it)
+ }
+ }
+}
\ No newline at end of file
Index: exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumn.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumn.kt (revision 102977f24751ad482b317db90da026d7a9e17fb8)
+++ exposed-money/src/main/kotlin/org/jetbrains/exposed/sql/money/CompositeMoneyColumn.kt (date 1588795290609)
@@ -1,81 +1,32 @@
package org.jetbrains.exposed.sql.money
-import org.jetbrains.exposed.dao.Entity
-import org.jetbrains.exposed.sql.Column
-import org.jetbrains.exposed.sql.CompositeColumn
-import org.jetbrains.exposed.sql.Table
+import org.jetbrains.exposed.sql.*
import java.math.BigDecimal
import javax.money.Monetary
import javax.money.MonetaryAmount
-import kotlin.reflect.KProperty
/**
* Represents amount of money and currency using Java Money API. Data are stored using two composite columns.
*
* @author Vladislav Kisel
*/
-class CompositeMoneyColumn(
- type: CompositeMoneyColumnType,
- amountName: String,
- currencyName: String,
- table: Table) : CompositeColumn<MonetaryAmount>(table, amountName, type) {
-
- val currency = getValueFromTable {
- table.currency(currencyName).nullable()
- }
-
- val amount = getValueFromTable {
- table.moneyAmount(amountName, type.precision, type.scale).nullable()
- }
-
- init {
- check(amountName != currencyName) {
- "Amount and currency column names must be different!"
- }
- }
-
- override fun getRealColumnsWithVales(compositeValue: MonetaryAmount): Map<Column<Any?>, Any?> {
- val currencyValue = compositeValue.currency as Any?
- val amountValue = compositeValue.number.numberValue(BigDecimal::class.java) as Any?
-
- return mapOf(
- (amount as Column<Any?>) to amountValue,
- (currency as Column<Any?>) to currencyValue
- )
- }
-
- override fun restoreValueFromParts(parts: List<Any?>): MonetaryAmount {
- // TODO validation
- return Monetary.getDefaultAmountFactory()
- .setNumber(parts[0] as Number)
- .setCurrency(parts[1] as String)
- .create()
- }
-
- override fun getRealColumns(): List<Column<*>> = listOf(amount, currency)
- operator fun getValue(thisRef: Any?, property: KProperty<*>): MonetaryAmount {
- val currency = getValueFromEntity(thisRef as Entity<*>) {
- currency.lookup()
- }
- val amount = getValueFromEntity(thisRef) {
- amount.lookup()
- }
-
- return Monetary.getDefaultAmountFactory()
- .setNumber(amount)
- .setCurrency(currency)
- .create()
+class CompositeMoneyColumn(amountColumn: Column<BigDecimal>, currencyColumn: Column<String>) : BiCompositeColumn<BigDecimal, String, MonetaryAmount>(
+ amountColumn, currencyColumn,
+ transformFromValue = { money ->
+ val currencyValue = money.currency
+ val amountValue = money.number.numberValue(BigDecimal::class.java)
+ amountValue to currencyValue.currencyCode
+ },
+ transformToValue = { amount, currency ->
+ Monetary.getDefaultAmountFactory()
+ .setNumber(amount as Number)
+ .setCurrency(currency)
+ .create()
}
-
- operator fun setValue(thisRef: Any?, property: KProperty<*>, value: MonetaryAmount) {
- TODO("NOT IMPL")
- }
-
- // TODO
- private fun <T> getValueFromEntity(entity: Entity<*>, receiver: Entity<*>.() -> T): T = entity.receiver()
-
- // TODO
- private fun <T> getValueFromTable(receiver: Table.() -> T): T = table.receiver()
-
+) {
+ constructor(table: Table, precision: Int, scale: Int, amountName: String, currencyName: String) : this(
+ amountColumn = Column(table, amountName, DecimalColumnType(precision, scale)),
+ currencyColumn = Column(table, currencyName, VarCharColumnType(3))
+ )
}
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment