Skip to content

Commit 2b5c262

Browse files
conflict fixed
2 parents 1709356 + 47ef102 commit 2b5c262

File tree

14 files changed

+240
-223
lines changed

14 files changed

+240
-223
lines changed

ktorm-core/src/main/kotlin/me/liuwj/ktorm/entity/EntityDml.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ private fun EntityImplementation.findChangedColumns(fromTable: Table<*>): Map<Co
111111
var anyChanged = false
112112
var curr: Any? = this
113113

114-
for ((i, prop) in binding.withIndex()) {
114+
for ((i, prop) in binding.properties.withIndex()) {
115+
if (curr is Entity<*>) {
116+
curr = curr.implementation
117+
}
118+
115119
check(curr is EntityImplementation?)
116120

117121
val changed = if (curr == null) false else prop.name in curr.changedProperties
@@ -121,17 +125,13 @@ private fun EntityImplementation.findChangedColumns(fromTable: Table<*>): Map<Co
121125
check(curr != null)
122126

123127
if (curr.fromTable != null && curr.getRoot() != this) {
124-
val propPath = binding.subList(0, i + 1).joinToString(separator = ".", prefix = "this.") { it.name }
128+
val propPath = binding.properties.subList(0, i + 1).joinToString(separator = ".", prefix = "this.") { it.name }
125129
throw IllegalStateException("$propPath may be unexpectedly discarded after flushChanges, please save it to database first.")
126130
}
127131
}
128132

129133
anyChanged = anyChanged || changed
130-
131134
curr = curr?.getProperty(prop.name)
132-
if (curr is Entity<*>) {
133-
curr = curr.implementation
134-
}
135135
}
136136

137137
if (anyChanged) {
@@ -166,18 +166,17 @@ internal fun EntityImplementation.doDiscardChanges() {
166166
is NestedBinding -> {
167167
var curr: Any? = this
168168

169-
for (prop in binding) {
169+
for (prop in binding.properties) {
170170
if (curr == null) {
171171
break
172172
}
173+
if (curr is Entity<*>) {
174+
curr = curr.implementation
175+
}
173176

174177
check(curr is EntityImplementation)
175178
curr.changedProperties.remove(prop.name)
176-
177179
curr = curr.getProperty(prop.name)
178-
if (curr is Entity<*>) {
179-
curr = curr.implementation
180-
}
181180
}
182181
}
183182
}

ktorm-core/src/main/kotlin/me/liuwj/ktorm/entity/EntityExtensions.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ internal fun EntityImplementation.getColumnValue(column: Column<*>): Any? {
1919
}
2020
is NestedBinding -> {
2121
var curr: EntityImplementation? = this
22-
for ((i, prop) in binding.withIndex()) {
23-
if (i != binding.lastIndex) {
22+
for ((i, prop) in binding.properties.withIndex()) {
23+
if (i != binding.properties.lastIndex) {
2424
val child = curr?.getProperty(prop.name) as Entity<*>?
2525
curr = child?.implementation
2626
}
2727
}
28-
return curr?.getProperty(binding.last().name)
28+
return curr?.getProperty(binding.properties.last().name)
2929
}
3030
}
3131
}
@@ -50,19 +50,19 @@ internal fun EntityImplementation.setColumnValue(column: Column<*>, value: Any?,
5050
}
5151
is NestedBinding -> {
5252
var curr: EntityImplementation = this
53-
for ((i, prop) in binding.withIndex()) {
54-
if (i != binding.lastIndex) {
53+
for ((i, prop) in binding.properties.withIndex()) {
54+
if (i != binding.properties.lastIndex) {
5555
var child = curr.getProperty(prop.name) as Entity<*>?
5656
if (child == null) {
57-
child = Entity.create(prop.returnType.classifier as KClass<*>, parent = curr, fromTable = column.table)
57+
child = Entity.create(prop.returnType.classifier as KClass<*>, parent = curr)
5858
curr.setProperty(prop.name, child, forceSet)
5959
}
6060

6161
curr = child.implementation
6262
}
6363
}
6464

65-
curr.setProperty(binding.last().name, value, forceSet)
65+
curr.setProperty(binding.properties.last().name, value, forceSet)
6666
}
6767
}
6868
}
@@ -93,7 +93,7 @@ internal fun EntityImplementation.isPrimaryKey(name: String): Boolean {
9393
}
9494

9595
for ((i, possibleFields) in namesPath.withIndex()) {
96-
if (binding[i].name !in possibleFields) {
96+
if (binding.properties[i].name !in possibleFields) {
9797
return false
9898
}
9999
}

ktorm-core/src/main/kotlin/me/liuwj/ktorm/entity/EntityFinding.kt

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package me.liuwj.ktorm.entity
22

33
import me.liuwj.ktorm.dsl.*
4-
import me.liuwj.ktorm.expression.*
4+
import me.liuwj.ktorm.expression.BinaryExpression
5+
import me.liuwj.ktorm.expression.BinaryExpressionType
6+
import me.liuwj.ktorm.expression.QuerySourceExpression
57
import me.liuwj.ktorm.schema.*
68
import kotlin.reflect.KClass
79

@@ -162,20 +164,7 @@ private fun QueryRowSet.retrieveColumn(column: Column<*>, intoEntity: Entity<*>,
162164
}
163165
}
164166
is NestedBinding -> {
165-
var curr = intoEntity.implementation
166-
for ((i, prop) in binding.withIndex()) {
167-
if (i != binding.lastIndex) {
168-
var child = curr.getProperty(prop.name) as Entity<*>?
169-
if (child == null) {
170-
child = Entity.create(prop.returnType.classifier as KClass<*>, parent = curr)
171-
curr.setProperty(prop.name, child)
172-
}
173-
174-
curr = child.implementation
175-
}
176-
}
177-
178-
curr.setProperty(binding.last().name, columnValue)
167+
intoEntity.implementation.setColumnValue(column, columnValue)
179168
}
180169
}
181170
}

