AryaWu/sqlite
0
1/*2** This program is used to generate and verify databases with hot journals.3** Use this program to generate a hot journal on one machine and verify4** that it rolls back correctly on another machine with a different5** architecture.6**7** Usage:8**9** rollback-test new [-utf8] [-utf16le] [-utf16be] [-pagesize=N] DATABASE10** rollback-test check DATABASE11** rollback-test crash [-wal] [-rollback] DATABASE12*/13#include <stdio.h>14#include <stdlib.h>15#include <string.h>16#include "sqlite3.h"17 18static void usage(char *argv0){19 fprintf(stderr,20 "Usage: %s new [-utf8] [-utf16le] [-utf16be] [-pagesize=N] DATABASE\n"21 " %s check DATABASE\n"22 " %s crash [-wal] DATABASE\n",23 argv0, argv0, argv024 );25 exit(1);26}27 28static sqlite3 *openDb(const char *zFilename){29 int rc;30 sqlite3 *db;31 rc = sqlite3_open(zFilename, &db);32 if( rc ){33 fprintf(stderr, "Cannot open \"%s\": %s\n",34 zFilename, sqlite3_errmsg(db));35 sqlite3_close(db);36 exit(1);37 }38 return db;39}40 41static int nReply = 0;42static char zReply[1000];43 44static int execCallback(void *NotUsed, int nArg, char **azArg, char **azCol){45 int i, n;46 char *z;47 for(i=0; i<nArg; i++){48 z = azArg[i];49 if( z==0 ) z = "NULL";50 if( nReply>0 && nReply<sizeof(zReply)-1 ) zReply[nReply++] = ' ';51 n = strlen(z);52 if( nReply+n>=sizeof(zReply)-1 ) n = sizeof(zReply) - nReply - 1;53 memcpy(&zReply[nReply], z, n);54 nReply += n;55 zReply[nReply] = 0;56 }57 return 0;58}59 60static void runSql(sqlite3 *db, const char *zSql){61 char *zErr = 0;62 int rc;63 nReply = 0;64 rc = sqlite3_exec(db, zSql, execCallback, 0, &zErr);65 if( zErr ){66 fprintf(stderr, "SQL error: %s\n", zErr);67 exit(1);68 }69 if( rc ){70 fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));71 exit(1);72 }73}74 75int main(int argc, char **argv){76 sqlite3 *db;77 int i;78 79 if( argc<3 ) usage(argv[0]);80 if( strcmp(argv[1], "new")==0 ){81 db = openDb(argv[argc-1]);82 for(i=2; i<argc-1; i++){83 if( strcmp(argv[i],"-utf8")==0 ){84 runSql(db, "PRAGMA encoding=UTF8");85 }else if( strcmp(argv[i], "-utf16le")==0 ){86 runSql(db, "PRAGMA encoding=UTF16LE");87 }else if( strcmp(argv[i], "-utf16be")==0 ){88 runSql(db, "PRAGMA encoding=UTF16BE");89 }else if( strncmp(argv[i], "-pagesize=", 10)==0 ){90 int szPg = atoi(&argv[i][10]);91 char zBuf[100];92 sprintf(zBuf, "PRAGMA pagesize=%d", szPg);93 runSql(db, zBuf);94 }else{95 fprintf(stderr, "unknown option %s\n", argv[i]);96 usage(argv[0]);97 }98 }99 runSql(db, 100 "BEGIN;"101 "CREATE TABLE t1(x INTEGER PRIMARY KEY, y);"102 "INSERT INTO t1(y) VALUES('abcdefghijklmnopqrstuvwxyz');"103 "INSERT INTO t1(y) VALUES('abcdefghijklmnopqrstuvwxyz');"104 "INSERT INTO t1(y) SELECT y FROM t1;" /* 4 */105 "INSERT INTO t1(y) SELECT y FROM t1;" /* 8 */106 "INSERT INTO t1(y) SELECT y FROM t1;" /* 16 */107 "INSERT INTO t1(y) SELECT y FROM t1;" /* 32 */108 "INSERT INTO t1(y) SELECT y FROM t1;" /* 64 */109 "INSERT INTO t1(y) SELECT y FROM t1;" /* 128 */110 "INSERT INTO t1(y) SELECT y FROM t1;" /* 256 */111 "INSERT INTO t1(y) SELECT y FROM t1;" /* 512 */112 "INSERT INTO t1(y) SELECT y FROM t1;" /* 1024 */113 "UPDATE t1 SET y=(y || x);"114 "CREATE INDEX t1y ON t1(y);"115 "COMMIT;"116 );117 sqlite3_close(db);118 }else if( strcmp(argv[1], "check")==0 ){119 db = openDb(argv[argc-1]);120 runSql(db, "PRAGMA integrity_check");121 if( strcmp(zReply, "ok")!=0 ){122 fprintf(stderr, "Integrity check: %s\n", zReply);123 exit(1);124 }125 runSql(db, 126 "SELECT count(*) FROM t1 WHERE y<>('abcdefghijklmnopqrstuvwxyz' || x)"127 );128 if( strcmp(zReply, "0")!=0 ){129 fprintf(stderr, "Wrong content\n");130 exit(1);131 }132 printf("Ok\n");133 }else if( strcmp(argv[1], "crash")==0 ){134 db = openDb(argv[argc-1]);135 for(i=2; i<argc-1; i++){136 if( strcmp(argv[i],"-wal")==0 ){137 runSql(db, "PRAGMA journal_mode=WAL");138 }else if( strcmp(argv[i], "-rollback")==0 ){139 runSql(db, "PRAGMA journal_mode=DELETE");140 }else{141 fprintf(stderr, "unknown option %s\n", argv[i]);142 usage(argv[0]);143 }144 }145 runSql(db,146 "PRAGMA cache_size=10;"147 "BEGIN;"148 "UPDATE t1 SET y=(y || -x)"149 );150 exit(0);151 }else{152 usage(argv[0]);153 }154 return 0;155}156 