Ti.Database schema change leaves database partially migrated on failure
0 reputation · 30 Aug 2024, 18:38 UTC
0 reputation · 30 Aug 2024, 18:38 UTC
The goal is to guarantee that a series of DDL statements applied through Ti.Database either fully succeed or leave the local SQLite database unchanged.
Titanium supplies only low‑level SQLite access; there is no built‑in migration runner, and the explicit transaction API (BEGIN/COMMIT/ROLLBACK) varies across SDK releases, so developers often rely on a Ti.App.Properties version key and idempotent DDL to gate upgrades.
It remains unclear whether a failure partway through a multi‑statement upgrade triggers an automatic compensating rollback or simply aborts the transaction, leaving the schema and data out of sync.
Does a failing ALTER TABLE inside a transaction roll back a preceding CREATE TABLE on current SDK versions? How can an app reliably detect a partially applied schema on the next launch? What pattern can provide atomic schema upgrades without a dedicated migration framework?
34775 reputation · 31 Aug 2024, 06:30 UTC
No. A failing ALTER TABLE does not reliably roll back a preceding CREATE TABLE on all current Titanium SDK versions and platforms. SQLite itself can roll back DDL inside an explicit transaction, but Ti.Database does not guarantee that your DDL runs inside one transaction. The explicit transaction API, error propagation, and autocommit behavior vary across SDK releases and between iOS and Android. Relying on Ti.App.Properties version alone will hide a partial migration.
Ti.Database is low‑level SQLite access. There is no built‑in migration runner.Ti.App.Properties with hand‑written DDL.BEGIN…COMMIT block, including CREATE TABLE followed by a failing ALTER TABLE.Ti.Database.execute calls in autocommit mode. Each successful statement is committed immediately.Ti.Database.transaction behavior is version and platform sensitive. Some releases do not wrap DDL in a true SQLite transaction, or they commit on first success.COMMIT makes a partial schema invisible on restart and prevents safe retry.ALTER TABLE is limited. Complex changes require multi‑statement table recreation which is more prone to partial apply if not wrapped correctly.Do not trust the version key alone. Introspect the database.
Ti.App.Properties.sqlite_master for expected tables and PRAGMA table_info for expected columns and indexes for the target version.journal_mode to confirm whether BEGIN/COMMIT are actually sent by your SDK version on the platform in use.// Example introspection, not a full runner
var db = Ti.Database.open('app.db');
var tables = db.execute('SELECT name FROM sqlite_master WHERE type="table"');
Ti.Database.transaction is reliable, use it; otherwise send BEGIN IMMEDIATE via execute and manage COMMIT/ROLLBACK yourself.sqlite_master and PRAGMA table_info before COMMIT.COMMIT, then persist the new version to Ti.App.Properties.ROLLBACK and leave the version unchanged so the upgrade can be retried safely.Idempotent DDL and a pre‑upgrade snapshot of sqlite_master make retries safer, but idempotency does not guarantee atomicity and can mask data‑schema drift.
The recommendation changes with the exact Titanium SDK version and target platform. Confirm which SDK version and iOS/Android you are running, and whether Ti.Database.transaction in that release actually sends BEGIN/COMMIT for DDL. That determines whether an explicit transaction wrapper is sufficient or you need to fall back to manual BEGIN IMMEDIATE with manual rollback.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 30 Aug 2024, 20:12 UTC
The core issue is that Ti.Database.execute calls run in autocommit mode by default. Each statement commits immediately, so a failure after CREATE TABLE leaves that table behind. To get atomicity, execute a single raw SQL string containing BEGIN TRANSACTION; CREATE TABLE ...; ALTER TABLE ...; COMMIT;. SQLite will roll back the entire block on any error.
Verification pattern: Before applying migrations, query sqlite_master to confirm expected tables/columns exist. Store the schema version in Ti.App.Properties only after successful verification, never optimistically. If a mismatch is detected, either re-run the migration or prompt the user to restore from backup.