expo-sqlite 6,418 bundles its own SQLite 4,756 , the same version on every device. Wrap the app in <SQLiteProvider databaseName="booknest.db" onInit={migrate}> and any screen gets the open database from useSQLiteContext(). Schema changes go in onInit, versioned with SQLite's own user_version counter:
export async function migrate(db: SQLiteDatabase) {
const { user_version: v } =
(await db.getFirstAsync<{ user_version: number }>('PRAGMA user_version'))!;
if (v < 1) {
await db.execAsync(`
PRAGMA journal_mode = WAL;
CREATE TABLE notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
book_id INTEGER NOT NULL,
page INTEGER NOT NULL DEFAULT 0,
body TEXT NOT NULL,
created TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX notes_by_book ON notes (book_id);
PRAGMA user_version = 1;`);
}
console.log('database at version', Math.max(v, 1));
}A later release adds if (v < 2) { ... } below, so every install, however old, walks forward one step at a time. The reading-notes modal from Reading Notes Screen now saves and lists notes:
const load = useCallback(async () => {
setNotes(await db.getAllAsync<Note>(
'SELECT * FROM notes WHERE book_id = ? ORDER BY id DESC', bookId));
}, [db, bookId]);
const add = async () => {
const r = await db.runAsync('INSERT INTO notes (book_id, body) VALUES (?, ?)',
bookId, text.trim()); // ? placeholders: never build SQL by hand
console.log('note', r.lastInsertRowId, 'saved for book', bookId);LOG database at version 1 LOG note 1 saved for book 3
After a force-stop and relaunch, the note "The cardamom bread on page 88" was still listed under Salt and Saffron. WAL mode (hence the booknest.db-wal file beside the database) lets reads continue while a write is in progress. Use withTransactionAsync() to group writes, so a failure leaves nothing half-written.