Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ class Naksha private constructor() {
}
}
val localS = s
if (localS != null && localS.config == config) {
if (localS != null && localS.config.configEquals(config)) {
// Only invoke initStorage, when we are forced to do it!
if (forceCreateOrUpgrade == true) localS.invokeInitStorage(config, create = true, upgrade = true)
return localS
Expand All @@ -867,7 +867,9 @@ class Naksha private constructor() {
"The storage-id (${config.id}) and -number (${config.number}) belong to different storages")
}
if (storage != null) {
if (storage.config == config) return storage
if (storage.config.configEquals(config)) {
return storage
}
storage.invokeShutdownStorage(false)
}
val klass = Platform.klassForName<AbstractStorage<*>>(config.className)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,20 @@ open class NakshaStorage() : NakshaFeature() {
*/
val number: Int64
get() = featureNumber

/**
* Compares this configuration with another [NakshaStorage] instance.
*
* This method is designed to be overridden by subclasses that want to define
* equality based on a subset of configuration fields rather than performing
* a full object comparison.
*
* When not overridden, this method falls back to the standard [equals] implementation.
*
* @param other another [NakshaStorage] instance to compare against
* @return `true` if the two configurations are considered equal under the
* comparison rules; otherwise `false`
* @since 3.0
*/
open fun configEquals(other: NakshaStorage) = this == other
}
31 changes: 31 additions & 0 deletions here-naksha-lib-psql/src/commonMain/kotlin/naksha/psql/PgConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,35 @@ class PgConfig() : NakshaStorage() {
* @since 3.0
*/
val ephemeral_tablespace by STRING_NULL

override fun configEquals(other: NakshaStorage): Boolean {
val otherConfig = other.proxy(this::class)
return hardCap == otherConfig.hardCap &&
create == otherConfig.create &&
upgrade == otherConfig.upgrade &&
version == otherConfig.version &&
pgInstancesEquals(master, otherConfig.master) &&
replicasEquals(replicas, otherConfig.replicas)
}

private fun pgInstancesEquals(i1: PgInstanceConfig, i2: PgInstanceConfig): Boolean {
return i1.host == i2.host &&
i1.port == i2.port &&
i1.db == i2.db &&
i1.user == i2.user &&
i1.password == i2.password &&
i1.readOnly == i2.readOnly &&
i1.connectionLimit == i2.connectionLimit
}

private fun replicasEquals(l1: PgInstanceConfigList, l2: PgInstanceConfigList): Boolean {
if(l1.size != l2.size) return false
val l1Sorted = l1.sortedBy { it.toString() }
val l2Sorted = l2.sortedBy { it.toString() }
return l1Sorted
.zip(l2Sorted)
.all { (i1, i2) ->
(i1 == null && i2 == null) || (i1 != null && i2 != null && pgInstancesEquals(i1, i2))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ open class PgMap internal constructor(
collectionCache[collection.number] = collection
}

protected fun invalidateCollection(collection: PgCollection) {
fun invalidateCollection(collection: PgCollection) {
collectionCache.remove(collection.number, collection)
//collectionNumberById.remove(collection.id, collection.number)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,10 @@ open class PgWriter internal constructor(
} else if (write.isCollectionModification) {
val map = write.map
val col = write.asPgCollection
if (col != null) transaction.useMap(map.id, map.number).useCollection(col.id, col.number, write.action)
if (col != null) {
transaction.useMap(map.id, map.number).useCollection(col.id, col.number, write.action)
map.invalidateCollection(col)
}
}
if (tuple != null) tupleList.add(tuple)
}
Expand Down
111 changes: 111 additions & 0 deletions here-naksha-lib-psql/src/commonTest/kotlin/naksha/psql/PgConfigTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package naksha.psql

import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class PgConfigTest {
private val exampleUri = "jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password"
private val config1 = PgConfig()
.withMasterUri(exampleUri)
private val config2 = PgConfig()
.withMasterUri(exampleUri)

@Test
fun shouldBeEqualWhenIrrelevantRawParameterAdded() {
// Given
config1.setRaw("fake", "fake")

// And
config2.setRaw("fake", "fake2")

// When & Then
assertTrue(config1.configEquals(config2))
}

@Test
fun shouldNotBeEqualWhenMastersDiffers() {
// Given
config1
.withMaster(PgInstanceConfig.fromUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password"))
// And
config2
.withMaster(PgInstanceConfig.fromUri("jdbc:postgresql://192.168.100.1:1234/db2?user=user&password=password"))

// When & Then
assertFalse(config1.configEquals(config2))
}

@Test
fun shouldBeEqualWhenSameReplicasButInDifferentOrder() {
// Given: first config with replicas
config1.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
}

// And: second config with the same replicas in different order
config2.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
}

// When & Then
assertTrue(config1.configEquals(config2))
}

@Test
fun shouldBeEqualWhenSameReplicas() {
// Given: first config with replicas
config1.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
}

// And: second config with the same replicas
config2.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
}

// When & Then
assertTrue(config1.configEquals(config2))
}

@Test
fun shouldNotBeEqualWhenReplicasDiffer() {
// Given: first config with replicas
config1.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
}

// And: second config with different replicas
config2.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:12356/db?user=user&password=password")
}

// When & Then
assertFalse(config1.configEquals(config2))
}

@Test
fun shouldNotBeEqualWhenDifferentAmountOfReplicas() {
// Given: first config with replicas
config1.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
}

// And: second config with more replicas
config2.replicas.apply {
addUri("jdbc:postgresql://192.168.100.1:1234/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:123/db?user=user&password=password")
addUri("jdbc:postgresql://192.168.100.1:12356/db?user=user&password=password")
}

// When & Then
assertFalse(config1.configEquals(config2))
}
}
Loading