realm / realm-kotlin

Kotlin Multiplatform and Android SDK for the Realm Mobile Database: Build Better Apps Faster.
Apache License 2.0
947 stars 57 forks source link

Breaking changes which don't make sense between 1.9.1 and 1.10.1 #1450

Closed beachcitiessoftware closed 1 year ago

beachcitiessoftware commented 1 year ago

How frequently does the bug occur?

Always on 1.10.1

Description

In 1.9.1, the following would work, where defaultRealmConfiguration is a RealmConfiguration

    open val hasAnyRecords: Boolean
        get() = if (
            isDefaultRealmOpen &&
            defaultRealmConfiguration.schema.isNotEmpty()
        ) {
            var hasAny = false
            for (it in defaultRealmConfiguration.schema) {
                if (defaultRealm.query(clazz = it).count().find() > 0L) {
                    hasAny = true
                    break
                }
            }
            Timber.tag(TAG).v("Repo contains records: $hasAny")
            hasAny
        } else {
            false
        }

As of 1.10.1 you are now requiring a TypedRealmObject for the defaultRealm.query(...) method. Why not still allow the more loose type BaseRealmObject? Especially, considering that's the type you're storing in the schema property for the RealmConfiguration, which makes it a convenient place to know all the types available in the Realm, and to be able to query them easily.

Or, is there an easier way to know if the Realm has any data in it?

Stacktrace & log output

There is not a stack trace, there's a built-time error in Android Studio, which says:

Type mismatch: inferred type is BaseRealmObject but TypedRealmObject was expected

Can you reproduce the bug?

Always

Reproduction Steps

Use the code with a RealmConfiguration on 1.9.1 and 1.10.1

Version

1.10.1

What Atlas App Services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

Android 33

Build environment

Android Studio version: Android Studio Flamingo | 2022.2.1 Patch

Android Build Tools version:

Build #AI-222.4459.24.2221.10121639, built on May 12, 2023

Gradle version: 8.0.2

clementetb commented 1 year ago

We are not allowing the more loose type BaseRealmObject because we have introduced unidirectional data ingest. It adds AsymmetricRealmObject a new kind of object that only support write operations, it cannot be read or queried. Because it is still part of the schema but cannot be queried, we have enforced this restriction in the type system.

A workaround, if you are not using the unidirectional data ingest feature, would be safe to type casting each schema entry to KClass<TypedRealmObject>:

open val hasAnyRecords: Boolean
    get() = if (
        isDefaultRealmOpen &&
        defaultRealmConfiguration.schema.isNotEmpty()
    ) {
        var hasAny = false
        for (it in defaultRealmConfiguration.schema) {
            it as KClass<TypedRealmObject>
            if (defaultRealm.query(clazz = it).count().find() > 0L) {
                hasAny = true
                break
            }
        }
        Timber.tag(TAG).v("Repo contains records: $hasAny")
        hasAny
    } else {
        false
    }
beachcitiessoftware commented 1 year ago

Thank you for the reply. I was almost there. I will look into the unidirectional data ingest.