Как подключить SQLDelight driver в Kotlin Multiplatform library

В Kotlin Multiplatform нельзя подключить один SQLDelight driver сразу для всех платформ. Общий код знает про схему базы и тип SqlDriver, а конкретный драйвер подключается в platform source set: Android, JVM, iOS или Native

Идея такая:

  • в commonMain лежит общий код базы;
  • в androidMain подключается Android-драйвер;
  • в iosMain или другом native source set подключается Native-драйвер;
  • общий код получает драйвер через фабрику.

Gradle-зависимости

Упрощенный пример для KMP-проекта:

kotlin {
    androidTarget()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        commonMain.dependencies {
            implementation("app.cash.sqldelight:runtime:2.3.2")
            implementation("app.cash.sqldelight:coroutines-extensions:2.3.2")
        }

        androidMain.dependencies {
            implementation("app.cash.sqldelight:android-driver:2.3.2")
        }

        iosMain.dependencies {
            implementation("app.cash.sqldelight:native-driver:2.3.2")
        }
    }
}

Версию проверяйте перед публикацией проекта. На 1 июня 2026 года в Maven Central видна ветка 2.3.x, но в вашем проекте важнее совместимость plugin, runtime и drivers. Смысл примера не в конкретной цифре, а в разделении: runtime в общий код, driver — в платформенный код

Общая фабрика

В commonMain можно объявить ожидаемую фабрику:

expect class DatabaseDriverFactory {
    fun createDriver(): SqlDriver
}

А общий код базы принимает драйвер:

class AppDatabaseProvider(
    driverFactory: DatabaseDriverFactory
) {
    private val database = AppDatabase(driverFactory.createDriver())
}

Android-реализация

actual class DatabaseDriverFactory(
    private val context: Context
) {
    actual fun createDriver(): SqlDriver {
        return AndroidSqliteDriver(
            schema = AppDatabase.Schema,
            context = context,
            name = "app.db"
        )
    }
}

Для Android нужен Context, поэтому фабрику обычно создают в app-слое, DI-модуле или рядом с инициализацией приложения

iOS-реализация

В iosMain:

actual class DatabaseDriverFactory {
    actual fun createDriver(): SqlDriver {
        return NativeSqliteDriver(
            schema = AppDatabase.Schema,
            name = "app.db"
        )
    }
}

Так общий код не знает, на какой платформе работает приложение, но получает готовый SqlDriver

Как проверить

  1. Синхронизируйте Gradle.
  2. Убедитесь, что SQLDelight сгенерировал класс AppDatabase.
  3. Соберите Android target.
  4. Соберите iOS target или хотя бы запустите Gradle-задачу компиляции.
  5. Создайте простую таблицу и выполните первый select.

Если класс базы не генерируется, проблема чаще всего не в driver, а в SQLDelight plugin, package name или расположении .sq файлов

Частые ошибки

Класть Android-драйвер в commonMain

Так делать нельзя: commonMain не должен зависеть от Android API

Забыть schema

При создании драйвера нужно передать AppDatabase.Schema. Без схемы SQLDelight не сможет создать таблицы

Смешать версии SQLDelight

Runtime, plugin и drivers должны быть совместимыми. Не собирайте зависимости из разных примеров без проверки версии

Если Gradle ругается на несовместимость, сначала приведите все SQLDelight-зависимости к одной версии, затем пересинхронизируйте проект и только потом ищите ошибку в .sq файлах

Что почитать дальше по Kotlin

Если нужен общий маршрут по теме, откройте рубрику Kotlin. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x