Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ForeignKey: Inconsistent behavior across different KMP targets, especially during migration #18

Closed
tamimattafi opened this issue May 17, 2024 · 0 comments · Fixed by #19
Assignees
Labels
bug Something isn't working

Comments

@tamimattafi
Copy link
Owner

tamimattafi commented May 17, 2024

Problem

Enabling and disabling foreign keys currently works through the API provided by sqldelight, however, this leads to inconsistent behavior between android and iOS.

Explanation

Inside NativeSqliteDriver, and exactly during the creation of a connection through DatabaseManager, PRAGMA foreign_keys = ON; is called before migrate.

migrate is executed inside a transaction, therefore, our PRAGMA foreign_keys = OFF; call inside KabinSqlSchema.migrate function has no effect, because according to the official docs, it should be called before BEGIN TRANSACTION or after COMMIT https://www.sqlite.org/pragma.html#pragma_foreign_keys

Even tho we have defer_foreign_keys calls inside our transactions, some errors triggered by foreign keys during migration are not handled, since they are not directly related to constraints, for example, having table not found errors when dropping related tables. This throws an error immediately and doesn't wait for COMMIT to recheck the integrity of the keys https://www.sqlite.org/pragma.html#pragma_defer_foreign_keys

On android, foreign keys are enabled inside the callback onOpen, here's the official documentation of the method:

Called when the database has been opened. The implementation should check SupportSQLiteDatabase.isReadOnly before updating the database.
This method is called after the database connection has been configured and after the database schema has been created, upgraded or downgraded as necessary. If the database connection must be configured in some way before the schema is created, upgraded, or downgraded, do it in onConfigure instead.
Params:
db - The database.

As we can see, onOpen is called after all the work with the scheme is done, including migration, which means during migration, foreign keys are disabled, and enabled only after everything is set.

Solution

Make a unified logic to enabled and disable foreign keys during driver creation, using raw SQL calls, rather than using platform specific config. This will help to increase the consistency and similarity.

@tamimattafi tamimattafi self-assigned this May 17, 2024
@tamimattafi tamimattafi added the bug Something isn't working label May 17, 2024
@tamimattafi tamimattafi changed the title ForeignKey: Inconsistent behavior between targets, especially during migration ForeignKey: Inconsistent behavior across different KMP targets, especially during migration May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant