Skip to content

Commit

Permalink
Support updating a view which has a INSTEAD OF trigger (#3050)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alec Strong authored and AlecKazakova committed Apr 11, 2022
1 parent 6874e43 commit 23468f3
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ class MutatorQueryGenerator(
}

query.containingFile.iterateSqlFiles { psiFile ->
val tablesAffected = mutableListOf(query.tableEffected)
val tablesAffected = query.tablesAffected.toMutableList()

if (foreignKeyCascadeCheck != null) {
psiFile.sqlStmtList?.stmtList?.mapNotNull { it.createTableStmt }?.forEach { table ->
val effected = table.findChildrenOfType<SqlForeignKeyClause>().any {
(it.foreignTable.name == query.tableEffected.name) && it.node.findChildByType(foreignKeyCascadeCheck) != null
(it.foreignTable.name in query.tablesAffected.map { it.name }) && it.node.findChildByType(foreignKeyCascadeCheck) != null
}
if (effected) tablesAffected.add(TableNameElement.CreateTableName(table.tableName))
}
}

psiFile.triggers.forEach { trigger ->
if (trigger.tableName?.name == query.tableEffected.name) {
if (trigger.tableName?.name in query.tablesAffected.map { it.name }) {
val triggered = when (query) {
is NamedMutator.Delete -> trigger.childOfType(SqlTypes.DELETE) != null
is NamedMutator.Insert -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ abstract class QueryGenerator(
if (result == 0L) throw %T(%S)
""".trimIndent(),
ClassName("app.cash.sqldelight.db", "OptimisticLockException"),
"UPDATE on ${query.tableEffected.name} failed because optimistic lock ${optimisticLock.name} did not match"
"UPDATE on ${query.tablesAffected.single().name} failed because optimistic lock ${optimisticLock.name} did not match"
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ sealed class NamedMutator(
) : NamedExecute(identifier, statement) {
val containingFile = statement.sqFile() as SqlDelightQueriesFile

internal val tableEffected: TableNameElement by lazy {
tableName.referencedTables().single()
internal val tablesAffected: Collection<TableNameElement> by lazy {
tableName.referencedTables()
}

class Insert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -767,4 +767,57 @@ class MutatorQueryTypeTest {
|""".trimMargin()
)
}

@Test fun `update on a view with a trigger`() {
val file = FixtureCompiler.parseSql(
"""
|CREATE TABLE foo (
| id INTEGER NOT NULL PRIMARY KEY,
| name TEXT NOT NULL,
| selected INTEGER AS kotlin.Boolean NOT NULL
|);
|
|CREATE TABLE bar (
| id INTEGER NOT NULL PRIMARY KEY,
| short_name TEXT NOT NULL,
| full_name TEXT NOT NULL,
| selected INTEGER AS kotlin.Boolean NOT NULL
|);
|
|CREATE VIEW foobar AS
|SELECT id, name, selected FROM foo
|UNION
|SELECT id, short_name AS name, selected FROM bar;
|
|CREATE TRIGGER foobar_update_added
|INSTEAD OF UPDATE OF selected ON foobar
|BEGIN
| UPDATE foo SET selected = new.selected WHERE id = new.id;
| UPDATE bar SET selected = new.selected WHERE id = new.id;
|END;
|
|updateFoobarSelected:
|UPDATE OR IGNORE foobar SET selected = ? WHERE id = ?;
|""".trimMargin(),
tempFolder, fileName = "Data.sq"
)

val mutator = file.namedMutators.first()
val generator = MutatorQueryGenerator(mutator)

assertThat(generator.function().toString()).isEqualTo(
"""
|public fun updateFoobarSelected(selected: kotlin.Boolean, id: kotlin.Long): kotlin.Unit {
| driver.execute(1531606598, ""${'"'}UPDATE OR IGNORE foobar SET selected = ? WHERE id = ?""${'"'}, 2) {
| bindBoolean(1, selected)
| bindLong(2, id)
| }
| notifyQueries(1531606598) { emit ->
| emit("bar")
| emit("foo")
| }
|}
|""".trimMargin()
)
}
}

0 comments on commit 23468f3

Please sign in to comment.