Skip to content

Commit

Permalink
relation synchronization
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsamson7 committed Sep 23, 2024
1 parent 5a7768c commit 25193ba
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 42 deletions.
61 changes: 39 additions & 22 deletions src/main/kotlin/org/sirius/dorm/object/MultiValuedRelation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,19 @@ import org.sirius.dorm.model.ObjectDescriptor
import org.sirius.dorm.model.PropertyDescriptor
import org.sirius.dorm.model.RelationDescriptor
import org.sirius.dorm.persistence.entity.PropertyEntity
import org.sirius.dorm.persistence.entity.EntityEntity
import org.sirius.dorm.transaction.TransactionState
import java.util.HashMap

class MultiValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObject, property: PropertyEntity?, val targetDescriptor: ObjectDescriptor) : Relation(property), MutableSet<DataObject> {
class MultiValuedRelation(relation: RelationDescriptor<*>, val obj: DataObject, property: PropertyEntity?, targetDescriptor: ObjectDescriptor) : Relation(relation, targetDescriptor, property), MutableSet<DataObject> {
// instance data

private var objects : HashSet<DataObject>? = null

// private

private fun isLoaded() : Boolean {
return objects !== null
}

private fun load(objectManager: ObjectManager) {
objects = HashSet()
for ( target in property!!.relations ) {
for ( target in property!!.targets ) {
objects!!.add(objectManager.mapper.read(TransactionState.current(), targetDescriptor, target.entity))
}
}
Expand All @@ -37,6 +32,19 @@ class MultiValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObje
obj.state!!.takeSnapshot(obj)
}

// implement Relation

override fun isLoaded() : Boolean {
return objects !== null
}

override fun addInverse(element: DataObject) {
this.objects!!.add(element)
}
override fun removeInverse(element: DataObject) {
this.objects!!.remove(element)
}

// implement Property

override fun get(objectManager: ObjectManager) : Any? {
Expand All @@ -50,23 +58,12 @@ class MultiValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObje
throw Error("relations don't allow to be set")
}

override fun save(): Any {
return this
}

override fun restore(state: Any) {
}

override fun isDirty(snapshot: Any) : Boolean {
return isLoaded()
}

override fun flush() {
if (isLoaded()) {
// synchronize the objects set with the property.relations

val targetMap = HashMap<Int, PropertyEntity>()
val relations = property!!.relations
val relations = property!!.targets

// collect all targets in a map

Expand Down Expand Up @@ -97,7 +94,17 @@ class MultiValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObje
override fun add(element: DataObject): Boolean {
markDirty()

return objects!!.add(element)
if (objects!!.add(element)) {
// take care of inverse

val inverse = inverseRelation(element)
if ( inverse !== null) {
inverse.addInverse(obj)
}

return true
}
else return false
}

override fun addAll(elements: Collection<DataObject>): Boolean {
Expand All @@ -112,14 +119,24 @@ class MultiValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObje
override fun remove(element: DataObject): Boolean {
markDirty()

return objects!!.remove(element)
if (objects!!.remove(element)) {
// take care of inverse

val inverse = inverseRelation(element!!)
if ( inverse !== null) {
inverse.removeInverse(element)
}

return true
}
else return false
}

override val size: Int
get() = objects!!.size

override fun clear() {
markDirty()
markDirty() // TODO

return objects!!.clear()
}
Expand Down
26 changes: 25 additions & 1 deletion src/main/kotlin/org/sirius/dorm/object/Relation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,31 @@ package org.sirius.dorm.`object`
* All rights reserved
*/

import org.sirius.dorm.model.ObjectDescriptor
import org.sirius.dorm.model.RelationDescriptor
import org.sirius.dorm.persistence.entity.PropertyEntity

abstract class Relation(property: PropertyEntity?) : Property(property) {
abstract class Relation(val relation: RelationDescriptor<*>, val targetDescriptor: ObjectDescriptor, property: PropertyEntity?) : Property(property) {
abstract fun isLoaded(): Boolean

override fun save(): Any {
return this
}

override fun restore(state: Any) {
}

override fun isDirty(snapshot: Any) : Boolean {
return isLoaded()
}

protected fun inverseRelation(obj: DataObject?) : Relation? {
if ( obj !== null && isLoaded()) {
val relation = obj.values[relation.inverseRelation!!.index] as Relation
return if (relation.isLoaded()) relation else null
}
else return null
}
abstract fun addInverse(element: DataObject)
abstract fun removeInverse(element: DataObject)
}
47 changes: 30 additions & 17 deletions src/main/kotlin/org/sirius/dorm/object/SingleValuedRelation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,31 @@ import org.sirius.dorm.model.RelationDescriptor
import org.sirius.dorm.persistence.entity.PropertyEntity
import org.sirius.dorm.transaction.TransactionState

class SingleValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObject, property: PropertyEntity?, val targetDescriptor: ObjectDescriptor) : Relation(property) {
class SingleValuedRelation(relation: RelationDescriptor<*>, val obj: DataObject, property: PropertyEntity?, targetDescriptor: ObjectDescriptor) : Relation(relation, targetDescriptor, property) {
// instance data

var target: DataObject? = DataObject.NONE

// private
// implement Relation

private fun isLoaded() : Boolean {
override fun isLoaded() : Boolean {
return target !== DataObject.NONE
}

// override

override fun isDirty(snapshot: Any) : Boolean {
return isLoaded()
}

override fun flush() {
if ( isLoaded()) {
property!!.relations.clear()
property!!.targets.clear()
if ( target !== null) {
property!!.relations.add(target!!.values[relation.inverseRelation!!.index].property!!)
property!!.targets.add(target!!.values[relation.inverseRelation!!.index].property!!)
}
}
}
override fun get(objectManager: ObjectManager) : Any? {
if ( !isLoaded() && property !== null) {
if ( property!!.relations.size == 1) {
val targetProperty = property!!.relations.first()
if ( property!!.targets.size == 1) {
val targetProperty = property!!.targets.first()
target = objectManager.mapper.read(TransactionState.current(), targetDescriptor, targetProperty.entity)
}
else
Expand All @@ -51,15 +47,32 @@ class SingleValuedRelation(val relation: RelationDescriptor<*>, val obj: DataObj
}

override fun set(propertyDescriptor: PropertyDescriptor<Any>, value: Any?) : Boolean {
this.target = value as DataObject?
if ( value !== this.target) {
var inverse = inverseRelation(this.target)
if ( inverse !== null)
inverse.removeInverse(this.target!!)

return true
}
this.target = value as DataObject?

if ( this.target !== null) {
inverse = inverseRelation(this.target)
if ( inverse !== null)
inverse.addInverse(value!!)
}

override fun save(): Any {
return this
// done

return true
}
else return false
}

override fun restore(state: Any) {
// new

override fun addInverse(element: DataObject) {
this.target = element
}
override fun removeInverse(element: DataObject) {
this.target = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package org.sirius.dorm.persistence.entity
*/

import jakarta.persistence.*
import org.sirius.dorm.`object`.DataObject
import java.io.Serializable

data class PropertyId(private val entity: Int = 0, private val attribute: String = "") : Serializable
Expand Down Expand Up @@ -48,5 +49,21 @@ data class PropertyEntity(
joinColumns = [JoinColumn(name = "FROM_ENTITY"), JoinColumn(name = "FROM_ATTRIBUTE")],
inverseJoinColumns = [JoinColumn(name = "TO_ENTITY"), JoinColumn(name = "TO_ATTRIBUTE")]
)
val relations : MutableSet<PropertyEntity> = HashSet()
)
val targets : MutableSet<PropertyEntity> = HashSet(),

@ManyToMany(mappedBy="targets", fetch = FetchType.LAZY)
val sources : MutableSet<PropertyEntity> = HashSet(),
) {
// override Object

/*override fun equals(other: Any?): Boolean { TODO
if ( other is DataObject)
return id == other.id && this.type === other.type
else
return false
}*/

override fun hashCode(): Int {
return type.hashCode() + attribute.hashCode()
}
}

0 comments on commit 25193ba

Please sign in to comment.