Sqldelight: Generate Creator wrapper method to allow easy constructor reference in Kotlin companion object

Created on 2 Jul 2016  路  3Comments  路  Source: cashapp/sqldelight

By generating an extra Java method like this one (for example inside the Factory):

static <T extends FooModel> Creator<T> creator(@NonNull Creator<T> creator) {
    return creator;
}

Then it's easy to make a companion object in Kotlin that implements the Creator interface for a model:

package com.example

import com.example.FooModel.Creator
import com.example.FooModel.Factory
import com.example.FooModel.Factory.creator
import com.google.auto.value.AutoValue
import com.squareup.sqldelight.RowMapper

@AutoValue
abstract class Foo : FooModel {
    companion object : Creator<Foo> by creator(::AutoValue_Foo) {
        val FACTORY = Factory<Foo>(this)
        val MAPPER: RowMapper<Foo> = FACTORY.some_query()
    }
}

And use it like:

Foo.create(...)

Plus, by annotating the create method in the interface with @JvmStatic then the same is possible in Java.

This technique could be taken further by creating a base class for the companion object that automatically exposes the factory (and perhaps more).

P.S. I'm afraid that creating the extra method is necessary because of how SAM conversions work, but maybe there's a better way?

Most helpful comment

If anyone like me will end up having a .sq model with more than 24 fields, then beware that method reference will not compile with exception that Function25 is an unknown interface. This may seem a bit confusing at first, but it makes sense - kotlin only has as much as Function24 interfaces :)

In this case you need to replace a reference you pass to the Creator with some plain function call.

All 3 comments

Nevermind, I just discovered that this can be done in Kotlin without the wrapper method with this syntax:

companion object : Creator<Foo> by Creator(::AutoValue_Foo) {

The point about having the option to add @JvmStatic to the interface still holds though.

coolcool i'll link #227 here and close this for now then

If anyone like me will end up having a .sq model with more than 24 fields, then beware that method reference will not compile with exception that Function25 is an unknown interface. This may seem a bit confusing at first, but it makes sense - kotlin only has as much as Function24 interfaces :)

In this case you need to replace a reference you pass to the Creator with some plain function call.

Was this page helpful?
0 / 5 - 0 ratings