ktorm-core/src/main/kotlin/me/liuwj/ktorm/entity/EntityImplementation.kt

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package me.liuwj.ktorm.entity
22

33
import me.liuwj.ktorm.schema.Table
4-
import org.slf4j.LoggerFactory
4+
import me.liuwj.ktorm.schema.defaultValue
5+
import me.liuwj.ktorm.schema.kotlinProperty
56
import java.io.ObjectInputStream
67
import java.io.ObjectOutputStream
78
import java.io.Serializable
@@ -12,13 +13,6 @@ import java.util.*
1213
import kotlin.collections.LinkedHashMap
1314
import kotlin.collections.LinkedHashSet
1415
import kotlin.reflect.KClass
15-
import kotlin.reflect.KMutableProperty
16-
import kotlin.reflect.KProperty
17-
import kotlin.reflect.full.createInstance
18-
import kotlin.reflect.full.isSubclassOf
19-
import kotlin.reflect.full.memberProperties
20-
import kotlin.reflect.jvm.javaGetter
21-
import kotlin.reflect.jvm.javaSetter
2216
import kotlin.reflect.jvm.jvmName
2317
import kotlin.reflect.jvm.kotlinFunction
2418

@@ -36,7 +30,6 @@ internal class EntityImplementation(
3630

3731
companion object {
3832
private const val serialVersionUID = 1L
39-
private val logger = LoggerFactory.getLogger(EntityImplementation::class.java)
4033
private val defaultImplsCache: MutableMap<Method, Method> = Collections.synchronizedMap(WeakHashMap())
4134
}
4235

@@ -117,68 +110,10 @@ internal class EntityImplementation(
117110
throw e.targetException
118111

119112
} catch (e: Throwable) {
120-
logger.error("proxy: ${proxy.javaClass}: $proxy")
121-
logger.error("method: $method")
122-
logger.error("args: ${args?.contentToString()}")
123-
logger.error("arg types: ${args?.map { it.javaClass }}")
124-
logger.error("implementation: $impl")
125-
logger.error("cache: $defaultImplsCache")
126113
throw e
127114
}
128115
}
129116

130-
private val Method.kotlinProperty: Pair<KProperty<*>, Boolean>? get() {
131-
for (prop in entityClass.memberProperties) {
132-
if (prop.javaGetter == this) {
133-
return prop to true
134-
}
135-
if (prop is KMutableProperty<*> && prop.javaSetter == this) {
136-
return prop to false
137-
}
138-
}
139-
return null
140-
}
141-
142-
private val KClass<*>.defaultValue: Any get() {
143-
val value: Any = try {
144-
when {
145-
this == Boolean::class -> false
146-
this == Char::class -> 0.toChar()
147-
this == Byte::class -> 0.toByte()
148-
this == Short::class -> 0.toShort()
149-
this == Int::class -> 0
150-
this == Long::class -> 0L
151-
this == Float::class -> 0.0F
152-
this == Double::class -> 0.0
153-
this == String::class -> ""
154-
this.isSubclassOf(Entity::class) -> Entity.create(this)
155-
this.java.isEnum -> this.java.enumConstants[0]
156-
this.java.isArray -> this.java.componentType.createArray(0)
157-
this == Set::class || this == MutableSet::class -> LinkedHashSet<Any?>()
158-
this == List::class || this == MutableList::class -> ArrayList<Any?>()
159-
this == Collection::class || this == MutableCollection::class -> ArrayList<Any?>()
160-
this == Map::class || this == MutableMap::class -> LinkedHashMap<Any?, Any?>()
161-
this == Queue::class || this == Deque::class -> LinkedList<Any?>()
162-
this == SortedSet::class || this == NavigableSet::class -> TreeSet<Any?>()
163-
this == SortedMap::class || this == NavigableMap::class -> TreeMap<Any?, Any?>()
164-
else -> this.createInstance()
165-
}
166-
} catch (e: Throwable) {
167-
throw IllegalArgumentException("Error creating a default value for non-null type: ${this.jvmName}", e)
168-
}
169-
170-
if (this.isInstance(value)) {
171-
return value
172-
} else {
173-
// never happens...
174-
throw AssertionError("$value must be instance of $this")
175-
}
176-
}
177-
178-
private fun Class<*>.createArray(length: Int): Any {
179-
return java.lang.reflect.Array.newInstance(this, length)
180-
}
181-
182117
fun getProperty(name: String): Any? {
183118
return values[name]
184119
}

