Created
May 7, 2020 10:52
-
-
Save Tapac/a5dfa1f37b4a584898dae3e123b88500 to your computer and use it in GitHub Desktop.
Exposed PR #857 patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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