realm-kotlin icon indicating copy to clipboard operation
realm-kotlin copied to clipboard

Add support for type adapters

Open clementetb opened this issue 1 year ago • 0 comments

Type adapters allow users to persist their types in Realm by doing some transformation to Realm-supported types.

Use cases

Compile time adapter

Adapters defined as objects will be globally available on all Realm instances.

object RealmInstantDateAdapter: RealmTypeAdapter<RealmInstant, Date> {
    override fun fromRealm(realmValue: RealmInstant): Date = TODO()

    override fun toRealm(value: Date): RealmInstant = TODO()
}

class MyObject: RealmObject {
    @TypeAdapter(RealmInstantDateAdapter::class)
    var date: Date = Date()
}

Runtime adapter

Adapters defined as classes require an adapter instance to be passed to the Realm instance.

class EncryptedStringAdapter(
    val encryptionKey: String,
) : RealmTypeAdapter<ByteArray, String> {
    override fun fromRealm(realmValue: ByteArray): String = TODO()

    override fun toRealm(value: String): ByteArray = TODO()
}

class MyObject : RealmObject {
    @TypeAdapter(EncryptedStringAdapter::class)
    var secureString: String = "some content"
}

fun createRealmConfig() =
    RealmConfiguration
        .Builder(setOf(MyObject::class))
        .typeAdapters {
            add(EncryptedStringAdapter("my encryption key"))
        }
        .build()

Use adapters in Realm collection type parameters.

class MyObject : RealmObject {
    var secureStringList: RealmList<@TypeAdapter(EncryptedStringAdapter::class) String> = realmListOf()
}

Type alias compatibility

typealias EncryptedString = @TypeAdapter(EncryptedStringAdapter::class) String

class MyObject : RealmObject {
    var secureString: EncryptedString = ""
    var secureStringList: RealmList<EncryptedString> = realmListOf()
}

Compatibility with other annotations

object StringDateAdapter: RealmTypeAdapter<String, Date> {
    override fun fromRealm(realmValue: String): Date = TODO()

    override fun toRealm(value: Date): String = TODO()
}

class MyObject : RealmObject {
    @PrimaryKey
    @TypeAdapter(StringDateAdapter::class)
    var primaryKey: Date = Date()
    
    @Index
    @TypeAdapter(StringDateAdapter::class)
    var indexed: Date = Date()

    @PersistedName
    @TypeAdapter(StringDateAdapter::class)
    var persistedName: Date = Date()

    @FullText
    @TypeAdapter(StringDateAdapter::class)
    var date: Date = Date()
}

Not in this PR

Apply adapters to a whole class/file

@file:UseTypeAdapters(adapters = [EncryptedStringAdapter::class])
// or
@UseTypeAdapters(adapters = [EncryptedStringAdapter::class])
class MyObject : RealmObject {
    var secureString: String = "some content"
}

Automatic enum support (https://github.com/realm/realm-kotlin/issues/829)

enum class Numbers {
    ONE,
    TWO,
    THREE,
}

class MyObject : RealmObject {
    var enumValue: Numbers = ONE
}

clementetb avatar Dec 05 '23 11:12 clementetb