ktorm-core/src/main/kotlin/me/liuwj/ktorm/schema/Column.kt

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,7 @@ sealed class ColumnBinding
1515
/**
1616
* Bind the column to nested properties, eg. employee.manager.department.id
1717
*/
18-
sealed class NestedBinding(vararg properties: KProperty1<*, *>) : ColumnBinding(), List<KProperty1<*, *>> by properties.asList()
19-
20-
/**
21-
* Bind the column to a simple property.
22-
*/
23-
data class NestedBinding1(
24-
val property: KProperty1<*, *>
25-
) : NestedBinding(property)
26-
27-
/**
28-
* Bind the column to double nested properties.
29-
*/
30-
data class NestedBinding2(
31-
val property1: KProperty1<*, *>,
32-
val property2: KProperty1<*, *>
33-
) : NestedBinding(property1, property2)
34-
35-
/**
36-
* Bind the column to triple nested properties
37-
*/
38-
data class NestedBinding3(
39-
val property1: KProperty1<*, *>,
40-
val property2: KProperty1<*, *>,
41-
val property3: KProperty1<*, *>
42-
) : NestedBinding(property1, property2, property3)
43-
44-
/**
45-
* Bind the column to 4 levels of nested properties
46-
*/
47-
data class NestedBinding4(
48-
val property1: KProperty1<*, *>,
49-
val property2: KProperty1<*, *>,
50-
val property3: KProperty1<*, *>,
51-
val property4: KProperty1<*, *>
52-
) : NestedBinding(property1, property2, property3, property4)
18+
data class NestedBinding(val properties: List<KProperty1<*, *>>) : ColumnBinding()
5319

5420
/**
5521
* Bind the column to a reference table, equivalent to a foreign key in relational databases.
@@ -58,10 +24,7 @@ data class NestedBinding4(
5824
* @see me.liuwj.ktorm.entity.joinReferencesAndSelect
5925
* @see me.liuwj.ktorm.entity.createEntity
6026
*/
61-
data class ReferenceBinding(
62-
val referenceTable: Table<*>,
63-
val onProperty: KProperty1<*, *>
64-
) : ColumnBinding()
27+
data class ReferenceBinding(val referenceTable: Table<*>, val onProperty: KProperty1<*, *>) : ColumnBinding()
6528

6629
/**
6730
* 列声明
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package me.liuwj.ktorm.schema
2+
3+
import me.liuwj.ktorm.entity.Entity
4+
import java.lang.reflect.InvocationHandler
5+
import java.lang.reflect.Method
6+
import java.lang.reflect.Proxy
7+
import kotlin.reflect.KClass
8+
import kotlin.reflect.KProperty1
9+
import kotlin.reflect.full.isSubclassOf
10+
11+
/* internal */
12+
class ColumnBindingHandler(val properties: MutableList<KProperty1<*, *>>) : InvocationHandler {
13+
14+
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any? {
15+
when (method.declaringClass.kotlin) {
16+
Any::class, Entity::class -> {
17+
throw UnsupportedOperationException("Unsupported method: $method")
18+
}
19+
else -> {
20+
val (prop, isGetter) = method.kotlinProperty ?: throw UnsupportedOperationException("Unsupported method: $method")
21+
if (!prop.isAbstract) {
22+
throw UnsupportedOperationException("Cannot bind a column to a non-abstract property: $prop")
23+
}
24+
if (!isGetter) {
25+
throw UnsupportedOperationException("Cannot modify a property while we are binding a column to it, property: $prop")
26+
}
27+
28+
properties += prop
29+
30+
val returnType = prop.returnType.classifier as KClass<*>
31+
return when {
32+
returnType.isSubclassOf(Entity::class) -> createProxy(returnType, properties)
33+
returnType.java.isPrimitive -> returnType.defaultValue
34+
else -> null
35+
}
36+
}
37+
}
38+
}
39+
40+
companion object {
41+
42+
fun createProxy(entityClass: KClass<*>, properties: MutableList<KProperty1<*, *>>): Entity<*> {
43+
val classLoader = Thread.currentThread().contextClassLoader
44+
val handler = ColumnBindingHandler(properties)
45+
return Proxy.newProxyInstance(classLoader, arrayOf(entityClass.java), handler) as Entity<*>
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)