Skip to content

Commit

Permalink
synchronize unloaded relations...
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsamson7 committed Sep 25, 2024
1 parent 03067bd commit 2c25883
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 23 deletions.
28 changes: 19 additions & 9 deletions src/main/kotlin/org/sirius/dorm/object/MultiValuedRelation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ 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.transaction.AddToRelation
import org.sirius.dorm.transaction.RemoveFromRelation
import org.sirius.dorm.transaction.Status
import org.sirius.dorm.transaction.TransactionState
import java.util.HashMap
Expand All @@ -23,10 +25,15 @@ class MultiValuedRelation(relation: RelationDescriptor<*>, status: Status, val o

override fun load(objectManager: ObjectManager) {
objects = HashSet()
if ( property !== null)
for ( target in relations() ) {
objects!!.add(objectManager.mapper.read(TransactionState.current(), targetDescriptor, target.entity))
}
if ( property !== null) {
val transactionState = TransactionState.current()
for (target in relations())
objects!!.add(objectManager.mapper.read(transactionState, targetDescriptor, target.entity))

// redo anything related to me

transactionState.checkRedos(this.obj.id, relation.name, this)
}
}

private fun markDirty() {
Expand Down Expand Up @@ -100,17 +107,18 @@ class MultiValuedRelation(relation: RelationDescriptor<*>, status: Status, val o
override fun add(element: DataObject): Boolean {
markDirty()

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

val inverse = inverseRelation(element)
if ( inverse !== null) {
if ( inverse !== null)
inverse.addInverse(obj)
}
else
TransactionState.current().addRedo(element.id, relation.inverseRelation!!.name, AddToRelation(this.obj))

return true
true
}
else return false
else false
}

override fun addAll(elements: Collection<DataObject>): Boolean {
Expand All @@ -131,6 +139,8 @@ class MultiValuedRelation(relation: RelationDescriptor<*>, status: Status, val o
val inverse = inverseRelation(element)
if ( inverse !== null)
inverse.removeInverse(element)
else
TransactionState.current().addRedo(element.id, relation.inverseRelation!!.name, RemoveFromRelation(this.obj))

true
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/org/sirius/dorm/object/Relation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ abstract class Relation(val relation: RelationDescriptor<*>, val targetDescripto
}

protected fun inverseRelation(obj: DataObject?) : Relation? {
if ( obj !== null && isLoaded()) {
return if ( obj !== null && isLoaded()) {
val relation = obj.values[relation.inverseRelation!!.index] as Relation
return if (relation.isLoaded()) relation else null
if (relation.isLoaded()) relation else null
}
else return null
else null
}

fun relations() : MutableSet<PropertyEntity> {
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/org/sirius/dorm/object/SingleValuedRelation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ 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.transaction.AddToRelation
import org.sirius.dorm.transaction.RemoveFromRelation
import org.sirius.dorm.transaction.Status
import org.sirius.dorm.transaction.TransactionState

Expand All @@ -27,12 +29,18 @@ class SingleValuedRelation(relation: RelationDescriptor<*>, status: Status, val

override fun load(objectManager: ObjectManager) {
if ( property !== null) {
// start with the persistent state

if ( relations().size == 1) {
val targetProperty = relations().first()
target = objectManager.mapper.read(TransactionState.current(), targetDescriptor, targetProperty.entity)
}
else
target = null

// redo anything related to me

TransactionState.current().checkRedos(this.obj.id, relation.name, this)
}
else target = null
}
Expand Down Expand Up @@ -67,13 +75,17 @@ class SingleValuedRelation(relation: RelationDescriptor<*>, status: Status, val
var inverse = inverseRelation(this.target)
if ( inverse !== null)
inverse.removeInverse(this.obj)
else if ( this.target !== null)
TransactionState.current().addRedo(this.target!!.id, relation.inverseRelation!!.name, RemoveFromRelation(this.obj))

this.target = value as DataObject?

if ( this.target !== null) {
inverse = inverseRelation(this.target)
if ( inverse !== null)
inverse.addInverse(this.obj)
else
TransactionState.current().addRedo(this.target!!.id, relation.inverseRelation!!.name, AddToRelation(this.obj))
}

// done
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class DataObjectMapper() {

// update entity

obj.entity!!.json = mapper.writeValueAsString(obj)
obj.entity!!.json = ""//TODO ? mapper.writeValueAsString(obj)
}

fun delete(state: TransactionState, obj: DataObject) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,17 @@ data class EntityEntity(

@OneToMany(mappedBy = "entity", cascade = [CascadeType.ALL], orphanRemoval = true)
var properties : MutableList<PropertyEntity> = ArrayList()
)
) {
// override Object

override fun equals(other: Any?): Boolean {
if ( other is EntityEntity)
return this === other
else
return false
}

override fun hashCode(): Int {
return id.hashCode() + type.hashCode()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ data class PropertyEntity(
) {
// override Object

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

override fun hashCode(): Int {
return type.hashCode() + attribute.hashCode()
Expand Down
57 changes: 54 additions & 3 deletions src/main/kotlin/org/sirius/dorm/transaction/TransactionState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,54 @@ import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.TransactionDefinition
import org.springframework.transaction.TransactionStatus
import org.springframework.transaction.support.DefaultTransactionDefinition
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet


abstract class Operation() {
abstract fun execute()
}

data class RedoKey(val id : Long, val relation: String) {}

abstract class UpdateRelation {
abstract fun execute(relation: Relation)
}

class AddToRelation(val obj: DataObject) : UpdateRelation() {
override fun execute(relation: Relation) {
relation.addInverse(obj)
}
}

class RemoveFromRelation(val obj: DataObject) : UpdateRelation() {
override fun execute(relation: Relation) {
relation.removeInverse(obj)
}
}
class Redo() {
val operations = LinkedList<UpdateRelation>()

fun add(update: UpdateRelation) {
operations.add(update)
}

fun execute(relation: Relation) {
for ( operation in operations)
operation.execute(relation)
}
}

class TransactionState(val objectManager: ObjectManager, val transactionManager: PlatformTransactionManager) {
// instance data

val states = HashMap<Long, ObjectState>()
private val states = HashMap<Long, ObjectState>()
val status : TransactionStatus

val pendingOperations = ArrayList<Operation>()
private val pendingOperations = ArrayList<Operation>()
private val redos = HashMap<RedoKey, Redo> ()

init {
val def = DefaultTransactionDefinition()
Expand All @@ -39,6 +74,21 @@ class TransactionState(val objectManager: ObjectManager, val transactionManager:
status = transactionManager.getTransaction(def)
}

fun addRedo(id: Long, relation: String, redo: UpdateRelation) {
val key = RedoKey(id, relation)
redos.getOrPut(key, { Redo() }).add(redo)
}

fun checkRedos(id: Long, relationName: String, relation: Relation) {
val key = RedoKey(id, relationName)
val redo = redos[key]
if ( redo !== null) {
redo.execute(relation)

redos.remove(key)
} // if
}

fun addOperation(operation: Operation) {
pendingOperations.add(operation)
}
Expand All @@ -51,6 +101,7 @@ class TransactionState(val objectManager: ObjectManager, val transactionManager:

}

// TODO do it in waves
fun processDeletedObjects() {
val objects = states.values.filter { state -> state.status == Status.DELETED }

Expand Down Expand Up @@ -79,7 +130,7 @@ class TransactionState(val objectManager: ObjectManager, val transactionManager:
for (r in relation.relations())
queue.add(r.entity.id)
}
else { // FROM_ATTR | FROM_ENTITY | TO_ATTR | TO_ENTITY |
else { // TODO prepeared statement?
objectManager.jdbcTemplate.query<Long>("SELECT DISTINCT TO_ENTITY FROM RELATIONS WHERE FROM_ENTITY = ${id} AND FROM_ATTR='${property.name}'") { rs, _ ->
rs.getLong("TO_ENTITY")
}.forEach { id -> queue.add(id) }
Expand Down
3 changes: 1 addition & 2 deletions src/test/kotlin/org/sirius/dorm/RelationTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class RelationTests: AbstractTest() {
fun testOneToMany() {
// create schema


withTransaction {
objectManager.type("p")
.attribute("name", string())
Expand All @@ -80,7 +79,7 @@ class RelationTests: AbstractTest() {

// force load

person["children"]
//person["children"]

id = person.id

Expand Down

0 comments on commit 2c25883

Please sign in to comment.