How to provide SqlDelight database in Compose Multiplatform using KodeIn

359 views Asked by At

So far i've managed to declare expect class for DriverFactory

expect class DriverFactory {
    fun createDriver(): SqlDriver
}

actual class DriverFactory(private val context: Context) {
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db")
    }
}

actual class DriverFactory {
    actual fun createDriver(): SqlDriver {
        return NativeSqliteDriver(AppDatabase.Schema, "test.db")
    }
}

Then create the database

class LocalDatabase(databaseDriverFactory: DriverFactory) {
     val database = AppDatabase(
        driver = databaseDriverFactory.createDriver(),
        saved_team_tableAdapter = Saved_team_table.Adapter(
            playersAdapter = dbPlayerListAdapter,
            playerOffsetsAdapter = dbOffsetListAdapter
        )
    )
}

But now when i'd like to provide the database, I'm unable to provide the DriverFactory as it's an expect class.

Attempting to provide the specific Android or iOS factory's is also difficult as the Android one needs a context?

val dataModule = DI.Module(name = "dataModule") {
    // Need to provide DriverFactory
    bindSingleton { LocalDatabase(instance()) }
    bindProvider<SavedTeamRepository> { SavedTeamRepositoryImpl(instance()) }
}
1

There are 1 answers

0
Captain Jacky On

But now when i'd like to provide the database, I'm unable to provide the DriverFactory as it's an expect class.

The instance() you are trying to access in bindSingleton { LocalDatabase(instance()) } must be provided somewhere by the KodeIn.

  1. For the purpose of understanding let's rename your driver factory for Android:
actual class AndroidDriverFactory(private val context: Context) {
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db")
    }
}
  1. Now we have to provide this in Your androidMain package
bind<DriverFactory>() with singleton { AndroidDriverFactory(androidContext()) }
  1. Now the instance() value mentioned in bindSingleton { LocalDatabase(instance()) } (this must be under commonMain) would have the provided value by the KodeIn.

Attempting to provide the specific Android or iOS factory's is also difficult as the Android one needs a context?

Now you can provide DriverFactory for iOS as well under iOSMain. This time context is not needed.