Skip to content

Commit

Permalink
multi valued relations starting to work
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsamson7 committed Sep 23, 2024
1 parent b9d43b5 commit 8c47f88
Show file tree
Hide file tree
Showing 16 changed files with 297 additions and 64 deletions.
2 changes: 1 addition & 1 deletion src/main/kotlin/org/sirius/common/tracer/Tracer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Tracer(private val trace: org.sirius.common.tracer.Trace, layout : String

fun trace(path: String, level: TraceLevel, message: String, vararg args: Any) {
if (this.isTraced(path, level))
this.trace.trace(org.sirius.common.tracer.TraceEntry(path, level, message.format(*args), Date()), formatter)
this.trace.trace(TraceEntry(path, level, message.format(*args), Date()), formatter)
}

// private
Expand Down
22 changes: 7 additions & 15 deletions src/main/kotlin/org/sirius/dorm/ObjectManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import org.sirius.dorm.`object`.DataObject
import org.sirius.dorm.persistence.DataObjectMapper
import org.sirius.dorm.persistence.entity.EntityEntity
import org.sirius.dorm.query.*
import org.sirius.dorm.query.parser.OQLLexer
import org.sirius.dorm.query.parser.OQLParser
import org.sirius.dorm.transaction.Status
import org.sirius.dorm.transaction.TransactionState
import org.sirius.common.type.Type
Expand Down Expand Up @@ -126,7 +124,7 @@ class ObjectManager() {
fun create(objectDescriptor: ObjectDescriptor) : DataObject {
val obj = objectDescriptor.create()

transactionState().create(obj)
TransactionState.current().create(obj)

return obj
}
Expand All @@ -139,33 +137,29 @@ class ObjectManager() {
// tx

fun begin() {
transactionState.set(TransactionState(this, transactionManager))
TransactionState.set(this, transactionManager)
}

fun commit() {
try {
transactionState().commit(mapper)
TransactionState.current().commit(mapper)
}
finally {
mapper.clear()
transactionState.remove()
TransactionState.remove()
}
}

fun rollback() {
try {
transactionState().rollback(mapper)
TransactionState.current().rollback(mapper)
}
finally {
mapper.clear()
transactionState.remove()
TransactionState.remove()
}
}

fun transactionState() : TransactionState {
return transactionState.get()
}

fun queryManager() : QueryManager {
return QueryManager(this, entityManager, mapper)
}
Expand All @@ -190,16 +184,14 @@ class ObjectManager() {
val entity = entityManager.find(EntityEntity::class.java, id)

return if ( entity !== null)
mapper.read(transactionState(), descriptor, entity)
mapper.read(TransactionState.current(), descriptor, entity)
else
null
}

// companion

companion object {
val transactionState = ThreadLocal<TransactionState>()

lateinit var instance : ObjectManager
}
}
6 changes: 3 additions & 3 deletions src/main/kotlin/org/sirius/dorm/model/ObjectDescriptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class ObjectDescriptor(val name: String, val properties: Array<PropertyDescripto

// public

private fun createValues(): Array<Property> {
return properties.map { property -> property.createProperty(null) }.toTypedArray()
fun createValues(obj: DataObject): Array<Property> {
return properties.map { property -> property.createProperty(obj, null) }.toTypedArray()
}

fun resolve(objectManager: ObjectManager) {
Expand All @@ -31,7 +31,7 @@ class ObjectDescriptor(val name: String, val properties: Array<PropertyDescripto
}

fun create() : DataObject {
return DataObject(this, null, createValues())
return DataObject(this, null) // TODO
}

fun property(property: String) : PropertyDescriptor<Any> {
Expand Down
13 changes: 5 additions & 8 deletions src/main/kotlin/org/sirius/dorm/model/PropertyDescriptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ package org.sirius.dorm.model
*/

import org.sirius.dorm.*
import org.sirius.dorm.`object`.Attribute
import org.sirius.dorm.`object`.MultiValuedRelation
import org.sirius.dorm.`object`.Property
import org.sirius.dorm.`object`.SingleValuedRelation
import org.sirius.dorm.persistence.entity.AttributeEntity
import org.sirius.common.type.Type
import org.sirius.dorm.`object`.*

abstract class PropertyDescriptor<T:Any>(val name: String) {
var index = 0

abstract fun createProperty(entity: AttributeEntity?) : Property
abstract fun createProperty(obj: DataObject, entity: AttributeEntity?) : Property

abstract fun defaultValue() : Any?

Expand Down Expand Up @@ -47,7 +44,7 @@ class AttributeDescriptor<T:Any>(name: String, val type: Type<T>, val isPrimaryK

// override

override fun createProperty(entity: AttributeEntity?) : Property {
override fun createProperty(obj: DataObject, entity: AttributeEntity?) : Property {
return Attribute(entity, defaultValue()!!)
}

Expand Down Expand Up @@ -82,8 +79,8 @@ open class RelationDescriptor<T:Any>(name: String, val target: String, val multi

// override

override fun createProperty(entity: AttributeEntity?) : Property {
return if ( multiplicity === Multiplicity.ONE ) SingleValuedRelation(entity, targetDescriptor!!) else MultiValuedRelation(entity, targetDescriptor!!)
override fun createProperty(obj: DataObject, entity: AttributeEntity?) : Property {
return if ( multiplicity === Multiplicity.ONE ) SingleValuedRelation(obj, entity, targetDescriptor!!) else MultiValuedRelation(obj, entity, targetDescriptor!!)
}

override fun resolve(objectManager: ObjectManager, descriptor: ObjectDescriptor) {
Expand Down
22 changes: 18 additions & 4 deletions src/main/kotlin/org/sirius/dorm/object/DataObject.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import org.sirius.dorm.persistence.entity.EntityEntity
import org.sirius.dorm.transaction.ObjectState


class DataObject(val type: ObjectDescriptor, var state : ObjectState?, val values: Array<Property>) {
class DataObject(val type: ObjectDescriptor, var state : ObjectState?) {
// instance data

var entity: EntityEntity? = null
val values = type.createValues(this)

// public

Expand All @@ -37,11 +38,11 @@ class DataObject(val type: ObjectDescriptor, var state : ObjectState?, val value

// public operators

fun <T:Any> value(index: Int) : T {
fun <T:Any> value(index: Int) : T { // TODO???
return values[index].get(objectManager) as T
}

/*fun reference(index: Int) : SingleValuedRelation {
/*fun reference(index: Int) : SingleValuedRelation { TODO
return values[index] as SingleValuedRelation
}
Expand All @@ -66,7 +67,20 @@ class DataObject(val type: ObjectDescriptor, var state : ObjectState?, val value
values[property.index].set(property, value)
}

// override Object

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

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

companion object {
val NONE = DataObject(ObjectDescriptor("none", arrayOf()), null, arrayOf())
val NONE = DataObject(ObjectDescriptor("none", arrayOf()), null)
}
}
140 changes: 135 additions & 5 deletions src/main/kotlin/org/sirius/dorm/object/MultiValuedRelation.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,153 @@
package org.sirius.dorm.`object`
/*
* @COPYRIGHT (C) 2023 Andreas Ernst
*
* All rights reserved
*/

import org.sirius.dorm.ObjectManager
import org.sirius.dorm.model.ObjectDescriptor
import org.sirius.dorm.model.PropertyDescriptor
import org.sirius.dorm.persistence.entity.AttributeEntity
import org.sirius.dorm.persistence.entity.EntityEntity
import org.sirius.dorm.transaction.TransactionState
import java.util.HashMap

class MultiValuedRelation(val obj: DataObject, property: AttributeEntity?, val targetDescriptor: ObjectDescriptor) : Relation(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 ) {
objects!!.add(objectManager.mapper.read(TransactionState.current(), targetDescriptor, target))
}
}

private fun markDirty() {
if ( obj.state!!.snapshot == null)
obj.state!!.takeSnapshot(obj)
}

// implement Property

class MultiValuedRelation(property: AttributeEntity?, targetDescriptor: ObjectDescriptor) : Relation(property) {
override fun get(objectManager: ObjectManager) : Any? {
return null // TODO RELATION
if ( !isLoaded())
load(objectManager)

return this
}

override fun set(propertyDescriptor: PropertyDescriptor<Any>, value: Any?) : Boolean {
// TODO RELATIONthis.value = value!!
return true
throw Error("relations don't allow to be set")
}

override fun save(): Any {
return this
}

override fun restore(state: Any) {}
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, EntityEntity>()
val relations = property!!.relations

// collect all targets in a map

for (previousTarget in relations)
targetMap[previousTarget.id] = previousTarget

// iterate over source objects

for (target in objects!!) {
val key = target.id

if (!targetMap.containsKey(key))
relations.add(target.entity!!)
else
targetMap.remove(key)
} // for

// deleted

for (deleted in targetMap.values) {
relations.remove(deleted)
} // if
}
}

// implement MutableSet

override fun add(element: DataObject): Boolean {
markDirty()

return objects!!.add(element)
}

override fun addAll(elements: Collection<DataObject>): Boolean {
var result = false
for (element in elements)
if (add(element))
result = true

return result
}

override fun remove(element: DataObject): Boolean {
markDirty()

return objects!!.remove(element)
}

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

override fun clear() {
markDirty()

return objects!!.clear()
}

override fun isEmpty(): Boolean {
return size == 0
}

override fun containsAll(elements: Collection<DataObject>): Boolean {
return objects!!.containsAll(elements)
}

override fun contains(element: DataObject): Boolean {
return objects!!.contains(element)
}

override fun iterator(): MutableIterator<DataObject> {
return objects!!.iterator()
}

override fun retainAll(elements: Collection<DataObject>): Boolean {
markDirty()

return objects!!.retainAll(elements)
}

override fun removeAll(elements: Collection<DataObject>): Boolean {
markDirty()

return objects!!.removeAll(elements)
}
}
8 changes: 8 additions & 0 deletions src/main/kotlin/org/sirius/dorm/object/Property.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@ package org.sirius.dorm.`object`

import org.sirius.dorm.ObjectManager
import org.sirius.dorm.model.PropertyDescriptor
/*
* @COPYRIGHT (C) 2023 Andreas Ernst
*
* All rights reserved
*/

abstract class Property() {
abstract fun get(objectManager: ObjectManager) : Any?

abstract fun set(propertyDescriptor: PropertyDescriptor<Any>, value: Any?) : Boolean

open fun init(propertyDescriptor: PropertyDescriptor<Any>, value: Any?) {
this.set(propertyDescriptor, value)
}

// snapshot stuff

abstract fun save(): Any;

abstract fun restore(state: Any);
Expand Down
5 changes: 5 additions & 0 deletions src/main/kotlin/org/sirius/dorm/object/Relation.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
package org.sirius.dorm.`object`
/*
* @COPYRIGHT (C) 2023 Andreas Ernst
*
* All rights reserved
*/

import org.sirius.dorm.persistence.entity.AttributeEntity

Expand Down
Loading

0 comments on commit 8c47f88

Please sign in to comment.