/ Hex Artifact Content
Login

Artifact d85694a9e5cd3908cb3e10bb5cb5d6a47ad101adb9fb477ca61f1e3725253b06:


0000: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 70 72 6f 67  ./*.** This prog
0010: 72 61 6d 20 61 74 74 65 6d 70 74 73 20 74 6f 20  ram attempts to 
0020: 74 65 73 74 20 74 68 65 20 63 6f 72 72 65 63 74  test the correct
0030: 6e 65 73 73 20 6f 66 20 73 6f 6d 65 20 66 61 63  ness of some fac
0040: 65 74 73 20 6f 66 20 74 68 65 20 0a 2a 2a 20 4c  ets of the .** L
0050: 53 4d 20 64 61 74 61 62 61 73 65 20 6c 69 62 72  SM database libr
0060: 61 72 79 2e 20 53 70 65 63 69 66 69 63 61 6c 6c  ary. Specificall
0070: 79 2c 20 74 68 61 74 20 74 68 65 20 63 6f 6e 74  y, that the cont
0080: 65 6e 74 73 20 6f 66 20 74 68 65 20 64 61 74 61  ents of the data
0090: 62 61 73 65 0a 2a 2a 20 61 72 65 20 6d 61 69 6e  base.** are main
00a0: 74 61 69 6e 65 64 20 63 6f 72 72 65 63 74 6c 79  tained correctly
00b0: 20 64 75 72 69 6e 67 20 61 20 73 65 72 69 65 73   during a series
00c0: 20 6f 66 20 69 6e 73 65 72 74 73 20 61 6e 64 20   of inserts and 
00d0: 64 65 6c 65 74 65 73 2e 0a 2a 2f 0a 0a 0a 23 69  deletes..*/...#i
00e0: 6e 63 6c 75 64 65 20 22 6c 73 6d 74 65 73 74 5f  nclude "lsmtest_
00f0: 74 64 62 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  tdb.h".#include 
0100: 22 6c 73 6d 2e 68 22 0a 0a 23 69 6e 63 6c 75 64  "lsm.h"..#includ
0110: 65 20 22 6c 73 6d 74 65 73 74 2e 68 22 0a 0a 23  e "lsmtest.h"..#
0120: 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e  include <stdlib.
0130: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72  h>.#include <str
0140: 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ing.h>.#include 
0150: 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 66 6e 64  <assert.h>.#ifnd
0160: 65 66 20 5f 57 49 4e 33 32 0a 23 20 69 6e 63 6c  ef _WIN32.# incl
0170: 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a 23  ude <unistd.h>.#
0180: 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65 20 3c  endif.#include <
0190: 73 74 64 69 6f 2e 68 3e 0a 0a 0a 74 79 70 65 64  stdio.h>...typed
01a0: 65 66 20 73 74 72 75 63 74 20 53 71 6c 44 62 20  ef struct SqlDb 
01b0: 53 71 6c 44 62 3b 0a 0a 73 74 61 74 69 63 20 69  SqlDb;..static i
01c0: 6e 74 20 65 72 72 6f 72 5f 74 72 61 6e 73 61 63  nt error_transac
01d0: 74 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e 28 54 65  tion_function(Te
01e0: 73 74 44 62 20 2a 70 2c 20 69 6e 74 20 69 4c 65  stDb *p, int iLe
01f0: 76 65 6c 29 7b 20 0a 20 20 75 6e 75 73 65 64 5f  vel){ .  unused_
0200: 70 61 72 61 6d 65 74 65 72 28 70 29 3b 0a 20 20  parameter(p);.  
0210: 75 6e 75 73 65 64 5f 70 61 72 61 6d 65 74 65 72  unused_parameter
0220: 28 69 4c 65 76 65 6c 29 3b 0a 20 20 72 65 74 75  (iLevel);.  retu
0230: 72 6e 20 2d 31 3b 20 0a 7d 0a 0a 0a 2f 2a 2a 2a  rn -1; .}.../***
0240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0250: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0270: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0280: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 42 65 67 69 6e 20  ******.** Begin 
0290: 77 72 61 70 70 65 72 20 66 6f 72 20 4c 65 76 65  wrapper for Leve
02a0: 6c 44 42 2e 0a 2a 2f 0a 23 69 66 64 65 66 20 48  lDB..*/.#ifdef H
02b0: 41 56 45 5f 4c 45 56 45 4c 44 42 0a 0a 23 69 6e  AVE_LEVELDB..#in
02c0: 63 6c 75 64 65 20 3c 6c 65 76 65 6c 64 62 2f 63  clude <leveldb/c
02d0: 2e 68 3e 0a 0a 74 79 70 65 64 65 66 20 73 74 72  .h>..typedef str
02e0: 75 63 74 20 4c 65 76 65 6c 44 62 20 4c 65 76 65  uct LevelDb Leve
02f0: 6c 44 62 3b 0a 73 74 72 75 63 74 20 4c 65 76 65  lDb;.struct Leve
0300: 6c 44 62 20 7b 0a 20 20 54 65 73 74 44 62 20 62  lDb {.  TestDb b
0310: 61 73 65 3b 0a 20 20 6c 65 76 65 6c 64 62 5f 74  ase;.  leveldb_t
0320: 20 2a 64 62 3b 0a 20 20 6c 65 76 65 6c 64 62 5f   *db;.  leveldb_
0330: 6f 70 74 69 6f 6e 73 5f 74 20 2a 70 4f 70 74 3b  options_t *pOpt;
0340: 0a 20 20 6c 65 76 65 6c 64 62 5f 77 72 69 74 65  .  leveldb_write
0350: 6f 70 74 69 6f 6e 73 5f 74 20 2a 70 57 72 69 74  options_t *pWrit
0360: 65 4f 70 74 3b 0a 20 20 6c 65 76 65 6c 64 62 5f  eOpt;.  leveldb_
0370: 72 65 61 64 6f 70 74 69 6f 6e 73 5f 74 20 2a 70  readoptions_t *p
0380: 52 65 61 64 4f 70 74 3b 0a 0a 20 20 63 68 61 72  ReadOpt;..  char
0390: 20 2a 70 56 61 6c 3b 0a 7d 3b 0a 0a 73 74 61 74   *pVal;.};..stat
03a0: 69 63 20 69 6e 74 20 74 65 73 74 5f 6c 65 76 65  ic int test_leve
03b0: 6c 64 62 5f 63 6c 6f 73 65 28 54 65 73 74 44 62  ldb_close(TestDb
03c0: 20 2a 70 54 65 73 74 44 62 29 7b 0a 20 20 4c 65   *pTestDb){.  Le
03d0: 76 65 6c 44 62 20 2a 70 44 62 20 3d 20 28 4c 65  velDb *pDb = (Le
03e0: 76 65 6c 44 62 20 2a 29 70 54 65 73 74 44 62 3b  velDb *)pTestDb;
03f0: 0a 0a 20 20 6c 65 76 65 6c 64 62 5f 63 6c 6f 73  ..  leveldb_clos
0400: 65 28 70 44 62 2d 3e 64 62 29 3b 0a 20 20 6c 65  e(pDb->db);.  le
0410: 76 65 6c 64 62 5f 77 72 69 74 65 6f 70 74 69 6f  veldb_writeoptio
0420: 6e 73 5f 64 65 73 74 72 6f 79 28 70 44 62 2d 3e  ns_destroy(pDb->
0430: 70 57 72 69 74 65 4f 70 74 29 3b 0a 20 20 6c 65  pWriteOpt);.  le
0440: 76 65 6c 64 62 5f 72 65 61 64 6f 70 74 69 6f 6e  veldb_readoption
0450: 73 5f 64 65 73 74 72 6f 79 28 70 44 62 2d 3e 70  s_destroy(pDb->p
0460: 52 65 61 64 4f 70 74 29 3b 0a 20 20 6c 65 76 65  ReadOpt);.  leve
0470: 6c 64 62 5f 6f 70 74 69 6f 6e 73 5f 64 65 73 74  ldb_options_dest
0480: 72 6f 79 28 70 44 62 2d 3e 70 4f 70 74 29 3b 0a  roy(pDb->pOpt);.
0490: 20 20 66 72 65 65 28 70 44 62 2d 3e 70 56 61 6c    free(pDb->pVal
04a0: 29 3b 0a 20 20 66 72 65 65 28 70 44 62 29 3b 0a  );.  free(pDb);.
04b0: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
04c0: 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f  static int test_
04d0: 6c 65 76 65 6c 64 62 5f 77 72 69 74 65 28 0a 20  leveldb_write(. 
04e0: 20 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62   TestDb *pTestDb
04f0: 2c 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c  , .  void *pKey,
0500: 20 0a 20 20 69 6e 74 20 6e 4b 65 79 2c 20 0a 20   .  int nKey, . 
0510: 20 76 6f 69 64 20 2a 70 56 61 6c 2c 20 0a 20 20   void *pVal, .  
0520: 69 6e 74 20 6e 56 61 6c 0a 29 7b 0a 20 20 4c 65  int nVal.){.  Le
0530: 76 65 6c 44 62 20 2a 70 44 62 20 3d 20 28 4c 65  velDb *pDb = (Le
0540: 76 65 6c 44 62 20 2a 29 70 54 65 73 74 44 62 3b  velDb *)pTestDb;
0550: 0a 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20  .  char *zErr = 
0560: 30 3b 0a 20 20 6c 65 76 65 6c 64 62 5f 70 75 74  0;.  leveldb_put
0570: 28 70 44 62 2d 3e 64 62 2c 20 70 44 62 2d 3e 70  (pDb->db, pDb->p
0580: 57 72 69 74 65 4f 70 74 2c 20 70 4b 65 79 2c 20  WriteOpt, pKey, 
0590: 6e 4b 65 79 2c 20 70 56 61 6c 2c 20 6e 56 61 6c  nKey, pVal, nVal
05a0: 2c 20 26 7a 45 72 72 29 3b 0a 20 20 72 65 74 75  , &zErr);.  retu
05b0: 72 6e 20 28 7a 45 72 72 21 3d 30 29 3b 0a 7d 0a  rn (zErr!=0);.}.
05c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
05d0: 5f 6c 65 76 65 6c 64 62 5f 64 65 6c 65 74 65 28  _leveldb_delete(
05e0: 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c  TestDb *pTestDb,
05f0: 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74   void *pKey, int
0600: 20 6e 4b 65 79 29 7b 0a 20 20 4c 65 76 65 6c 44   nKey){.  LevelD
0610: 62 20 2a 70 44 62 20 3d 20 28 4c 65 76 65 6c 44  b *pDb = (LevelD
0620: 62 20 2a 29 70 54 65 73 74 44 62 3b 0a 20 20 63  b *)pTestDb;.  c
0630: 68 61 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a 20  har *zErr = 0;. 
0640: 20 6c 65 76 65 6c 64 62 5f 64 65 6c 65 74 65 28   leveldb_delete(
0650: 70 44 62 2d 3e 64 62 2c 20 70 44 62 2d 3e 70 57  pDb->db, pDb->pW
0660: 72 69 74 65 4f 70 74 2c 20 70 4b 65 79 2c 20 6e  riteOpt, pKey, n
0670: 4b 65 79 2c 20 26 7a 45 72 72 29 3b 0a 20 20 72  Key, &zErr);.  r
0680: 65 74 75 72 6e 20 28 7a 45 72 72 21 3d 30 29 3b  eturn (zErr!=0);
0690: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
06a0: 65 73 74 5f 6c 65 76 65 6c 64 62 5f 66 65 74 63  est_leveldb_fetc
06b0: 68 28 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65  h(.  TestDb *pTe
06c0: 73 74 44 62 2c 20 0a 20 20 76 6f 69 64 20 2a 70  stDb, .  void *p
06d0: 4b 65 79 2c 20 0a 20 20 69 6e 74 20 6e 4b 65 79  Key, .  int nKey
06e0: 2c 20 0a 20 20 76 6f 69 64 20 2a 2a 70 70 56 61  , .  void **ppVa
06f0: 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e 56 61 6c  l, .  int *pnVal
0700: 0a 29 7b 0a 20 20 4c 65 76 65 6c 44 62 20 2a 70  .){.  LevelDb *p
0710: 44 62 20 3d 20 28 4c 65 76 65 6c 44 62 20 2a 29  Db = (LevelDb *)
0720: 70 54 65 73 74 44 62 3b 0a 20 20 63 68 61 72 20  pTestDb;.  char 
0730: 2a 7a 45 72 72 20 3d 20 30 3b 0a 20 20 73 69 7a  *zErr = 0;.  siz
0740: 65 5f 74 20 6e 56 61 6c 20 3d 20 30 3b 0a 0a 20  e_t nVal = 0;.. 
0750: 20 69 66 28 20 70 4b 65 79 3d 3d 30 20 29 20 72   if( pKey==0 ) r
0760: 65 74 75 72 6e 20 30 3b 0a 20 20 66 72 65 65 28  eturn 0;.  free(
0770: 70 44 62 2d 3e 70 56 61 6c 29 3b 0a 20 20 70 44  pDb->pVal);.  pD
0780: 62 2d 3e 70 56 61 6c 20 3d 20 6c 65 76 65 6c 64  b->pVal = leveld
0790: 62 5f 67 65 74 28 70 44 62 2d 3e 64 62 2c 20 70  b_get(pDb->db, p
07a0: 44 62 2d 3e 70 52 65 61 64 4f 70 74 2c 20 70 4b  Db->pReadOpt, pK
07b0: 65 79 2c 20 6e 4b 65 79 2c 20 26 6e 56 61 6c 2c  ey, nKey, &nVal,
07c0: 20 26 7a 45 72 72 29 3b 0a 20 20 2a 70 70 56 61   &zErr);.  *ppVa
07d0: 6c 20 3d 20 28 76 6f 69 64 20 2a 29 28 70 44 62  l = (void *)(pDb
07e0: 2d 3e 70 56 61 6c 29 3b 0a 20 20 69 66 28 20 70  ->pVal);.  if( p
07f0: 44 62 2d 3e 70 56 61 6c 3d 3d 30 20 29 7b 0a 20  Db->pVal==0 ){. 
0800: 20 20 20 2a 70 6e 56 61 6c 20 3d 20 2d 31 3b 0a     *pnVal = -1;.
0810: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 6e    }else{.    *pn
0820: 56 61 6c 20 3d 20 28 69 6e 74 29 6e 56 61 6c 3b  Val = (int)nVal;
0830: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 28  .  }..  return (
0840: 7a 45 72 72 21 3d 30 29 3b 0a 7d 0a 0a 73 74 61  zErr!=0);.}..sta
0850: 74 69 63 20 69 6e 74 20 74 65 73 74 5f 6c 65 76  tic int test_lev
0860: 65 6c 64 62 5f 73 63 61 6e 28 0a 20 20 54 65 73  eldb_scan(.  Tes
0870: 74 44 62 20 2a 70 54 65 73 74 44 62 2c 0a 20 20  tDb *pTestDb,.  
0880: 76 6f 69 64 20 2a 70 43 74 78 2c 0a 20 20 69 6e  void *pCtx,.  in
0890: 74 20 62 52 65 76 65 72 73 65 2c 0a 20 20 76 6f  t bReverse,.  vo
08a0: 69 64 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e  id *pKey1, int n
08b0: 4b 65 79 31 2c 20 20 20 20 20 20 20 20 20 2f 2a  Key1,         /*
08c0: 20 53 74 61 72 74 20 6f 66 20 73 65 61 72 63 68   Start of search
08d0: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79   */.  void *pKey
08e0: 32 2c 20 69 6e 74 20 6e 4b 65 79 32 2c 20 20 20  2, int nKey2,   
08f0: 20 20 20 20 20 20 2f 2a 20 45 6e 64 20 6f 66 20        /* End of 
0900: 73 65 61 72 63 68 20 2a 2f 0a 20 20 76 6f 69 64  search */.  void
0910: 20 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 76 6f   (*xCallback)(vo
0920: 69 64 20 2a 2c 20 76 6f 69 64 20 2a 2c 20 69 6e  id *, void *, in
0930: 74 20 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29  t , void *, int)
0940: 0a 29 7b 0a 20 20 4c 65 76 65 6c 44 62 20 2a 70  .){.  LevelDb *p
0950: 44 62 20 3d 20 28 4c 65 76 65 6c 44 62 20 2a 29  Db = (LevelDb *)
0960: 70 54 65 73 74 44 62 3b 0a 20 20 6c 65 76 65 6c  pTestDb;.  level
0970: 64 62 5f 69 74 65 72 61 74 6f 72 5f 74 20 2a 69  db_iterator_t *i
0980: 74 65 72 3b 0a 0a 20 20 69 74 65 72 20 3d 20 6c  ter;..  iter = l
0990: 65 76 65 6c 64 62 5f 63 72 65 61 74 65 5f 69 74  eveldb_create_it
09a0: 65 72 61 74 6f 72 28 70 44 62 2d 3e 64 62 2c 20  erator(pDb->db, 
09b0: 70 44 62 2d 3e 70 52 65 61 64 4f 70 74 29 3b 0a  pDb->pReadOpt);.
09c0: 0a 20 20 69 66 28 20 62 52 65 76 65 72 73 65 3d  .  if( bReverse=
09d0: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 4b  =0 ){.    if( pK
09e0: 65 79 31 20 29 7b 0a 20 20 20 20 20 20 6c 65 76  ey1 ){.      lev
09f0: 65 6c 64 62 5f 69 74 65 72 5f 73 65 65 6b 28 69  eldb_iter_seek(i
0a00: 74 65 72 2c 20 70 4b 65 79 31 2c 20 6e 4b 65 79  ter, pKey1, nKey
0a10: 31 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  1);.    }else{. 
0a20: 20 20 20 20 20 6c 65 76 65 6c 64 62 5f 69 74 65       leveldb_ite
0a30: 72 5f 73 65 65 6b 5f 74 6f 5f 66 69 72 73 74 28  r_seek_to_first(
0a40: 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  iter);.    }.  }
0a50: 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 70 4b  else{.    if( pK
0a60: 65 79 32 20 29 7b 0a 20 20 20 20 20 20 6c 65 76  ey2 ){.      lev
0a70: 65 6c 64 62 5f 69 74 65 72 5f 73 65 65 6b 28 69  eldb_iter_seek(i
0a80: 74 65 72 2c 20 70 4b 65 79 32 2c 20 6e 4b 65 79  ter, pKey2, nKey
0a90: 32 29 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 6c  2);..      if( l
0aa0: 65 76 65 6c 64 62 5f 69 74 65 72 5f 76 61 6c 69  eveldb_iter_vali
0ab0: 64 28 69 74 65 72 29 3d 3d 30 20 29 7b 0a 20 20  d(iter)==0 ){.  
0ac0: 20 20 20 20 20 20 6c 65 76 65 6c 64 62 5f 69 74        leveldb_it
0ad0: 65 72 5f 73 65 65 6b 5f 74 6f 5f 6c 61 73 74 28  er_seek_to_last(
0ae0: 69 74 65 72 29 3b 0a 20 20 20 20 20 20 7d 65 6c  iter);.      }el
0af0: 73 65 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73  se{.        cons
0b00: 74 20 63 68 61 72 20 2a 6b 3b 20 73 69 7a 65 5f  t char *k; size_
0b10: 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  t n;.        int
0b20: 20 72 65 73 3b 0a 20 20 20 20 20 20 20 20 6b 20   res;.        k 
0b30: 3d 20 6c 65 76 65 6c 64 62 5f 69 74 65 72 5f 6b  = leveldb_iter_k
0b40: 65 79 28 69 74 65 72 2c 20 26 6e 29 3b 0a 20 20  ey(iter, &n);.  
0b50: 20 20 20 20 20 20 72 65 73 20 3d 20 6d 65 6d 63        res = memc
0b60: 6d 70 28 6b 2c 20 70 4b 65 79 32 2c 20 4d 49 4e  mp(k, pKey2, MIN
0b70: 28 6e 2c 20 6e 4b 65 79 32 29 29 3b 0a 20 20 20  (n, nKey2));.   
0b80: 20 20 20 20 20 69 66 28 20 72 65 73 3d 3d 30 20       if( res==0 
0b90: 29 20 72 65 73 20 3d 20 6e 20 2d 20 6e 4b 65 79  ) res = n - nKey
0ba0: 32 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  2;.        asser
0bb0: 74 28 20 72 65 73 3e 3d 30 20 29 3b 0a 20 20 20  t( res>=0 );.   
0bc0: 20 20 20 20 20 69 66 28 20 72 65 73 3e 30 20 29       if( res>0 )
0bd0: 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 65 76 65  {.          leve
0be0: 6c 64 62 5f 69 74 65 72 5f 70 72 65 76 28 69 74  ldb_iter_prev(it
0bf0: 65 72 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  er);.        }. 
0c00: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
0c10: 7b 0a 20 20 20 20 20 20 6c 65 76 65 6c 64 62 5f  {.      leveldb_
0c20: 69 74 65 72 5f 73 65 65 6b 5f 74 6f 5f 6c 61 73  iter_seek_to_las
0c30: 74 28 69 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20  t(iter);.    }. 
0c40: 20 7d 0a 0a 0a 20 20 77 68 69 6c 65 28 20 6c 65   }...  while( le
0c50: 76 65 6c 64 62 5f 69 74 65 72 5f 76 61 6c 69 64  veldb_iter_valid
0c60: 28 69 74 65 72 29 20 29 7b 0a 20 20 20 20 63 6f  (iter) ){.    co
0c70: 6e 73 74 20 63 68 61 72 20 2a 6b 3b 20 73 69 7a  nst char *k; siz
0c80: 65 5f 74 20 6e 3b 0a 20 20 20 20 63 6f 6e 73 74  e_t n;.    const
0c90: 20 63 68 61 72 20 2a 76 3b 20 73 69 7a 65 5f 74   char *v; size_t
0ca0: 20 6e 32 3b 0a 20 20 20 20 69 6e 74 20 72 65 73   n2;.    int res
0cb0: 3b 0a 0a 20 20 20 20 6b 20 3d 20 6c 65 76 65 6c  ;..    k = level
0cc0: 64 62 5f 69 74 65 72 5f 6b 65 79 28 69 74 65 72  db_iter_key(iter
0cd0: 2c 20 26 6e 29 3b 0a 20 20 20 20 69 66 28 20 62  , &n);.    if( b
0ce0: 52 65 76 65 72 73 65 3d 3d 30 20 26 26 20 70 4b  Reverse==0 && pK
0cf0: 65 79 32 20 29 7b 0a 20 20 20 20 20 20 72 65 73  ey2 ){.      res
0d00: 20 3d 20 6d 65 6d 63 6d 70 28 6b 2c 20 70 4b 65   = memcmp(k, pKe
0d10: 79 32 2c 20 4d 49 4e 28 6e 2c 20 6e 4b 65 79 32  y2, MIN(n, nKey2
0d20: 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 65  ));.      if( re
0d30: 73 3d 3d 30 20 29 20 72 65 73 20 3d 20 6e 20 2d  s==0 ) res = n -
0d40: 20 6e 4b 65 79 32 3b 0a 20 20 20 20 20 20 69 66   nKey2;.      if
0d50: 28 20 72 65 73 3e 30 20 29 20 62 72 65 61 6b 3b  ( res>0 ) break;
0d60: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62  .    }.    if( b
0d70: 52 65 76 65 72 73 65 21 3d 30 20 26 26 20 70 4b  Reverse!=0 && pK
0d80: 65 79 31 20 29 7b 0a 20 20 20 20 20 20 72 65 73  ey1 ){.      res
0d90: 20 3d 20 6d 65 6d 63 6d 70 28 6b 2c 20 70 4b 65   = memcmp(k, pKe
0da0: 79 31 2c 20 4d 49 4e 28 6e 2c 20 6e 4b 65 79 31  y1, MIN(n, nKey1
0db0: 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 65  ));.      if( re
0dc0: 73 3d 3d 30 20 29 20 72 65 73 20 3d 20 6e 20 2d  s==0 ) res = n -
0dd0: 20 6e 4b 65 79 31 3b 0a 20 20 20 20 20 20 69 66   nKey1;.      if
0de0: 28 20 72 65 73 3c 30 20 29 20 62 72 65 61 6b 3b  ( res<0 ) break;
0df0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 76 20 3d 20  .    }..    v = 
0e00: 6c 65 76 65 6c 64 62 5f 69 74 65 72 5f 76 61 6c  leveldb_iter_val
0e10: 75 65 28 69 74 65 72 2c 20 26 6e 32 29 3b 0a 0a  ue(iter, &n2);..
0e20: 20 20 20 20 78 43 61 6c 6c 62 61 63 6b 28 70 43      xCallback(pC
0e30: 74 78 2c 20 28 76 6f 69 64 20 2a 29 6b 2c 20 6e  tx, (void *)k, n
0e40: 2c 20 28 76 6f 69 64 20 2a 29 76 2c 20 6e 32 29  , (void *)v, n2)
0e50: 3b 0a 0a 20 20 20 20 69 66 28 20 62 52 65 76 65  ;..    if( bReve
0e60: 72 73 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  rse==0 ){.      
0e70: 6c 65 76 65 6c 64 62 5f 69 74 65 72 5f 6e 65 78  leveldb_iter_nex
0e80: 74 28 69 74 65 72 29 3b 0a 20 20 20 20 7d 65 6c  t(iter);.    }el
0e90: 73 65 7b 0a 20 20 20 20 20 20 6c 65 76 65 6c 64  se{.      leveld
0ea0: 62 5f 69 74 65 72 5f 70 72 65 76 28 69 74 65 72  b_iter_prev(iter
0eb0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
0ec0: 6c 65 76 65 6c 64 62 5f 69 74 65 72 5f 64 65 73  leveldb_iter_des
0ed0: 74 72 6f 79 28 69 74 65 72 29 3b 0a 20 20 72 65  troy(iter);.  re
0ee0: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69  turn 0;.}..stati
0ef0: 63 20 69 6e 74 20 74 65 73 74 5f 6c 65 76 65 6c  c int test_level
0f00: 64 62 5f 6f 70 65 6e 28 0a 20 20 63 6f 6e 73 74  db_open(.  const
0f10: 20 63 68 61 72 20 2a 7a 53 70 65 63 2c 20 0a 20   char *zSpec, . 
0f20: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69   const char *zFi
0f30: 6c 65 6e 61 6d 65 2c 20 0a 20 20 69 6e 74 20 62  lename, .  int b
0f40: 43 6c 65 61 72 2c 20 0a 20 20 54 65 73 74 44 62  Clear, .  TestDb
0f50: 20 2a 2a 70 70 44 62 0a 29 7b 0a 20 20 73 74 61   **ppDb.){.  sta
0f60: 74 69 63 20 63 6f 6e 73 74 20 44 61 74 61 62 61  tic const Databa
0f70: 73 65 4d 65 74 68 6f 64 73 20 4c 65 76 65 6c 64  seMethods Leveld
0f80: 62 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20  bMethods = {.   
0f90: 20 74 65 73 74 5f 6c 65 76 65 6c 64 62 5f 63 6c   test_leveldb_cl
0fa0: 6f 73 65 2c 0a 20 20 20 20 74 65 73 74 5f 6c 65  ose,.    test_le
0fb0: 76 65 6c 64 62 5f 77 72 69 74 65 2c 0a 20 20 20  veldb_write,.   
0fc0: 20 74 65 73 74 5f 6c 65 76 65 6c 64 62 5f 64 65   test_leveldb_de
0fd0: 6c 65 74 65 2c 0a 20 20 20 20 30 2c 0a 20 20 20  lete,.    0,.   
0fe0: 20 74 65 73 74 5f 6c 65 76 65 6c 64 62 5f 66 65   test_leveldb_fe
0ff0: 74 63 68 2c 0a 20 20 20 20 74 65 73 74 5f 6c 65  tch,.    test_le
1000: 76 65 6c 64 62 5f 73 63 61 6e 2c 0a 20 20 20 20  veldb_scan,.    
1010: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
1020: 6e 5f 66 75 6e 63 74 69 6f 6e 2c 0a 20 20 20 20  n_function,.    
1030: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
1040: 6e 5f 66 75 6e 63 74 69 6f 6e 2c 0a 20 20 20 20  n_function,.    
1050: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
1060: 6e 5f 66 75 6e 63 74 69 6f 6e 0a 20 20 7d 3b 0a  n_function.  };.
1070: 0a 20 20 4c 65 76 65 6c 44 62 20 2a 70 4c 65 76  .  LevelDb *pLev
1080: 65 6c 44 62 3b 0a 20 20 63 68 61 72 20 2a 7a 45  elDb;.  char *zE
1090: 72 72 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 62  rr = 0;..  if( b
10a0: 43 6c 65 61 72 20 29 7b 0a 20 20 20 20 63 68 61  Clear ){.    cha
10b0: 72 20 2a 7a 43 6d 64 20 3d 20 73 71 6c 69 74 65  r *zCmd = sqlite
10c0: 33 5f 6d 70 72 69 6e 74 66 28 22 72 6d 20 2d 72  3_mprintf("rm -r
10d0: 66 20 25 73 5c 6e 22 2c 20 7a 46 69 6c 65 6e 61  f %s\n", zFilena
10e0: 6d 65 29 3b 0a 20 20 20 20 73 79 73 74 65 6d 28  me);.    system(
10f0: 7a 43 6d 64 29 3b 0a 20 20 20 20 73 71 6c 69 74  zCmd);.    sqlit
1100: 65 33 5f 66 72 65 65 28 7a 43 6d 64 29 3b 0a 20  e3_free(zCmd);. 
1110: 20 7d 0a 0a 20 20 70 4c 65 76 65 6c 44 62 20 3d   }..  pLevelDb =
1120: 20 28 4c 65 76 65 6c 44 62 20 2a 29 6d 61 6c 6c   (LevelDb *)mall
1130: 6f 63 28 73 69 7a 65 6f 66 28 4c 65 76 65 6c 44  oc(sizeof(LevelD
1140: 62 29 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4c  b));.  memset(pL
1150: 65 76 65 6c 44 62 2c 20 30 2c 20 73 69 7a 65 6f  evelDb, 0, sizeo
1160: 66 28 4c 65 76 65 6c 44 62 29 29 3b 0a 0a 20 20  f(LevelDb));..  
1170: 70 4c 65 76 65 6c 44 62 2d 3e 70 4f 70 74 20 3d  pLevelDb->pOpt =
1180: 20 6c 65 76 65 6c 64 62 5f 6f 70 74 69 6f 6e 73   leveldb_options
1190: 5f 63 72 65 61 74 65 28 29 3b 0a 20 20 6c 65 76  _create();.  lev
11a0: 65 6c 64 62 5f 6f 70 74 69 6f 6e 73 5f 73 65 74  eldb_options_set
11b0: 5f 63 72 65 61 74 65 5f 69 66 5f 6d 69 73 73 69  _create_if_missi
11c0: 6e 67 28 70 4c 65 76 65 6c 44 62 2d 3e 70 4f 70  ng(pLevelDb->pOp
11d0: 74 2c 20 31 29 3b 0a 20 20 70 4c 65 76 65 6c 44  t, 1);.  pLevelD
11e0: 62 2d 3e 70 57 72 69 74 65 4f 70 74 20 3d 20 6c  b->pWriteOpt = l
11f0: 65 76 65 6c 64 62 5f 77 72 69 74 65 6f 70 74 69  eveldb_writeopti
1200: 6f 6e 73 5f 63 72 65 61 74 65 28 29 3b 0a 20 20  ons_create();.  
1210: 70 4c 65 76 65 6c 44 62 2d 3e 70 52 65 61 64 4f  pLevelDb->pReadO
1220: 70 74 20 3d 20 6c 65 76 65 6c 64 62 5f 72 65 61  pt = leveldb_rea
1230: 64 6f 70 74 69 6f 6e 73 5f 63 72 65 61 74 65 28  doptions_create(
1240: 29 3b 0a 0a 20 20 70 4c 65 76 65 6c 44 62 2d 3e  );..  pLevelDb->
1250: 64 62 20 3d 20 6c 65 76 65 6c 64 62 5f 6f 70 65  db = leveldb_ope
1260: 6e 28 70 4c 65 76 65 6c 44 62 2d 3e 70 4f 70 74  n(pLevelDb->pOpt
1270: 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 20 26 7a 45  , zFilename, &zE
1280: 72 72 29 3b 0a 0a 20 20 69 66 28 20 7a 45 72 72  rr);..  if( zErr
1290: 20 29 7b 0a 20 20 20 20 74 65 73 74 5f 6c 65 76   ){.    test_lev
12a0: 65 6c 64 62 5f 63 6c 6f 73 65 28 28 54 65 73 74  eldb_close((Test
12b0: 44 62 20 2a 29 70 4c 65 76 65 6c 44 62 29 3b 0a  Db *)pLevelDb);.
12c0: 20 20 20 20 2a 70 70 44 62 20 3d 20 30 3b 0a 20      *ppDb = 0;. 
12d0: 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d     return 1;.  }
12e0: 0a 0a 20 20 2a 70 70 44 62 20 3d 20 28 54 65 73  ..  *ppDb = (Tes
12f0: 74 44 62 20 2a 29 70 4c 65 76 65 6c 44 62 3b 0a  tDb *)pLevelDb;.
1300: 20 20 70 4c 65 76 65 6c 44 62 2d 3e 62 61 73 65    pLevelDb->base
1310: 2e 70 4d 65 74 68 6f 64 73 20 3d 20 26 4c 65 76  .pMethods = &Lev
1320: 65 6c 64 62 4d 65 74 68 6f 64 73 3b 0a 20 20 72  eldbMethods;.  r
1330: 65 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69  eturn 0;.}.#endi
1340: 66 20 20 2f 2a 20 48 41 56 45 5f 4c 45 56 45 4c  f  /* HAVE_LEVEL
1350: 44 42 20 2a 2f 0a 2f 2a 20 0a 2a 2a 20 45 6e 64  DB */./* .** End
1360: 20 77 72 61 70 70 65 72 20 66 6f 72 20 4c 65 76   wrapper for Lev
1370: 65 6c 44 42 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  elDB..**********
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
13c0: 0a 0a 23 69 66 64 65 66 20 48 41 56 45 5f 4b 59  ..#ifdef HAVE_KY
13d0: 4f 54 4f 43 41 42 49 4e 45 54 0a 73 74 61 74 69  OTOCABINET.stati
13e0: 63 20 69 6e 74 20 6b 63 5f 63 6c 6f 73 65 28 54  c int kc_close(T
13f0: 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 29 7b  estDb *pTestDb){
1400: 0a 20 20 72 65 74 75 72 6e 20 74 65 73 74 5f 6b  .  return test_k
1410: 63 5f 63 6c 6f 73 65 28 70 54 65 73 74 44 62 29  c_close(pTestDb)
1420: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
1430: 6b 63 5f 77 72 69 74 65 28 0a 20 20 54 65 73 74  kc_write(.  Test
1440: 44 62 20 2a 70 54 65 73 74 44 62 2c 20 0a 20 20  Db *pTestDb, .  
1450: 76 6f 69 64 20 2a 70 4b 65 79 2c 20 0a 20 20 69  void *pKey, .  i
1460: 6e 74 20 6e 4b 65 79 2c 20 0a 20 20 76 6f 69 64  nt nKey, .  void
1470: 20 2a 70 56 61 6c 2c 20 0a 20 20 69 6e 74 20 6e   *pVal, .  int n
1480: 56 61 6c 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  Val.){.  return 
1490: 74 65 73 74 5f 6b 63 5f 77 72 69 74 65 28 70 54  test_kc_write(pT
14a0: 65 73 74 44 62 2c 20 70 4b 65 79 2c 20 6e 4b 65  estDb, pKey, nKe
14b0: 79 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b 0a  y, pVal, nVal);.
14c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 6b 63  }..static int kc
14d0: 5f 64 65 6c 65 74 65 28 54 65 73 74 44 62 20 2a  _delete(TestDb *
14e0: 70 54 65 73 74 44 62 2c 20 76 6f 69 64 20 2a 70  pTestDb, void *p
14f0: 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 29 7b 0a  Key, int nKey){.
1500: 20 20 72 65 74 75 72 6e 20 74 65 73 74 5f 6b 63    return test_kc
1510: 5f 64 65 6c 65 74 65 28 70 54 65 73 74 44 62 2c  _delete(pTestDb,
1520: 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 7d 0a   pKey, nKey);.}.
1530: 0a 73 74 61 74 69 63 20 69 6e 74 20 6b 63 5f 64  .static int kc_d
1540: 65 6c 65 74 65 5f 72 61 6e 67 65 28 0a 20 20 54  elete_range(.  T
1550: 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20  estDb *pTestDb, 
1560: 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20  .  void *pKey1, 
1570: 69 6e 74 20 6e 4b 65 79 31 2c 0a 20 20 76 6f 69  int nKey1,.  voi
1580: 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b  d *pKey2, int nK
1590: 65 79 32 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  ey2.){.  return 
15a0: 74 65 73 74 5f 6b 63 5f 64 65 6c 65 74 65 5f 72  test_kc_delete_r
15b0: 61 6e 67 65 28 70 54 65 73 74 44 62 2c 20 70 4b  ange(pTestDb, pK
15c0: 65 79 31 2c 20 6e 4b 65 79 31 2c 20 70 4b 65 79  ey1, nKey1, pKey
15d0: 32 2c 20 6e 4b 65 79 32 29 3b 0a 7d 0a 0a 73 74  2, nKey2);.}..st
15e0: 61 74 69 63 20 69 6e 74 20 6b 63 5f 66 65 74 63  atic int kc_fetc
15f0: 68 28 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65  h(.  TestDb *pTe
1600: 73 74 44 62 2c 20 0a 20 20 76 6f 69 64 20 2a 70  stDb, .  void *p
1610: 4b 65 79 2c 20 0a 20 20 69 6e 74 20 6e 4b 65 79  Key, .  int nKey
1620: 2c 20 0a 20 20 76 6f 69 64 20 2a 2a 70 70 56 61  , .  void **ppVa
1630: 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e 56 61 6c  l, .  int *pnVal
1640: 0a 29 7b 0a 20 20 69 66 28 20 70 4b 65 79 3d 3d  .){.  if( pKey==
1650: 30 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f  0 ) return LSM_O
1660: 4b 3b 0a 20 20 72 65 74 75 72 6e 20 74 65 73 74  K;.  return test
1670: 5f 6b 63 5f 66 65 74 63 68 28 70 54 65 73 74 44  _kc_fetch(pTestD
1680: 62 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 70  b, pKey, nKey, p
1690: 70 56 61 6c 2c 20 70 6e 56 61 6c 29 3b 0a 7d 0a  pVal, pnVal);.}.
16a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6b 63 5f 73  .static int kc_s
16b0: 63 61 6e 28 0a 20 20 54 65 73 74 44 62 20 2a 70  can(.  TestDb *p
16c0: 54 65 73 74 44 62 2c 0a 20 20 76 6f 69 64 20 2a  TestDb,.  void *
16d0: 70 43 74 78 2c 0a 20 20 69 6e 74 20 62 52 65 76  pCtx,.  int bRev
16e0: 65 72 73 65 2c 0a 20 20 76 6f 69 64 20 2a 70 46  erse,.  void *pF
16f0: 69 72 73 74 2c 20 69 6e 74 20 6e 46 69 72 73 74  irst, int nFirst
1700: 2c 0a 20 20 76 6f 69 64 20 2a 70 4c 61 73 74 2c  ,.  void *pLast,
1710: 20 69 6e 74 20 6e 4c 61 73 74 2c 0a 20 20 76 6f   int nLast,.  vo
1720: 69 64 20 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28  id (*xCallback)(
1730: 76 6f 69 64 20 2a 2c 20 76 6f 69 64 20 2a 2c 20  void *, void *, 
1740: 69 6e 74 20 2c 20 76 6f 69 64 20 2a 2c 20 69 6e  int , void *, in
1750: 74 29 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 74  t).){.  return t
1760: 65 73 74 5f 6b 63 5f 73 63 61 6e 28 0a 20 20 20  est_kc_scan(.   
1770: 20 20 20 70 54 65 73 74 44 62 2c 20 70 43 74 78     pTestDb, pCtx
1780: 2c 20 62 52 65 76 65 72 73 65 2c 20 70 46 69 72  , bReverse, pFir
1790: 73 74 2c 20 6e 46 69 72 73 74 2c 20 70 4c 61 73  st, nFirst, pLas
17a0: 74 2c 20 6e 4c 61 73 74 2c 20 78 43 61 6c 6c 62  t, nLast, xCallb
17b0: 61 63 6b 0a 20 20 29 3b 0a 7d 0a 0a 73 74 61 74  ack.  );.}..stat
17c0: 69 63 20 69 6e 74 20 6b 63 5f 6f 70 65 6e 28 0a  ic int kc_open(.
17d0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
17e0: 70 65 63 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  pec, .  const ch
17f0: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 0a  ar *zFilename, .
1800: 20 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20    int bClear, . 
1810: 20 54 65 73 74 44 62 20 2a 2a 70 70 44 62 0a 29   TestDb **ppDb.)
1820: 7b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74  {.  static const
1830: 20 44 61 74 61 62 61 73 65 4d 65 74 68 6f 64 73   DatabaseMethods
1840: 20 4b 63 64 62 4d 65 74 68 6f 64 73 20 3d 20 7b   KcdbMethods = {
1850: 0a 20 20 20 20 6b 63 5f 63 6c 6f 73 65 2c 0a 20  .    kc_close,. 
1860: 20 20 20 6b 63 5f 77 72 69 74 65 2c 0a 20 20 20     kc_write,.   
1870: 20 6b 63 5f 64 65 6c 65 74 65 2c 0a 20 20 20 20   kc_delete,.    
1880: 6b 63 5f 64 65 6c 65 74 65 5f 72 61 6e 67 65 2c  kc_delete_range,
1890: 0a 20 20 20 20 6b 63 5f 66 65 74 63 68 2c 0a 20  .    kc_fetch,. 
18a0: 20 20 20 6b 63 5f 73 63 61 6e 2c 0a 20 20 20 20     kc_scan,.    
18b0: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
18c0: 6e 5f 66 75 6e 63 74 69 6f 6e 2c 0a 20 20 20 20  n_function,.    
18d0: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
18e0: 6e 5f 66 75 6e 63 74 69 6f 6e 2c 0a 20 20 20 20  n_function,.    
18f0: 65 72 72 6f 72 5f 74 72 61 6e 73 61 63 74 69 6f  error_transactio
1900: 6e 5f 66 75 6e 63 74 69 6f 6e 0a 20 20 7d 3b 0a  n_function.  };.
1910: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 65 73  .  int rc;.  Tes
1920: 74 44 62 20 2a 70 54 65 73 74 44 62 20 3d 20 30  tDb *pTestDb = 0
1930: 3b 0a 0a 20 20 72 63 20 3d 20 74 65 73 74 5f 6b  ;..  rc = test_k
1940: 63 5f 6f 70 65 6e 28 7a 46 69 6c 65 6e 61 6d 65  c_open(zFilename
1950: 2c 20 62 43 6c 65 61 72 2c 20 26 70 54 65 73 74  , bClear, &pTest
1960: 44 62 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 30  Db);.  if( rc!=0
1970: 20 29 7b 0a 20 20 20 20 2a 70 70 44 62 20 3d 20   ){.    *ppDb = 
1980: 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  0;.    return rc
1990: 3b 0a 20 20 7d 0a 20 20 70 54 65 73 74 44 62 2d  ;.  }.  pTestDb-
19a0: 3e 70 4d 65 74 68 6f 64 73 20 3d 20 26 4b 63 64  >pMethods = &Kcd
19b0: 62 4d 65 74 68 6f 64 73 3b 0a 20 20 2a 70 70 44  bMethods;.  *ppD
19c0: 62 20 3d 20 70 54 65 73 74 44 62 3b 0a 20 20 72  b = pTestDb;.  r
19d0: 65 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69  eturn 0;.}.#endi
19e0: 66 20 2f 2a 20 48 41 56 45 5f 4b 59 4f 54 4f 43  f /* HAVE_KYOTOC
19f0: 41 42 49 4e 45 54 20 2a 2f 0a 2f 2a 20 0a 2a 2a  ABINET */./* .**
1a00: 20 45 6e 64 20 77 72 61 70 70 65 72 20 66 6f 72   End wrapper for
1a10: 20 4b 79 6f 74 6f 20 63 61 62 69 6e 65 74 2e 0a   Kyoto cabinet..
1a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66 64  *********/..#ifd
1a70: 65 66 20 48 41 56 45 5f 4d 44 42 0a 73 74 61 74  ef HAVE_MDB.stat
1a80: 69 63 20 69 6e 74 20 6d 64 62 5f 63 6c 6f 73 65  ic int mdb_close
1a90: 28 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62  (TestDb *pTestDb
1aa0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 74 65 73 74  ){.  return test
1ab0: 5f 6d 64 62 5f 63 6c 6f 73 65 28 70 54 65 73 74  _mdb_close(pTest
1ac0: 44 62 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  Db);.}..static i
1ad0: 6e 74 20 6d 64 62 5f 77 72 69 74 65 28 0a 20 20  nt mdb_write(.  
1ae0: 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c  TestDb *pTestDb,
1af0: 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20   .  void *pKey, 
1b00: 0a 20 20 69 6e 74 20 6e 4b 65 79 2c 20 0a 20 20  .  int nKey, .  
1b10: 76 6f 69 64 20 2a 70 56 61 6c 2c 20 0a 20 20 69  void *pVal, .  i
1b20: 6e 74 20 6e 56 61 6c 0a 29 7b 0a 20 20 72 65 74  nt nVal.){.  ret
1b30: 75 72 6e 20 74 65 73 74 5f 6d 64 62 5f 77 72 69  urn test_mdb_wri
1b40: 74 65 28 70 54 65 73 74 44 62 2c 20 70 4b 65 79  te(pTestDb, pKey
1b50: 2c 20 6e 4b 65 79 2c 20 70 56 61 6c 2c 20 6e 56  , nKey, pVal, nV
1b60: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  al);.}..static i
1b70: 6e 74 20 6d 64 62 5f 64 65 6c 65 74 65 28 54 65  nt mdb_delete(Te
1b80: 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20 76  stDb *pTestDb, v
1b90: 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e  oid *pKey, int n
1ba0: 4b 65 79 29 7b 0a 20 20 72 65 74 75 72 6e 20 74  Key){.  return t
1bb0: 65 73 74 5f 6d 64 62 5f 64 65 6c 65 74 65 28 70  est_mdb_delete(p
1bc0: 54 65 73 74 44 62 2c 20 70 4b 65 79 2c 20 6e 4b  TestDb, pKey, nK
1bd0: 65 79 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  ey);.}..static i
1be0: 6e 74 20 6d 64 62 5f 66 65 74 63 68 28 0a 20 20  nt mdb_fetch(.  
1bf0: 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c  TestDb *pTestDb,
1c00: 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20   .  void *pKey, 
1c10: 0a 20 20 69 6e 74 20 6e 4b 65 79 2c 20 0a 20 20  .  int nKey, .  
1c20: 76 6f 69 64 20 2a 2a 70 70 56 61 6c 2c 20 0a 20  void **ppVal, . 
1c30: 20 69 6e 74 20 2a 70 6e 56 61 6c 0a 29 7b 0a 20   int *pnVal.){. 
1c40: 20 69 66 28 20 70 4b 65 79 3d 3d 30 20 29 20 72   if( pKey==0 ) r
1c50: 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20 20  eturn LSM_OK;.  
1c60: 72 65 74 75 72 6e 20 74 65 73 74 5f 6d 64 62 5f  return test_mdb_
1c70: 66 65 74 63 68 28 70 54 65 73 74 44 62 2c 20 70  fetch(pTestDb, p
1c80: 4b 65 79 2c 20 6e 4b 65 79 2c 20 70 70 56 61 6c  Key, nKey, ppVal
1c90: 2c 20 70 6e 56 61 6c 29 3b 0a 7d 0a 0a 73 74 61  , pnVal);.}..sta
1ca0: 74 69 63 20 69 6e 74 20 6d 64 62 5f 73 63 61 6e  tic int mdb_scan
1cb0: 28 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65 73  (.  TestDb *pTes
1cc0: 74 44 62 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74  tDb,.  void *pCt
1cd0: 78 2c 0a 20 20 69 6e 74 20 62 52 65 76 65 72 73  x,.  int bRevers
1ce0: 65 2c 0a 20 20 76 6f 69 64 20 2a 70 46 69 72 73  e,.  void *pFirs
1cf0: 74 2c 20 69 6e 74 20 6e 46 69 72 73 74 2c 0a 20  t, int nFirst,. 
1d00: 20 76 6f 69 64 20 2a 70 4c 61 73 74 2c 20 69 6e   void *pLast, in
1d10: 74 20 6e 4c 61 73 74 2c 0a 20 20 76 6f 69 64 20  t nLast,.  void 
1d20: 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 76 6f 69  (*xCallback)(voi
1d30: 64 20 2a 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74  d *, void *, int
1d40: 20 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 0a   , void *, int).
1d50: 29 7b 0a 20 20 72 65 74 75 72 6e 20 74 65 73 74  ){.  return test
1d60: 5f 6d 64 62 5f 73 63 61 6e 28 0a 20 20 20 20 20  _mdb_scan(.     
1d70: 20 70 54 65 73 74 44 62 2c 20 70 43 74 78 2c 20   pTestDb, pCtx, 
1d80: 62 52 65 76 65 72 73 65 2c 20 70 46 69 72 73 74  bReverse, pFirst
1d90: 2c 20 6e 46 69 72 73 74 2c 20 70 4c 61 73 74 2c  , nFirst, pLast,
1da0: 20 6e 4c 61 73 74 2c 20 78 43 61 6c 6c 62 61 63   nLast, xCallbac
1db0: 6b 0a 20 20 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  k.  );.}..static
1dc0: 20 69 6e 74 20 6d 64 62 5f 6f 70 65 6e 28 0a 20   int mdb_open(. 
1dd0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 70   const char *zSp
1de0: 65 63 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  ec, .  const cha
1df0: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 0a 20  r *zFilename, . 
1e00: 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 0a 20 20   int bClear, .  
1e10: 54 65 73 74 44 62 20 2a 2a 70 70 44 62 0a 29 7b  TestDb **ppDb.){
1e20: 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20  .  static const 
1e30: 44 61 74 61 62 61 73 65 4d 65 74 68 6f 64 73 20  DatabaseMethods 
1e40: 4b 63 64 62 4d 65 74 68 6f 64 73 20 3d 20 7b 0a  KcdbMethods = {.
1e50: 20 20 20 20 6d 64 62 5f 63 6c 6f 73 65 2c 0a 20      mdb_close,. 
1e60: 20 20 20 6d 64 62 5f 77 72 69 74 65 2c 0a 20 20     mdb_write,.  
1e70: 20 20 6d 64 62 5f 64 65 6c 65 74 65 2c 0a 20 20    mdb_delete,.  
1e80: 20 20 30 2c 0a 20 20 20 20 6d 64 62 5f 66 65 74    0,.    mdb_fet
1e90: 63 68 2c 0a 20 20 20 20 6d 64 62 5f 73 63 61 6e  ch,.    mdb_scan
1ea0: 2c 0a 20 20 20 20 65 72 72 6f 72 5f 74 72 61 6e  ,.    error_tran
1eb0: 73 61 63 74 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e  saction_function
1ec0: 2c 0a 20 20 20 20 65 72 72 6f 72 5f 74 72 61 6e  ,.    error_tran
1ed0: 73 61 63 74 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e  saction_function
1ee0: 2c 0a 20 20 20 20 65 72 72 6f 72 5f 74 72 61 6e  ,.    error_tran
1ef0: 73 61 63 74 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e  saction_function
1f00: 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74 20 72 63 3b  .  };..  int rc;
1f10: 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65 73 74  .  TestDb *pTest
1f20: 44 62 20 3d 20 30 3b 0a 0a 20 20 72 63 20 3d 20  Db = 0;..  rc = 
1f30: 74 65 73 74 5f 6d 64 62 5f 6f 70 65 6e 28 7a 53  test_mdb_open(zS
1f40: 70 65 63 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 20  pec, zFilename, 
1f50: 62 43 6c 65 61 72 2c 20 26 70 54 65 73 74 44 62  bClear, &pTestDb
1f60: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 30 20 29  );.  if( rc!=0 )
1f70: 7b 0a 20 20 20 20 2a 70 70 44 62 20 3d 20 30 3b  {.    *ppDb = 0;
1f80: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
1f90: 20 20 7d 0a 20 20 70 54 65 73 74 44 62 2d 3e 70    }.  pTestDb->p
1fa0: 4d 65 74 68 6f 64 73 20 3d 20 26 4b 63 64 62 4d  Methods = &KcdbM
1fb0: 65 74 68 6f 64 73 3b 0a 20 20 2a 70 70 44 62 20  ethods;.  *ppDb 
1fc0: 3d 20 70 54 65 73 74 44 62 3b 0a 20 20 72 65 74  = pTestDb;.  ret
1fd0: 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 20  urn 0;.}.#endif 
1fe0: 2f 2a 20 48 41 56 45 5f 4d 44 42 20 2a 2f 0a 0a  /* HAVE_MDB */..
1ff0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
2000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2010: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2020: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2030: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 42 65  **********.** Be
2040: 67 69 6e 20 77 72 61 70 70 65 72 20 66 6f 72 20  gin wrapper for 
2050: 53 51 4c 69 74 65 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a  SQLite..*/../*.*
2060: 2a 20 6e 4f 70 65 6e 54 72 61 6e 73 3a 0a 2a 2a  * nOpenTrans:.**
2070: 20 20 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66     The number of
2080: 20 6f 70 65 6e 20 6e 65 73 74 65 64 20 74 72 61   open nested tra
2090: 6e 73 61 63 74 69 6f 6e 73 2c 20 69 6e 20 74 68  nsactions, in th
20a0: 65 20 73 61 6d 65 20 73 65 6e 73 65 20 61 73 20  e same sense as 
20b0: 75 73 65 64 0a 2a 2a 20 20 20 62 79 20 74 68 65  used.**   by the
20c0: 20 74 64 62 5f 62 65 67 69 6e 2f 63 6f 6d 6d 69   tdb_begin/commi
20d0: 74 2f 72 6f 6c 6c 62 61 63 6b 20 61 6e 64 20 53  t/rollback and S
20e0: 51 4c 69 74 65 20 34 20 4b 56 20 69 6e 74 65 72  QLite 4 KV inter
20f0: 66 61 63 65 73 2e 20 49 66 20 74 68 69 73 0a 2a  faces. If this.*
2100: 2a 20 20 20 76 61 6c 75 65 20 69 73 20 30 2c 20  *   value is 0, 
2110: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 74 72 61  there are no tra
2120: 6e 73 61 63 74 69 6f 6e 73 20 6f 70 65 6e 20 61  nsactions open a
2130: 74 20 61 6c 6c 2e 20 49 66 20 69 74 20 69 73 20  t all. If it is 
2140: 31 2c 20 74 68 65 6e 0a 2a 2a 20 20 20 74 68 65  1, then.**   the
2150: 72 65 20 69 73 20 61 20 72 65 61 64 20 74 72 61  re is a read tra
2160: 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20 69 74 20  nsaction. If it 
2170: 69 73 20 32 20 6f 72 20 67 72 65 61 74 65 72 2c  is 2 or greater,
2180: 20 74 68 65 6e 20 74 68 65 72 65 20 61 72 65 0a   then there are.
2190: 2a 2a 20 20 20 28 6e 4f 70 65 6e 54 72 61 6e 73  **   (nOpenTrans
21a0: 2d 31 29 20 6e 65 73 74 65 64 20 77 72 69 74 65  -1) nested write
21b0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 6f 70   transactions op
21c0: 65 6e 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 53 71  en..*/.struct Sq
21d0: 6c 44 62 20 7b 0a 20 20 54 65 73 74 44 62 20 62  lDb {.  TestDb b
21e0: 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  ase;.  sqlite3 *
21f0: 64 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  db;.  sqlite3_st
2200: 6d 74 20 2a 70 49 6e 73 65 72 74 3b 0a 20 20 73  mt *pInsert;.  s
2210: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 44 65  qlite3_stmt *pDe
2220: 6c 65 74 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f  lete;.  sqlite3_
2230: 73 74 6d 74 20 2a 70 44 65 6c 65 74 65 52 61 6e  stmt *pDeleteRan
2240: 67 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  ge;.  sqlite3_st
2250: 6d 74 20 2a 70 46 65 74 63 68 3b 0a 20 20 73 71  mt *pFetch;.  sq
2260: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 61 70 53 63  lite3_stmt *apSc
2270: 61 6e 5b 38 5d 3b 0a 0a 20 20 69 6e 74 20 6e 4f  an[8];..  int nO
2280: 70 65 6e 54 72 61 6e 73 3b 0a 0a 20 20 2f 2a 20  penTrans;..  /* 
2290: 55 73 65 64 20 62 79 20 73 71 6c 5f 66 65 74 63  Used by sql_fetc
22a0: 68 28 29 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  h() to allocate 
22b0: 73 70 61 63 65 20 66 6f 72 20 72 65 73 75 6c 74  space for result
22c0: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f  s */.  int nAllo
22d0: 63 3b 0a 20 20 75 38 20 2a 61 41 6c 6c 6f 63 3b  c;.  u8 *aAlloc;
22e0: 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  .};..static int 
22f0: 73 71 6c 5f 63 6c 6f 73 65 28 54 65 73 74 44 62  sql_close(TestDb
2300: 20 2a 70 54 65 73 74 44 62 29 7b 0a 20 20 53 71   *pTestDb){.  Sq
2310: 6c 44 62 20 2a 70 44 62 20 3d 20 28 53 71 6c 44  lDb *pDb = (SqlD
2320: 62 20 2a 29 70 54 65 73 74 44 62 3b 0a 20 20 73  b *)pTestDb;.  s
2330: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
2340: 70 44 62 2d 3e 70 49 6e 73 65 72 74 29 3b 0a 20  pDb->pInsert);. 
2350: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
2360: 65 28 70 44 62 2d 3e 70 44 65 6c 65 74 65 29 3b  e(pDb->pDelete);
2370: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
2380: 69 7a 65 28 70 44 62 2d 3e 70 44 65 6c 65 74 65  ize(pDb->pDelete
2390: 52 61 6e 67 65 29 3b 0a 20 20 73 71 6c 69 74 65  Range);.  sqlite
23a0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 44 62 2d 3e  3_finalize(pDb->
23b0: 70 46 65 74 63 68 29 3b 0a 20 20 73 71 6c 69 74  pFetch);.  sqlit
23c0: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 44 62 2d  e3_finalize(pDb-
23d0: 3e 61 70 53 63 61 6e 5b 30 5d 29 3b 0a 20 20 73  >apScan[0]);.  s
23e0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
23f0: 70 44 62 2d 3e 61 70 53 63 61 6e 5b 31 5d 29 3b  pDb->apScan[1]);
2400: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
2410: 69 7a 65 28 70 44 62 2d 3e 61 70 53 63 61 6e 5b  ize(pDb->apScan[
2420: 32 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  2]);.  sqlite3_f
2430: 69 6e 61 6c 69 7a 65 28 70 44 62 2d 3e 61 70 53  inalize(pDb->apS
2440: 63 61 6e 5b 33 5d 29 3b 0a 20 20 73 71 6c 69 74  can[3]);.  sqlit
2450: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 44 62 2d  e3_finalize(pDb-
2460: 3e 61 70 53 63 61 6e 5b 34 5d 29 3b 0a 20 20 73  >apScan[4]);.  s
2470: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
2480: 70 44 62 2d 3e 61 70 53 63 61 6e 5b 35 5d 29 3b  pDb->apScan[5]);
2490: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
24a0: 69 7a 65 28 70 44 62 2d 3e 61 70 53 63 61 6e 5b  ize(pDb->apScan[
24b0: 36 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  6]);.  sqlite3_f
24c0: 69 6e 61 6c 69 7a 65 28 70 44 62 2d 3e 61 70 53  inalize(pDb->apS
24d0: 63 61 6e 5b 37 5d 29 3b 0a 20 20 73 71 6c 69 74  can[7]);.  sqlit
24e0: 65 33 5f 63 6c 6f 73 65 28 70 44 62 2d 3e 64 62  e3_close(pDb->db
24f0: 29 3b 0a 20 20 66 72 65 65 28 28 63 68 61 72 20  );.  free((char 
2500: 2a 29 70 44 62 2d 3e 61 41 6c 6c 6f 63 29 3b 0a  *)pDb->aAlloc);.
2510: 20 20 66 72 65 65 28 28 63 68 61 72 20 2a 29 70    free((char *)p
2520: 44 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  Db);.  return SQ
2530: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74  LITE_OK;.}..stat
2540: 69 63 20 69 6e 74 20 73 71 6c 5f 77 72 69 74 65  ic int sql_write
2550: 28 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65 73  (.  TestDb *pTes
2560: 74 44 62 2c 20 0a 20 20 76 6f 69 64 20 2a 70 4b  tDb, .  void *pK
2570: 65 79 2c 20 0a 20 20 69 6e 74 20 6e 4b 65 79 2c  ey, .  int nKey,
2580: 20 0a 20 20 76 6f 69 64 20 2a 70 56 61 6c 2c 20   .  void *pVal, 
2590: 0a 20 20 69 6e 74 20 6e 56 61 6c 0a 29 7b 0a 20  .  int nVal.){. 
25a0: 20 53 71 6c 44 62 20 2a 70 44 62 20 3d 20 28 53   SqlDb *pDb = (S
25b0: 71 6c 44 62 20 2a 29 70 54 65 73 74 44 62 3b 0a  qlDb *)pTestDb;.
25c0: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62    sqlite3_bind_b
25d0: 6c 6f 62 28 70 44 62 2d 3e 70 49 6e 73 65 72 74  lob(pDb->pInsert
25e0: 2c 20 31 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c  , 1, pKey, nKey,
25f0: 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b   SQLITE_STATIC);
2600: 0a 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f  .  sqlite3_bind_
2610: 62 6c 6f 62 28 70 44 62 2d 3e 70 49 6e 73 65 72  blob(pDb->pInser
2620: 74 2c 20 32 2c 20 70 56 61 6c 2c 20 6e 56 61 6c  t, 2, pVal, nVal
2630: 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29  , SQLITE_STATIC)
2640: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70  ;.  sqlite3_step
2650: 28 70 44 62 2d 3e 70 49 6e 73 65 72 74 29 3b 0a  (pDb->pInsert);.
2660: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
2670: 5f 72 65 73 65 74 28 70 44 62 2d 3e 70 49 6e 73  _reset(pDb->pIns
2680: 65 72 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  ert);.}..static 
2690: 69 6e 74 20 73 71 6c 5f 64 65 6c 65 74 65 28 54  int sql_delete(T
26a0: 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20  estDb *pTestDb, 
26b0: 76 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20  void *pKey, int 
26c0: 6e 4b 65 79 29 7b 0a 20 20 53 71 6c 44 62 20 2a  nKey){.  SqlDb *
26d0: 70 44 62 20 3d 20 28 53 71 6c 44 62 20 2a 29 70  pDb = (SqlDb *)p
26e0: 54 65 73 74 44 62 3b 0a 20 20 73 71 6c 69 74 65  TestDb;.  sqlite
26f0: 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 70 44 62 2d  3_bind_blob(pDb-
2700: 3e 70 44 65 6c 65 74 65 2c 20 31 2c 20 70 4b 65  >pDelete, 1, pKe
2710: 79 2c 20 6e 4b 65 79 2c 20 53 51 4c 49 54 45 5f  y, nKey, SQLITE_
2720: 53 54 41 54 49 43 29 3b 0a 20 20 73 71 6c 69 74  STATIC);.  sqlit
2730: 65 33 5f 73 74 65 70 28 70 44 62 2d 3e 70 44 65  e3_step(pDb->pDe
2740: 6c 65 74 65 29 3b 0a 20 20 72 65 74 75 72 6e 20  lete);.  return 
2750: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 44  sqlite3_reset(pD
2760: 62 2d 3e 70 44 65 6c 65 74 65 29 3b 0a 7d 0a 0a  b->pDelete);.}..
2770: 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 64  static int sql_d
2780: 65 6c 65 74 65 5f 72 61 6e 67 65 28 0a 20 20 54  elete_range(.  T
2790: 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20  estDb *pTestDb, 
27a0: 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 31 2c 20  .  void *pKey1, 
27b0: 69 6e 74 20 6e 4b 65 79 31 2c 0a 20 20 76 6f 69  int nKey1,.  voi
27c0: 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20 6e 4b  d *pKey2, int nK
27d0: 65 79 32 0a 29 7b 0a 20 20 53 71 6c 44 62 20 2a  ey2.){.  SqlDb *
27e0: 70 44 62 20 3d 20 28 53 71 6c 44 62 20 2a 29 70  pDb = (SqlDb *)p
27f0: 54 65 73 74 44 62 3b 0a 20 20 73 71 6c 69 74 65  TestDb;.  sqlite
2800: 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 70 44 62 2d  3_bind_blob(pDb-
2810: 3e 70 44 65 6c 65 74 65 52 61 6e 67 65 2c 20 31  >pDeleteRange, 1
2820: 2c 20 70 4b 65 79 31 2c 20 6e 4b 65 79 31 2c 20  , pKey1, nKey1, 
2830: 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a  SQLITE_STATIC);.
2840: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62    sqlite3_bind_b
2850: 6c 6f 62 28 70 44 62 2d 3e 70 44 65 6c 65 74 65  lob(pDb->pDelete
2860: 52 61 6e 67 65 2c 20 32 2c 20 70 4b 65 79 32 2c  Range, 2, pKey2,
2870: 20 6e 4b 65 79 32 2c 20 53 51 4c 49 54 45 5f 53   nKey2, SQLITE_S
2880: 54 41 54 49 43 29 3b 0a 20 20 73 71 6c 69 74 65  TATIC);.  sqlite
2890: 33 5f 73 74 65 70 28 70 44 62 2d 3e 70 44 65 6c  3_step(pDb->pDel
28a0: 65 74 65 52 61 6e 67 65 29 3b 0a 20 20 72 65 74  eteRange);.  ret
28b0: 75 72 6e 20 73 71 6c 69 74 65 33 5f 72 65 73 65  urn sqlite3_rese
28c0: 74 28 70 44 62 2d 3e 70 44 65 6c 65 74 65 52 61  t(pDb->pDeleteRa
28d0: 6e 67 65 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  nge);.}..static 
28e0: 69 6e 74 20 73 71 6c 5f 66 65 74 63 68 28 0a 20  int sql_fetch(. 
28f0: 20 54 65 73 74 44 62 20 2a 70 54 65 73 74 44 62   TestDb *pTestDb
2900: 2c 20 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 2c  , .  void *pKey,
2910: 20 0a 20 20 69 6e 74 20 6e 4b 65 79 2c 20 0a 20   .  int nKey, . 
2920: 20 76 6f 69 64 20 2a 2a 70 70 56 61 6c 2c 20 0a   void **ppVal, .
2930: 20 20 69 6e 74 20 2a 70 6e 56 61 6c 0a 29 7b 0a    int *pnVal.){.
2940: 20 20 53 71 6c 44 62 20 2a 70 44 62 20 3d 20 28    SqlDb *pDb = (
2950: 53 71 6c 44 62 20 2a 29 70 54 65 73 74 44 62 3b  SqlDb *)pTestDb;
2960: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 73 71  .  int rc;..  sq
2970: 6c 69 74 65 33 5f 72 65 73 65 74 28 70 44 62 2d  lite3_reset(pDb-
2980: 3e 70 46 65 74 63 68 29 3b 0a 20 20 69 66 28 20  >pFetch);.  if( 
2990: 70 4b 65 79 3d 3d 30 20 29 7b 0a 20 20 20 20 61  pKey==0 ){.    a
29a0: 73 73 65 72 74 28 20 70 70 56 61 6c 3d 3d 30 20  ssert( ppVal==0 
29b0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
29c0: 6e 56 61 6c 3d 3d 30 20 29 3b 0a 20 20 20 20 72  nVal==0 );.    r
29d0: 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20 20  eturn LSM_OK;.  
29e0: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 62 69 6e  }..  sqlite3_bin
29f0: 64 5f 62 6c 6f 62 28 70 44 62 2d 3e 70 46 65 74  d_blob(pDb->pFet
2a00: 63 68 2c 20 31 2c 20 70 4b 65 79 2c 20 6e 4b 65  ch, 1, pKey, nKe
2a10: 79 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43  y, SQLITE_STATIC
2a20: 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  );.  rc = sqlite
2a30: 33 5f 73 74 65 70 28 70 44 62 2d 3e 70 46 65 74  3_step(pDb->pFet
2a40: 63 68 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ch);.  if( rc==S
2a50: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
2a60: 20 69 6e 74 20 6e 56 61 6c 20 3d 20 73 71 6c 69   int nVal = sqli
2a70: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73  te3_column_bytes
2a80: 28 70 44 62 2d 3e 70 46 65 74 63 68 2c 20 30 29  (pDb->pFetch, 0)
2a90: 3b 0a 20 20 20 20 75 38 20 2a 61 56 61 6c 20 3d  ;.    u8 *aVal =
2aa0: 20 28 76 6f 69 64 20 2a 29 73 71 6c 69 74 65 33   (void *)sqlite3
2ab0: 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70 44 62  _column_blob(pDb
2ac0: 2d 3e 70 46 65 74 63 68 2c 20 30 29 3b 0a 0a 20  ->pFetch, 0);.. 
2ad0: 20 20 20 69 66 28 20 6e 56 61 6c 3e 70 44 62 2d     if( nVal>pDb-
2ae0: 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 20  >nAlloc ){.     
2af0: 20 66 72 65 65 28 70 44 62 2d 3e 61 41 6c 6c 6f   free(pDb->aAllo
2b00: 63 29 3b 0a 20 20 20 20 20 20 70 44 62 2d 3e 61  c);.      pDb->a
2b10: 41 6c 6c 6f 63 20 3d 20 28 75 38 20 2a 29 6d 61  Alloc = (u8 *)ma
2b20: 6c 6c 6f 63 28 6e 56 61 6c 2a 32 29 3b 0a 20 20  lloc(nVal*2);.  
2b30: 20 20 20 20 70 44 62 2d 3e 6e 41 6c 6c 6f 63 20      pDb->nAlloc 
2b40: 3d 20 6e 56 61 6c 2a 32 3b 0a 20 20 20 20 7d 0a  = nVal*2;.    }.
2b50: 20 20 20 20 6d 65 6d 63 70 79 28 70 44 62 2d 3e      memcpy(pDb->
2b60: 61 41 6c 6c 6f 63 2c 20 61 56 61 6c 2c 20 6e 56  aAlloc, aVal, nV
2b70: 61 6c 29 3b 0a 20 20 20 20 2a 70 6e 56 61 6c 20  al);.    *pnVal 
2b80: 3d 20 6e 56 61 6c 3b 0a 20 20 20 20 2a 70 70 56  = nVal;.    *ppV
2b90: 61 6c 20 3d 20 28 76 6f 69 64 20 2a 29 70 44 62  al = (void *)pDb
2ba0: 2d 3e 61 41 6c 6c 6f 63 3b 0a 20 20 7d 65 6c 73  ->aAlloc;.  }els
2bb0: 65 7b 0a 20 20 20 20 2a 70 6e 56 61 6c 20 3d 20  e{.    *pnVal = 
2bc0: 2d 31 3b 0a 20 20 20 20 2a 70 70 56 61 6c 20 3d  -1;.    *ppVal =
2bd0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20   0;.  }..  rc = 
2be0: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 44  sqlite3_reset(pD
2bf0: 62 2d 3e 70 46 65 74 63 68 29 3b 0a 20 20 72 65  b->pFetch);.  re
2c00: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
2c10: 69 63 20 69 6e 74 20 73 71 6c 5f 73 63 61 6e 28  ic int sql_scan(
2c20: 0a 20 20 54 65 73 74 44 62 20 2a 70 54 65 73 74  .  TestDb *pTest
2c30: 44 62 2c 0a 20 20 76 6f 69 64 20 2a 70 43 74 78  Db,.  void *pCtx
2c40: 2c 0a 20 20 69 6e 74 20 62 52 65 76 65 72 73 65  ,.  int bReverse
2c50: 2c 0a 20 20 76 6f 69 64 20 2a 70 46 69 72 73 74  ,.  void *pFirst
2c60: 2c 20 69 6e 74 20 6e 46 69 72 73 74 2c 0a 20 20  , int nFirst,.  
2c70: 76 6f 69 64 20 2a 70 4c 61 73 74 2c 20 69 6e 74  void *pLast, int
2c80: 20 6e 4c 61 73 74 2c 0a 20 20 76 6f 69 64 20 28   nLast,.  void (
2c90: 2a 78 43 61 6c 6c 62 61 63 6b 29 28 76 6f 69 64  *xCallback)(void
2ca0: 20 2a 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 20   *, void *, int 
2cb0: 2c 20 76 6f 69 64 20 2a 2c 20 69 6e 74 29 0a 29  , void *, int).)
2cc0: 7b 0a 20 20 53 71 6c 44 62 20 2a 70 44 62 20 3d  {.  SqlDb *pDb =
2cd0: 20 28 53 71 6c 44 62 20 2a 29 70 54 65 73 74 44   (SqlDb *)pTestD
2ce0: 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  b;.  sqlite3_stm
2cf0: 74 20 2a 70 53 63 61 6e 3b 0a 0a 20 20 61 73 73  t *pScan;..  ass
2d00: 65 72 74 28 20 62 52 65 76 65 72 73 65 3d 3d 31  ert( bReverse==1
2d10: 20 7c 7c 20 62 52 65 76 65 72 73 65 3d 3d 30 20   || bReverse==0 
2d20: 29 3b 0a 20 20 70 53 63 61 6e 20 3d 20 70 44 62  );.  pScan = pDb
2d30: 2d 3e 61 70 53 63 61 6e 5b 28 70 46 69 72 73 74  ->apScan[(pFirst
2d40: 3d 3d 30 29 20 2b 20 28 70 4c 61 73 74 3d 3d 30  ==0) + (pLast==0
2d50: 29 2a 32 20 2b 20 62 52 65 76 65 72 73 65 2a 34  )*2 + bReverse*4
2d60: 5d 3b 0a 0a 20 20 69 66 28 20 70 46 69 72 73 74  ];..  if( pFirst
2d70: 20 29 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   ) sqlite3_bind_
2d80: 62 6c 6f 62 28 70 53 63 61 6e 2c 20 31 2c 20 70  blob(pScan, 1, p
2d90: 46 69 72 73 74 2c 20 6e 46 69 72 73 74 2c 20 53  First, nFirst, S
2da0: 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20  QLITE_STATIC);. 
2db0: 20 69 66 28 20 70 4c 61 73 74 20 29 20 73 71 6c   if( pLast ) sql
2dc0: 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 70  ite3_bind_blob(p
2dd0: 53 63 61 6e 2c 20 32 2c 20 70 4c 61 73 74 2c 20  Scan, 2, pLast, 
2de0: 6e 4c 61 73 74 2c 20 53 51 4c 49 54 45 5f 53 54  nLast, SQLITE_ST
2df0: 41 54 49 43 29 3b 0a 0a 20 20 77 68 69 6c 65 28  ATIC);..  while(
2e00: 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c   SQLITE_ROW==sql
2e10: 69 74 65 33 5f 73 74 65 70 28 70 53 63 61 6e 29  ite3_step(pScan)
2e20: 20 29 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 4b   ){.    void *pK
2e30: 65 79 3b 20 69 6e 74 20 6e 4b 65 79 3b 0a 20 20  ey; int nKey;.  
2e40: 20 20 76 6f 69 64 20 2a 70 56 61 6c 3b 20 69 6e    void *pVal; in
2e50: 74 20 6e 56 61 6c 3b 0a 0a 20 20 20 20 6e 4b 65  t nVal;..    nKe
2e60: 79 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  y = sqlite3_colu
2e70: 6d 6e 5f 62 79 74 65 73 28 70 53 63 61 6e 2c 20  mn_bytes(pScan, 
2e80: 30 29 3b 0a 20 20 20 20 70 4b 65 79 20 3d 20 28  0);.    pKey = (
2e90: 76 6f 69 64 20 2a 29 73 71 6c 69 74 65 33 5f 63  void *)sqlite3_c
2ea0: 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70 53 63 61 6e  olumn_blob(pScan
2eb0: 2c 20 30 29 3b 0a 20 20 20 20 6e 56 61 6c 20 3d  , 0);.    nVal =
2ec0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
2ed0: 62 79 74 65 73 28 70 53 63 61 6e 2c 20 31 29 3b  bytes(pScan, 1);
2ee0: 0a 20 20 20 20 70 56 61 6c 20 3d 20 28 76 6f 69  .    pVal = (voi
2ef0: 64 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  d *)sqlite3_colu
2f00: 6d 6e 5f 62 6c 6f 62 28 70 53 63 61 6e 2c 20 31  mn_blob(pScan, 1
2f10: 29 3b 0a 0a 20 20 20 20 78 43 61 6c 6c 62 61 63  );..    xCallbac
2f20: 6b 28 70 43 74 78 2c 20 70 4b 65 79 2c 20 6e 4b  k(pCtx, pKey, nK
2f30: 65 79 2c 20 70 56 61 6c 2c 20 6e 56 61 6c 29 3b  ey, pVal, nVal);
2f40: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71  .  }.  return sq
2f50: 6c 69 74 65 33 5f 72 65 73 65 74 28 70 53 63 61  lite3_reset(pSca
2f60: 6e 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  n);.}..static in
2f70: 74 20 73 71 6c 5f 62 65 67 69 6e 28 54 65 73 74  t sql_begin(Test
2f80: 44 62 20 2a 70 54 65 73 74 44 62 2c 20 69 6e 74  Db *pTestDb, int
2f90: 20 69 4c 65 76 65 6c 29 7b 0a 20 20 69 6e 74 20   iLevel){.  int 
2fa0: 69 3b 0a 20 20 53 71 6c 44 62 20 2a 70 44 62 20  i;.  SqlDb *pDb 
2fb0: 3d 20 28 53 71 6c 44 62 20 2a 29 70 54 65 73 74  = (SqlDb *)pTest
2fc0: 44 62 3b 0a 0a 20 20 2f 2a 20 69 4c 65 76 65 6c  Db;..  /* iLevel
2fd0: 3d 3d 30 20 69 73 20 61 20 6e 6f 2d 6f 70 20 2a  ==0 is a no-op *
2fe0: 2f 0a 20 20 69 66 28 20 69 4c 65 76 65 6c 3d 3d  /.  if( iLevel==
2ff0: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20  0 ) return 0;.. 
3000: 20 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72 65   /* If there are
3010: 20 6e 6f 20 74 72 61 6e 73 61 63 74 69 6f 6e 73   no transactions
3020: 20 61 74 20 61 6c 6c 20 6f 70 65 6e 2c 20 6f 70   at all open, op
3030: 65 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  en a read transa
3040: 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 69 66 28 20  ction. */.  if( 
3050: 70 44 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73 3d  pDb->nOpenTrans=
3060: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63  =0 ){.    int rc
3070: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
3080: 70 44 62 2d 3e 64 62 2c 20 0a 20 20 20 20 20 20  pDb->db, .      
3090: 20 20 22 42 45 47 49 4e 3b 20 53 45 4c 45 43 54    "BEGIN; SELECT
30a0: 20 2a 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d   * FROM sqlite_m
30b0: 61 73 74 65 72 20 4c 49 4d 49 54 20 31 3b 22 20  aster LIMIT 1;" 
30c0: 2c 20 30 2c 20 30 2c 20 30 0a 20 20 20 20 29 3b  , 0, 0, 0.    );
30d0: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 30 20 29  .    if( rc!=0 )
30e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
30f0: 70 44 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73 20  pDb->nOpenTrans 
3100: 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f  = 1;.  }..  /* O
3110: 70 65 6e 20 61 6e 79 20 72 65 71 75 69 72 65 64  pen any required
3120: 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
3130: 6f 6e 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 70  ons */.  for(i=p
3140: 44 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73 3b 20  Db->nOpenTrans; 
3150: 69 3c 69 4c 65 76 65 6c 3b 20 69 2b 2b 29 7b 0a  i<iLevel; i++){.
3160: 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d      char *zSql =
3170: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
3180: 28 22 53 41 56 45 50 4f 49 4e 54 20 78 25 64 22  ("SAVEPOINT x%d"
3190: 2c 20 69 29 3b 0a 20 20 20 20 69 6e 74 20 72 63  , i);.    int rc
31a0: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
31b0: 70 44 62 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30  pDb->db, zSql, 0
31c0: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c  , 0, 0);.    sql
31d0: 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b  ite3_free(zSql);
31e0: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
31f0: 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  ITE_OK ) return 
3200: 72 63 3b 0a 20 20 7d 0a 0a 20 20 70 44 62 2d 3e  rc;.  }..  pDb->
3210: 6e 4f 70 65 6e 54 72 61 6e 73 20 3d 20 69 4c 65  nOpenTrans = iLe
3220: 76 65 6c 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b  vel;.  return 0;
3230: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .}..static int s
3240: 71 6c 5f 63 6f 6d 6d 69 74 28 54 65 73 74 44 62  ql_commit(TestDb
3250: 20 2a 70 54 65 73 74 44 62 2c 20 69 6e 74 20 69   *pTestDb, int i
3260: 4c 65 76 65 6c 29 7b 0a 20 20 53 71 6c 44 62 20  Level){.  SqlDb 
3270: 2a 70 44 62 20 3d 20 28 53 71 6c 44 62 20 2a 29  *pDb = (SqlDb *)
3280: 70 54 65 73 74 44 62 3b 0a 20 20 61 73 73 65 72  pTestDb;.  asser
3290: 74 28 20 69 4c 65 76 65 6c 3e 3d 30 20 29 3b 0a  t( iLevel>=0 );.
32a0: 0a 20 20 2f 2a 20 43 6c 6f 73 65 20 74 68 65 20  .  /* Close the 
32b0: 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
32c0: 20 69 66 20 72 65 71 75 65 73 74 65 64 2e 20 2a   if requested. *
32d0: 2f 0a 20 20 69 66 28 20 70 44 62 2d 3e 6e 4f 70  /.  if( pDb->nOp
32e0: 65 6e 54 72 61 6e 73 3e 3d 31 20 26 26 20 69 4c  enTrans>=1 && iL
32f0: 65 76 65 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 69  evel==0 ){.    i
3300: 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  nt rc = sqlite3_
3310: 65 78 65 63 28 70 44 62 2d 3e 64 62 2c 20 22 43  exec(pDb->db, "C
3320: 4f 4d 4d 49 54 22 2c 20 30 2c 20 30 2c 20 30 29  OMMIT", 0, 0, 0)
3330: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 30 20  ;.    if( rc!=0 
3340: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
3350: 20 70 44 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73   pDb->nOpenTrans
3360: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20   = 0;.  }..  /* 
3370: 43 6c 6f 73 65 20 77 72 69 74 65 20 74 72 61 6e  Close write tran
3380: 73 61 63 74 69 6f 6e 73 20 61 73 20 72 65 71 75  sactions as requ
3390: 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20 70 44  ired */.  if( pD
33a0: 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73 3e 69 4c  b->nOpenTrans>iL
33b0: 65 76 65 6c 20 29 7b 0a 20 20 20 20 63 68 61 72  evel ){.    char
33c0: 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33   *zSql = sqlite3
33d0: 5f 6d 70 72 69 6e 74 66 28 22 52 45 4c 45 41 53  _mprintf("RELEAS
33e0: 45 20 78 25 64 22 2c 20 69 4c 65 76 65 6c 29 3b  E x%d", iLevel);
33f0: 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73 71  .    int rc = sq
3400: 6c 69 74 65 33 5f 65 78 65 63 28 70 44 62 2d 3e  lite3_exec(pDb->
3410: 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20  db, zSql, 0, 0, 
3420: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
3430: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20  free(zSql);.    
3440: 69 66 28 20 72 63 21 3d 30 20 29 20 72 65 74 75  if( rc!=0 ) retu
3450: 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 70 44  rn rc;.  }..  pD
3460: 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e 73 20 3d 20  b->nOpenTrans = 
3470: 69 4c 65 76 65 6c 3b 0a 20 20 72 65 74 75 72 6e  iLevel;.  return
3480: 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e   0;.}..static in
3490: 74 20 73 71 6c 5f 72 6f 6c 6c 62 61 63 6b 28 54  t sql_rollback(T
34a0: 65 73 74 44 62 20 2a 70 54 65 73 74 44 62 2c 20  estDb *pTestDb, 
34b0: 69 6e 74 20 69 4c 65 76 65 6c 29 7b 0a 20 20 53  int iLevel){.  S
34c0: 71 6c 44 62 20 2a 70 44 62 20 3d 20 28 53 71 6c  qlDb *pDb = (Sql
34d0: 44 62 20 2a 29 70 54 65 73 74 44 62 3b 0a 20 20  Db *)pTestDb;.  
34e0: 61 73 73 65 72 74 28 20 69 4c 65 76 65 6c 3e 3d  assert( iLevel>=
34f0: 30 20 29 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d  0 );..  if( pDb-
3500: 3e 6e 4f 70 65 6e 54 72 61 6e 73 3e 3d 31 20 26  >nOpenTrans>=1 &
3510: 26 20 69 4c 65 76 65 6c 3d 3d 30 20 29 7b 0a 20  & iLevel==0 ){. 
3520: 20 20 20 2f 2a 20 43 6c 6f 73 65 20 74 68 65 20     /* Close the 
3530: 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
3540: 20 69 66 20 72 65 71 75 65 73 74 65 64 2e 20 2a   if requested. *
3550: 2f 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20 73  /.    int rc = s
3560: 71 6c 69 74 65 33 5f 65 78 65 63 28 70 44 62 2d  qlite3_exec(pDb-
3570: 3e 64 62 2c 20 22 52 4f 4c 4c 42 41 43 4b 22 2c  >db, "ROLLBACK",
3580: 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69   0, 0, 0);.    i
3590: 66 28 20 72 63 21 3d 30 20 29 20 72 65 74 75 72  f( rc!=0 ) retur
35a0: 6e 20 72 63 3b 0a 20 20 7d 65 6c 73 65 20 69 66  n rc;.  }else if
35b0: 28 20 70 44 62 2d 3e 6e 4f 70 65 6e 54 72 61 6e  ( pDb->nOpenTran
35c0: 73 3e 31 20 26 26 20 69 4c 65 76 65 6c 3d 3d 31  s>1 && iLevel==1
35d0: 20 29 7b 0a 20 20 20 20 2f 2a 20 4f 72 2c 20 72   ){.    /* Or, r
35e0: 6f 6c 6c 62 61 63 6b 20 61 6e 64 20 63 6c 6f 73  ollback and clos
35f0: 65 20 74 68 65 20 74 6f 70 2d 6c 65 76 65 6c 20  e the top-level 
3600: 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
3610: 6e 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63 20  n */.    int rc 
3620: 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  = sqlite3_exec(p
3630: 44 62 2d 3e 64 62 2c 20 22 52 4f 4c 4c 42 41 43  Db->db, "ROLLBAC
3640: 4b 20 54 4f 20 78 31 3b 20 52 45 4c 45 41 53 45  K TO x1; RELEASE
3650: 20 78 31 3b 22 2c 20 30 2c 20 30 2c 20 30 29 3b   x1;", 0, 0, 0);
3660: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 30 20 29  .    if( rc!=0 )
3670: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 65   return rc;.  }e
3680: 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 4f 72 2c 20  lse{.    /* Or, 
3690: 6a 75 73 74 20 72 6f 6c 6c 20 62 61 63 6b 20 73  just roll back s
36a0: 6f 6d 65 20 6e 65 73 74 65 64 20 74 72 61 6e 73  ome nested trans
36b0: 61 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 20 20 63  actions */.    c
36c0: 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69  har *zSql = sqli
36d0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 52 4f 4c  te3_mprintf("ROL
36e0: 4c 42 41 43 4b 20 54 4f 20 78 25 64 22 2c 20 69  LBACK TO x%d", i
36f0: 4c 65 76 65 6c 2d 31 29 3b 0a 20 20 20 20 69 6e  Level-1);.    in
3700: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65  t rc = sqlite3_e
3710: 78 65 63 28 70 44 62 2d 3e 64 62 2c 20 7a 53 71  xec(pDb->db, zSq
3720: 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20  l, 0, 0, 0);.   
3730: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
3740: 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  ql);.    if( rc!
3750: 3d 30 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  =0 ) return rc;.
3760: 20 20 7d 0a 0a 20 20 70 44 62 2d 3e 6e 4f 70 65    }..  pDb->nOpe
3770: 6e 54 72 61 6e 73 20 3d 20 69 4c 65 76 65 6c 3b  nTrans = iLevel;
3780: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
3790: 73 74 61 74 69 63 20 69 6e 74 20 73 71 6c 5f 6f  static int sql_o
37a0: 70 65 6e 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  pen(.  const cha
37b0: 72 20 2a 7a 53 70 65 63 2c 20 0a 20 20 63 6f 6e  r *zSpec, .  con
37c0: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61  st char *zFilena
37d0: 6d 65 2c 20 0a 20 20 69 6e 74 20 62 43 6c 65 61  me, .  int bClea
37e0: 72 2c 20 0a 20 20 54 65 73 74 44 62 20 2a 2a 70  r, .  TestDb **p
37f0: 70 44 62 0a 29 7b 0a 20 20 73 74 61 74 69 63 20  pDb.){.  static 
3800: 63 6f 6e 73 74 20 44 61 74 61 62 61 73 65 4d 65  const DatabaseMe
3810: 74 68 6f 64 73 20 53 71 6c 4d 65 74 68 6f 64 73  thods SqlMethods
3820: 20 3d 20 7b 0a 20 20 20 20 73 71 6c 5f 63 6c 6f   = {.    sql_clo
3830: 73 65 2c 0a 20 20 20 20 73 71 6c 5f 77 72 69 74  se,.    sql_writ
3840: 65 2c 0a 20 20 20 20 73 71 6c 5f 64 65 6c 65 74  e,.    sql_delet
3850: 65 2c 0a 20 20 20 20 73 71 6c 5f 64 65 6c 65 74  e,.    sql_delet
3860: 65 5f 72 61 6e 67 65 2c 0a 20 20 20 20 73 71 6c  e_range,.    sql
3870: 5f 66 65 74 63 68 2c 0a 20 20 20 20 73 71 6c 5f  _fetch,.    sql_
3880: 73 63 61 6e 2c 0a 20 20 20 20 73 71 6c 5f 62 65  scan,.    sql_be
3890: 67 69 6e 2c 0a 20 20 20 20 73 71 6c 5f 63 6f 6d  gin,.    sql_com
38a0: 6d 69 74 2c 0a 20 20 20 20 73 71 6c 5f 72 6f 6c  mit,.    sql_rol
38b0: 6c 62 61 63 6b 0a 20 20 7d 3b 0a 20 20 63 6f 6e  lback.  };.  con
38c0: 73 74 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65  st char *zCreate
38d0: 20 3d 20 22 43 52 45 41 54 45 20 54 41 42 4c 45   = "CREATE TABLE
38e0: 20 49 46 20 4e 4f 54 20 45 58 49 53 54 53 20 74   IF NOT EXISTS t
38f0: 31 28 6b 20 50 52 49 4d 41 52 59 20 4b 45 59 2c  1(k PRIMARY KEY,
3900: 20 76 29 22 3b 0a 20 20 63 6f 6e 73 74 20 63 68   v)";.  const ch
3910: 61 72 20 2a 7a 49 6e 73 65 72 74 20 3d 20 22 52  ar *zInsert = "R
3920: 45 50 4c 41 43 45 20 49 4e 54 4f 20 74 31 20 56  EPLACE INTO t1 V
3930: 41 4c 55 45 53 28 3f 2c 20 3f 29 22 3b 0a 20 20  ALUES(?, ?)";.  
3940: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65 6c  const char *zDel
3950: 65 74 65 20 3d 20 22 44 45 4c 45 54 45 20 46 52  ete = "DELETE FR
3960: 4f 4d 20 74 31 20 57 48 45 52 45 20 6b 20 3d 20  OM t1 WHERE k = 
3970: 3f 22 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  ?";.  const char
3980: 20 2a 7a 52 61 6e 67 65 20 3d 20 22 44 45 4c 45   *zRange = "DELE
3990: 54 45 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45  TE FROM t1 WHERE
39a0: 20 6b 3e 3f 20 41 4e 44 20 6b 3c 3f 22 3b 0a 20   k>? AND k<?";. 
39b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 65   const char *zFe
39c0: 74 63 68 20 20 3d 20 22 53 45 4c 45 43 54 20 76  tch  = "SELECT v
39d0: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 6b   FROM t1 WHERE k
39e0: 20 3d 20 3f 22 3b 0a 0a 20 20 63 6f 6e 73 74 20   = ?";..  const 
39f0: 63 68 61 72 20 2a 7a 53 63 61 6e 30 20 20 3d 20  char *zScan0  = 
3a00: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74  "SELECT * FROM t
3a10: 31 20 57 48 45 52 45 20 6b 20 42 45 54 57 45 45  1 WHERE k BETWEE
3a20: 4e 20 3f 31 20 41 4e 44 20 3f 32 20 4f 52 44 45  N ?1 AND ?2 ORDE
3a30: 52 20 42 59 20 6b 22 3b 0a 20 20 63 6f 6e 73 74  R BY k";.  const
3a40: 20 63 68 61 72 20 2a 7a 53 63 61 6e 31 20 20 3d   char *zScan1  =
3a50: 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20   "SELECT * FROM 
3a60: 74 31 20 57 48 45 52 45 20 6b 20 3c 3d 20 3f 32  t1 WHERE k <= ?2
3a70: 20 4f 52 44 45 52 20 42 59 20 6b 22 3b 0a 20 20   ORDER BY k";.  
3a80: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 63 61  const char *zSca
3a90: 6e 32 20 20 3d 20 22 53 45 4c 45 43 54 20 2a 20  n2  = "SELECT * 
3aa0: 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 6b 20  FROM t1 WHERE k 
3ab0: 3e 3d 20 3f 31 20 4f 52 44 45 52 20 42 59 20 6b  >= ?1 ORDER BY k
3ac0: 22 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ";.  const char 
3ad0: 2a 7a 53 63 61 6e 33 20 20 3d 20 22 53 45 4c 45  *zScan3  = "SELE
3ae0: 43 54 20 2a 20 46 52 4f 4d 20 74 31 20 4f 52 44  CT * FROM t1 ORD
3af0: 45 52 20 42 59 20 6b 22 3b 0a 0a 20 20 63 6f 6e  ER BY k";..  con
3b00: 73 74 20 63 68 61 72 20 2a 7a 53 63 61 6e 34 20  st char *zScan4 
3b10: 20 3d 20 0a 20 20 20 20 22 53 45 4c 45 43 54 20   = .    "SELECT 
3b20: 2a 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20  * FROM t1 WHERE 
3b30: 6b 20 42 45 54 57 45 45 4e 20 3f 31 20 41 4e 44  k BETWEEN ?1 AND
3b40: 20 3f 32 20 4f 52 44 45 52 20 42 59 20 6b 20 44   ?2 ORDER BY k D
3b50: 45 53 43 22 3b 0a 20 20 63 6f 6e 73 74 20 63 68  ESC";.  const ch
3b60: 61 72 20 2a 7a 53 63 61 6e 35 20 20 3d 20 22 53  ar *zScan5  = "S
3b70: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 31 20  ELECT * FROM t1 
3b80: 57 48 45 52 45 20 6b 20 3c 3d 20 3f 32 20 4f 52  WHERE k <= ?2 OR
3b90: 44 45 52 20 42 59 20 6b 20 44 45 53 43 22 3b 0a  DER BY k DESC";.
3ba0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53    const char *zS
3bb0: 63 61 6e 36 20 20 3d 20 22 53 45 4c 45 43 54 20  can6  = "SELECT 
3bc0: 2a 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20  * FROM t1 WHERE 
3bd0: 6b 20 3e 3d 20 3f 31 20 4f 52 44 45 52 20 42 59  k >= ?1 ORDER BY
3be0: 20 6b 20 44 45 53 43 22 3b 0a 20 20 63 6f 6e 73   k DESC";.  cons
3bf0: 74 20 63 68 61 72 20 2a 7a 53 63 61 6e 37 20 20  t char *zScan7  
3c00: 3d 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  = "SELECT * FROM
3c10: 20 74 31 20 4f 52 44 45 52 20 42 59 20 6b 20 44   t1 ORDER BY k D
3c20: 45 53 43 22 3b 0a 0a 20 20 69 6e 74 20 72 63 3b  ESC";..  int rc;
3c30: 0a 20 20 53 71 6c 44 62 20 2a 70 44 62 3b 0a 20  .  SqlDb *pDb;. 
3c40: 20 63 68 61 72 20 2a 7a 50 72 61 67 6d 61 3b 0a   char *zPragma;.
3c50: 0a 20 20 69 66 28 20 62 43 6c 65 61 72 20 26 26  .  if( bClear &&
3c60: 20 7a 46 69 6c 65 6e 61 6d 65 20 26 26 20 7a 46   zFilename && zF
3c70: 69 6c 65 6e 61 6d 65 5b 30 5d 20 29 7b 0a 20 20  ilename[0] ){.  
3c80: 20 20 75 6e 6c 69 6e 6b 28 7a 46 69 6c 65 6e 61    unlink(zFilena
3c90: 6d 65 29 3b 0a 20 20 7d 0a 0a 20 20 70 44 62 20  me);.  }..  pDb 
3ca0: 3d 20 28 53 71 6c 44 62 20 2a 29 6d 61 6c 6c 6f  = (SqlDb *)mallo
3cb0: 63 28 73 69 7a 65 6f 66 28 53 71 6c 44 62 29 29  c(sizeof(SqlDb))
3cc0: 3b 0a 20 20 6d 65 6d 73 65 74 28 70 44 62 2c 20  ;.  memset(pDb, 
3cd0: 30 2c 20 73 69 7a 65 6f 66 28 53 71 6c 44 62 29  0, sizeof(SqlDb)
3ce0: 29 3b 0a 20 20 70 44 62 2d 3e 62 61 73 65 2e 70  );.  pDb->base.p
3cf0: 4d 65 74 68 6f 64 73 20 3d 20 26 53 71 6c 4d 65  Methods = &SqlMe
3d00: 74 68 6f 64 73 3b 0a 0a 20 20 69 66 28 20 30 21  thods;..  if( 0!
3d10: 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 6f  =(rc = sqlite3_o
3d20: 70 65 6e 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 26  pen(zFilename, &
3d30: 70 44 62 2d 3e 64 62 29 29 0a 20 20 20 7c 7c 20  pDb->db)).   || 
3d40: 30 21 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33  0!=(rc = sqlite3
3d50: 5f 65 78 65 63 28 70 44 62 2d 3e 64 62 2c 20 7a  _exec(pDb->db, z
3d60: 43 72 65 61 74 65 2c 20 30 2c 20 30 2c 20 30 29  Create, 0, 0, 0)
3d70: 29 0a 20 20 20 7c 7c 20 30 21 3d 28 72 63 20 3d  ).   || 0!=(rc =
3d80: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
3d90: 5f 76 32 28 70 44 62 2d 3e 64 62 2c 20 7a 49 6e  _v2(pDb->db, zIn
3da0: 73 65 72 74 2c 20 2d 31 2c 20 26 70 44 62 2d 3e  sert, -1, &pDb->
3db0: 70 49 6e 73 65 72 74 2c 20 30 29 29 0a 20 20 20  pInsert, 0)).   
3dc0: 7c 7c 20 30 21 3d 28 72 63 20 3d 20 73 71 6c 69  || 0!=(rc = sqli
3dd0: 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 70  te3_prepare_v2(p
3de0: 44 62 2d 3e 64 62 2c 20 7a 44 65 6c 65 74 65 2c  Db->db, zDelete,
3df0: 20 2d 31 2c 20 26 70 44 62 2d 3e 70 44 65 6c 65   -1, &pDb->pDele
3e00: 74 65 2c 20 30 29 29 0a 20 20 20 7c 7c 20 30 21  te, 0)).   || 0!
3e10: 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70  =(rc = sqlite3_p
3e20: 72 65 70 61 72 65 5f 76 32 28 70 44 62 2d 3e 64  repare_v2(pDb->d
3e30: 62 2c 20 7a 52 61 6e 67 65 2c 20 2d 31 2c 20 26  b, zRange, -1, &
3e40: 70 44 62 2d 3e 70 44 65 6c 65 74 65 52 61 6e 67  pDb->pDeleteRang
3e50: 65 2c 20 30 29 29 0a 20 20 20 7c 7c 20 30 21 3d  e, 0)).   || 0!=
3e60: 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72  (rc = sqlite3_pr
3e70: 65 70 61 72 65 5f 76 32 28 70 44 62 2d 3e 64 62  epare_v2(pDb->db
3e80: 2c 20 7a 46 65 74 63 68 2c 20 2d 31 2c 20 26 70  , zFetch, -1, &p
3e90: 44 62 2d 3e 70 46 65 74 63 68 2c 20 30 29 29 0a  Db->pFetch, 0)).
3ea0: 20 20 20 7c 7c 20 30 21 3d 28 72 63 20 3d 20 73     || 0!=(rc = s
3eb0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
3ec0: 32 28 70 44 62 2d 3e 64 62 2c 20 7a 53 63 61 6e  2(pDb->db, zScan
3ed0: 30 2c 20 2d 31 2c 20 26 70 44 62 2d 3e 61 70 53  0, -1, &pDb->apS
3ee0: 63 61 6e 5b 30 5d 2c 20 30 29 29 0a 20 20 20 7c  can[0], 0)).   |
3ef0: 7c 20 30 21 3d 28 72 63 20 3d 20 73 71 6c 69 74  | 0!=(rc = sqlit
3f00: 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 70 44  e3_prepare_v2(pD
3f10: 62 2d 3e 64 62 2c 20 7a 53 63 61 6e 31 2c 20 2d  b->db, zScan1, -
3f20: 31 2c 20 26 70 44 62 2d 3e 61 70 53 63 61 6e 5b  1, &pDb->apScan[
3f30: 31 5d 2c 20 30 29 29 0a 20 20 20 7c 7c 20 30 21  1], 0)).   || 0!
3f40: 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70  =(rc = sqlite3_p
3f50: 72 65 70 61 72 65 5f 76 32 28 70 44 62 2d 3e 64  repare_v2(pDb->d
3f60: 62 2c 20 7a 53 63 61 6e 32 2c 20 2d 31 2c 20 26  b, zScan2, -1, &
3f70: 70 44 62 2d 3e 61 70 53 63 61 6e 5b 32 5d 2c 20  pDb->apScan[2], 
3f80: 30 29 29 0a 20 20 20 7c 7c 20 30 21 3d 28 72 63  0)).   || 0!=(rc
3f90: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
3fa0: 72 65 5f 76 32 28 70 44 62 2d 3e 64 62 2c 20 7a  re_v2(pDb->db, z
3fb0: 53 63 61 6e 33 2c 20 2d 31 2c 20 26 70 44 62 2d  Scan3, -1, &pDb-
3fc0: 3e 61 70 53 63 61 6e 5b 33 5d 2c 20 30 29 29 0a  >apScan[3], 0)).
3fd0: 20 20 20 7c 7c 20 30 21 3d 28 72 63 20 3d 20 73     || 0!=(rc = s
3fe0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
3ff0: 32 28 70 44 62 2d 3e 64 62 2c 20 7a 53 63 61 6e  2(pDb->db, zScan
4000: 34 2c 20 2d 31 2c 20 26 70 44 62 2d 3e 61 70 53  4, -1, &pDb->apS
4010: 63 61 6e 5b 34 5d 2c 20 30 29 29 0a 20 20 20 7c  can[4], 0)).   |
4020: 7c 20 30 21 3d 28 72 63 20 3d 20 73 71 6c 69 74  | 0!=(rc = sqlit
4030: 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28 70 44  e3_prepare_v2(pD
4040: 62 2d 3e 64 62 2c 20 7a 53 63 61 6e 35 2c 20 2d  b->db, zScan5, -
4050: 31 2c 20 26 70 44 62 2d 3e 61 70 53 63 61 6e 5b  1, &pDb->apScan[
4060: 35 5d 2c 20 30 29 29 0a 20 20 20 7c 7c 20 30 21  5], 0)).   || 0!
4070: 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70  =(rc = sqlite3_p
4080: 72 65 70 61 72 65 5f 76 32 28 70 44 62 2d 3e 64  repare_v2(pDb->d
4090: 62 2c 20 7a 53 63 61 6e 36 2c 20 2d 31 2c 20 26  b, zScan6, -1, &
40a0: 70 44 62 2d 3e 61 70 53 63 61 6e 5b 36 5d 2c 20  pDb->apScan[6], 
40b0: 30 29 29 0a 20 20 20 7c 7c 20 30 21 3d 28 72 63  0)).   || 0!=(rc
40c0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
40d0: 72 65 5f 76 32 28 70 44 62 2d 3e 64 62 2c 20 7a  re_v2(pDb->db, z
40e0: 53 63 61 6e 37 2c 20 2d 31 2c 20 26 70 44 62 2d  Scan7, -1, &pDb-
40f0: 3e 61 70 53 63 61 6e 5b 37 5d 2c 20 30 29 29 0a  >apScan[7], 0)).
4100: 20 20 29 7b 0a 20 20 20 20 2a 70 70 44 62 20 3d    ){.    *ppDb =
4110: 20 30 3b 0a 20 20 20 20 73 71 6c 5f 63 6c 6f 73   0;.    sql_clos
4120: 65 28 28 54 65 73 74 44 62 20 2a 29 70 44 62 29  e((TestDb *)pDb)
4130: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  ;.    return rc;
4140: 0a 20 20 7d 0a 0a 20 20 7a 50 72 61 67 6d 61 20  .  }..  zPragma 
4150: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
4160: 66 28 22 50 52 41 47 4d 41 20 70 61 67 65 5f 73  f("PRAGMA page_s
4170: 69 7a 65 3d 25 64 22 2c 20 54 45 53 54 44 42 5f  ize=%d", TESTDB_
4180: 44 45 46 41 55 4c 54 5f 50 41 47 45 5f 53 49 5a  DEFAULT_PAGE_SIZ
4190: 45 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 65 78  E);.  sqlite3_ex
41a0: 65 63 28 70 44 62 2d 3e 64 62 2c 20 7a 50 72 61  ec(pDb->db, zPra
41b0: 67 6d 61 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  gma, 0, 0, 0);. 
41c0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 50   sqlite3_free(zP
41d0: 72 61 67 6d 61 29 3b 0a 20 20 7a 50 72 61 67 6d  ragma);.  zPragm
41e0: 61 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  a = sqlite3_mpri
41f0: 6e 74 66 28 22 50 52 41 47 4d 41 20 63 61 63 68  ntf("PRAGMA cach
4200: 65 5f 73 69 7a 65 3d 25 64 22 2c 20 54 45 53 54  e_size=%d", TEST
4210: 44 42 5f 44 45 46 41 55 4c 54 5f 43 41 43 48 45  DB_DEFAULT_CACHE
4220: 5f 53 49 5a 45 29 3b 0a 20 20 73 71 6c 69 74 65  _SIZE);.  sqlite
4230: 33 5f 65 78 65 63 28 70 44 62 2d 3e 64 62 2c 20  3_exec(pDb->db, 
4240: 7a 50 72 61 67 6d 61 2c 20 30 2c 20 30 2c 20 30  zPragma, 0, 0, 0
4250: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
4260: 65 28 7a 50 72 61 67 6d 61 29 3b 0a 0a 20 20 2f  e(zPragma);..  /
4270: 2a 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  * sqlite3_exec(p
4280: 44 62 2d 3e 64 62 2c 20 22 50 52 41 47 4d 41 20  Db->db, "PRAGMA 
4290: 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43  locking_mode=EXC
42a0: 4c 55 53 49 56 45 22 2c 20 30 2c 20 30 2c 20 30  LUSIVE", 0, 0, 0
42b0: 29 3b 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ); */.  sqlite3_
42c0: 65 78 65 63 28 70 44 62 2d 3e 64 62 2c 20 22 50  exec(pDb->db, "P
42d0: 52 41 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75  RAGMA synchronou
42e0: 73 3d 4f 46 46 22 2c 20 30 2c 20 30 2c 20 30 29  s=OFF", 0, 0, 0)
42f0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 65 78 65 63  ;.  sqlite3_exec
4300: 28 70 44 62 2d 3e 64 62 2c 20 22 50 52 41 47 4d  (pDb->db, "PRAGM
4310: 41 20 6a 6f 75 72 6e 61 6c 5f 6d 6f 64 65 3d 57  A journal_mode=W
4320: 41 4c 22 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  AL", 0, 0, 0);. 
4330: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 44   sqlite3_exec(pD
4340: 62 2d 3e 64 62 2c 20 22 50 52 41 47 4d 41 20 77  b->db, "PRAGMA w
4350: 61 6c 5f 61 75 74 6f 63 68 65 63 6b 70 6f 69 6e  al_autocheckpoin
4360: 74 3d 34 30 39 36 22 2c 20 30 2c 20 30 2c 20 30  t=4096", 0, 0, 0
4370: 29 3b 0a 20 20 69 66 28 20 7a 53 70 65 63 20 29  );.  if( zSpec )
4380: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
4390: 65 33 5f 65 78 65 63 28 70 44 62 2d 3e 64 62 2c  e3_exec(pDb->db,
43a0: 20 7a 53 70 65 63 2c 20 30 2c 20 30 2c 20 30 29   zSpec, 0, 0, 0)
43b0: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
43c0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
43d0: 20 73 71 6c 5f 63 6c 6f 73 65 28 28 54 65 73 74   sql_close((Test
43e0: 44 62 20 2a 29 70 44 62 29 3b 0a 20 20 20 20 20  Db *)pDb);.     
43f0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
4400: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 44 62 20 3d  }.  }..  *ppDb =
4410: 20 28 54 65 73 74 44 62 20 2a 29 70 44 62 3b 0a   (TestDb *)pDb;.
4420: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 2f 2a    return 0;.}./*
4430: 20 0a 2a 2a 20 45 6e 64 20 77 72 61 70 70 65 72   .** End wrapper
4440: 20 66 6f 72 20 53 51 4c 69 74 65 2e 0a 2a 2a 2a   for SQLite..***
4450: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4490: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 2a 2a 2a 2a 2a  ******/../******
44a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44e0: 2a 2a 2a 0a 2a 2a 20 42 65 67 69 6e 20 65 78 70  ***.** Begin exp
44f0: 6f 72 74 65 64 20 66 75 6e 63 74 69 6f 6e 73 2e  orted functions.
4500: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63  .*/.static struc
4510: 74 20 4c 69 62 20 7b 0a 20 20 63 6f 6e 73 74 20  t Lib {.  const 
4520: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 63  char *zName;.  c
4530: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65 66 61  onst char *zDefa
4540: 75 6c 74 44 62 3b 0a 20 20 69 6e 74 20 28 2a 78  ultDb;.  int (*x
4550: 4f 70 65 6e 29 28 63 6f 6e 73 74 20 63 68 61 72  Open)(const char
4560: 20 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a   *, const char *
4570: 7a 46 69 6c 65 6e 61 6d 65 2c 20 69 6e 74 20 62  zFilename, int b
4580: 43 6c 65 61 72 2c 20 54 65 73 74 44 62 20 2a 2a  Clear, TestDb **
4590: 70 70 44 62 29 3b 0a 7d 20 61 4c 69 62 5b 5d 20  ppDb);.} aLib[] 
45a0: 3d 20 7b 0a 20 20 7b 20 22 73 71 6c 69 74 65 33  = {.  { "sqlite3
45b0: 22 2c 20 20 20 20 20 20 22 74 65 73 74 64 62 2e  ",      "testdb.
45c0: 73 71 6c 69 74 65 22 2c 20 20 20 20 73 71 6c 5f  sqlite",    sql_
45d0: 6f 70 65 6e 20 7d 2c 0a 20 20 7b 20 22 6c 73 6d  open },.  { "lsm
45e0: 5f 73 6d 61 6c 6c 22 2c 20 20 20 20 22 74 65 73  _small",    "tes
45f0: 74 64 62 2e 6c 73 6d 5f 73 6d 61 6c 6c 22 2c 20  tdb.lsm_small", 
4600: 74 65 73 74 5f 6c 73 6d 5f 73 6d 61 6c 6c 5f 6f  test_lsm_small_o
4610: 70 65 6e 20 7d 2c 0a 20 20 7b 20 22 6c 73 6d 5f  pen },.  { "lsm_
4620: 6c 6f 6d 65 6d 22 2c 20 20 20 20 22 74 65 73 74  lomem",    "test
4630: 64 62 2e 6c 73 6d 5f 6c 6f 6d 65 6d 22 2c 20 74  db.lsm_lomem", t
4640: 65 73 74 5f 6c 73 6d 5f 6c 6f 6d 65 6d 5f 6f 70  est_lsm_lomem_op
4650: 65 6e 20 7d 2c 0a 23 69 66 64 65 66 20 48 41 56  en },.#ifdef HAV
4660: 45 5f 5a 4c 49 42 0a 20 20 7b 20 22 6c 73 6d 5f  E_ZLIB.  { "lsm_
4670: 7a 69 70 22 2c 20 20 20 20 20 20 22 74 65 73 74  zip",      "test
4680: 64 62 2e 6c 73 6d 5f 7a 69 70 22 2c 20 20 20 74  db.lsm_zip",   t
4690: 65 73 74 5f 6c 73 6d 5f 7a 69 70 5f 6f 70 65 6e  est_lsm_zip_open
46a0: 20 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7b 20 22   },.#endif.  { "
46b0: 6c 73 6d 22 2c 20 20 20 20 20 20 20 20 20 20 22  lsm",          "
46c0: 74 65 73 74 64 62 2e 6c 73 6d 22 2c 20 20 20 20  testdb.lsm",    
46d0: 20 20 20 74 65 73 74 5f 6c 73 6d 5f 6f 70 65 6e     test_lsm_open
46e0: 20 7d 2c 0a 23 69 66 64 65 66 20 4c 53 4d 5f 4d   },.#ifdef LSM_M
46f0: 55 54 45 58 5f 50 54 48 52 45 41 44 53 0a 20 20  UTEX_PTHREADS.  
4700: 7b 20 22 6c 73 6d 5f 6d 74 32 22 2c 20 20 20 20  { "lsm_mt2",    
4710: 20 20 22 74 65 73 74 64 62 2e 6c 73 6d 5f 6d 74    "testdb.lsm_mt
4720: 32 22 2c 20 20 20 74 65 73 74 5f 6c 73 6d 5f 6d  2",   test_lsm_m
4730: 74 32 20 7d 2c 0a 20 20 7b 20 22 6c 73 6d 5f 6d  t2 },.  { "lsm_m
4740: 74 33 22 2c 20 20 20 20 20 20 22 74 65 73 74 64  t3",      "testd
4750: 62 2e 6c 73 6d 5f 6d 74 33 22 2c 20 20 20 74 65  b.lsm_mt3",   te
4760: 73 74 5f 6c 73 6d 5f 6d 74 33 20 7d 2c 0a 23 65  st_lsm_mt3 },.#e
4770: 6e 64 69 66 0a 23 69 66 64 65 66 20 48 41 56 45  ndif.#ifdef HAVE
4780: 5f 4c 45 56 45 4c 44 42 0a 20 20 7b 20 22 6c 65  _LEVELDB.  { "le
4790: 76 65 6c 64 62 22 2c 20 20 20 20 20 20 22 74 65  veldb",      "te
47a0: 73 74 64 62 2e 6c 65 76 65 6c 64 62 22 2c 20 20  stdb.leveldb",  
47b0: 20 74 65 73 74 5f 6c 65 76 65 6c 64 62 5f 6f 70   test_leveldb_op
47c0: 65 6e 20 7d 2c 0a 23 65 6e 64 69 66 0a 23 69 66  en },.#endif.#if
47d0: 64 65 66 20 48 41 56 45 5f 4b 59 4f 54 4f 43 41  def HAVE_KYOTOCA
47e0: 42 49 4e 45 54 0a 20 20 7b 20 22 6b 79 6f 74 6f  BINET.  { "kyoto
47f0: 63 61 62 69 6e 65 74 22 2c 20 22 74 65 73 74 64  cabinet", "testd
4800: 62 2e 6b 63 22 2c 20 20 20 20 20 20 20 20 6b 63  b.kc",        kc
4810: 5f 6f 70 65 6e 20 7d 2c 0a 23 65 6e 64 69 66 0a  _open },.#endif.
4820: 23 69 66 64 65 66 20 48 41 56 45 5f 4d 44 42 0a  #ifdef HAVE_MDB.
4830: 20 20 7b 20 22 6d 64 62 22 2c 20 22 2e 2f 74 65    { "mdb", "./te
4840: 73 74 64 62 2e 6d 64 62 22 2c 20 20 20 20 20 20  stdb.mdb",      
4850: 20 20 6d 64 62 5f 6f 70 65 6e 20 7d 0a 23 65 6e    mdb_open }.#en
4860: 64 69 66 0a 7d 3b 0a 0a 63 6f 6e 73 74 20 63 68  dif.};..const ch
4870: 61 72 20 2a 74 64 62 5f 73 79 73 74 65 6d 5f 6e  ar *tdb_system_n
4880: 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20 20 69 66  ame(int i){.  if
4890: 28 20 69 3c 30 20 7c 7c 20 69 3e 3d 41 72 72 61  ( i<0 || i>=Arra
48a0: 79 53 69 7a 65 28 61 4c 69 62 29 20 29 20 72 65  ySize(aLib) ) re
48b0: 74 75 72 6e 20 30 3b 0a 20 20 72 65 74 75 72 6e  turn 0;.  return
48c0: 20 61 4c 69 62 5b 69 5d 2e 7a 4e 61 6d 65 3b 0a   aLib[i].zName;.
48d0: 7d 0a 0a 69 6e 74 20 74 64 62 5f 6f 70 65 6e 28  }..int tdb_open(
48e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4c 69 62  const char *zLib
48f0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  , const char *zD
4900: 62 2c 20 69 6e 74 20 62 43 6c 65 61 72 2c 20 54  b, int bClear, T
4910: 65 73 74 44 62 20 2a 2a 70 70 44 62 29 7b 0a 20  estDb **ppDb){. 
4920: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63   int i;.  int rc
4930: 20 3d 20 31 3b 0a 20 20 63 6f 6e 73 74 20 63 68   = 1;.  const ch
4940: 61 72 20 2a 7a 53 70 65 63 20 3d 20 30 3b 0a 0a  ar *zSpec = 0;..
4950: 20 20 69 6e 74 20 6e 4c 69 62 20 3d 20 30 3b 0a    int nLib = 0;.
4960: 20 20 77 68 69 6c 65 28 20 7a 4c 69 62 5b 6e 4c    while( zLib[nL
4970: 69 62 5d 20 26 26 20 7a 4c 69 62 5b 6e 4c 69 62  ib] && zLib[nLib
4980: 5d 21 3d 27 20 27 20 29 7b 0a 20 20 20 20 6e 4c  ]!=' ' ){.    nL
4990: 69 62 2b 2b 3b 0a 20 20 7d 0a 20 20 7a 53 70 65  ib++;.  }.  zSpe
49a0: 63 20 3d 20 26 7a 4c 69 62 5b 6e 4c 69 62 5d 3b  c = &zLib[nLib];
49b0: 0a 20 20 77 68 69 6c 65 28 20 2a 7a 53 70 65 63  .  while( *zSpec
49c0: 3d 3d 27 20 27 20 29 20 7a 53 70 65 63 2b 2b 3b  ==' ' ) zSpec++;
49d0: 0a 20 20 69 66 28 20 2a 7a 53 70 65 63 3d 3d 27  .  if( *zSpec=='
49e0: 5c 30 27 20 29 20 7a 53 70 65 63 20 3d 20 30 3b  \0' ) zSpec = 0;
49f0: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 41  ..  for(i=0; i<A
4a00: 72 72 61 79 53 69 7a 65 28 61 4c 69 62 29 3b 20  rraySize(aLib); 
4a10: 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 73 74  i++){.    if( st
4a20: 72 6c 65 6e 28 61 4c 69 62 5b 69 5d 2e 7a 4e 61  rlen(aLib[i].zNa
4a30: 6d 65 29 3d 3d 6e 4c 69 62 20 26 26 20 30 3d 3d  me)==nLib && 0==
4a40: 6d 65 6d 63 6d 70 28 7a 4c 69 62 2c 20 61 4c 69  memcmp(zLib, aLi
4a50: 62 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 6e 4c 69 62  b[i].zName, nLib
4a60: 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  ) ){.      rc = 
4a70: 61 4c 69 62 5b 69 5d 2e 78 4f 70 65 6e 28 7a 53  aLib[i].xOpen(zS
4a80: 70 65 63 2c 20 28 7a 44 62 20 3f 20 7a 44 62 20  pec, (zDb ? zDb 
4a90: 3a 20 61 4c 69 62 5b 69 5d 2e 7a 44 65 66 61 75  : aLib[i].zDefau
4aa0: 6c 74 44 62 29 2c 20 62 43 6c 65 61 72 2c 20 70  ltDb), bClear, p
4ab0: 70 44 62 29 3b 0a 20 20 20 20 20 20 69 66 28 20  pDb);.      if( 
4ac0: 72 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  rc==0 ){.       
4ad0: 20 28 2a 70 70 44 62 29 2d 3e 7a 4c 69 62 72 61   (*ppDb)->zLibra
4ae0: 72 79 20 3d 20 61 4c 69 62 5b 69 5d 2e 7a 4e 61  ry = aLib[i].zNa
4af0: 6d 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  me;.      }.    
4b00: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
4b10: 20 7d 0a 0a 20 20 69 66 28 20 72 63 20 29 7b 0a   }..  if( rc ){.
4b20: 20 20 20 20 2f 2a 20 46 61 69 6c 65 64 20 74 6f      /* Failed to
4b30: 20 66 69 6e 64 20 74 68 65 20 72 65 71 75 65 73   find the reques
4b40: 74 65 64 20 64 61 74 61 62 61 73 65 20 6c 69 62  ted database lib
4b50: 72 61 72 79 2e 20 52 65 74 75 72 6e 20 61 6e 20  rary. Return an 
4b60: 65 72 72 6f 72 2e 20 2a 2f 0a 20 20 20 20 2a 70  error. */.    *p
4b70: 70 44 62 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72  pDb = 0;.  }.  r
4b80: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74  eturn rc;.}..int
4b90: 20 74 64 62 5f 63 6c 6f 73 65 28 54 65 73 74 44   tdb_close(TestD
4ba0: 62 20 2a 70 44 62 29 7b 0a 20 20 69 66 28 20 70  b *pDb){.  if( p
4bb0: 44 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  Db ){.    return
4bc0: 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e   pDb->pMethods->
4bd0: 78 43 6c 6f 73 65 28 70 44 62 29 3b 0a 20 20 7d  xClose(pDb);.  }
4be0: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
4bf0: 69 6e 74 20 74 64 62 5f 77 72 69 74 65 28 54 65  int tdb_write(Te
4c00: 73 74 44 62 20 2a 70 44 62 2c 20 76 6f 69 64 20  stDb *pDb, void 
4c10: 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c  *pKey, int nKey,
4c20: 20 76 6f 69 64 20 2a 70 56 61 6c 2c 20 69 6e 74   void *pVal, int
4c30: 20 6e 56 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e   nVal){.  return
4c40: 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e   pDb->pMethods->
4c50: 78 57 72 69 74 65 28 70 44 62 2c 20 70 4b 65 79  xWrite(pDb, pKey
4c60: 2c 20 6e 4b 65 79 2c 20 70 56 61 6c 2c 20 6e 56  , nKey, pVal, nV
4c70: 61 6c 29 3b 0a 7d 0a 0a 69 6e 74 20 74 64 62 5f  al);.}..int tdb_
4c80: 64 65 6c 65 74 65 28 54 65 73 74 44 62 20 2a 70  delete(TestDb *p
4c90: 44 62 2c 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20  Db, void *pKey, 
4ca0: 69 6e 74 20 6e 4b 65 79 29 7b 0a 20 20 72 65 74  int nKey){.  ret
4cb0: 75 72 6e 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64  urn pDb->pMethod
4cc0: 73 2d 3e 78 44 65 6c 65 74 65 28 70 44 62 2c 20  s->xDelete(pDb, 
4cd0: 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 7d 0a 0a  pKey, nKey);.}..
4ce0: 69 6e 74 20 74 64 62 5f 64 65 6c 65 74 65 5f 72  int tdb_delete_r
4cf0: 61 6e 67 65 28 0a 20 20 20 20 54 65 73 74 44 62  ange(.    TestDb
4d00: 20 2a 70 44 62 2c 20 76 6f 69 64 20 2a 70 4b 65   *pDb, void *pKe
4d10: 79 31 2c 20 69 6e 74 20 6e 4b 65 79 31 2c 20 76  y1, int nKey1, v
4d20: 6f 69 64 20 2a 70 4b 65 79 32 2c 20 69 6e 74 20  oid *pKey2, int 
4d30: 6e 4b 65 79 32 0a 29 7b 0a 20 20 72 65 74 75 72  nKey2.){.  retur
4d40: 6e 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d  n pDb->pMethods-
4d50: 3e 78 44 65 6c 65 74 65 52 61 6e 67 65 28 70 44  >xDeleteRange(pD
4d60: 62 2c 20 70 4b 65 79 31 2c 20 6e 4b 65 79 31 2c  b, pKey1, nKey1,
4d70: 20 70 4b 65 79 32 2c 20 6e 4b 65 79 32 29 3b 0a   pKey2, nKey2);.
4d80: 7d 0a 0a 69 6e 74 20 74 64 62 5f 66 65 74 63 68  }..int tdb_fetch
4d90: 28 54 65 73 74 44 62 20 2a 70 44 62 2c 20 76 6f  (TestDb *pDb, vo
4da0: 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b  id *pKey, int nK
4db0: 65 79 2c 20 76 6f 69 64 20 2a 2a 70 70 56 61 6c  ey, void **ppVal
4dc0: 2c 20 69 6e 74 20 2a 70 6e 56 61 6c 29 7b 0a 20  , int *pnVal){. 
4dd0: 20 72 65 74 75 72 6e 20 70 44 62 2d 3e 70 4d 65   return pDb->pMe
4de0: 74 68 6f 64 73 2d 3e 78 46 65 74 63 68 28 70 44  thods->xFetch(pD
4df0: 62 2c 20 70 4b 65 79 2c 20 6e 4b 65 79 2c 20 70  b, pKey, nKey, p
4e00: 70 56 61 6c 2c 20 70 6e 56 61 6c 29 3b 0a 7d 0a  pVal, pnVal);.}.
4e10: 0a 69 6e 74 20 74 64 62 5f 73 63 61 6e 28 0a 20  .int tdb_scan(. 
4e20: 20 54 65 73 74 44 62 20 2a 70 44 62 2c 20 20 20   TestDb *pDb,   
4e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e40: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
4e50: 64 6c 65 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  dle */.  void *p
4e60: 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20 20  Ctx,            
4e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
4e80: 65 78 74 20 70 6f 69 6e 74 65 72 20 74 6f 20 70  ext pointer to p
4e90: 61 73 73 20 74 6f 20 78 43 61 6c 6c 62 61 63 6b  ass to xCallback
4ea0: 20 2a 2f 0a 20 20 69 6e 74 20 62 52 65 76 65 72   */.  int bRever
4eb0: 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
4ec0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
4ed0: 20 73 63 61 6e 20 69 6e 20 72 65 76 65 72 73 65   scan in reverse
4ee0: 20 6f 72 64 65 72 20 2a 2f 0a 20 20 76 6f 69 64   order */.  void
4ef0: 20 2a 70 4b 65 79 31 2c 20 69 6e 74 20 6e 4b 65   *pKey1, int nKe
4f00: 79 31 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 53  y1,         /* S
4f10: 74 61 72 74 20 6f 66 20 73 65 61 72 63 68 20 2a  tart of search *
4f20: 2f 0a 20 20 76 6f 69 64 20 2a 70 4b 65 79 32 2c  /.  void *pKey2,
4f30: 20 69 6e 74 20 6e 4b 65 79 32 2c 20 20 20 20 20   int nKey2,     
4f40: 20 20 20 20 2f 2a 20 45 6e 64 20 6f 66 20 73 65      /* End of se
4f50: 61 72 63 68 20 2a 2f 0a 20 20 76 6f 69 64 20 28  arch */.  void (
4f60: 2a 78 43 61 6c 6c 62 61 63 6b 29 28 76 6f 69 64  *xCallback)(void
4f70: 20 2a 70 43 74 78 2c 20 76 6f 69 64 20 2a 70 4b   *pCtx, void *pK
4f80: 65 79 2c 20 69 6e 74 20 6e 4b 65 79 2c 20 76 6f  ey, int nKey, vo
4f90: 69 64 20 2a 70 56 61 6c 2c 20 69 6e 74 20 6e 56  id *pVal, int nV
4fa0: 61 6c 29 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20  al).){.  return 
4fb0: 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pDb->pMethods->x
4fc0: 53 63 61 6e 28 0a 20 20 20 20 20 20 70 44 62 2c  Scan(.      pDb,
4fd0: 20 70 43 74 78 2c 20 62 52 65 76 65 72 73 65 2c   pCtx, bReverse,
4fe0: 20 70 4b 65 79 31 2c 20 6e 4b 65 79 31 2c 20 70   pKey1, nKey1, p
4ff0: 4b 65 79 32 2c 20 6e 4b 65 79 32 2c 20 78 43 61  Key2, nKey2, xCa
5000: 6c 6c 62 61 63 6b 0a 20 20 29 3b 0a 7d 0a 0a 69  llback.  );.}..i
5010: 6e 74 20 74 64 62 5f 62 65 67 69 6e 28 54 65 73  nt tdb_begin(Tes
5020: 74 44 62 20 2a 70 44 62 2c 20 69 6e 74 20 69 4c  tDb *pDb, int iL
5030: 65 76 65 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20  evel){.  return 
5040: 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pDb->pMethods->x
5050: 42 65 67 69 6e 28 70 44 62 2c 20 69 4c 65 76 65  Begin(pDb, iLeve
5060: 6c 29 3b 0a 7d 0a 69 6e 74 20 74 64 62 5f 63 6f  l);.}.int tdb_co
5070: 6d 6d 69 74 28 54 65 73 74 44 62 20 2a 70 44 62  mmit(TestDb *pDb
5080: 2c 20 69 6e 74 20 69 4c 65 76 65 6c 29 7b 0a 20  , int iLevel){. 
5090: 20 72 65 74 75 72 6e 20 70 44 62 2d 3e 70 4d 65   return pDb->pMe
50a0: 74 68 6f 64 73 2d 3e 78 43 6f 6d 6d 69 74 28 70  thods->xCommit(p
50b0: 44 62 2c 20 69 4c 65 76 65 6c 29 3b 0a 7d 0a 69  Db, iLevel);.}.i
50c0: 6e 74 20 74 64 62 5f 72 6f 6c 6c 62 61 63 6b 28  nt tdb_rollback(
50d0: 54 65 73 74 44 62 20 2a 70 44 62 2c 20 69 6e 74  TestDb *pDb, int
50e0: 20 69 4c 65 76 65 6c 29 7b 0a 20 20 72 65 74 75   iLevel){.  retu
50f0: 72 6e 20 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73  rn pDb->pMethods
5100: 2d 3e 78 52 6f 6c 6c 62 61 63 6b 28 70 44 62 2c  ->xRollback(pDb,
5110: 20 69 4c 65 76 65 6c 29 3b 0a 7d 0a 0a 69 6e 74   iLevel);.}..int
5120: 20 74 64 62 5f 74 72 61 6e 73 61 63 74 69 6f 6e   tdb_transaction
5130: 5f 73 75 70 70 6f 72 74 28 54 65 73 74 44 62 20  _support(TestDb 
5140: 2a 70 44 62 29 7b 0a 20 20 72 65 74 75 72 6e 20  *pDb){.  return 
5150: 28 70 44 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  (pDb->pMethods->
5160: 78 42 65 67 69 6e 20 21 3d 20 65 72 72 6f 72 5f  xBegin != error_
5170: 74 72 61 6e 73 61 63 74 69 6f 6e 5f 66 75 6e 63  transaction_func
5180: 74 69 6f 6e 29 3b 0a 7d 0a 0a 63 6f 6e 73 74 20  tion);.}..const 
5190: 63 68 61 72 20 2a 74 64 62 5f 6c 69 62 72 61 72  char *tdb_librar
51a0: 79 5f 6e 61 6d 65 28 54 65 73 74 44 62 20 2a 70  y_name(TestDb *p
51b0: 44 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 44  Db){.  return pD
51c0: 62 2d 3e 7a 4c 69 62 72 61 72 79 3b 0a 7d 0a 0a  b->zLibrary;.}..
51d0: 2f 2a 20 0a 2a 2a 20 45 6e 64 20 65 78 70 6f 72  /* .** End expor
51e0: 74 65 64 20 66 75 6e 63 74 69 6f 6e 73 2e 0a 2a  ted functions..*
51f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5200: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5230: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a                    ********/.