cashapp / sqldelight

SQLDelight - Generates typesafe Kotlin APIs from SQL
https://cashapp.github.io/sqldelight/
Apache License 2.0
6.03k stars 503 forks source link

INSERT statements are ignored in a fresh install of the Application #4799

Open arcslash opened 8 months ago

arcslash commented 8 months ago

SQLDelight Version

1.5.4

SQLDelight Dialect

SQLite ( Multiplatform )

Describe the Bug

INSERT statements are ignored in a fresh install of the application,

Where the gradle configuration is as followed,

sqldelight {
    database("AppDatabase") {
        dialect = "sqlite:3.25"
        packageName = "com.application.shared.cache"
        deriveSchemaFromMigrations = true
        verifyMigrations = true
    }
}

INSERT statements do work on application update but not of fresh install of the application where INSERTS are simply ignored.

Stacktrace

No response

kansson commented 7 months ago

Also have this issue.

JakeWharton commented 7 months ago

Where are these inserts? In the .sq? or .sqm?

kansson commented 7 months ago

Where are these inserts? In the .sq? or .sqm?

They are directly after the table definition in a .sqm file with deriveSchemaFromMigrations enabled. If you add a subsequent migration file with insert statements they execute as expected.

JakeWharton commented 7 months ago

Ah, I see. I don't know anything about the implementation of that flag. Sorry!

alex-z0 commented 4 months ago

I can confirm the same behavior of version 2.0.1, insert statements from migrations are ignored in the create() function.

Gradle config:

sqldelight {
    databases {
        create("AppDatabase") {
            packageName = "com.example.data.sqldelight"
            schemaOutputDirectory = file("build/db")
            migrationOutputDirectory = file("build/db")
            deriveSchemaFromMigrations = true
            verifyMigrations = true
        }
    }
}

1.sqm:

CREATE TABLE example (
  key_id INTEGER PRIMARY KEY NOT NULL,
  key TEXT NOT NULL,
  value TEXT NOT NULL
);

INSERT INTO example (key, value) VALUES ('my_key', 'my value');

2.sqm:

INSERT INTO example(key, value) VALUES ('second', 'second value');

AppDatabase.kt (generated):

    override fun create(driver: SqlDriver): QueryResult.Value<Unit> {
      driver.execute(null, """
          |CREATE TABLE example (
          |  key_id INTEGER PRIMARY KEY NOT NULL,
          |  key TEXT NOT NULL,
          |  value TEXT NOT NULL
          |)
          """.trimMargin(), 0)
      return QueryResult.Unit
    }

    private fun migrateInternal(
      driver: SqlDriver,
      oldVersion: Long,
      newVersion: Long,
    ): QueryResult.Value<Unit> {
      if (oldVersion <= 1 && newVersion > 1) {
        driver.execute(null, """
            |CREATE TABLE example (
            |  key_id INTEGER PRIMARY KEY NOT NULL,
            |  key TEXT NOT NULL,
            |  value TEXT NOT NULL
            |)
            """.trimMargin(), 0)
        driver.execute(null, "INSERT INTO example (key, value) VALUES ('my_key', 'my value')", 0)
      }
      if (oldVersion <= 2 && newVersion > 2) {
        driver.execute(null, "INSERT INTO example(key, value) VALUES ('second', 'second value')", 0)
      }
      return QueryResult.Unit
    }

Line responsible for filtering out insert (and other non-schema statements) in version 2.0.1: https://github.com/cashapp/sqldelight/blob/704dadeec44907027537ce6896d82579ed978d5d/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/DatabaseGenerator.kt#L225