16fa255fdSdan# 2011 November 16 26fa255fdSdan# 36fa255fdSdan# The author disclaims copyright to this source code. In place of 46fa255fdSdan# a legal notice, here is a blessing: 56fa255fdSdan# 66fa255fdSdan# May you do good and not evil. 76fa255fdSdan# May you find forgiveness for yourself and forgive others. 86fa255fdSdan# May you share freely, never taking more than you give. 96fa255fdSdan# 106fa255fdSdan#*********************************************************************** 116fa255fdSdan# 126fa255fdSdan# This file contains test cases for sqlite3_db_cacheflush API. 136fa255fdSdan# 146fa255fdSdan 156fa255fdSdanset testdir [file dirname $argv0] 166fa255fdSdansource $testdir/tester.tcl 176fa255fdSdanset testprefix cacheflush 186fa255fdSdantest_set_config_pagecache 0 0 196fa255fdSdan 206fa255fdSdan# Run the supplied SQL on a copy of the database currently stored on 216fa255fdSdan# disk in file $dbfile. 226fa255fdSdanproc diskquery {dbfile sql} { 236fa255fdSdan forcecopy $dbfile dq.db 246fa255fdSdan sqlite3 dq dq.db 256fa255fdSdan set res [execsql $sql dq] 266fa255fdSdan dq close 276fa255fdSdan set res 286fa255fdSdan} 296fa255fdSdan 306fa255fdSdan# Simplest possible test. 316fa255fdSdan# 326fa255fdSdando_execsql_test 1.1.0 { 336fa255fdSdan CREATE TABLE t1(a, b); 346fa255fdSdan INSERT INTO t1 VALUES(1, 2); 356fa255fdSdan BEGIN; 366fa255fdSdan INSERT INTO t1 VALUES(3, 4); 376fa255fdSdan} 386fa255fdSdando_test 1.1.1 { 396fa255fdSdan diskquery test.db { SELECT * FROM t1 } 406fa255fdSdan} {1 2} 416fa255fdSdando_test 1.1.2 { 426fa255fdSdan sqlite3_db_cacheflush db 436fa255fdSdan diskquery test.db { SELECT * FROM t1 } 446fa255fdSdan} {1 2 3 4} 456fa255fdSdan 466fa255fdSdan# Test that multiple pages may be flushed to disk. 476fa255fdSdan# 486fa255fdSdando_execsql_test 1.2.0 { 496fa255fdSdan COMMIT; 506fa255fdSdan CREATE TABLE t2(a, b); 516fa255fdSdan BEGIN; 526fa255fdSdan INSERT INTO t1 VALUES(5, 6); 536fa255fdSdan INSERT INTO t2 VALUES('a', 'b'); 546fa255fdSdan} 556fa255fdSdando_test 1.2.1 { 566fa255fdSdan diskquery test.db { 576fa255fdSdan SELECT * FROM t1; 586fa255fdSdan SELECT * FROM t2; 596fa255fdSdan } 606fa255fdSdan} {1 2 3 4} 616fa255fdSdando_test 1.2.2 { 626fa255fdSdan sqlite3_db_cacheflush db 636fa255fdSdan diskquery test.db { 646fa255fdSdan SELECT * FROM t1; 656fa255fdSdan SELECT * FROM t2; 666fa255fdSdan } 676fa255fdSdan} {1 2 3 4 5 6 a b} 686fa255fdSdan 696fa255fdSdan# Test that pages with nRef!=0 are not flushed to disk. 706fa255fdSdan# 716fa255fdSdando_execsql_test 1.3.0 { 726fa255fdSdan COMMIT; 736fa255fdSdan CREATE TABLE t3(a, b); 746fa255fdSdan BEGIN; 756fa255fdSdan INSERT INTO t1 VALUES(7, 8); 766fa255fdSdan INSERT INTO t2 VALUES('c', 'd'); 776fa255fdSdan INSERT INTO t3 VALUES('i', 'ii'); 786fa255fdSdan} 796fa255fdSdando_test 1.3.1 { 806fa255fdSdan diskquery test.db { 816fa255fdSdan SELECT * FROM t1; 826fa255fdSdan SELECT * FROM t2; 836fa255fdSdan SELECT * FROM t3; 846fa255fdSdan } 856fa255fdSdan} {1 2 3 4 5 6 a b} 866fa255fdSdando_test 1.3.2 { 876fa255fdSdan db eval { SELECT a FROM t1 } { 886fa255fdSdan if {$a==3} { 896fa255fdSdan sqlite3_db_cacheflush db 906fa255fdSdan } 916fa255fdSdan } 926fa255fdSdan diskquery test.db { 936fa255fdSdan SELECT * FROM t1; 946fa255fdSdan SELECT * FROM t2; 956fa255fdSdan SELECT * FROM t3; 966fa255fdSdan } 976fa255fdSdan} {1 2 3 4 5 6 a b c d i ii} 986fa255fdSdando_test 1.3.2 { 996fa255fdSdan sqlite3_db_cacheflush db 1006fa255fdSdan diskquery test.db { 1016fa255fdSdan SELECT * FROM t1; 1026fa255fdSdan SELECT * FROM t2; 1036fa255fdSdan SELECT * FROM t3; 1046fa255fdSdan } 1056fa255fdSdan} {1 2 3 4 5 6 7 8 a b c d i ii} 1066fa255fdSdan 1076fa255fdSdan# Check that SQLITE_BUSY is returned if pages cannot be flushed due to 1086fa255fdSdan# conflicting read locks. 1096fa255fdSdan# 1106fa255fdSdando_execsql_test 1.4.0 { 1116fa255fdSdan COMMIT; 1126fa255fdSdan BEGIN; 1136fa255fdSdan INSERT INTO t1 VALUES(9, 10); 1146fa255fdSdan} 1156fa255fdSdando_test 1.4.1 { 1166fa255fdSdan sqlite3 db2 test.db 1176fa255fdSdan db2 eval { 1186fa255fdSdan BEGIN; 1196fa255fdSdan SELECT * FROM t1; 1206fa255fdSdan } 1216fa255fdSdan diskquery test.db { 1226fa255fdSdan SELECT * FROM t1; 1236fa255fdSdan } 1246fa255fdSdan} {1 2 3 4 5 6 7 8} 1256fa255fdSdando_test 1.4.2 { 1266fa255fdSdan list [catch { sqlite3_db_cacheflush db } msg] $msg 1276fa255fdSdan} {1 {database is locked}} 1286fa255fdSdando_test 1.4.3 { 1296fa255fdSdan diskquery test.db { 1306fa255fdSdan SELECT * FROM t1; 1316fa255fdSdan } 1326fa255fdSdan} {1 2 3 4 5 6 7 8} 1336fa255fdSdando_test 1.4.4 { 1346fa255fdSdan db2 close 1356fa255fdSdan sqlite3_db_cacheflush db 1366fa255fdSdan diskquery test.db { 1376fa255fdSdan SELECT * FROM t1; 1386fa255fdSdan } 1396fa255fdSdan} {1 2 3 4 5 6 7 8 9 10} 1406fa255fdSdando_execsql_test 1.4.5 { COMMIT } 1416fa255fdSdan 1426fa255fdSdan#------------------------------------------------------------------------- 1436fa255fdSdan# Test that ATTACHed database caches are also flushed. 1446fa255fdSdan# 1456fa255fdSdanforcedelete test.db2 1466fa255fdSdando_execsql_test 2.1.0 { 1476fa255fdSdan ATTACH 'test.db2' AS aux; 1486fa255fdSdan CREATE TABLE aux.t4(x, y); 1496fa255fdSdan INSERT INTO t4 VALUES('A', 'B'); 1506fa255fdSdan BEGIN; 1516fa255fdSdan INSERT INTO t1 VALUES(11, 12); 1526fa255fdSdan INSERT INTO t4 VALUES('C', 'D'); 1536fa255fdSdan} 1546fa255fdSdando_test 2.1.1 { 1556fa255fdSdan diskquery test.db { SELECT * FROM t1; } 1566fa255fdSdan} {1 2 3 4 5 6 7 8 9 10} 1576fa255fdSdando_test 2.1.2 { 1586fa255fdSdan diskquery test.db2 { SELECT * FROM t4; } 1596fa255fdSdan} {A B} 1606fa255fdSdando_test 2.1.3 { 1616fa255fdSdan sqlite3_db_cacheflush db 1626fa255fdSdan diskquery test.db { SELECT * FROM t1; } 1636fa255fdSdan} {1 2 3 4 5 6 7 8 9 10 11 12} 1646fa255fdSdando_test 2.1.4 { 1656fa255fdSdan sqlite3_db_cacheflush db 1666fa255fdSdan diskquery test.db2 { SELECT * FROM t4; } 1676fa255fdSdan} {A B C D} 1686fa255fdSdando_execsql_test 2.1.5 { COMMIT } 1696fa255fdSdan 1706fa255fdSdan# And that hitting an SQLITE_BUSY when flushing "main" does not stop 1716fa255fdSdan# SQLite from going on to flush "aux". 1726fa255fdSdan# 1736fa255fdSdando_execsql_test 2.2.0 { 1746fa255fdSdan BEGIN; 1756fa255fdSdan INSERT INTO t1 VALUES(13, 14); 1766fa255fdSdan INSERT INTO t4 VALUES('E', 'F'); 1776fa255fdSdan} 1786fa255fdSdando_test 2.2.1 { 1796fa255fdSdan diskquery test.db { SELECT * FROM t1; } 1806fa255fdSdan} {1 2 3 4 5 6 7 8 9 10 11 12} 1816fa255fdSdando_test 2.2.2 { 1826fa255fdSdan diskquery test.db2 { SELECT * FROM t4; } 1836fa255fdSdan} {A B C D} 1846fa255fdSdando_test 2.2.3 { 1856fa255fdSdan sqlite3 db2 test.db 1866fa255fdSdan execsql { 1876fa255fdSdan BEGIN; 1886fa255fdSdan SELECT * FROM t1; 1896fa255fdSdan } db2 1906fa255fdSdan list [catch { sqlite3_db_cacheflush db } msg] $msg 1916fa255fdSdan} {1 {database is locked}} 1926fa255fdSdando_test 2.2.4 { 1936fa255fdSdan diskquery test.db { SELECT * FROM t1; } 1946fa255fdSdan} {1 2 3 4 5 6 7 8 9 10 11 12} 1956fa255fdSdando_test 2.2.5 { 1966fa255fdSdan diskquery test.db2 { SELECT * FROM t4; } 1976fa255fdSdan} {A B C D E F} 1986fa255fdSdando_test 2.2.6 { 1996fa255fdSdan db2 close 2006fa255fdSdan sqlite3_db_cacheflush db 2016fa255fdSdan diskquery test.db { SELECT * FROM t1; } 2026fa255fdSdan} {1 2 3 4 5 6 7 8 9 10 11 12 13 14} 2036fa255fdSdando_execsql_test 2.2.7 { COMMIT } 2046fa255fdSdan 2054a6beac2Sdan#------------------------------------------------------------------------- 2064a6beac2Sdan# Test that nothing terrible happens if sqlite3_db_cacheflush() is 2074a6beac2Sdan# called on an in-memory database. 2084a6beac2Sdan# 2094a6beac2Sdando_test 3.0 { 2104a6beac2Sdan db close 2114a6beac2Sdan sqlite3 db :memory: 2124a6beac2Sdan db eval { 2134a6beac2Sdan CREATE TABLE t1(x PRIMARY KEY); 2144a6beac2Sdan CREATE TABLE t2(y PRIMARY KEY); 2154a6beac2Sdan BEGIN; 2164a6beac2Sdan INSERT INTO t1 VALUES(randomblob(100)); 2174a6beac2Sdan INSERT INTO t2 VALUES(randomblob(100)); 2184a6beac2Sdan INSERT INTO t1 VALUES(randomblob(100)); 2194a6beac2Sdan INSERT INTO t2 VALUES(randomblob(100)); 2204a6beac2Sdan } 2214a6beac2Sdan sqlite3_db_cacheflush db 2224a6beac2Sdan} {} 2234a6beac2Sdan 2244a6beac2Sdando_execsql_test 3.1 { PRAGMA integrity_check } ok 2254a6beac2Sdando_execsql_test 3.2 { COMMIT } 2264a6beac2Sdando_execsql_test 3.3 { PRAGMA integrity_check } ok 2274a6beac2Sdando_execsql_test 3.4 { 2284a6beac2Sdan SELECT count(*) FROM t1; 2294a6beac2Sdan SELECT count(*) FROM t2; 2304a6beac2Sdan} {2 2} 2314a6beac2Sdan 232*e8e6657fSdan#------------------------------------------------------------------------- 233*e8e6657fSdan# Test that calling sqlite3_db_cacheflush() does not interfere with 234*e8e6657fSdan# savepoint transactions. 235*e8e6657fSdan# 236*e8e6657fSdando_test 4.0 { 237*e8e6657fSdan reset_db 238*e8e6657fSdan execsql { 239*e8e6657fSdan CREATE TABLE ta(a, aa); 240*e8e6657fSdan CREATE TABLE tb(b, bb); 241*e8e6657fSdan INSERT INTO ta VALUES('a', randomblob(500)); 242*e8e6657fSdan INSERT INTO tb VALUES('b', randomblob(500)); 243*e8e6657fSdan BEGIN; 244*e8e6657fSdan UPDATE ta SET a = 'A'; 245*e8e6657fSdan SAVEPOINT one; 246*e8e6657fSdan UPDATE tb SET b = 'B'; 247*e8e6657fSdan } 248*e8e6657fSdan 249*e8e6657fSdan sqlite3_db_cacheflush db 250*e8e6657fSdan diskquery test.db { 251*e8e6657fSdan SELECT a FROM ta; 252*e8e6657fSdan SELECT b FROM tb; 253*e8e6657fSdan } 254*e8e6657fSdan} {A B} 255*e8e6657fSdan 256*e8e6657fSdando_test 4.1 { 257*e8e6657fSdan execsql { 258*e8e6657fSdan ROLLBACK TO one; 259*e8e6657fSdan } 260*e8e6657fSdan sqlite3_db_cacheflush db 261*e8e6657fSdan diskquery test.db { 262*e8e6657fSdan SELECT a FROM ta; 263*e8e6657fSdan SELECT b FROM tb; 264*e8e6657fSdan } 265*e8e6657fSdan} {A b} 266*e8e6657fSdan 267*e8e6657fSdando_test 4.2 { 268*e8e6657fSdan execsql { 269*e8e6657fSdan INSERT INTO tb VALUES('c', randomblob(10)); 270*e8e6657fSdan INSERT INTO tb VALUES('d', randomblob(10)); 271*e8e6657fSdan INSERT INTO tb VALUES('e', randomblob(10)); 272*e8e6657fSdan } 273*e8e6657fSdan sqlite3_db_cacheflush db 274*e8e6657fSdan diskquery test.db { 275*e8e6657fSdan SELECT a FROM ta; 276*e8e6657fSdan SELECT b FROM tb; 277*e8e6657fSdan } 278*e8e6657fSdan} {A b c d e} 279*e8e6657fSdan 280*e8e6657fSdando_test 4.3 { 281*e8e6657fSdan execsql { 282*e8e6657fSdan SAVEPOINT two; 283*e8e6657fSdan UPDATE tb SET b = upper(b); 284*e8e6657fSdan } 285*e8e6657fSdan sqlite3_db_cacheflush db 286*e8e6657fSdan diskquery test.db { 287*e8e6657fSdan SELECT a FROM ta; 288*e8e6657fSdan SELECT b FROM tb; 289*e8e6657fSdan } 290*e8e6657fSdan} {A B C D E} 291*e8e6657fSdan 292*e8e6657fSdando_test 4.4 { 293*e8e6657fSdan execsql { 294*e8e6657fSdan ROLLBACK TO two; 295*e8e6657fSdan } 296*e8e6657fSdan sqlite3_db_cacheflush db 297*e8e6657fSdan diskquery test.db { 298*e8e6657fSdan SELECT a FROM ta; 299*e8e6657fSdan SELECT b FROM tb; 300*e8e6657fSdan } 301*e8e6657fSdan} {A b c d e} 302*e8e6657fSdan 303*e8e6657fSdando_test 4.4 { 304*e8e6657fSdan execsql { 305*e8e6657fSdan ROLLBACK TO one; 306*e8e6657fSdan } 307*e8e6657fSdan sqlite3_db_cacheflush db 308*e8e6657fSdan diskquery test.db { 309*e8e6657fSdan SELECT a FROM ta; 310*e8e6657fSdan SELECT b FROM tb; 311*e8e6657fSdan } 312*e8e6657fSdan} {A b} 313*e8e6657fSdan 314*e8e6657fSdando_test 4.5 { 315*e8e6657fSdan execsql { 316*e8e6657fSdan ROLLBACK; 317*e8e6657fSdan SELECT a FROM ta; 318*e8e6657fSdan SELECT b FROM tb; 319*e8e6657fSdan } 320*e8e6657fSdan} {a b} 3214a6beac2Sdan 3226fa255fdSdantest_restore_config_pagecache 3236fa255fdSdanfinish_test 324