From 7eda90d30d21e37ebf9e2c654aed32eb71512b82 Mon Sep 17 00:00:00 2001 From: rnentjes Date: Mon, 6 May 2024 20:50:29 +0200 Subject: [PATCH] Fix currentTransaction in references while using query --- .../nl/astraeus/persistence/Persistent.kt | 14 +++- .../persistence/reference/Reference.kt | 8 ++- .../persistence/TestPersistenceJava.java | 5 +- .../persistence/TestOptimisticLocking.kt | 17 +---- .../astraeus/persistence/TestPersistence.kt | 50 +------------- .../TestPersistenceJavaInKotlin.kt | 67 +++++++++++++++++++ .../nl/astraeus/persistence/TestReferences.kt | 24 +------ .../nl/astraeus/persistence/TestThreaded.kt | 42 +----------- .../nl/astraeus/persistence/domain/Company.kt | 20 ++++++ .../nl/astraeus/persistence/domain/Person.kt | 22 ++++++ 10 files changed, 136 insertions(+), 133 deletions(-) create mode 100644 src/test/kotlin/nl/astraeus/persistence/TestPersistenceJavaInKotlin.kt create mode 100644 src/test/kotlin/nl/astraeus/persistence/domain/Company.kt create mode 100644 src/test/kotlin/nl/astraeus/persistence/domain/Person.kt diff --git a/src/main/kotlin/nl/astraeus/persistence/Persistent.kt b/src/main/kotlin/nl/astraeus/persistence/Persistent.kt index 0be2949..b199665 100644 --- a/src/main/kotlin/nl/astraeus/persistence/Persistent.kt +++ b/src/main/kotlin/nl/astraeus/persistence/Persistent.kt @@ -16,7 +16,19 @@ class Persistent( val datastore: Datastore = Datastore(directory, indexes, enableOptimisticLocking) fun query(block: Query.() -> T): T { - return block(Query(this)) + var cleanup = false + if (transactions.get() == null) { + transactions.set(Transaction(this)) + cleanup = true + } + + try { + return block(Query(this)) + } finally { + if (cleanup) { + transactions.remove() + } + } } fun transaction(block: Transaction.() -> Unit) { diff --git a/src/main/kotlin/nl/astraeus/persistence/reference/Reference.kt b/src/main/kotlin/nl/astraeus/persistence/reference/Reference.kt index 5895b0f..5cd11d5 100644 --- a/src/main/kotlin/nl/astraeus/persistence/reference/Reference.kt +++ b/src/main/kotlin/nl/astraeus/persistence/reference/Reference.kt @@ -10,7 +10,8 @@ inline fun reference( ) = Reference(T::class.java, initialValue) inline fun nullableReference( -) = NullableReference(T::class.java) + initialValue:T? = null +) = NullableReference(T::class.java, initialValue) class Reference( val cls: Class, @@ -33,9 +34,10 @@ class Reference( } class NullableReference( - val cls: Class + val cls: Class, + initialValue: S? = null ) : Serializable { - var id: Long? = null + var id: Long? = initialValue?.id operator fun getValue(thisRef: Persistable, property: KProperty<*>): S? { return currentTransaction()?.find(cls.kotlin, id ?: 0L) diff --git a/src/test/java/nl/astraeus/persistence/TestPersistenceJava.java b/src/test/java/nl/astraeus/persistence/TestPersistenceJava.java index c8eefc6..798b24c 100644 --- a/src/test/java/nl/astraeus/persistence/TestPersistenceJava.java +++ b/src/test/java/nl/astraeus/persistence/TestPersistenceJava.java @@ -2,14 +2,13 @@ package nl.astraeus.persistence; import nl.astraeus.nl.astraeus.persistence.AbstractPersistable; import nl.astraeus.nl.astraeus.persistence.Index; -import nl.astraeus.nl.astraeus.persistence.Persistable; import nl.astraeus.nl.astraeus.persistence.Persistent; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import java.io.File; import java.util.List; + public class TestPersistenceJava { static class Person extends AbstractPersistable { @@ -100,7 +99,7 @@ public class TestPersistenceJava { return null; }); - persistent.transaction((t) -> { + persistent.query((t) -> { List persons = t.findByIndex( Person.class, "name", diff --git a/src/test/kotlin/nl/astraeus/persistence/TestOptimisticLocking.kt b/src/test/kotlin/nl/astraeus/persistence/TestOptimisticLocking.kt index 2feebc9..e5c7e52 100644 --- a/src/test/kotlin/nl/astraeus/persistence/TestOptimisticLocking.kt +++ b/src/test/kotlin/nl/astraeus/persistence/TestOptimisticLocking.kt @@ -1,12 +1,12 @@ package nl.astraeus.persistence import nl.astraeus.nl.astraeus.persistence.OptimisticLockingException -import nl.astraeus.nl.astraeus.persistence.Persistable import nl.astraeus.nl.astraeus.persistence.Persistent import nl.astraeus.nl.astraeus.persistence.TransactionLog import nl.astraeus.nl.astraeus.persistence.find import nl.astraeus.nl.astraeus.persistence.findByIndex import nl.astraeus.nl.astraeus.persistence.index +import nl.astraeus.persistence.domain.Person import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.assertThrows import java.io.File @@ -14,21 +14,6 @@ import kotlin.test.Test class TestOptimisticLocking { - class Person( - override var id: Long = 0, - override var version: Long = 0, - val name: String, - val age: Int, - ) : Persistable, Cloneable { - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Person(id=$id, version=$version, name='$name', age=$age)" - } - } - @Test fun showTransactions() { val log = TransactionLog(File("data", "test-locking")) diff --git a/src/test/kotlin/nl/astraeus/persistence/TestPersistence.kt b/src/test/kotlin/nl/astraeus/persistence/TestPersistence.kt index 3f356a6..49380ad 100644 --- a/src/test/kotlin/nl/astraeus/persistence/TestPersistence.kt +++ b/src/test/kotlin/nl/astraeus/persistence/TestPersistence.kt @@ -1,13 +1,12 @@ package nl.astraeus.persistence -import nl.astraeus.nl.astraeus.persistence.Persistable import nl.astraeus.nl.astraeus.persistence.Persistent import nl.astraeus.nl.astraeus.persistence.TransactionLog -import nl.astraeus.nl.astraeus.persistence.currentTransaction import nl.astraeus.nl.astraeus.persistence.find import nl.astraeus.nl.astraeus.persistence.findByIndex import nl.astraeus.nl.astraeus.persistence.index -import nl.astraeus.nl.astraeus.persistence.reference.ReferenceCollection +import nl.astraeus.persistence.domain.Company +import nl.astraeus.persistence.domain.Person import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Assertions.assertNull import java.io.File @@ -15,51 +14,6 @@ import kotlin.test.Test class TestPersistence { - class Company( - override var id: Long = 0, - override var version: Long = 0, - val name: String - ) : Persistable, Cloneable { - val personIds: MutableList = ArrayList() - val persons: MutableCollection - get() { - return ReferenceCollection(Person::class.java, personIds) - } - - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Company(id=$id, version=$version, name='$name')" - } - } - - class Person( - override var id: Long = 0, - override var version: Long = 0, - val name: String, - val age: Int, - private var companyId: Long? = null - ) : Persistable, Cloneable { - var company: Company? - get() = currentTransaction()?.find(Company::class, companyId ?: 0L) - set(value) { - if (value != null) { - currentTransaction()?.store(value) - } - companyId = value?.id - } - - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Person(id=$id, version=$version, name='$name', age=$age, company=$companyId)" - } - } - @Test fun showTransactions() { val log = TransactionLog(File("data", "test-persistence")) diff --git a/src/test/kotlin/nl/astraeus/persistence/TestPersistenceJavaInKotlin.kt b/src/test/kotlin/nl/astraeus/persistence/TestPersistenceJavaInKotlin.kt new file mode 100644 index 0000000..1bd2a89 --- /dev/null +++ b/src/test/kotlin/nl/astraeus/persistence/TestPersistenceJavaInKotlin.kt @@ -0,0 +1,67 @@ +package nl.astraeus.persistence + +import nl.astraeus.nl.astraeus.persistence.Index +import nl.astraeus.nl.astraeus.persistence.Persistable +import nl.astraeus.nl.astraeus.persistence.Persistent +import org.junit.jupiter.api.Test +import java.io.File + + +class TestPersistenceJavaInKotlin { + internal class Person( + var name: String, + var age: Int + ) : Persistable { + override var id: Long = 0 + override var version: Long = 0 + + companion object { + private const val serialVersionUID = 1L + } + } + + @Test + fun testPersistence() { + println("TestPersistenceJavaInKotlin.testPersistence") + + val persistent = Persistent( + File("data", "java-kotlin-test"), + arrayOf( + Index( + Person::class, + "name" + ) { p -> (p as Person).name } + ), + false + ) + + persistent.transaction { + val person = find(Person::class.java, 1L) + if (person != null) { + println("Person: ${person.name} is ${person.age} years old." + ) + } + } + + persistent.transaction { + val person = Person("John Doe", 42) + + store(person) + } + + persistent.query { + val persons = findByIndex( + Person::class.java, + "name", + "John Doe" + ) + for (person in persons) { + println("Person: ${person.name} is ${person.age} years old.") + } + } + + persistent.snapshot() + persistent.datastore.printStatus() + persistent.removeOldFiles() + } +} diff --git a/src/test/kotlin/nl/astraeus/persistence/TestReferences.kt b/src/test/kotlin/nl/astraeus/persistence/TestReferences.kt index 5200031..bec78f9 100644 --- a/src/test/kotlin/nl/astraeus/persistence/TestReferences.kt +++ b/src/test/kotlin/nl/astraeus/persistence/TestReferences.kt @@ -4,34 +4,17 @@ import nl.astraeus.nl.astraeus.persistence.Persistable import nl.astraeus.nl.astraeus.persistence.Persistent import nl.astraeus.nl.astraeus.persistence.TransactionLog import nl.astraeus.nl.astraeus.persistence.reference.reference -import nl.astraeus.nl.astraeus.persistence.reference.referenceCollection +import nl.astraeus.persistence.domain.Company import org.junit.jupiter.api.assertThrows import java.io.File import kotlin.test.Test class TestReferences { - class Company( - override var id: Long = 0, - override var version: Long = 0, - val name: String - ) : Persistable, Cloneable { - val persons: MutableCollection = referenceCollection() - - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Company(id=$id, version=$version, name='$name', persons=${persons.size})" - } - } - class Person( override var id: Long = 0, override var version: Long = 0, val name: String, - val age: Int, company: Company ) : Persistable, Cloneable { var company: Company by reference(company) @@ -41,7 +24,7 @@ class TestReferences { } override fun toString(): String { - return "Person(id=$id, version=$version, name='$name', age=$age)" + return "Person(id=$id, version=$version, name='$name')" } } @@ -67,13 +50,10 @@ class TestReferences { val person = Person( id = 0L, name = "John Doe", - age = 25, company = company ) store(person) - company.persons.add(person) - store(company) for (p in company.persons) { diff --git a/src/test/kotlin/nl/astraeus/persistence/TestThreaded.kt b/src/test/kotlin/nl/astraeus/persistence/TestThreaded.kt index bcf5a26..9a397e3 100644 --- a/src/test/kotlin/nl/astraeus/persistence/TestThreaded.kt +++ b/src/test/kotlin/nl/astraeus/persistence/TestThreaded.kt @@ -7,52 +7,14 @@ import nl.astraeus.nl.astraeus.persistence.TransactionLog import nl.astraeus.nl.astraeus.persistence.count import nl.astraeus.nl.astraeus.persistence.index import nl.astraeus.nl.astraeus.persistence.searchIndex +import nl.astraeus.persistence.domain.Company +import nl.astraeus.persistence.domain.Person import java.io.File import kotlin.random.Random import kotlin.test.Test class TestThreaded { - class Company( - override var id: Long = 0, - override var version: Long = 0, - val name: String, - val adres: String = "Blaat" - ) : Persistable, Cloneable { - //var persons: MutableList by ListReference(Person::class.java) - - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Company(id=$id, version=$version, name='$name', adres='$adres')" - } - - } - - class Person( - override var id: Long = 0, - override var version: Long = 0, - val name: String, - val age: Int, - var companyId: Long? = null - ) : Persistable, Cloneable { -/* var company: Company? by Reference( - Company::class.java, - { id -> companyId = id }, - { companyId } - )*/ - - companion object { - private const val serialVersionUID: Long = 1L - } - - override fun toString(): String { - return "Person(id=$id, version=$version, name='$name', age=$age)" - } - } - @Test fun showTransactions() { val log = TransactionLog(File("data", "test-threaded")) diff --git a/src/test/kotlin/nl/astraeus/persistence/domain/Company.kt b/src/test/kotlin/nl/astraeus/persistence/domain/Company.kt new file mode 100644 index 0000000..05ad009 --- /dev/null +++ b/src/test/kotlin/nl/astraeus/persistence/domain/Company.kt @@ -0,0 +1,20 @@ +package nl.astraeus.persistence.domain + +import nl.astraeus.nl.astraeus.persistence.Persistable +import nl.astraeus.nl.astraeus.persistence.reference.referenceCollection + +class Company( + override var id: Long = 0, + override var version: Long = 0, + val name: String +) : Persistable, Cloneable { + val persons: MutableCollection = referenceCollection() + + companion object { + private const val serialVersionUID: Long = 1L + } + + override fun toString(): String { + return "Company(id=$id, version=$version, name='$name', persons=${persons.size})" + } +} diff --git a/src/test/kotlin/nl/astraeus/persistence/domain/Person.kt b/src/test/kotlin/nl/astraeus/persistence/domain/Person.kt new file mode 100644 index 0000000..568da37 --- /dev/null +++ b/src/test/kotlin/nl/astraeus/persistence/domain/Person.kt @@ -0,0 +1,22 @@ +package nl.astraeus.persistence.domain + +import nl.astraeus.nl.astraeus.persistence.Persistable +import nl.astraeus.nl.astraeus.persistence.reference.nullableReference + +class Person( + override var id: Long = 0, + override var version: Long = 0, + val name: String, + val age: Int, + company: Company? = null +) : Persistable, Cloneable { + var company: Company? by nullableReference(company) + + companion object { + private const val serialVersionUID: Long = 1L + } + + override fun toString(): String { + return "Person(id=$id, version=$version, name='$name', age=$age)" + } +} \ No newline at end of file