| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- MODULE SQLiteBackup;
- (* Online backup API:
- backup_init/step/finish/remaining/pagecount. *)
- FROM SYSTEM IMPORT ADDRESS;
- FROM SQLite IMPORT
- SQLiteOk, SQLiteRow, SQLiteDone,
- sqlite3_open, sqlite3_close, sqlite3_exec,
- sqlite3_prepare_v2, sqlite3_step, sqlite3_column_int,
- sqlite3_finalize,
- sqlite3_backup_init, sqlite3_backup_step, sqlite3_backup_finish,
- sqlite3_backup_remaining, sqlite3_backup_pagecount,
- sqlite3_free;
- VAR
- ExitCode : INTEGER;
- src, dst, dst2, bk : ADDRESS;
- rc, pages : INTEGER;
- ok : BOOLEAN;
- PROCEDURE ExecSQL (h : ADDRESS; sql : ARRAY OF CHAR) : BOOLEAN;
- VAR
- errmsg : ADDRESS;
- good : BOOLEAN;
- BEGIN
- errmsg := NIL;
- good := sqlite3_exec(h, sql, NIL, NIL, errmsg) = SQLiteOk;
- IF errmsg # NIL THEN
- sqlite3_free(errmsg)
- END;
- RETURN good
- END ExecSQL;
- PROCEDURE CountRows (h : ADDRESS; want : INTEGER) : BOOLEAN;
- VAR
- s : ADDRESS;
- code, got : INTEGER;
- good : BOOLEAN;
- BEGIN
- s := NIL; got := -1; good := FALSE;
- code := sqlite3_prepare_v2(h, "SELECT count(*) FROM t;",
- -1, s, NIL);
- IF (code = SQLiteOk) AND (s # NIL) THEN
- IF sqlite3_step(s) = SQLiteRow THEN
- got := sqlite3_column_int(s, 0);
- IF sqlite3_step(s) = SQLiteDone THEN good := TRUE END
- END;
- IF sqlite3_finalize(s) # SQLiteOk THEN good := FALSE END
- END;
- RETURN good AND (got = want)
- END CountRows;
- BEGIN
- ExitCode := 1;
- src := NIL; dst := NIL; dst2 := NIL; bk := NIL;
- ok := FALSE;
- IF (sqlite3_open(":memory:", src) = SQLiteOk) AND (src # NIL)
- AND (sqlite3_open(":memory:", dst) = SQLiteOk) AND (dst # NIL)
- AND (sqlite3_open(":memory:", dst2) = SQLiteOk) AND (dst2 # NIL) THEN
- ok := ExecSQL(src, "CREATE TABLE t(x INTEGER);")
- AND ExecSQL(src, "INSERT INTO t VALUES(1);")
- AND ExecSQL(src, "INSERT INTO t VALUES(2);")
- END;
- (* Full backup into another in-memory database. *)
- IF ok THEN
- bk := sqlite3_backup_init(dst, "main", src, "main");
- ok := bk # NIL;
- IF ok THEN
- ok := sqlite3_backup_step(bk, -1) = SQLiteDone
- END;
- IF ok THEN
- pages := sqlite3_backup_pagecount(bk);
- ok := (pages > 0) AND (sqlite3_backup_remaining(bk) = 0)
- END;
- IF sqlite3_backup_finish(bk) # SQLiteOk THEN ok := FALSE END;
- bk := NIL
- END;
- IF ok THEN ok := CountRows(dst, 2) END;
- (* Incremental backup, one page at a time. *)
- IF ok THEN
- bk := sqlite3_backup_init(dst2, "main", src, "main");
- ok := bk # NIL;
- IF ok THEN
- rc := sqlite3_backup_step(bk, 1);
- WHILE (rc = SQLiteOk) DO
- rc := sqlite3_backup_step(bk, 1)
- END;
- ok := (rc = SQLiteDone) AND (sqlite3_backup_remaining(bk) = 0);
- IF sqlite3_backup_finish(bk) # SQLiteOk THEN ok := FALSE END;
- bk := NIL
- END
- END;
- IF ok THEN ok := CountRows(dst2, 2) END;
- IF bk # NIL THEN
- IF sqlite3_backup_finish(bk) # SQLiteOk THEN ok := FALSE END
- END;
- IF src # NIL THEN
- IF sqlite3_close(src) # SQLiteOk THEN ok := FALSE END
- END;
- IF dst # NIL THEN
- IF sqlite3_close(dst) # SQLiteOk THEN ok := FALSE END
- END;
- IF dst2 # NIL THEN
- IF sqlite3_close(dst2) # SQLiteOk THEN ok := FALSE END
- END;
- IF ok THEN ExitCode := 42 END
- END SQLiteBackup.
|