mptest.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. /*
  2. ** 2013-04-05
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. **
  13. ** This is a program used for testing SQLite, and specifically for testing
  14. ** the ability of independent processes to access the same SQLite database
  15. ** concurrently.
  16. **
  17. ** Compile this program as follows:
  18. **
  19. ** gcc -g -c -Wall sqlite3.c $(OPTS)
  20. ** gcc -g -o mptest mptest.c sqlite3.o $(LIBS)
  21. **
  22. ** Recommended options:
  23. **
  24. ** -DHAVE_USLEEP
  25. ** -DSQLITE_NO_SYNC
  26. ** -DSQLITE_THREADSAFE=0
  27. ** -DSQLITE_OMIT_LOAD_EXTENSION
  28. **
  29. ** Run like this:
  30. **
  31. ** ./mptest $database $script
  32. **
  33. ** where $database is the database to use for testing and $script is a
  34. ** test script.
  35. */
  36. #include "sqlite3.h"
  37. #include <stdio.h>
  38. #if defined(_WIN32)
  39. # define WIN32_LEAN_AND_MEAN
  40. # include <windows.h>
  41. #else
  42. # include <unistd.h>
  43. #endif
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <assert.h>
  47. #include <ctype.h>
  48. /* The suffix to append to the child command lines, if any */
  49. #if defined(_WIN32)
  50. # define GETPID (int)GetCurrentProcessId
  51. #else
  52. # define GETPID getpid
  53. #endif
  54. /* Mark a parameter as unused to suppress compiler warnings */
  55. #define UNUSED_PARAMETER(x) (void)x
  56. /* Global data
  57. */
  58. static struct Global {
  59. char *argv0; /* Name of the executable */
  60. const char *zVfs; /* Name of VFS to use. Often NULL meaning "default" */
  61. char *zDbFile; /* Name of the database */
  62. sqlite3 *db; /* Open connection to database */
  63. char *zErrLog; /* Filename for error log */
  64. FILE *pErrLog; /* Where to write errors */
  65. char *zLog; /* Name of output log file */
  66. FILE *pLog; /* Where to write log messages */
  67. char zName[32]; /* Symbolic name of this process */
  68. int taskId; /* Task ID. 0 means supervisor. */
  69. int iTrace; /* Tracing level */
  70. int bSqlTrace; /* True to trace SQL commands */
  71. int bIgnoreSqlErrors; /* Ignore errors in SQL statements */
  72. int nError; /* Number of errors */
  73. int nTest; /* Number of --match operators */
  74. int iTimeout; /* Milliseconds until a busy timeout */
  75. int bSync; /* Call fsync() */
  76. } g;
  77. /* Default timeout */
  78. #define DEFAULT_TIMEOUT 10000
  79. /*
  80. ** Print a message adding zPrefix[] to the beginning of every line.
  81. */
  82. static void printWithPrefix(FILE *pOut, const char *zPrefix, const char *zMsg){
  83. while( zMsg && zMsg[0] ){
  84. int i;
  85. for(i=0; zMsg[i] && zMsg[i]!='\n' && zMsg[i]!='\r'; i++){}
  86. fprintf(pOut, "%s%.*s\n", zPrefix, i, zMsg);
  87. zMsg += i;
  88. while( zMsg[0]=='\n' || zMsg[0]=='\r' ) zMsg++;
  89. }
  90. }
  91. /*
  92. ** Compare two pointers to strings, where the pointers might be NULL.
  93. */
  94. static int safe_strcmp(const char *a, const char *b){
  95. if( a==b ) return 0;
  96. if( a==0 ) return -1;
  97. if( b==0 ) return 1;
  98. return strcmp(a,b);
  99. }
  100. /*
  101. ** Return TRUE if string z[] matches glob pattern zGlob[].
  102. ** Return FALSE if the pattern does not match.
  103. **
  104. ** Globbing rules:
  105. **
  106. ** '*' Matches any sequence of zero or more characters.
  107. **
  108. ** '?' Matches exactly one character.
  109. **
  110. ** [...] Matches one character from the enclosed list of
  111. ** characters.
  112. **
  113. ** [^...] Matches one character not in the enclosed list.
  114. **
  115. ** '#' Matches any sequence of one or more digits with an
  116. ** optional + or - sign in front
  117. */
  118. int strglob(const char *zGlob, const char *z){
  119. int c, c2;
  120. int invert;
  121. int seen;
  122. while( (c = (*(zGlob++)))!=0 ){
  123. if( c=='*' ){
  124. while( (c=(*(zGlob++))) == '*' || c=='?' ){
  125. if( c=='?' && (*(z++))==0 ) return 0;
  126. }
  127. if( c==0 ){
  128. return 1;
  129. }else if( c=='[' ){
  130. while( *z && strglob(zGlob-1,z) ){
  131. z++;
  132. }
  133. return (*z)!=0;
  134. }
  135. while( (c2 = (*(z++)))!=0 ){
  136. while( c2!=c ){
  137. c2 = *(z++);
  138. if( c2==0 ) return 0;
  139. }
  140. if( strglob(zGlob,z) ) return 1;
  141. }
  142. return 0;
  143. }else if( c=='?' ){
  144. if( (*(z++))==0 ) return 0;
  145. }else if( c=='[' ){
  146. int prior_c = 0;
  147. seen = 0;
  148. invert = 0;
  149. c = *(z++);
  150. if( c==0 ) return 0;
  151. c2 = *(zGlob++);
  152. if( c2=='^' ){
  153. invert = 1;
  154. c2 = *(zGlob++);
  155. }
  156. if( c2==']' ){
  157. if( c==']' ) seen = 1;
  158. c2 = *(zGlob++);
  159. }
  160. while( c2 && c2!=']' ){
  161. if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
  162. c2 = *(zGlob++);
  163. if( c>=prior_c && c<=c2 ) seen = 1;
  164. prior_c = 0;
  165. }else{
  166. if( c==c2 ){
  167. seen = 1;
  168. }
  169. prior_c = c2;
  170. }
  171. c2 = *(zGlob++);
  172. }
  173. if( c2==0 || (seen ^ invert)==0 ) return 0;
  174. }else if( c=='#' ){
  175. if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++;
  176. if( !isdigit(z[0]) ) return 0;
  177. z++;
  178. while( isdigit(z[0]) ){ z++; }
  179. }else{
  180. if( c!=(*(z++)) ) return 0;
  181. }
  182. }
  183. return *z==0;
  184. }
  185. /*
  186. ** Close output stream pOut if it is not stdout or stderr
  187. */
  188. static void maybeClose(FILE *pOut){
  189. if( pOut!=stdout && pOut!=stderr ) fclose(pOut);
  190. }
  191. /*
  192. ** Print an error message
  193. */
  194. static void errorMessage(const char *zFormat, ...){
  195. va_list ap;
  196. char *zMsg;
  197. char zPrefix[30];
  198. va_start(ap, zFormat);
  199. zMsg = sqlite3_vmprintf(zFormat, ap);
  200. va_end(ap);
  201. sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:ERROR: ", g.zName);
  202. if( g.pLog ){
  203. printWithPrefix(g.pLog, zPrefix, zMsg);
  204. fflush(g.pLog);
  205. }
  206. if( g.pErrLog && safe_strcmp(g.zErrLog,g.zLog) ){
  207. printWithPrefix(g.pErrLog, zPrefix, zMsg);
  208. fflush(g.pErrLog);
  209. }
  210. sqlite3_free(zMsg);
  211. g.nError++;
  212. }
  213. /* Forward declaration */
  214. static int trySql(const char*, ...);
  215. /*
  216. ** Print an error message and then quit.
  217. */
  218. static void fatalError(const char *zFormat, ...){
  219. va_list ap;
  220. char *zMsg;
  221. char zPrefix[30];
  222. va_start(ap, zFormat);
  223. zMsg = sqlite3_vmprintf(zFormat, ap);
  224. va_end(ap);
  225. sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:FATAL: ", g.zName);
  226. if( g.pLog ){
  227. printWithPrefix(g.pLog, zPrefix, zMsg);
  228. fflush(g.pLog);
  229. maybeClose(g.pLog);
  230. }
  231. if( g.pErrLog && safe_strcmp(g.zErrLog,g.zLog) ){
  232. printWithPrefix(g.pErrLog, zPrefix, zMsg);
  233. fflush(g.pErrLog);
  234. maybeClose(g.pErrLog);
  235. }
  236. sqlite3_free(zMsg);
  237. if( g.db ){
  238. int nTry = 0;
  239. g.iTimeout = 0;
  240. while( trySql("UPDATE client SET wantHalt=1;")==SQLITE_BUSY
  241. && (nTry++)<100 ){
  242. sqlite3_sleep(10);
  243. }
  244. }
  245. sqlite3_close(g.db);
  246. exit(1);
  247. }
  248. /*
  249. ** Print a log message
  250. */
  251. static void logMessage(const char *zFormat, ...){
  252. va_list ap;
  253. char *zMsg;
  254. char zPrefix[30];
  255. va_start(ap, zFormat);
  256. zMsg = sqlite3_vmprintf(zFormat, ap);
  257. va_end(ap);
  258. sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s: ", g.zName);
  259. if( g.pLog ){
  260. printWithPrefix(g.pLog, zPrefix, zMsg);
  261. fflush(g.pLog);
  262. }
  263. sqlite3_free(zMsg);
  264. }
  265. /*
  266. ** Return the length of a string omitting trailing whitespace
  267. */
  268. static int clipLength(const char *z){
  269. int n = (int)strlen(z);
  270. while( n>0 && isspace(z[n-1]) ){ n--; }
  271. return n;
  272. }
  273. /*
  274. ** Auxiliary SQL function to return the name of the VFS
  275. */
  276. static void vfsNameFunc(
  277. sqlite3_context *context,
  278. int argc,
  279. sqlite3_value **argv
  280. ){
  281. sqlite3 *db = sqlite3_context_db_handle(context);
  282. char *zVfs = 0;
  283. UNUSED_PARAMETER(argc);
  284. UNUSED_PARAMETER(argv);
  285. sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zVfs);
  286. if( zVfs ){
  287. sqlite3_result_text(context, zVfs, -1, sqlite3_free);
  288. }
  289. }
  290. /*
  291. ** Busy handler with a g.iTimeout-millisecond timeout
  292. */
  293. static int busyHandler(void *pCD, int count){
  294. UNUSED_PARAMETER(pCD);
  295. if( count*10>g.iTimeout ){
  296. if( g.iTimeout>0 ) errorMessage("timeout after %dms", g.iTimeout);
  297. return 0;
  298. }
  299. sqlite3_sleep(10);
  300. return 1;
  301. }
  302. /*
  303. ** SQL Trace callback
  304. */
  305. static void sqlTraceCallback(void *NotUsed1, const char *zSql){
  306. UNUSED_PARAMETER(NotUsed1);
  307. logMessage("[%.*s]", clipLength(zSql), zSql);
  308. }
  309. /*
  310. ** SQL error log callback
  311. */
  312. static void sqlErrorCallback(void *pArg, int iErrCode, const char *zMsg){
  313. UNUSED_PARAMETER(pArg);
  314. if( iErrCode==SQLITE_ERROR && g.bIgnoreSqlErrors ) return;
  315. if( (iErrCode&0xff)==SQLITE_SCHEMA && g.iTrace<3 ) return;
  316. if( g.iTimeout==0 && (iErrCode&0xff)==SQLITE_BUSY && g.iTrace<3 ) return;
  317. if( (iErrCode&0xff)==SQLITE_NOTICE ){
  318. logMessage("(info) %s", zMsg);
  319. }else{
  320. errorMessage("(errcode=%d) %s", iErrCode, zMsg);
  321. }
  322. }
  323. /*
  324. ** Prepare an SQL statement. Issue a fatal error if unable.
  325. */
  326. static sqlite3_stmt *prepareSql(const char *zFormat, ...){
  327. va_list ap;
  328. char *zSql;
  329. int rc;
  330. sqlite3_stmt *pStmt = 0;
  331. va_start(ap, zFormat);
  332. zSql = sqlite3_vmprintf(zFormat, ap);
  333. va_end(ap);
  334. rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
  335. if( rc!=SQLITE_OK ){
  336. sqlite3_finalize(pStmt);
  337. fatalError("%s\n%s\n", sqlite3_errmsg(g.db), zSql);
  338. }
  339. sqlite3_free(zSql);
  340. return pStmt;
  341. }
  342. /*
  343. ** Run arbitrary SQL. Issue a fatal error on failure.
  344. */
  345. static void runSql(const char *zFormat, ...){
  346. va_list ap;
  347. char *zSql;
  348. int rc;
  349. va_start(ap, zFormat);
  350. zSql = sqlite3_vmprintf(zFormat, ap);
  351. va_end(ap);
  352. rc = sqlite3_exec(g.db, zSql, 0, 0, 0);
  353. if( rc!=SQLITE_OK ){
  354. fatalError("%s\n%s\n", sqlite3_errmsg(g.db), zSql);
  355. }
  356. sqlite3_free(zSql);
  357. }
  358. /*
  359. ** Try to run arbitrary SQL. Return success code.
  360. */
  361. static int trySql(const char *zFormat, ...){
  362. va_list ap;
  363. char *zSql;
  364. int rc;
  365. va_start(ap, zFormat);
  366. zSql = sqlite3_vmprintf(zFormat, ap);
  367. va_end(ap);
  368. rc = sqlite3_exec(g.db, zSql, 0, 0, 0);
  369. sqlite3_free(zSql);
  370. return rc;
  371. }
  372. /* Structure for holding an arbitrary length string
  373. */
  374. typedef struct String String;
  375. struct String {
  376. char *z; /* the string */
  377. int n; /* Slots of z[] used */
  378. int nAlloc; /* Slots of z[] allocated */
  379. };
  380. /* Free a string */
  381. static void stringFree(String *p){
  382. if( p->z ) sqlite3_free(p->z);
  383. memset(p, 0, sizeof(*p));
  384. }
  385. /* Append n bytes of text to a string. If n<0 append the entire string. */
  386. static void stringAppend(String *p, const char *z, int n){
  387. if( n<0 ) n = (int)strlen(z);
  388. if( p->n+n>=p->nAlloc ){
  389. int nAlloc = p->nAlloc*2 + n + 100;
  390. char *z = sqlite3_realloc(p->z, nAlloc);
  391. if( z==0 ) fatalError("out of memory");
  392. p->z = z;
  393. p->nAlloc = nAlloc;
  394. }
  395. memcpy(p->z+p->n, z, n);
  396. p->n += n;
  397. p->z[p->n] = 0;
  398. }
  399. /* Reset a string to an empty string */
  400. static void stringReset(String *p){
  401. if( p->z==0 ) stringAppend(p, " ", 1);
  402. p->n = 0;
  403. p->z[0] = 0;
  404. }
  405. /* Append a new token onto the end of the string */
  406. static void stringAppendTerm(String *p, const char *z){
  407. int i;
  408. if( p->n ) stringAppend(p, " ", 1);
  409. if( z==0 ){
  410. stringAppend(p, "nil", 3);
  411. return;
  412. }
  413. for(i=0; z[i] && !isspace(z[i]); i++){}
  414. if( i>0 && z[i]==0 ){
  415. stringAppend(p, z, i);
  416. return;
  417. }
  418. stringAppend(p, "'", 1);
  419. while( z[0] ){
  420. for(i=0; z[i] && z[i]!='\''; i++){}
  421. if( z[i] ){
  422. stringAppend(p, z, i+1);
  423. stringAppend(p, "'", 1);
  424. z += i+1;
  425. }else{
  426. stringAppend(p, z, i);
  427. break;
  428. }
  429. }
  430. stringAppend(p, "'", 1);
  431. }
  432. /*
  433. ** Callback function for evalSql()
  434. */
  435. static int evalCallback(void *pCData, int argc, char **argv, char **azCol){
  436. String *p = (String*)pCData;
  437. int i;
  438. UNUSED_PARAMETER(azCol);
  439. for(i=0; i<argc; i++) stringAppendTerm(p, argv[i]);
  440. return 0;
  441. }
  442. /*
  443. ** Run arbitrary SQL and record the results in an output string
  444. ** given by the first parameter.
  445. */
  446. static int evalSql(String *p, const char *zFormat, ...){
  447. va_list ap;
  448. char *zSql;
  449. int rc;
  450. char *zErrMsg = 0;
  451. va_start(ap, zFormat);
  452. zSql = sqlite3_vmprintf(zFormat, ap);
  453. va_end(ap);
  454. assert( g.iTimeout>0 );
  455. rc = sqlite3_exec(g.db, zSql, evalCallback, p, &zErrMsg);
  456. sqlite3_free(zSql);
  457. if( rc ){
  458. char zErr[30];
  459. sqlite3_snprintf(sizeof(zErr), zErr, "error(%d)", rc);
  460. stringAppendTerm(p, zErr);
  461. if( zErrMsg ){
  462. stringAppendTerm(p, zErrMsg);
  463. sqlite3_free(zErrMsg);
  464. }
  465. }
  466. return rc;
  467. }
  468. /*
  469. ** Auxiliary SQL function to recursively evaluate SQL.
  470. */
  471. static void evalFunc(
  472. sqlite3_context *context,
  473. int argc,
  474. sqlite3_value **argv
  475. ){
  476. sqlite3 *db = sqlite3_context_db_handle(context);
  477. const char *zSql = (const char*)sqlite3_value_text(argv[0]);
  478. String res;
  479. char *zErrMsg = 0;
  480. int rc;
  481. UNUSED_PARAMETER(argc);
  482. memset(&res, 0, sizeof(res));
  483. rc = sqlite3_exec(db, zSql, evalCallback, &res, &zErrMsg);
  484. if( zErrMsg ){
  485. sqlite3_result_error(context, zErrMsg, -1);
  486. sqlite3_free(zErrMsg);
  487. }else if( rc ){
  488. sqlite3_result_error_code(context, rc);
  489. }else{
  490. sqlite3_result_text(context, res.z, -1, SQLITE_TRANSIENT);
  491. }
  492. stringFree(&res);
  493. }
  494. /*
  495. ** Look up the next task for client iClient in the database.
  496. ** Return the task script and the task number and mark that
  497. ** task as being under way.
  498. */
  499. static int startScript(
  500. int iClient, /* The client number */
  501. char **pzScript, /* Write task script here */
  502. int *pTaskId, /* Write task number here */
  503. char **pzTaskName /* Name of the task */
  504. ){
  505. sqlite3_stmt *pStmt = 0;
  506. int taskId;
  507. int rc;
  508. int totalTime = 0;
  509. *pzScript = 0;
  510. g.iTimeout = 0;
  511. while(1){
  512. rc = trySql("BEGIN IMMEDIATE");
  513. if( rc==SQLITE_BUSY ){
  514. sqlite3_sleep(10);
  515. totalTime += 10;
  516. continue;
  517. }
  518. if( rc!=SQLITE_OK ){
  519. fatalError("in startScript: %s", sqlite3_errmsg(g.db));
  520. }
  521. if( g.nError || g.nTest ){
  522. runSql("UPDATE counters SET nError=nError+%d, nTest=nTest+%d",
  523. g.nError, g.nTest);
  524. g.nError = 0;
  525. g.nTest = 0;
  526. }
  527. pStmt = prepareSql("SELECT 1 FROM client WHERE id=%d AND wantHalt",iClient);
  528. rc = sqlite3_step(pStmt);
  529. sqlite3_finalize(pStmt);
  530. if( rc==SQLITE_ROW ){
  531. runSql("DELETE FROM client WHERE id=%d", iClient);
  532. g.iTimeout = DEFAULT_TIMEOUT;
  533. runSql("COMMIT TRANSACTION;");
  534. return SQLITE_DONE;
  535. }
  536. pStmt = prepareSql(
  537. "SELECT script, id, name FROM task"
  538. " WHERE client=%d AND starttime IS NULL"
  539. " ORDER BY id LIMIT 1", iClient);
  540. rc = sqlite3_step(pStmt);
  541. if( rc==SQLITE_ROW ){
  542. int n = sqlite3_column_bytes(pStmt, 0);
  543. *pzScript = sqlite3_malloc(n+1);
  544. strcpy(*pzScript, (const char*)sqlite3_column_text(pStmt, 0));
  545. *pTaskId = taskId = sqlite3_column_int(pStmt, 1);
  546. *pzTaskName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 2));
  547. sqlite3_finalize(pStmt);
  548. runSql("UPDATE task"
  549. " SET starttime=strftime('%%Y-%%m-%%d %%H:%%M:%%f','now')"
  550. " WHERE id=%d;", taskId);
  551. g.iTimeout = DEFAULT_TIMEOUT;
  552. runSql("COMMIT TRANSACTION;");
  553. return SQLITE_OK;
  554. }
  555. sqlite3_finalize(pStmt);
  556. if( rc==SQLITE_DONE ){
  557. if( totalTime>30000 ){
  558. errorMessage("Waited over 30 seconds with no work. Giving up.");
  559. runSql("DELETE FROM client WHERE id=%d; COMMIT;", iClient);
  560. sqlite3_close(g.db);
  561. exit(1);
  562. }
  563. while( trySql("COMMIT")==SQLITE_BUSY ){
  564. sqlite3_sleep(10);
  565. totalTime += 10;
  566. }
  567. sqlite3_sleep(100);
  568. totalTime += 100;
  569. continue;
  570. }
  571. fatalError("%s", sqlite3_errmsg(g.db));
  572. }
  573. g.iTimeout = DEFAULT_TIMEOUT;
  574. }
  575. /*
  576. ** Mark a script as having finished. Remove the CLIENT table entry
  577. ** if bShutdown is true.
  578. */
  579. static int finishScript(int iClient, int taskId, int bShutdown){
  580. runSql("UPDATE task"
  581. " SET endtime=strftime('%%Y-%%m-%%d %%H:%%M:%%f','now')"
  582. " WHERE id=%d;", taskId);
  583. if( bShutdown ){
  584. runSql("DELETE FROM client WHERE id=%d", iClient);
  585. }
  586. return SQLITE_OK;
  587. }
  588. /*
  589. ** Start up a client process for iClient, if it is not already
  590. ** running. If the client is already running, then this routine
  591. ** is a no-op.
  592. */
  593. static void startClient(int iClient){
  594. runSql("INSERT OR IGNORE INTO client VALUES(%d,0)", iClient);
  595. if( sqlite3_changes(g.db) ){
  596. char *zSys;
  597. int rc;
  598. zSys = sqlite3_mprintf("%s \"%s\" --client %d --trace %d",
  599. g.argv0, g.zDbFile, iClient, g.iTrace);
  600. if( g.bSqlTrace ){
  601. zSys = sqlite3_mprintf("%z --sqltrace", zSys);
  602. }
  603. if( g.bSync ){
  604. zSys = sqlite3_mprintf("%z --sync", zSys);
  605. }
  606. if( g.zVfs ){
  607. zSys = sqlite3_mprintf("%z --vfs \"%s\"", zSys, g.zVfs);
  608. }
  609. if( g.iTrace>=2 ) logMessage("system('%q')", zSys);
  610. #if !defined(_WIN32)
  611. zSys = sqlite3_mprintf("%z &", zSys);
  612. rc = system(zSys);
  613. if( rc ) errorMessage("system() fails with error code %d", rc);
  614. #else
  615. {
  616. STARTUPINFOA startupInfo;
  617. PROCESS_INFORMATION processInfo;
  618. memset(&startupInfo, 0, sizeof(startupInfo));
  619. startupInfo.cb = sizeof(startupInfo);
  620. memset(&processInfo, 0, sizeof(processInfo));
  621. rc = CreateProcessA(NULL, zSys, NULL, NULL, FALSE, 0, NULL, NULL,
  622. &startupInfo, &processInfo);
  623. if( rc ){
  624. CloseHandle(processInfo.hThread);
  625. CloseHandle(processInfo.hProcess);
  626. }else{
  627. errorMessage("CreateProcessA() fails with error code %lu",
  628. GetLastError());
  629. }
  630. }
  631. #endif
  632. sqlite3_free(zSys);
  633. }
  634. }
  635. /*
  636. ** Read the entire content of a file into memory
  637. */
  638. static char *readFile(const char *zFilename){
  639. FILE *in = fopen(zFilename, "rb");
  640. long sz;
  641. char *z;
  642. if( in==0 ){
  643. fatalError("cannot open \"%s\" for reading", zFilename);
  644. }
  645. fseek(in, 0, SEEK_END);
  646. sz = ftell(in);
  647. rewind(in);
  648. z = sqlite3_malloc( sz+1 );
  649. sz = (long)fread(z, 1, sz, in);
  650. z[sz] = 0;
  651. fclose(in);
  652. return z;
  653. }
  654. /*
  655. ** Return the length of the next token.
  656. */
  657. static int tokenLength(const char *z, int *pnLine){
  658. int n = 0;
  659. if( isspace(z[0]) || (z[0]=='/' && z[1]=='*') ){
  660. int inC = 0;
  661. int c;
  662. if( z[0]=='/' ){
  663. inC = 1;
  664. n = 2;
  665. }
  666. while( (c = z[n++])!=0 ){
  667. if( c=='\n' ) (*pnLine)++;
  668. if( isspace(c) ) continue;
  669. if( inC && c=='*' && z[n]=='/' ){
  670. n++;
  671. inC = 0;
  672. }else if( !inC && c=='/' && z[n]=='*' ){
  673. n++;
  674. inC = 1;
  675. }else if( !inC ){
  676. break;
  677. }
  678. }
  679. n--;
  680. }else if( z[0]=='-' && z[1]=='-' ){
  681. for(n=2; z[n] && z[n]!='\n'; n++){}
  682. if( z[n] ){ (*pnLine)++; n++; }
  683. }else if( z[0]=='"' || z[0]=='\'' ){
  684. int delim = z[0];
  685. for(n=1; z[n]; n++){
  686. if( z[n]=='\n' ) (*pnLine)++;
  687. if( z[n]==delim ){
  688. n++;
  689. if( z[n+1]!=delim ) break;
  690. }
  691. }
  692. }else{
  693. int c;
  694. for(n=1; (c = z[n])!=0 && !isspace(c) && c!='"' && c!='\'' && c!=';'; n++){}
  695. }
  696. return n;
  697. }
  698. /*
  699. ** Copy a single token into a string buffer.
  700. */
  701. static int extractToken(const char *zIn, int nIn, char *zOut, int nOut){
  702. int i;
  703. if( nIn<=0 ){
  704. zOut[0] = 0;
  705. return 0;
  706. }
  707. for(i=0; i<nIn && i<nOut-1 && !isspace(zIn[i]); i++){ zOut[i] = zIn[i]; }
  708. zOut[i] = 0;
  709. return i;
  710. }
  711. /*
  712. ** Find the number of characters up to the start of the next "--end" token.
  713. */
  714. static int findEnd(const char *z, int *pnLine){
  715. int n = 0;
  716. while( z[n] && (strncmp(z+n,"--end",5) || !isspace(z[n+5])) ){
  717. n += tokenLength(z+n, pnLine);
  718. }
  719. return n;
  720. }
  721. /*
  722. ** Find the number of characters up to the first character past the
  723. ** of the next "--endif" or "--else" token. Nested --if commands are
  724. ** also skipped.
  725. */
  726. static int findEndif(const char *z, int stopAtElse, int *pnLine){
  727. int n = 0;
  728. while( z[n] ){
  729. int len = tokenLength(z+n, pnLine);
  730. if( (strncmp(z+n,"--endif",7)==0 && isspace(z[n+7]))
  731. || (stopAtElse && strncmp(z+n,"--else",6)==0 && isspace(z[n+6]))
  732. ){
  733. return n+len;
  734. }
  735. if( strncmp(z+n,"--if",4)==0 && isspace(z[n+4]) ){
  736. int skip = findEndif(z+n+len, 0, pnLine);
  737. n += skip + len;
  738. }else{
  739. n += len;
  740. }
  741. }
  742. return n;
  743. }
  744. /*
  745. ** Wait for a client process to complete all its tasks
  746. */
  747. static void waitForClient(int iClient, int iTimeout, char *zErrPrefix){
  748. sqlite3_stmt *pStmt;
  749. int rc;
  750. if( iClient>0 ){
  751. pStmt = prepareSql(
  752. "SELECT 1 FROM task"
  753. " WHERE client=%d"
  754. " AND client IN (SELECT id FROM client)"
  755. " AND endtime IS NULL",
  756. iClient);
  757. }else{
  758. pStmt = prepareSql(
  759. "SELECT 1 FROM task"
  760. " WHERE client IN (SELECT id FROM client)"
  761. " AND endtime IS NULL");
  762. }
  763. g.iTimeout = 0;
  764. while( ((rc = sqlite3_step(pStmt))==SQLITE_BUSY || rc==SQLITE_ROW)
  765. && iTimeout>0
  766. ){
  767. sqlite3_reset(pStmt);
  768. sqlite3_sleep(50);
  769. iTimeout -= 50;
  770. }
  771. sqlite3_finalize(pStmt);
  772. g.iTimeout = DEFAULT_TIMEOUT;
  773. if( rc!=SQLITE_DONE ){
  774. if( zErrPrefix==0 ) zErrPrefix = "";
  775. if( iClient>0 ){
  776. errorMessage("%stimeout waiting for client %d", zErrPrefix, iClient);
  777. }else{
  778. errorMessage("%stimeout waiting for all clients", zErrPrefix);
  779. }
  780. }
  781. }
  782. /* Return a pointer to the tail of a filename
  783. */
  784. static char *filenameTail(char *z){
  785. int i, j;
  786. for(i=j=0; z[i]; i++) if( z[i]=='/' ) j = i+1;
  787. return z+j;
  788. }
  789. /*
  790. ** Interpret zArg as a boolean value. Return either 0 or 1.
  791. */
  792. static int booleanValue(char *zArg){
  793. int i;
  794. if( zArg==0 ) return 0;
  795. for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
  796. if( i>0 && zArg[i]==0 ) return atoi(zArg);
  797. if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
  798. return 1;
  799. }
  800. if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
  801. return 0;
  802. }
  803. errorMessage("unknown boolean: [%s]", zArg);
  804. return 0;
  805. }
  806. /* This routine exists as a convenient place to set a debugger
  807. ** breakpoint.
  808. */
  809. static void test_breakpoint(void){ static volatile int cnt = 0; cnt++; }
  810. /* Maximum number of arguments to a --command */
  811. #define MX_ARG 2
  812. /*
  813. ** Run a script.
  814. */
  815. static void runScript(
  816. int iClient, /* The client number, or 0 for the master */
  817. int taskId, /* The task ID for clients. 0 for master */
  818. char *zScript, /* Text of the script */
  819. char *zFilename /* File from which script was read. */
  820. ){
  821. int lineno = 1;
  822. int prevLine = 1;
  823. int ii = 0;
  824. int iBegin = 0;
  825. int n, c, j;
  826. int len;
  827. int nArg;
  828. String sResult;
  829. char zCmd[30];
  830. char zError[1000];
  831. char azArg[MX_ARG][100];
  832. memset(&sResult, 0, sizeof(sResult));
  833. stringReset(&sResult);
  834. while( (c = zScript[ii])!=0 ){
  835. prevLine = lineno;
  836. len = tokenLength(zScript+ii, &lineno);
  837. if( isspace(c) || (c=='/' && zScript[ii+1]=='*') ){
  838. ii += len;
  839. continue;
  840. }
  841. if( c!='-' || zScript[ii+1]!='-' || !isalpha(zScript[ii+2]) ){
  842. ii += len;
  843. continue;
  844. }
  845. /* Run any prior SQL before processing the new --command */
  846. if( ii>iBegin ){
  847. char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
  848. evalSql(&sResult, zSql);
  849. sqlite3_free(zSql);
  850. iBegin = ii + len;
  851. }
  852. /* Parse the --command */
  853. if( g.iTrace>=2 ) logMessage("%.*s", len, zScript+ii);
  854. n = extractToken(zScript+ii+2, len-2, zCmd, sizeof(zCmd));
  855. for(nArg=0; n<len-2 && nArg<MX_ARG; nArg++){
  856. while( n<len-2 && isspace(zScript[ii+2+n]) ){ n++; }
  857. if( n>=len-2 ) break;
  858. n += extractToken(zScript+ii+2+n, len-2-n,
  859. azArg[nArg], sizeof(azArg[nArg]));
  860. }
  861. for(j=nArg; j<MX_ARG; j++) azArg[j++][0] = 0;
  862. /*
  863. ** --sleep N
  864. **
  865. ** Pause for N milliseconds
  866. */
  867. if( strcmp(zCmd, "sleep")==0 ){
  868. sqlite3_sleep(atoi(azArg[0]));
  869. }else
  870. /*
  871. ** --exit N
  872. **
  873. ** Exit this process. If N>0 then exit without shutting down
  874. ** SQLite. (In other words, simulate a crash.)
  875. */
  876. if( strcmp(zCmd, "exit")==0 ){
  877. int rc = atoi(azArg[0]);
  878. finishScript(iClient, taskId, 1);
  879. if( rc==0 ) sqlite3_close(g.db);
  880. exit(rc);
  881. }else
  882. /*
  883. ** --testcase NAME
  884. **
  885. ** Begin a new test case. Announce in the log that the test case
  886. ** has begun.
  887. */
  888. if( strcmp(zCmd, "testcase")==0 ){
  889. if( g.iTrace==1 ) logMessage("%.*s", len - 1, zScript+ii);
  890. stringReset(&sResult);
  891. }else
  892. /*
  893. ** --finish
  894. **
  895. ** Mark the current task as having finished, even if it is not.
  896. ** This can be used in conjunction with --exit to simulate a crash.
  897. */
  898. if( strcmp(zCmd, "finish")==0 && iClient>0 ){
  899. finishScript(iClient, taskId, 1);
  900. }else
  901. /*
  902. ** --reset
  903. **
  904. ** Reset accumulated results back to an empty string
  905. */
  906. if( strcmp(zCmd, "reset")==0 ){
  907. stringReset(&sResult);
  908. }else
  909. /*
  910. ** --match ANSWER...
  911. **
  912. ** Check to see if output matches ANSWER. Report an error if not.
  913. */
  914. if( strcmp(zCmd, "match")==0 ){
  915. int jj;
  916. char *zAns = zScript+ii;
  917. for(jj=7; jj<len-1 && isspace(zAns[jj]); jj++){}
  918. zAns += jj;
  919. if( len-jj-1!=sResult.n || strncmp(sResult.z, zAns, len-jj-1) ){
  920. errorMessage("line %d of %s:\nExpected [%.*s]\n Got [%s]",
  921. prevLine, zFilename, len-jj-1, zAns, sResult.z);
  922. }
  923. g.nTest++;
  924. stringReset(&sResult);
  925. }else
  926. /*
  927. ** --glob ANSWER...
  928. ** --notglob ANSWER....
  929. **
  930. ** Check to see if output does or does not match the glob pattern
  931. ** ANSWER.
  932. */
  933. if( strcmp(zCmd, "glob")==0 || strcmp(zCmd, "notglob")==0 ){
  934. int jj;
  935. char *zAns = zScript+ii;
  936. char *zCopy;
  937. int isGlob = (zCmd[0]=='g');
  938. for(jj=9-3*isGlob; jj<len-1 && isspace(zAns[jj]); jj++){}
  939. zAns += jj;
  940. zCopy = sqlite3_mprintf("%.*s", len-jj-1, zAns);
  941. if( (sqlite3_strglob(zCopy, sResult.z)==0)^isGlob ){
  942. errorMessage("line %d of %s:\nExpected [%s]\n Got [%s]",
  943. prevLine, zFilename, zCopy, sResult.z);
  944. }
  945. sqlite3_free(zCopy);
  946. g.nTest++;
  947. stringReset(&sResult);
  948. }else
  949. /*
  950. ** --output
  951. **
  952. ** Output the result of the previous SQL.
  953. */
  954. if( strcmp(zCmd, "output")==0 ){
  955. logMessage("%s", sResult.z);
  956. }else
  957. /*
  958. ** --source FILENAME
  959. **
  960. ** Run a subscript from a separate file.
  961. */
  962. if( strcmp(zCmd, "source")==0 ){
  963. char *zNewFile, *zNewScript;
  964. char *zToDel = 0;
  965. zNewFile = azArg[0];
  966. if( zNewFile[0]!='/' ){
  967. int k;
  968. for(k=(int)strlen(zFilename)-1; k>=0 && zFilename[k]!='/'; k--){}
  969. if( k>0 ){
  970. zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile);
  971. }
  972. }
  973. zNewScript = readFile(zNewFile);
  974. if( g.iTrace ) logMessage("begin script [%s]\n", zNewFile);
  975. runScript(0, 0, zNewScript, zNewFile);
  976. sqlite3_free(zNewScript);
  977. if( g.iTrace ) logMessage("end script [%s]\n", zNewFile);
  978. sqlite3_free(zToDel);
  979. }else
  980. /*
  981. ** --print MESSAGE....
  982. **
  983. ** Output the remainder of the line to the log file
  984. */
  985. if( strcmp(zCmd, "print")==0 ){
  986. int jj;
  987. for(jj=7; jj<len && isspace(zScript[ii+jj]); jj++){}
  988. logMessage("%.*s", len-jj, zScript+ii+jj);
  989. }else
  990. /*
  991. ** --if EXPR
  992. **
  993. ** Skip forward to the next matching --endif or --else if EXPR is false.
  994. */
  995. if( strcmp(zCmd, "if")==0 ){
  996. int jj, rc;
  997. sqlite3_stmt *pStmt;
  998. for(jj=4; jj<len && isspace(zScript[ii+jj]); jj++){}
  999. pStmt = prepareSql("SELECT %.*s", len-jj, zScript+ii+jj);
  1000. rc = sqlite3_step(pStmt);
  1001. if( rc!=SQLITE_ROW || sqlite3_column_int(pStmt, 0)==0 ){
  1002. ii += findEndif(zScript+ii+len, 1, &lineno);
  1003. }
  1004. sqlite3_finalize(pStmt);
  1005. }else
  1006. /*
  1007. ** --else
  1008. **
  1009. ** This command can only be encountered if currently inside an --if that
  1010. ** is true. Skip forward to the next matching --endif.
  1011. */
  1012. if( strcmp(zCmd, "else")==0 ){
  1013. ii += findEndif(zScript+ii+len, 0, &lineno);
  1014. }else
  1015. /*
  1016. ** --endif
  1017. **
  1018. ** This command can only be encountered if currently inside an --if that
  1019. ** is true or an --else of a false if. This is a no-op.
  1020. */
  1021. if( strcmp(zCmd, "endif")==0 ){
  1022. /* no-op */
  1023. }else
  1024. /*
  1025. ** --start CLIENT
  1026. **
  1027. ** Start up the given client.
  1028. */
  1029. if( strcmp(zCmd, "start")==0 && iClient==0 ){
  1030. int iNewClient = atoi(azArg[0]);
  1031. if( iNewClient>0 ){
  1032. startClient(iNewClient);
  1033. }
  1034. }else
  1035. /*
  1036. ** --wait CLIENT TIMEOUT
  1037. **
  1038. ** Wait until all tasks complete for the given client. If CLIENT is
  1039. ** "all" then wait for all clients to complete. Wait no longer than
  1040. ** TIMEOUT milliseconds (default 10,000)
  1041. */
  1042. if( strcmp(zCmd, "wait")==0 && iClient==0 ){
  1043. int iTimeout = nArg>=2 ? atoi(azArg[1]) : 10000;
  1044. sqlite3_snprintf(sizeof(zError),zError,"line %d of %s\n",
  1045. prevLine, zFilename);
  1046. waitForClient(atoi(azArg[0]), iTimeout, zError);
  1047. }else
  1048. /*
  1049. ** --task CLIENT
  1050. ** <task-content-here>
  1051. ** --end
  1052. **
  1053. ** Assign work to a client. Start the client if it is not running
  1054. ** already.
  1055. */
  1056. if( strcmp(zCmd, "task")==0 && iClient==0 ){
  1057. int iTarget = atoi(azArg[0]);
  1058. int iEnd;
  1059. char *zTask;
  1060. char *zTName;
  1061. iEnd = findEnd(zScript+ii+len, &lineno);
  1062. if( iTarget<0 ){
  1063. errorMessage("line %d of %s: bad client number: %d",
  1064. prevLine, zFilename, iTarget);
  1065. }else{
  1066. zTask = sqlite3_mprintf("%.*s", iEnd, zScript+ii+len);
  1067. if( nArg>1 ){
  1068. zTName = sqlite3_mprintf("%s", azArg[1]);
  1069. }else{
  1070. zTName = sqlite3_mprintf("%s:%d", filenameTail(zFilename), prevLine);
  1071. }
  1072. startClient(iTarget);
  1073. runSql("INSERT INTO task(client,script,name)"
  1074. " VALUES(%d,'%q',%Q)", iTarget, zTask, zTName);
  1075. sqlite3_free(zTask);
  1076. sqlite3_free(zTName);
  1077. }
  1078. iEnd += tokenLength(zScript+ii+len+iEnd, &lineno);
  1079. len += iEnd;
  1080. iBegin = ii+len;
  1081. }else
  1082. /*
  1083. ** --breakpoint
  1084. **
  1085. ** This command calls "test_breakpoint()" which is a routine provided
  1086. ** as a convenient place to set a debugger breakpoint.
  1087. */
  1088. if( strcmp(zCmd, "breakpoint")==0 ){
  1089. test_breakpoint();
  1090. }else
  1091. /*
  1092. ** --show-sql-errors BOOLEAN
  1093. **
  1094. ** Turn display of SQL errors on and off.
  1095. */
  1096. if( strcmp(zCmd, "show-sql-errors")==0 ){
  1097. g.bIgnoreSqlErrors = nArg>=1 ? !booleanValue(azArg[0]) : 1;
  1098. }else
  1099. /* error */{
  1100. errorMessage("line %d of %s: unknown command --%s",
  1101. prevLine, zFilename, zCmd);
  1102. }
  1103. ii += len;
  1104. }
  1105. if( iBegin<ii ){
  1106. char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
  1107. runSql(zSql);
  1108. sqlite3_free(zSql);
  1109. }
  1110. stringFree(&sResult);
  1111. }
  1112. /*
  1113. ** Look for a command-line option. If present, return a pointer.
  1114. ** Return NULL if missing.
  1115. **
  1116. ** hasArg==0 means the option is a flag. It is either present or not.
  1117. ** hasArg==1 means the option has an argument. Return a pointer to the
  1118. ** argument.
  1119. */
  1120. static char *findOption(
  1121. char **azArg,
  1122. int *pnArg,
  1123. const char *zOption,
  1124. int hasArg
  1125. ){
  1126. int i, j;
  1127. char *zReturn = 0;
  1128. int nArg = *pnArg;
  1129. assert( hasArg==0 || hasArg==1 );
  1130. for(i=0; i<nArg; i++){
  1131. const char *z;
  1132. if( i+hasArg >= nArg ) break;
  1133. z = azArg[i];
  1134. if( z[0]!='-' ) continue;
  1135. z++;
  1136. if( z[0]=='-' ){
  1137. if( z[1]==0 ) break;
  1138. z++;
  1139. }
  1140. if( strcmp(z,zOption)==0 ){
  1141. if( hasArg && i==nArg-1 ){
  1142. fatalError("command-line option \"--%s\" requires an argument", z);
  1143. }
  1144. if( hasArg ){
  1145. zReturn = azArg[i+1];
  1146. }else{
  1147. zReturn = azArg[i];
  1148. }
  1149. j = i+1+(hasArg!=0);
  1150. while( j<nArg ) azArg[i++] = azArg[j++];
  1151. *pnArg = i;
  1152. return zReturn;
  1153. }
  1154. }
  1155. return zReturn;
  1156. }
  1157. /* Print a usage message for the program and exit */
  1158. static void usage(const char *argv0){
  1159. int i;
  1160. const char *zTail = argv0;
  1161. for(i=0; argv0[i]; i++){
  1162. if( argv0[i]=='/' ) zTail = argv0+i+1;
  1163. }
  1164. fprintf(stderr,"Usage: %s DATABASE ?OPTIONS? ?SCRIPT?\n", zTail);
  1165. exit(1);
  1166. }
  1167. /* Report on unrecognized arguments */
  1168. static void unrecognizedArguments(
  1169. const char *argv0,
  1170. int nArg,
  1171. char **azArg
  1172. ){
  1173. int i;
  1174. fprintf(stderr,"%s: unrecognized arguments:", argv0);
  1175. for(i=0; i<nArg; i++){
  1176. fprintf(stderr," %s", azArg[i]);
  1177. }
  1178. fprintf(stderr,"\n");
  1179. exit(1);
  1180. }
  1181. int main(int argc, char **argv){
  1182. const char *zClient;
  1183. int iClient;
  1184. int n, i;
  1185. int openFlags = SQLITE_OPEN_READWRITE;
  1186. int rc;
  1187. char *zScript;
  1188. int taskId;
  1189. const char *zTrace;
  1190. const char *zCOption;
  1191. g.argv0 = argv[0];
  1192. g.iTrace = 1;
  1193. if( argc<2 ) usage(argv[0]);
  1194. g.zDbFile = argv[1];
  1195. if( strglob("*.test", g.zDbFile) ) usage(argv[0]);
  1196. if( strcmp(sqlite3_sourceid(), SQLITE_SOURCE_ID)!=0 ){
  1197. fprintf(stderr, "SQLite library and header mismatch\n"
  1198. "Library: %s\n"
  1199. "Header: %s\n",
  1200. sqlite3_sourceid(), SQLITE_SOURCE_ID);
  1201. exit(1);
  1202. }
  1203. n = argc-2;
  1204. sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
  1205. g.zVfs = findOption(argv+2, &n, "vfs", 1);
  1206. zClient = findOption(argv+2, &n, "client", 1);
  1207. g.zErrLog = findOption(argv+2, &n, "errlog", 1);
  1208. g.zLog = findOption(argv+2, &n, "log", 1);
  1209. zTrace = findOption(argv+2, &n, "trace", 1);
  1210. if( zTrace ) g.iTrace = atoi(zTrace);
  1211. if( findOption(argv+2, &n, "quiet", 0)!=0 ) g.iTrace = 0;
  1212. g.bSqlTrace = findOption(argv+2, &n, "sqltrace", 0)!=0;
  1213. g.bSync = findOption(argv+2, &n, "sync", 0)!=0;
  1214. if( g.zErrLog ){
  1215. g.pErrLog = fopen(g.zErrLog, "a");
  1216. }else{
  1217. g.pErrLog = stderr;
  1218. }
  1219. if( g.zLog ){
  1220. g.pLog = fopen(g.zLog, "a");
  1221. }else{
  1222. g.pLog = stdout;
  1223. }
  1224. sqlite3_config(SQLITE_CONFIG_LOG, sqlErrorCallback, 0);
  1225. if( zClient ){
  1226. iClient = atoi(zClient);
  1227. if( iClient<1 ) fatalError("illegal client number: %d\n", iClient);
  1228. sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.client%02d",
  1229. GETPID(), iClient);
  1230. }else{
  1231. if( g.iTrace>0 ){
  1232. printf("With SQLite " SQLITE_VERSION " " SQLITE_SOURCE_ID "\n" );
  1233. for(i=0; (zCOption = sqlite3_compileoption_get(i))!=0; i++){
  1234. printf("-DSQLITE_%s\n", zCOption);
  1235. }
  1236. fflush(stdout);
  1237. }
  1238. iClient = 0;
  1239. unlink(g.zDbFile);
  1240. openFlags |= SQLITE_OPEN_CREATE;
  1241. }
  1242. rc = sqlite3_open_v2(g.zDbFile, &g.db, openFlags, g.zVfs);
  1243. if( rc ) fatalError("cannot open [%s]", g.zDbFile);
  1244. sqlite3_enable_load_extension(g.db, 1);
  1245. sqlite3_busy_handler(g.db, busyHandler, 0);
  1246. sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0,
  1247. vfsNameFunc, 0, 0);
  1248. sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0,
  1249. evalFunc, 0, 0);
  1250. g.iTimeout = DEFAULT_TIMEOUT;
  1251. if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0);
  1252. if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
  1253. if( iClient>0 ){
  1254. if( n>0 ) unrecognizedArguments(argv[0], n, argv+2);
  1255. if( g.iTrace ) logMessage("start-client");
  1256. while(1){
  1257. char *zTaskName = 0;
  1258. rc = startScript(iClient, &zScript, &taskId, &zTaskName);
  1259. if( rc==SQLITE_DONE ) break;
  1260. if( g.iTrace ) logMessage("begin %s (%d)", zTaskName, taskId);
  1261. runScript(iClient, taskId, zScript, zTaskName);
  1262. if( g.iTrace ) logMessage("end %s (%d)", zTaskName, taskId);
  1263. finishScript(iClient, taskId, 0);
  1264. sqlite3_free(zTaskName);
  1265. sqlite3_sleep(10);
  1266. }
  1267. if( g.iTrace ) logMessage("end-client");
  1268. }else{
  1269. sqlite3_stmt *pStmt;
  1270. int iTimeout;
  1271. if( n==0 ){
  1272. fatalError("missing script filename");
  1273. }
  1274. if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
  1275. runSql(
  1276. "CREATE TABLE task(\n"
  1277. " id INTEGER PRIMARY KEY,\n"
  1278. " name TEXT,\n"
  1279. " client INTEGER,\n"
  1280. " starttime DATE,\n"
  1281. " endtime DATE,\n"
  1282. " script TEXT\n"
  1283. ");"
  1284. "CREATE INDEX task_i1 ON task(client, starttime);\n"
  1285. "CREATE INDEX task_i2 ON task(client, endtime);\n"
  1286. "CREATE TABLE counters(nError,nTest);\n"
  1287. "INSERT INTO counters VALUES(0,0);\n"
  1288. "CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
  1289. );
  1290. zScript = readFile(argv[2]);
  1291. if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]);
  1292. runScript(0, 0, zScript, argv[2]);
  1293. sqlite3_free(zScript);
  1294. if( g.iTrace ) logMessage("end script [%s]\n", argv[2]);
  1295. waitForClient(0, 2000, "during shutdown...\n");
  1296. trySql("UPDATE client SET wantHalt=1");
  1297. sqlite3_sleep(10);
  1298. g.iTimeout = 0;
  1299. iTimeout = 1000;
  1300. while( ((rc = trySql("SELECT 1 FROM client"))==SQLITE_BUSY
  1301. || rc==SQLITE_ROW) && iTimeout>0 ){
  1302. sqlite3_sleep(10);
  1303. iTimeout -= 10;
  1304. }
  1305. sqlite3_sleep(100);
  1306. pStmt = prepareSql("SELECT nError, nTest FROM counters");
  1307. iTimeout = 1000;
  1308. while( (rc = sqlite3_step(pStmt))==SQLITE_BUSY && iTimeout>0 ){
  1309. sqlite3_sleep(10);
  1310. iTimeout -= 10;
  1311. }
  1312. if( rc==SQLITE_ROW ){
  1313. g.nError += sqlite3_column_int(pStmt, 0);
  1314. g.nTest += sqlite3_column_int(pStmt, 1);
  1315. }
  1316. sqlite3_finalize(pStmt);
  1317. }
  1318. sqlite3_close(g.db);
  1319. maybeClose(g.pLog);
  1320. maybeClose(g.pErrLog);
  1321. if( iClient==0 ){
  1322. printf("Summary: %d errors in %d tests\n", g.nError, g.nTest);
  1323. }
  1324. return g.nError>0;
  1325. }