xref: /sqlite-3.40.0/test/snapshot2.test (revision 6ab91a7a)
193006cddSdan# 2016 November 18
293006cddSdan#
393006cddSdan# The author disclaims copyright to this source code.  In place of
493006cddSdan# a legal notice, here is a blessing:
593006cddSdan#
693006cddSdan#    May you do good and not evil.
793006cddSdan#    May you find forgiveness for yourself and forgive others.
893006cddSdan#    May you share freely, never taking more than you give.
993006cddSdan#
1093006cddSdan#***********************************************************************
1193006cddSdan# This file implements regression tests for SQLite library. The focus
1293006cddSdan# of this file is the sqlite3_snapshot_xxx() APIs.
1393006cddSdan#
1493006cddSdan
1593006cddSdanset testdir [file dirname $argv0]
1693006cddSdansource $testdir/tester.tcl
1793006cddSdanifcapable !snapshot {finish_test; return}
1893006cddSdanset testprefix snapshot2
1993006cddSdan
2093006cddSdan# This test does not work with the inmemory_journal permutation. The reason
2193006cddSdan# is that each connection opened as part of this permutation executes
2293006cddSdan# "PRAGMA journal_mode=memory", which fails if the database is in wal mode
2393006cddSdan# and there are one or more existing connections.
2493006cddSdanif {[permutation]=="inmemory_journal"} {
2593006cddSdan  finish_test
2693006cddSdan  return
2793006cddSdan}
2893006cddSdan
2993006cddSdan#-------------------------------------------------------------------------
3093006cddSdan# Check that it is not possible to obtain a snapshot immediately after
3193006cddSdan# a wal mode database with an empty wal file is opened. But it is after
3293006cddSdan# the file has been written, even by some other connection.
3393006cddSdan#
3493006cddSdando_execsql_test 1.0 {
3593006cddSdan  PRAGMA journal_mode = wal;
3693006cddSdan  CREATE TABLE t1(a, b, c);
3793006cddSdan  INSERT INTO t1 VALUES(1, 2, 3);
3893006cddSdan  INSERT INTO t1 VALUES(4, 5, 6);
3993006cddSdan} {wal}
4093006cddSdan
4193006cddSdandb close
4293006cddSdando_test 1.1.1 { list [file exists test.db] [file exists test.db-wal] } {1 0}
4393006cddSdan
4493006cddSdansqlite3 db test.db
4593006cddSdando_execsql_test 1.1.2 { SELECT * FROM t1 } {1 2 3 4 5 6}
4693006cddSdan
4793006cddSdando_test 1.1.3 {
4893006cddSdan  execsql BEGIN
4993006cddSdan  list [catch { sqlite3_snapshot_get_blob db main } msg] $msg
5093006cddSdan} {1 SQLITE_ERROR}
5193006cddSdanexecsql COMMIT
5293006cddSdan
5393006cddSdando_test 1.1.4 {
5493006cddSdan  execsql { INSERT INTO t1 VALUES(7, 8, 9) }
5593006cddSdan  execsql BEGIN
5693006cddSdan  string length [sqlite3_snapshot_get_blob db main]
5793006cddSdan} 48
5893006cddSdanexecsql COMMIT
5993006cddSdan
6093006cddSdandb close
6193006cddSdando_test 1.2.1 { list [file exists test.db] [file exists test.db-wal] } {1 0}
6293006cddSdan
6393006cddSdansqlite3 db test.db
6493006cddSdando_execsql_test 1.2.2 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9}
6593006cddSdan
6693006cddSdando_test 1.2.3 {
6793006cddSdan  execsql BEGIN
6893006cddSdan  list [catch { sqlite3_snapshot_get_blob db main } msg] $msg
6993006cddSdan} {1 SQLITE_ERROR}
7093006cddSdanexecsql COMMIT
7193006cddSdan
7293006cddSdando_test 1.2.4 {
7393006cddSdan  sqlite3 db2 test.db
7493006cddSdan  execsql { INSERT INTO t1 VALUES(10, 11, 12) } db2
7593006cddSdan  execsql BEGIN
7693006cddSdan  string length [sqlite3_snapshot_get_blob db main]
7793006cddSdan} 48
7893006cddSdanexecsql COMMIT
7993006cddSdandb2 close
8093006cddSdan
811158498dSdan#-------------------------------------------------------------------------
825b4009f6Sdan# Simple tests for sqlite3_snapshot_recover().
831158498dSdan#
841158498dSdanreset_db
851158498dSdando_execsql_test 2.0 {
861158498dSdan  CREATE TABLE t1(x);
871158498dSdan  PRAGMA journal_mode = wal;
881158498dSdan  INSERT INTO t1 VALUES(1);
891158498dSdan  INSERT INTO t1 VALUES(2);
901158498dSdan} {wal}
911158498dSdan
921158498dSdando_test 2.1 {
931158498dSdan  db trans { set snap [sqlite3_snapshot_get_blob db main] }
941158498dSdan  sqlite3_db_config db NO_CKPT_ON_CLOSE 1
951158498dSdan  db close
961158498dSdan  sqlite3 db test.db
971158498dSdan
981158498dSdan  execsql {SELECT * FROM sqlite_master}
991158498dSdan  execsql BEGIN
1001158498dSdan  sqlite3_snapshot_open_blob db main $snap
1011158498dSdan  execsql COMMIT;
1021158498dSdan  execsql { INSERT INTO t1 VALUES(3); }
1031158498dSdan} {}
1041158498dSdan
1051158498dSdando_test 2.2 {
1061158498dSdan  sqlite3_db_config db NO_CKPT_ON_CLOSE 1
1071158498dSdan  db close
1081158498dSdan  sqlite3 db test.db
1091158498dSdan
1101158498dSdan  execsql {SELECT * FROM sqlite_master}
1111158498dSdan  execsql BEGIN
1121158498dSdan  list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
113*8d4b7a3fSdan} {1 SQLITE_ERROR_SNAPSHOT}
1141158498dSdan
1151158498dSdando_test 2.3 {
1161158498dSdan  execsql COMMIT
1171158498dSdan  sqlite3_snapshot_recover db main
1181158498dSdan  execsql BEGIN
1191158498dSdan  sqlite3_snapshot_open_blob db main $snap
1201158498dSdan  execsql { SELECT * FROM t1 }
1211158498dSdan} {1 2}
1221158498dSdan
1231158498dSdando_test 2.4 {
1241158498dSdan  execsql COMMIT
1251158498dSdan  execsql { SELECT * FROM t1 }
1261158498dSdan} {1 2 3}
1271158498dSdan
1281158498dSdando_test 2.5 {
1291158498dSdan  execsql { PRAGMA wal_checkpoint }
1301158498dSdan  sqlite3_db_config db NO_CKPT_ON_CLOSE 1
1311158498dSdan  db close
1321158498dSdan  sqlite3 db test.db
1331158498dSdan
1341158498dSdan  sqlite3_snapshot_recover db main
1351158498dSdan  execsql BEGIN
1361158498dSdan  list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg
137*8d4b7a3fSdan} {1 SQLITE_ERROR_SNAPSHOT}
1381158498dSdan
1395b4009f6Sdan#-------------------------------------------------------------------------
1405b4009f6Sdan# Check that calling sqlite3_snapshot_recover() does not confuse the
1415b4009f6Sdan# pager cache.
1425b4009f6Sdanreset_db
1435b4009f6Sdando_execsql_test 3.0 {
1445b4009f6Sdan  PRAGMA journal_mode = wal;
1455b4009f6Sdan  CREATE TABLE t1(x, y);
1465b4009f6Sdan  INSERT INTO t1 VALUES('a', 'b');
1475b4009f6Sdan  INSERT INTO t1 VALUES('c', 'd');
1485b4009f6Sdan} {wal}
1495b4009f6Sdando_test 3.1 {
1505b4009f6Sdan  sqlite3 db2 test.db
1515b4009f6Sdan  execsql { INSERT INTO t1 VALUES('e', 'f') } db2
1525b4009f6Sdan  db2 close
1535b4009f6Sdan  sqlite3_snapshot_recover db main
1545b4009f6Sdan} {}
1555b4009f6Sdando_execsql_test 3.2 {
1565b4009f6Sdan  SELECT * FROM t1;
1575b4009f6Sdan} {a b c d e f}
15893006cddSdan
1594d4757fcSdan#-------------------------------------------------------------------------
1604d4757fcSdan# Check that sqlite3_snapshot_recover() returns an error if it is called
1614d4757fcSdan# with an open read-transaction. Or on a database that does not exist. Or
1624d4757fcSdan# on the temp database. Or on a db that is not in wal mode.
1634d4757fcSdan#
1644d4757fcSdando_test 4.1 {
1654d4757fcSdan  sqlite3_snapshot_recover db main
1664d4757fcSdan} {}
1674d4757fcSdando_test 4.2 {
1684d4757fcSdan  execsql {
1694d4757fcSdan    BEGIN;
1704d4757fcSdan      SELECT * FROM sqlite_master;
1714d4757fcSdan  }
1724d4757fcSdan  list [catch { sqlite3_snapshot_recover db main } msg] $msg
1734d4757fcSdan} {1 SQLITE_ERROR}
1744d4757fcSdando_test 4.3 {
1754d4757fcSdan  execsql COMMIT
1764d4757fcSdan  sqlite3_snapshot_recover db main
1774d4757fcSdan} {}
1784d4757fcSdando_test 4.4 {
1794d4757fcSdan  list [catch { sqlite3_snapshot_recover db aux } msg] $msg
1804d4757fcSdan} {1 SQLITE_ERROR}
1814d4757fcSdando_test 4.5 {
1824d4757fcSdan  forcedelete test.db2
1834d4757fcSdan  execsql {
1844d4757fcSdan    ATTACH 'test.db2' AS aux;
1854d4757fcSdan    PRAGMA aux.journal_mode = wal;
1864d4757fcSdan    CREATE TABLE aux.t2(x, y);
1874d4757fcSdan  }
1884d4757fcSdan  list [catch { sqlite3_snapshot_recover db aux } msg] $msg
1894d4757fcSdan} {0 {}}
1904d4757fcSdando_test 4.6 {
1914d4757fcSdan  list [catch { sqlite3_snapshot_recover db temp } msg] $msg
1924d4757fcSdan} {1 SQLITE_ERROR}
1934d4757fcSdando_test 4.7 {
1944d4757fcSdan  execsql {
1954d4757fcSdan    PRAGMA aux.journal_mode = delete;
1964d4757fcSdan  }
1974d4757fcSdan  list [catch { sqlite3_snapshot_recover db aux } msg] $msg
1984d4757fcSdan} {1 SQLITE_ERROR}
1994d4757fcSdan
200b92d585cSdan#-------------------------------------------------------------------------
201b92d585cSdanreset_db
202b92d585cSdansqlite3 db2 test.db
203b92d585cSdando_execsql_test 5.0 {
204b92d585cSdan  CREATE TABLE t2(x);
205b92d585cSdan  PRAGMA journal_mode = wal;
206b92d585cSdan  INSERT INTO t2 VALUES('abc');
207b92d585cSdan  INSERT INTO t2 VALUES('def');
208b92d585cSdan  INSERT INTO t2 VALUES('ghi');
209b92d585cSdan} {wal}
210b92d585cSdan
211b92d585cSdando_test 5.1 {
212b92d585cSdan  execsql {
213b92d585cSdan    SELECT * FROM t2;
214b92d585cSdan    BEGIN;
215b92d585cSdan  } db2
216b92d585cSdan  set snap [sqlite3_snapshot_get_blob db2 main]
217b92d585cSdan  db2 eval END
218b92d585cSdan} {}
219b92d585cSdan
220b92d585cSdando_test 5.2 {
221b92d585cSdan  execsql BEGIN db2
222b92d585cSdan  sqlite3_snapshot_open_blob db2 main $snap
223b92d585cSdan  db2 eval { SELECT * FROM t2 ; END }
224b92d585cSdan} {abc def ghi}
225b92d585cSdan
226b92d585cSdando_test 5.3 {
227b92d585cSdan  execsql { PRAGMA wal_checkpoint = RESTART }
228b92d585cSdan  execsql BEGIN db2
229b92d585cSdan  sqlite3_snapshot_open_blob db2 main $snap
230b92d585cSdan  db2 eval { SELECT * FROM t2 ; END }
231b92d585cSdan} {abc def ghi}
232b92d585cSdan
233b92d585cSdando_test 5.4 {
234b92d585cSdan  execsql { INSERT INTO t2 VALUES('jkl') }
235b92d585cSdan  execsql BEGIN db2
236b92d585cSdan  list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg
237*8d4b7a3fSdan} {1 SQLITE_ERROR_SNAPSHOT}
238b92d585cSdan
239b92d585cSdan
24093006cddSdanfinish_test
241