/ Hex Artifact Content
Login

Artifact 1b4f278d0ae164e2d02c11f5e1f2df3a2567ba41:


0000: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
0010: 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65 66  ITE_TEST) && def
0020: 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42  ined(SQLITE_ENAB
0030: 4c 45 5f 53 45 53 53 49 4f 4e 29 0a 0a 23 69 6e  LE_SESSION)..#in
0040: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 73 65  clude "sqlite3se
0050: 73 73 69 6f 6e 2e 68 22 0a 23 69 6e 63 6c 75 64  ssion.h".#includ
0060: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e  e <assert.h>.#in
0070: 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e  clude <string.h>
0080: 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68  .#include <tcl.h
0090: 3e 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65  >..static int te
00a0: 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72  st_session_error
00b0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
00c0: 65 72 70 2c 20 69 6e 74 20 72 63 29 7b 0a 20 20  erp, int rc){.  
00d0: 65 78 74 65 72 6e 20 63 6f 6e 73 74 20 63 68 61  extern const cha
00e0: 72 20 2a 73 71 6c 69 74 65 33 54 65 73 74 45 72  r *sqlite3TestEr
00f0: 72 6f 72 4e 61 6d 65 28 69 6e 74 29 3b 0a 20 20  rorName(int);.  
0100: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
0110: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
0120: 53 74 72 69 6e 67 4f 62 6a 28 73 71 6c 69 74 65  StringObj(sqlite
0130: 33 54 65 73 74 45 72 72 6f 72 4e 61 6d 65 28 72  3TestErrorName(r
0140: 63 29 2c 20 2d 31 29 29 3b 0a 20 20 72 65 74 75  c), -1));.  retu
0150: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a  rn TCL_ERROR;.}.
0160: 0a 2f 2a 0a 2a 2a 20 54 63 6c 63 6d 64 3a 20 20  ./*.** Tclcmd:  
0170: 24 73 65 73 73 69 6f 6e 20 61 74 74 61 63 68 20  $session attach 
0180: 54 41 42 4c 45 0a 2a 2a 20 20 20 20 20 20 20 20  TABLE.**        
0190: 20 20 24 73 65 73 73 69 6f 6e 20 63 68 61 6e 67    $session chang
01a0: 65 73 65 74 0a 2a 2a 20 20 20 20 20 20 20 20 20  eset.**         
01b0: 20 24 73 65 73 73 69 6f 6e 20 64 65 6c 65 74 65   $session delete
01c0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 24 73 65  .**          $se
01d0: 73 73 69 6f 6e 20 65 6e 61 62 6c 65 20 42 4f 4f  ssion enable BOO
01e0: 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  L.*/.static int 
01f0: 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 63 6d 64  test_session_cmd
0200: 28 0a 20 20 76 6f 69 64 20 2a 63 6c 69 65 6e 74  (.  void *client
0210: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
0220: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
0230: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
0240: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
0250: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73  ){.  sqlite3_ses
0260: 73 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 20 3d  sion *pSession =
0270: 20 28 73 71 6c 69 74 65 33 5f 73 65 73 73 69 6f   (sqlite3_sessio
0280: 6e 20 2a 29 63 6c 69 65 6e 74 44 61 74 61 3b 0a  n *)clientData;.
0290: 20 20 73 74 72 75 63 74 20 53 65 73 73 69 6f 6e    struct Session
02a0: 53 75 62 63 6d 64 20 7b 0a 20 20 20 20 63 6f 6e  Subcmd {.    con
02b0: 73 74 20 63 68 61 72 20 2a 7a 53 75 62 3b 0a 20  st char *zSub;. 
02c0: 20 20 20 69 6e 74 20 6e 41 72 67 3b 0a 20 20 20     int nArg;.   
02d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d 73   const char *zMs
02e0: 67 3b 0a 20 20 20 20 69 6e 74 20 69 53 75 62 3b  g;.    int iSub;
02f0: 0a 20 20 7d 20 61 53 75 62 5b 5d 20 3d 20 7b 0a  .  } aSub[] = {.
0300: 20 20 20 20 7b 20 22 61 74 74 61 63 68 22 2c 20      { "attach", 
0310: 20 20 20 31 2c 20 22 54 41 42 4c 45 22 2c 20 7d     1, "TABLE", }
0320: 2c 20 2f 2a 20 30 20 2a 2f 0a 20 20 20 20 7b 20  , /* 0 */.    { 
0330: 22 63 68 61 6e 67 65 73 65 74 22 2c 20 30 2c 20  "changeset", 0, 
0340: 22 22 2c 20 20 20 20 20 20 7d 2c 20 2f 2a 20 31  "",      }, /* 1
0350: 20 2a 2f 0a 20 20 20 20 7b 20 22 64 65 6c 65 74   */.    { "delet
0360: 65 22 2c 20 20 20 20 30 2c 20 22 22 2c 20 20 20  e",    0, "",   
0370: 20 20 20 7d 2c 20 2f 2a 20 32 20 2a 2f 0a 20 20     }, /* 2 */.  
0380: 20 20 7b 20 22 65 6e 61 62 6c 65 22 2c 20 20 20    { "enable",   
0390: 20 31 2c 20 22 22 2c 20 20 20 20 20 20 7d 2c 20   1, "",      }, 
03a0: 2f 2a 20 33 20 2a 2f 0a 20 20 20 20 7b 20 30 20  /* 3 */.    { 0 
03b0: 7d 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69 53 75  }.  };.  int iSu
03c0: 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  b;.  int rc;..  
03d0: 69 66 28 20 6f 62 6a 63 3c 32 20 29 7b 0a 20 20  if( objc<2 ){.  
03e0: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
03f0: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
0400: 6a 76 2c 20 22 53 55 42 43 4f 4d 4d 41 4e 44 20  jv, "SUBCOMMAND 
0410: 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 65 74 75 72  ...");.    retur
0420: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
0430: 0a 20 20 72 63 20 3d 20 54 63 6c 5f 47 65 74 49  .  rc = Tcl_GetI
0440: 6e 64 65 78 46 72 6f 6d 4f 62 6a 53 74 72 75 63  ndexFromObjStruc
0450: 74 28 69 6e 74 65 72 70 2c 20 0a 20 20 20 20 20  t(interp, .     
0460: 20 6f 62 6a 76 5b 31 5d 2c 20 61 53 75 62 2c 20   objv[1], aSub, 
0470: 73 69 7a 65 6f 66 28 61 53 75 62 5b 30 5d 29 2c  sizeof(aSub[0]),
0480: 20 22 73 75 62 2d 63 6f 6d 6d 61 6e 64 22 2c 20   "sub-command", 
0490: 30 2c 20 26 69 53 75 62 0a 20 20 29 3b 0a 20 20  0, &iSub.  );.  
04a0: 69 66 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29  if( rc!=TCL_OK )
04b0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 69 66   return rc;.  if
04c0: 28 20 6f 62 6a 63 21 3d 32 2b 61 53 75 62 5b 69  ( objc!=2+aSub[i
04d0: 53 75 62 5d 2e 6e 41 72 67 20 29 7b 0a 20 20 20  Sub].nArg ){.   
04e0: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
04f0: 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62 6a  s(interp, 2, obj
0500: 76 2c 20 61 53 75 62 5b 69 53 75 62 5d 2e 7a 4d  v, aSub[iSub].zM
0510: 73 67 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  sg);.    return 
0520: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  TCL_ERROR;.  }..
0530: 20 20 73 77 69 74 63 68 28 20 69 53 75 62 20 29    switch( iSub )
0540: 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 20 20 20  {.    case 0:   
0550: 20 20 20 20 20 2f 2a 20 61 74 74 61 63 68 20 2a       /* attach *
0560: 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  /.      rc = sql
0570: 69 74 65 33 73 65 73 73 69 6f 6e 5f 61 74 74 61  ite3session_atta
0580: 63 68 28 70 53 65 73 73 69 6f 6e 2c 20 54 63 6c  ch(pSession, Tcl
0590: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
05a0: 32 5d 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20  2]));.      if( 
05b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
05c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
05d0: 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72  test_session_err
05e0: 6f 72 28 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a  or(interp, rc);.
05f0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
0600: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 31  eak;..    case 1
0610: 3a 20 7b 20 20 20 20 20 20 2f 2a 20 63 68 61 6e  : {      /* chan
0620: 67 65 73 65 74 20 2a 2f 0a 20 20 20 20 20 20 69  geset */.      i
0630: 6e 74 20 6e 43 68 61 6e 67 65 3b 0a 20 20 20 20  nt nChange;.    
0640: 20 20 76 6f 69 64 20 2a 70 43 68 61 6e 67 65 3b    void *pChange;
0650: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
0660: 74 65 33 73 65 73 73 69 6f 6e 5f 63 68 61 6e 67  te3session_chang
0670: 65 73 65 74 28 70 53 65 73 73 69 6f 6e 2c 20 26  eset(pSession, &
0680: 6e 43 68 61 6e 67 65 2c 20 26 70 43 68 61 6e 67  nChange, &pChang
0690: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  e);.      if( rc
06a0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
06b0: 20 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62         Tcl_SetOb
06c0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
06d0: 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72 61 79  Tcl_NewByteArray
06e0: 4f 62 6a 28 70 43 68 61 6e 67 65 2c 20 6e 43 68  Obj(pChange, nCh
06f0: 61 6e 67 65 29 29 3b 20 0a 20 20 20 20 20 20 20  ange)); .       
0700: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
0710: 68 61 6e 67 65 29 3b 0a 20 20 20 20 20 20 7d 65  hange);.      }e
0720: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65 74  lse{.        ret
0730: 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e  urn test_session
0740: 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72  _error(interp, r
0750: 63 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  c);.      }.    
0760: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
0770: 20 20 20 20 63 61 73 65 20 32 3a 20 20 20 20 20      case 2:     
0780: 20 20 20 2f 2a 20 64 65 6c 65 74 65 20 2a 2f 0a     /* delete */.
0790: 20 20 20 20 20 20 54 63 6c 5f 44 65 6c 65 74 65        Tcl_Delete
07a0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
07b0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
07c0: 6a 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20 62  jv[0]));.      b
07d0: 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20  reak;..    case 
07e0: 33 3a 20 7b 20 20 20 20 20 20 2f 2a 20 65 6e 61  3: {      /* ena
07f0: 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74  ble */.      int
0800: 20 76 61 6c 3b 0a 20 20 20 20 20 20 69 66 28 20   val;.      if( 
0810: 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72  Tcl_GetBooleanFr
0820: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
0830: 6a 76 5b 32 5d 2c 20 26 76 61 6c 29 20 29 20 72  jv[2], &val) ) r
0840: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
0850: 0a 20 20 20 20 20 20 76 61 6c 20 3d 20 73 71 6c  .      val = sql
0860: 69 74 65 33 73 65 73 73 69 6f 6e 5f 65 6e 61 62  ite3session_enab
0870: 6c 65 28 70 53 65 73 73 69 6f 6e 2c 20 76 61 6c  le(pSession, val
0880: 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74  );.      Tcl_Set
0890: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
08a0: 2c 20 54 63 6c 5f 4e 65 77 42 6f 6f 6c 65 61 6e  , Tcl_NewBoolean
08b0: 4f 62 6a 28 76 61 6c 29 29 3b 0a 20 20 20 20 20  Obj(val));.     
08c0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
08d0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  }..  return TCL_
08e0: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  OK;.}..static vo
08f0: 69 64 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f  id test_session_
0900: 64 65 6c 28 76 6f 69 64 20 2a 63 6c 69 65 6e 74  del(void *client
0910: 44 61 74 61 29 7b 0a 20 20 73 71 6c 69 74 65 33  Data){.  sqlite3
0920: 5f 73 65 73 73 69 6f 6e 20 2a 70 53 65 73 73 69  _session *pSessi
0930: 6f 6e 20 3d 20 28 73 71 6c 69 74 65 33 5f 73 65  on = (sqlite3_se
0940: 73 73 69 6f 6e 20 2a 29 63 6c 69 65 6e 74 44 61  ssion *)clientDa
0950: 74 61 3b 0a 20 20 73 71 6c 69 74 65 33 73 65 73  ta;.  sqlite3ses
0960: 73 69 6f 6e 5f 64 65 6c 65 74 65 28 70 53 65 73  sion_delete(pSes
0970: 73 69 6f 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  sion);.}../*.** 
0980: 54 63 6c 63 6d 64 3a 20 20 73 71 6c 69 74 65 33  Tclcmd:  sqlite3
0990: 73 65 73 73 69 6f 6e 20 43 4d 44 20 44 42 2d 48  session CMD DB-H
09a0: 41 4e 44 4c 45 20 44 42 2d 4e 41 4d 45 0a 2a 2f  ANDLE DB-NAME.*/
09b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
09c0: 5f 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 28  _sqlite3session(
09d0: 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74  .  void * client
09e0: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
09f0: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
0a00: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
0a10: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
0a20: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  ){.  sqlite3 *db
0a30: 3b 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20  ;.  Tcl_CmdInfo 
0a40: 69 6e 66 6f 3b 0a 20 20 69 6e 74 20 72 63 3b 20  info;.  int rc; 
0a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a60: 20 20 20 20 20 20 20 20 2f 2a 20 73 71 6c 69 74          /* sqlit
0a70: 65 33 73 65 73 73 69 6f 6e 5f 63 72 65 61 74 65  e3session_create
0a80: 28 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a  () return code *
0a90: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73 65 73 73  /.  sqlite3_sess
0aa0: 69 6f 6e 20 2a 70 53 65 73 73 69 6f 6e 3b 20 20  ion *pSession;  
0ab0: 20 20 20 20 2f 2a 20 4e 65 77 20 73 65 73 73 69      /* New sessi
0ac0: 6f 6e 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a 20 20  on object */..  
0ad0: 69 66 28 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20  if( objc!=4 ){. 
0ae0: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
0af0: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
0b00: 62 6a 76 2c 20 22 43 4d 44 20 44 42 2d 48 41 4e  bjv, "CMD DB-HAN
0b10: 44 4c 45 20 44 42 2d 4e 41 4d 45 22 29 3b 0a 20  DLE DB-NAME");. 
0b20: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
0b30: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  ROR;.  }..  if( 
0b40: 30 3d 3d 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e  0==Tcl_GetComman
0b50: 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 54 63  dInfo(interp, Tc
0b60: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
0b70: 5b 32 5d 29 2c 20 26 69 6e 66 6f 29 20 29 7b 0a  [2]), &info) ){.
0b80: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
0b90: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f  sult(interp, "no
0ba0: 20 73 75 63 68 20 68 61 6e 64 6c 65 3a 20 22 2c   such handle: ",
0bb0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
0bc0: 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20  bjv[2]), 0);.   
0bd0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
0be0: 52 3b 0a 20 20 7d 0a 20 20 64 62 20 3d 20 2a 28  R;.  }.  db = *(
0bf0: 73 71 6c 69 74 65 33 20 2a 2a 29 69 6e 66 6f 2e  sqlite3 **)info.
0c00: 6f 62 6a 43 6c 69 65 6e 74 44 61 74 61 3b 0a 0a  objClientData;..
0c10: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 73 65    rc = sqlite3se
0c20: 73 73 69 6f 6e 5f 63 72 65 61 74 65 28 64 62 2c  ssion_create(db,
0c30: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
0c40: 62 6a 76 5b 33 5d 29 2c 20 26 70 53 65 73 73 69  bjv[3]), &pSessi
0c50: 6f 6e 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  on);.  if( rc!=S
0c60: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
0c70: 72 65 74 75 72 6e 20 74 65 73 74 5f 73 65 73 73  return test_sess
0c80: 69 6f 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72 70  ion_error(interp
0c90: 2c 20 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 54 63  , rc);.  }..  Tc
0ca0: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
0cb0: 6e 64 28 0a 20 20 20 20 20 20 69 6e 74 65 72 70  nd(.      interp
0cc0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
0cd0: 6f 62 6a 76 5b 31 5d 29 2c 20 74 65 73 74 5f 73  objv[1]), test_s
0ce0: 65 73 73 69 6f 6e 5f 63 6d 64 2c 20 28 43 6c 69  ession_cmd, (Cli
0cf0: 65 6e 74 44 61 74 61 29 70 53 65 73 73 69 6f 6e  entData)pSession
0d00: 2c 0a 20 20 20 20 20 20 74 65 73 74 5f 73 65 73  ,.      test_ses
0d10: 73 69 6f 6e 5f 64 65 6c 0a 20 20 29 3b 0a 20 20  sion_del.  );.  
0d20: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
0d30: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d  (interp, objv[1]
0d40: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
0d50: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  OK;.}..static vo
0d60: 69 64 20 74 65 73 74 5f 61 70 70 65 6e 64 5f 76  id test_append_v
0d70: 61 6c 75 65 28 54 63 6c 5f 4f 62 6a 20 2a 70 4c  alue(Tcl_Obj *pL
0d80: 69 73 74 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  ist, sqlite3_val
0d90: 75 65 20 2a 70 56 61 6c 29 7b 0a 20 20 69 66 28  ue *pVal){.  if(
0da0: 20 70 56 61 6c 3d 3d 30 20 29 7b 0a 20 20 20 20   pVal==0 ){.    
0db0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
0dc0: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73  dElement(0, pLis
0dd0: 74 2c 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 29  t, Tcl_NewObj())
0de0: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
0df0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30  jAppendElement(0
0e00: 2c 20 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65 77  , pList, Tcl_New
0e10: 4f 62 6a 28 29 29 3b 0a 20 20 7d 65 6c 73 65 7b  Obj());.  }else{
0e20: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f  .    Tcl_Obj *pO
0e30: 62 6a 3b 0a 20 20 20 20 73 77 69 74 63 68 28 20  bj;.    switch( 
0e40: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
0e50: 70 65 28 70 56 61 6c 29 20 29 7b 0a 20 20 20 20  pe(pVal) ){.    
0e60: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 4e 55    case SQLITE_NU
0e70: 4c 4c 3a 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  LL:.        Tcl_
0e80: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
0e90: 6d 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c 20 54  ment(0, pList, T
0ea0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
0eb0: 22 6e 22 2c 20 31 29 29 3b 0a 20 20 20 20 20 20  "n", 1));.      
0ec0: 20 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77    pObj = Tcl_New
0ed0: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 20 20 62  Obj();.        b
0ee0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65  reak;.      case
0ef0: 20 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 3a   SQLITE_INTEGER:
0f00: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73  .        Tcl_Lis
0f10: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
0f20: 74 28 30 2c 20 70 4c 69 73 74 2c 20 54 63 6c 5f  t(0, pList, Tcl_
0f30: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 69 22  NewStringObj("i"
0f40: 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 20 20 70  , 1));.        p
0f50: 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 57 69 64  Obj = Tcl_NewWid
0f60: 65 49 6e 74 4f 62 6a 28 73 71 6c 69 74 65 33 5f  eIntObj(sqlite3_
0f70: 76 61 6c 75 65 5f 69 6e 74 36 34 28 70 56 61 6c  value_int64(pVal
0f80: 29 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  ));.        brea
0f90: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  k;.      case SQ
0fa0: 4c 49 54 45 5f 46 4c 4f 41 54 3a 0a 20 20 20 20  LITE_FLOAT:.    
0fb0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
0fc0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
0fd0: 70 4c 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53 74  pList, Tcl_NewSt
0fe0: 72 69 6e 67 4f 62 6a 28 22 66 22 2c 20 31 29 29  ringObj("f", 1))
0ff0: 3b 0a 20 20 20 20 20 20 20 20 70 4f 62 6a 20 3d  ;.        pObj =
1000: 20 54 63 6c 5f 4e 65 77 44 6f 75 62 6c 65 4f 62   Tcl_NewDoubleOb
1010: 6a 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  j(sqlite3_value_
1020: 64 6f 75 62 6c 65 28 70 56 61 6c 29 29 3b 0a 20  double(pVal));. 
1030: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
1040: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
1050: 54 45 58 54 3a 0a 20 20 20 20 20 20 20 20 54 63  TEXT:.        Tc
1060: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
1070: 6c 65 6d 65 6e 74 28 30 2c 20 70 4c 69 73 74 2c  lement(0, pList,
1080: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
1090: 6a 28 22 74 22 2c 20 31 29 29 3b 0a 20 20 20 20  j("t", 1));.    
10a0: 20 20 20 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e      pObj = Tcl_N
10b0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 28 63 68 61  ewStringObj((cha
10c0: 72 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  r *)sqlite3_valu
10d0: 65 5f 74 65 78 74 28 70 56 61 6c 29 2c 20 2d 31  e_text(pVal), -1
10e0: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
10f0: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c  ;.      case SQL
1100: 49 54 45 5f 42 4c 4f 42 3a 0a 20 20 20 20 20 20  ITE_BLOB:.      
1110: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
1120: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 4c  endElement(0, pL
1130: 69 73 74 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  ist, Tcl_NewStri
1140: 6e 67 4f 62 6a 28 22 62 22 2c 20 31 29 29 3b 0a  ngObj("b", 1));.
1150: 20 20 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54          pObj = T
1160: 63 6c 5f 4e 65 77 42 79 74 65 41 72 72 61 79 4f  cl_NewByteArrayO
1170: 62 6a 28 0a 20 20 20 20 20 20 20 20 20 20 20 20  bj(.            
1180: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c  sqlite3_value_bl
1190: 6f 62 28 70 56 61 6c 29 2c 0a 20 20 20 20 20 20  ob(pVal),.      
11a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
11b0: 6c 75 65 5f 62 79 74 65 73 28 70 56 61 6c 29 0a  lue_bytes(pVal).
11c0: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
11d0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
11e0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
11f0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
1200: 70 4c 69 73 74 2c 20 70 4f 62 6a 29 3b 0a 20 20  pList, pObj);.  
1210: 7d 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73 74 72  }.}..typedef str
1220: 75 63 74 20 54 65 73 74 43 6f 6e 66 6c 69 63 74  uct TestConflict
1230: 48 61 6e 64 6c 65 72 20 54 65 73 74 43 6f 6e 66  Handler TestConf
1240: 6c 69 63 74 48 61 6e 64 6c 65 72 3b 0a 73 74 72  lictHandler;.str
1250: 75 63 74 20 54 65 73 74 43 6f 6e 66 6c 69 63 74  uct TestConflict
1260: 48 61 6e 64 6c 65 72 20 7b 0a 20 20 54 63 6c 5f  Handler {.  Tcl_
1270: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
1280: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72 69    Tcl_Obj *pScri
1290: 70 74 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 69  pt;.};..static i
12a0: 6e 74 20 74 65 73 74 5f 63 6f 6e 66 6c 69 63 74  nt test_conflict
12b0: 5f 68 61 6e 64 6c 65 72 28 0a 20 20 76 6f 69 64  _handler(.  void
12c0: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
12d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
12e0: 6f 69 6e 74 65 72 20 74 6f 20 54 65 73 74 43 6f  ointer to TestCo
12f0: 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 20 73 74  nflictHandler st
1300: 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74  ructure */.  int
1310: 20 65 43 6f 6e 66 2c 20 20 20 20 20 20 20 20 20   eConf,         
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1330: 44 41 54 41 2c 20 4d 49 53 53 49 4e 47 2c 20 43  DATA, MISSING, C
1340: 4f 4e 46 4c 49 43 54 2c 20 43 4f 4e 53 54 52 41  ONFLICT, CONSTRA
1350: 49 4e 54 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  INT */.  sqlite3
1360: 5f 63 68 61 6e 67 65 73 65 74 5f 69 74 65 72 20  _changeset_iter 
1370: 2a 70 49 74 65 72 20 20 20 2f 2a 20 48 61 6e 64  *pIter   /* Hand
1380: 6c 65 20 64 65 73 63 72 69 62 69 6e 67 20 63 68  le describing ch
1390: 61 6e 67 65 20 61 6e 64 20 63 6f 6e 66 6c 69 63  ange and conflic
13a0: 74 20 2a 2f 0a 29 7b 0a 20 20 54 65 73 74 43 6f  t */.){.  TestCo
13b0: 6e 66 6c 69 63 74 48 61 6e 64 6c 65 72 20 2a 70  nflictHandler *p
13c0: 20 3d 20 28 54 65 73 74 43 6f 6e 66 6c 69 63 74   = (TestConflict
13d0: 48 61 6e 64 6c 65 72 20 2a 29 70 43 74 78 3b 0a  Handler *)pCtx;.
13e0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 45 76 61 6c    Tcl_Obj *pEval
13f0: 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ;.  Tcl_Interp *
1400: 69 6e 74 65 72 70 20 3d 20 70 2d 3e 69 6e 74 65  interp = p->inte
1410: 72 70 3b 0a 0a 20 20 69 6e 74 20 6f 70 3b 20 20  rp;..  int op;  
1420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1430: 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49 54 45         /* SQLITE
1440: 5f 55 50 44 41 54 45 2c 20 44 45 4c 45 54 45 20  _UPDATE, DELETE 
1450: 6f 72 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20 63  or INSERT */.  c
1460: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 3b  onst char *zTab;
1470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1480: 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65 20  * Name of table 
1490: 63 6f 6e 66 6c 69 63 74 20 69 73 20 6f 6e 20 2a  conflict is on *
14a0: 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20  /.  int nCol;   
14b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14c0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
14d0: 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 61 62 6c   columns in tabl
14e0: 65 20 7a 54 61 62 20 2a 2f 0a 0a 20 20 70 45 76  e zTab */..  pEv
14f0: 61 6c 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61  al = Tcl_Duplica
1500: 74 65 4f 62 6a 28 70 2d 3e 70 53 63 72 69 70 74  teObj(p->pScript
1510: 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  );.  Tcl_IncrRef
1520: 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a 0a 20  Count(pEval);.. 
1530: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1540: 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 54 61  t_op(pIter, &zTa
1550: 62 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 29 3b 0a  b, &nCol, &op);.
1560: 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65  .  /* Append the
1570: 20 6f 70 65 72 61 74 69 6f 6e 20 74 79 70 65 2e   operation type.
1580: 20 2a 2f 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62   */.  Tcl_ListOb
1590: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30  jAppendElement(0
15a0: 2c 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77  , pEval, Tcl_New
15b0: 53 74 72 69 6e 67 4f 62 6a 28 0a 20 20 20 20 20  StringObj(.     
15c0: 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 53 45   op==SQLITE_INSE
15d0: 52 54 20 3f 20 22 49 4e 53 45 52 54 22 20 3a 0a  RT ? "INSERT" :.
15e0: 20 20 20 20 20 20 6f 70 3d 3d 53 51 4c 49 54 45        op==SQLITE
15f0: 5f 55 50 44 41 54 45 20 3f 20 22 55 50 44 41 54  _UPDATE ? "UPDAT
1600: 45 22 20 3a 20 0a 20 20 20 20 20 20 22 44 45 4c  E" : .      "DEL
1610: 45 54 45 22 2c 20 2d 31 0a 20 20 29 29 3b 0a 0a  ETE", -1.  ));..
1620: 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20    /* Append the 
1630: 74 61 62 6c 65 20 6e 61 6d 65 2e 20 2a 2f 0a 20  table name. */. 
1640: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
1650: 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76  ndElement(0, pEv
1660: 61 6c 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  al, Tcl_NewStrin
1670: 67 4f 62 6a 28 7a 54 61 62 2c 20 2d 31 29 29 3b  gObj(zTab, -1));
1680: 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68  ..  /* Append th
1690: 65 20 63 6f 6e 66 6c 69 63 74 20 74 79 70 65 2e  e conflict type.
16a0: 20 2a 2f 0a 20 20 73 77 69 74 63 68 28 20 65 43   */.  switch( eC
16b0: 6f 6e 66 20 29 7b 0a 20 20 20 20 63 61 73 65 20  onf ){.    case 
16c0: 53 51 4c 49 54 45 5f 43 48 41 4e 47 45 53 45 54  SQLITE_CHANGESET
16d0: 5f 44 41 54 41 3a 0a 20 20 20 20 20 20 54 63 6c  _DATA:.      Tcl
16e0: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
16f0: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 45  ement(interp, pE
1700: 76 61 6c 2c 54 63 6c 5f 4e 65 77 53 74 72 69 6e  val,Tcl_NewStrin
1710: 67 4f 62 6a 28 22 44 41 54 41 22 2c 2d 31 29 29  gObj("DATA",-1))
1720: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
1730: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
1740: 48 41 4e 47 45 53 45 54 5f 4e 4f 54 46 4f 55 4e  HANGESET_NOTFOUN
1750: 44 3a 0a 20 20 20 20 20 20 54 63 6c 5f 4c 69 73  D:.      Tcl_Lis
1760: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
1770: 74 28 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  t(interp, pEval,
1780: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
1790: 28 22 4e 4f 54 46 4f 55 4e 44 22 2c 2d 31 29 29  ("NOTFOUND",-1))
17a0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
17b0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
17c0: 48 41 4e 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43  HANGESET_CONFLIC
17d0: 54 3a 0a 20 20 20 20 20 20 54 63 6c 5f 4c 69 73  T:.      Tcl_Lis
17e0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
17f0: 74 28 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  t(interp, pEval,
1800: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
1810: 28 22 43 4f 4e 46 4c 49 43 54 22 2c 2d 31 29 29  ("CONFLICT",-1))
1820: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
1830: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 43     case SQLITE_C
1840: 48 41 4e 47 45 53 45 54 5f 43 4f 4e 53 54 52 41  HANGESET_CONSTRA
1850: 49 4e 54 3a 0a 20 20 20 20 20 20 54 63 6c 5f 4c  INT:.      Tcl_L
1860: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
1870: 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 45 76 61  ent(interp, pEva
1880: 6c 2c 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  l,Tcl_NewStringO
1890: 62 6a 28 22 43 4f 4e 53 54 52 41 49 4e 54 22 2c  bj("CONSTRAINT",
18a0: 2d 31 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  -1));.      brea
18b0: 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  k;.  }..  /* If 
18c0: 74 68 69 73 20 69 73 20 6e 6f 74 20 61 6e 20 49  this is not an I
18d0: 4e 53 45 52 54 2c 20 61 70 70 65 6e 64 20 74 68  NSERT, append th
18e0: 65 20 6f 6c 64 20 72 6f 77 20 2a 2f 0a 20 20 69  e old row */.  i
18f0: 66 28 20 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e  f( op!=SQLITE_IN
1900: 53 45 52 54 20 29 7b 0a 20 20 20 20 69 6e 74 20  SERT ){.    int 
1910: 69 3b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a  i;.    Tcl_Obj *
1920: 70 4f 6c 64 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  pOld = Tcl_NewOb
1930: 6a 28 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  j();.    for(i=0
1940: 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a  ; i<nCol; i++){.
1950: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61        sqlite3_va
1960: 6c 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20  lue *pVal;.     
1970: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
1980: 74 5f 6f 6c 64 28 70 49 74 65 72 2c 20 69 2c 20  t_old(pIter, i, 
1990: 26 70 56 61 6c 29 3b 0a 20 20 20 20 20 20 74 65  &pVal);.      te
19a0: 73 74 5f 61 70 70 65 6e 64 5f 76 61 6c 75 65 28  st_append_value(
19b0: 70 4f 6c 64 2c 20 70 56 61 6c 29 3b 0a 20 20 20  pOld, pVal);.   
19c0: 20 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f   }.    Tcl_ListO
19d0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
19e0: 30 2c 20 70 45 76 61 6c 2c 20 70 4f 6c 64 29 3b  0, pEval, pOld);
19f0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
1a00: 69 73 20 69 73 20 6e 6f 74 20 61 20 44 45 4c 45  is is not a DELE
1a10: 54 45 2c 20 61 70 70 65 6e 64 20 74 68 65 20 6e  TE, append the n
1a20: 65 77 20 72 6f 77 20 2a 2f 0a 20 20 69 66 28 20  ew row */.  if( 
1a30: 6f 70 21 3d 53 51 4c 49 54 45 5f 44 45 4c 45 54  op!=SQLITE_DELET
1a40: 45 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  E ){.    int i;.
1a50: 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4e 65      Tcl_Obj *pNe
1a60: 77 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29  w = Tcl_NewObj()
1a70: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
1a80: 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nCol; i++){.   
1a90: 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65     sqlite3_value
1aa0: 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20 73 71   *pVal;.      sq
1ab0: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e  lite3changeset_n
1ac0: 65 77 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56  ew(pIter, i, &pV
1ad0: 61 6c 29 3b 0a 20 20 20 20 20 20 74 65 73 74 5f  al);.      test_
1ae0: 61 70 70 65 6e 64 5f 76 61 6c 75 65 28 70 4e 65  append_value(pNe
1af0: 77 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 7d 0a  w, pVal);.    }.
1b00: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
1b10: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20  ppendElement(0, 
1b20: 70 45 76 61 6c 2c 20 70 4e 65 77 29 3b 0a 20 20  pEval, pNew);.  
1b30: 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20  }..  /* If this 
1b40: 69 73 20 61 20 43 48 41 4e 47 45 53 45 54 5f 44  is a CHANGESET_D
1b50: 41 54 41 20 6f 72 20 43 48 41 4e 47 45 53 45 54  ATA or CHANGESET
1b60: 5f 43 4f 4e 46 4c 49 43 54 20 63 6f 6e 66 6c 69  _CONFLICT confli
1b70: 63 74 2c 20 61 70 70 65 6e 64 0a 20 20 2a 2a 20  ct, append.  ** 
1b80: 74 68 65 20 63 6f 6e 66 6c 69 63 74 69 6e 67 20  the conflicting 
1b90: 72 6f 77 2e 20 2a 2f 0a 20 20 69 66 28 20 65 43  row. */.  if( eC
1ba0: 6f 6e 66 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e  onf==SQLITE_CHAN
1bb0: 47 45 53 45 54 5f 44 41 54 41 20 7c 7c 20 65 43  GESET_DATA || eC
1bc0: 6f 6e 66 3d 3d 53 51 4c 49 54 45 5f 43 48 41 4e  onf==SQLITE_CHAN
1bd0: 47 45 53 45 54 5f 43 4f 4e 46 4c 49 43 54 20 29  GESET_CONFLICT )
1be0: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
1bf0: 20 54 63 6c 5f 4f 62 6a 20 2a 70 43 6f 6e 66 6c   Tcl_Obj *pConfl
1c00: 69 63 74 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  ict = Tcl_NewObj
1c10: 28 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  ();.    for(i=0;
1c20: 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20   i<nCol; i++){. 
1c30: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c       sqlite3_val
1c40: 75 65 20 2a 70 56 61 6c 3b 0a 20 20 20 20 20 20  ue *pVal;.      
1c50: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
1c60: 5f 63 6f 6e 66 6c 69 63 74 28 70 49 74 65 72 2c  _conflict(pIter,
1c70: 20 69 2c 20 26 70 56 61 6c 29 3b 0a 20 20 20 20   i, &pVal);.    
1c80: 20 20 74 65 73 74 5f 61 70 70 65 6e 64 5f 76 61    test_append_va
1c90: 6c 75 65 28 70 43 6f 6e 66 6c 69 63 74 2c 20 70  lue(pConflict, p
1ca0: 56 61 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Val);.    }.    
1cb0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
1cc0: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76 61  dElement(0, pEva
1cd0: 6c 2c 20 70 43 6f 6e 66 6c 69 63 74 29 3b 0a 20  l, pConflict);. 
1ce0: 20 7d 0a 0a 20 20 69 66 28 20 54 43 4c 5f 4f 4b   }..  if( TCL_OK
1cf0: 21 3d 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28  !=Tcl_EvalObjEx(
1d00: 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 54  interp, pEval, T
1d10: 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 20  CL_EVAL_GLOBAL) 
1d20: 29 7b 0a 20 20 20 20 54 63 6c 5f 42 61 63 6b 67  ){.    Tcl_Backg
1d30: 72 6f 75 6e 64 45 72 72 6f 72 28 69 6e 74 65 72  roundError(inter
1d40: 70 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 44 65  p);.  }.  Tcl_De
1d50: 63 72 52 65 66 43 6f 75 6e 74 28 70 45 76 61 6c  crRefCount(pEval
1d60: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
1d70: 54 45 5f 43 48 41 4e 47 45 53 45 54 5f 4f 4d 49  TE_CHANGESET_OMI
1d80: 54 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69  T;.}../*.** sqli
1d90: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70  te3changeset_app
1da0: 6c 79 20 44 42 20 43 48 41 4e 47 45 53 45 54 20  ly DB CHANGESET 
1db0: 53 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74 69 63  SCRIPT.*/.static
1dc0: 20 69 6e 74 20 74 65 73 74 5f 73 71 6c 69 74 65   int test_sqlite
1dd0: 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79  3changeset_apply
1de0: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
1df0: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
1e00: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
1e10: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
1e20: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
1e30: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  .){.  sqlite3 *d
1e40: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b;              
1e50: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
1e60: 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 54 63  e handle */.  Tc
1e70: 6c 5f 43 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 20  l_CmdInfo info; 
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1e90: 20 44 61 74 61 62 61 73 65 20 54 63 6c 20 63 6f   Database Tcl co
1ea0: 6d 6d 61 6e 64 20 28 6f 62 6a 76 5b 31 5d 29 20  mmand (objv[1]) 
1eb0: 69 6e 66 6f 20 2a 2f 0a 20 20 69 6e 74 20 72 63  info */.  int rc
1ec0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1ed0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
1ee0: 75 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20 63 68  urn code from ch
1ef0: 61 6e 67 65 73 65 74 5f 69 6e 76 65 72 74 28 29  angeset_invert()
1f00: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43 68 61   */.  void *pCha
1f10: 6e 67 65 73 65 74 3b 20 20 20 20 20 20 20 20 20  ngeset;         
1f20: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
1f30: 63 6f 6e 74 61 69 6e 69 6e 67 20 63 68 61 6e 67  containing chang
1f40: 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  eset */.  int nC
1f50: 68 61 6e 67 65 73 65 74 3b 20 20 20 20 20 20 20  hangeset;       
1f60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
1f70: 65 20 6f 66 20 62 75 66 66 65 72 20 61 43 68 61  e of buffer aCha
1f80: 6e 67 65 73 65 74 20 69 6e 20 62 79 74 65 73 20  ngeset in bytes 
1f90: 2a 2f 0a 20 20 54 65 73 74 43 6f 6e 66 6c 69 63  */.  TestConflic
1fa0: 74 48 61 6e 64 6c 65 72 20 63 74 78 3b 0a 0a 20  tHandler ctx;.. 
1fb0: 20 69 66 28 20 6f 62 6a 63 21 3d 34 20 29 7b 0a   if( objc!=4 ){.
1fc0: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
1fd0: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
1fe0: 6f 62 6a 76 2c 20 22 44 42 20 43 48 41 4e 47 45  objv, "DB CHANGE
1ff0: 53 45 54 20 53 43 52 49 50 54 22 29 3b 0a 20 20  SET SCRIPT");.  
2000: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
2010: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 30 3d  OR;.  }.  if( 0=
2020: 3d 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49  =Tcl_GetCommandI
2030: 6e 66 6f 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  nfo(interp, Tcl_
2040: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
2050: 5d 29 2c 20 26 69 6e 66 6f 29 20 29 7b 0a 20 20  ]), &info) ){.  
2060: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
2070: 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73  lt(interp, "no s
2080: 75 63 68 20 68 61 6e 64 6c 65 3a 20 22 2c 20 54  uch handle: ", T
2090: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
20a0: 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 72  v[2]), 0);.    r
20b0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
20c0: 0a 20 20 7d 0a 20 20 64 62 20 3d 20 2a 28 73 71  .  }.  db = *(sq
20d0: 6c 69 74 65 33 20 2a 2a 29 69 6e 66 6f 2e 6f 62  lite3 **)info.ob
20e0: 6a 43 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 70  jClientData;.  p
20f0: 43 68 61 6e 67 65 73 65 74 20 3d 20 28 76 6f 69  Changeset = (voi
2100: 64 20 2a 29 54 63 6c 5f 47 65 74 42 79 74 65 41  d *)Tcl_GetByteA
2110: 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76  rrayFromObj(objv
2120: 5b 32 5d 2c 20 26 6e 43 68 61 6e 67 65 73 65 74  [2], &nChangeset
2130: 29 3b 0a 20 20 63 74 78 2e 70 53 63 72 69 70 74  );.  ctx.pScript
2140: 20 3d 20 6f 62 6a 76 5b 33 5d 3b 0a 20 20 63 74   = objv[3];.  ct
2150: 78 2e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72  x.interp = inter
2160: 70 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  p;..  rc = sqlit
2170: 65 33 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c  e3changeset_appl
2180: 79 28 0a 20 20 20 20 20 20 64 62 2c 20 6e 43 68  y(.      db, nCh
2190: 61 6e 67 65 73 65 74 2c 20 70 43 68 61 6e 67 65  angeset, pChange
21a0: 73 65 74 2c 20 74 65 73 74 5f 63 6f 6e 66 6c 69  set, test_confli
21b0: 63 74 5f 68 61 6e 64 6c 65 72 2c 20 28 76 6f 69  ct_handler, (voi
21c0: 64 20 2a 29 26 63 74 78 0a 20 20 29 3b 0a 20 20  d *)&ctx.  );.  
21d0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
21e0: 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  K ){.    return 
21f0: 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65 72 72  test_session_err
2200: 6f 72 28 69 6e 74 65 72 70 2c 20 72 63 29 3b 0a  or(interp, rc);.
2210: 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65 74 52    }.  Tcl_ResetR
2220: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20  esult(interp);. 
2230: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
2240: 7d 0a 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33  }../*.** sqlite3
2250: 63 68 61 6e 67 65 73 65 74 5f 69 6e 76 65 72 74  changeset_invert
2260: 20 43 48 41 4e 47 45 53 45 54 0a 2a 2f 0a 73 74   CHANGESET.*/.st
2270: 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 73 71  atic int test_sq
2280: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 69  lite3changeset_i
2290: 6e 76 65 72 74 28 0a 20 20 76 6f 69 64 20 2a 20  nvert(.  void * 
22a0: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
22b0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
22c0: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
22d0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
22e0: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e 74 20 72  bjv[].){.  int r
22f0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
2300: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
2310: 74 75 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20 63  turn code from c
2320: 68 61 6e 67 65 73 65 74 5f 69 6e 76 65 72 74 28  hangeset_invert(
2330: 29 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 61 43 68  ) */.  void *aCh
2340: 61 6e 67 65 73 65 74 3b 20 20 20 20 20 20 20 20  angeset;        
2350: 20 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20         /* Input 
2360: 63 68 61 6e 67 65 73 65 74 20 2a 2f 0a 20 20 69  changeset */.  i
2370: 6e 74 20 6e 43 68 61 6e 67 65 53 65 74 3b 20 20  nt nChangeSet;  
2380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2390: 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72  * Size of buffer
23a0: 20 61 43 68 61 6e 67 65 73 65 74 20 69 6e 20 62   aChangeset in b
23b0: 79 74 65 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  ytes */.  void *
23c0: 61 4f 75 74 3b 20 20 20 20 20 20 20 20 20 20 20  aOut;           
23d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 75 74            /* Out
23e0: 70 75 74 20 63 68 61 6e 67 65 73 65 74 20 2a 2f  put changeset */
23f0: 0a 20 20 69 6e 74 20 6e 4f 75 74 3b 20 20 20 20  .  int nOut;    
2400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2410: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75     /* Size of bu
2420: 66 66 65 72 20 61 4f 75 74 20 69 6e 20 62 79 74  ffer aOut in byt
2430: 65 73 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a  es */..  if( obj
2440: 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=2 ){.    Tcl_
2450: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
2460: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 43  erp, 1, objv, "C
2470: 48 41 4e 47 45 53 45 54 22 29 3b 0a 20 20 20 20  HANGESET");.    
2480: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
2490: 3b 0a 20 20 7d 0a 20 20 61 43 68 61 6e 67 65 73  ;.  }.  aChanges
24a0: 65 74 20 3d 20 28 76 6f 69 64 20 2a 29 54 63 6c  et = (void *)Tcl
24b0: 5f 47 65 74 42 79 74 65 41 72 72 61 79 46 72 6f  _GetByteArrayFro
24c0: 6d 4f 62 6a 28 6f 62 6a 76 5b 31 5d 2c 20 26 6e  mObj(objv[1], &n
24d0: 43 68 61 6e 67 65 53 65 74 29 3b 0a 0a 20 20 72  ChangeSet);..  r
24e0: 63 20 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67  c = sqlite3chang
24f0: 65 73 65 74 5f 69 6e 76 65 72 74 28 6e 43 68 61  eset_invert(nCha
2500: 6e 67 65 53 65 74 2c 20 61 43 68 61 6e 67 65 73  ngeSet, aChanges
2510: 65 74 2c 20 26 6e 4f 75 74 2c 20 26 61 4f 75 74  et, &nOut, &aOut
2520: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
2530: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65  ITE_OK ){.    re
2540: 74 75 72 6e 20 74 65 73 74 5f 73 65 73 73 69 6f  turn test_sessio
2550: 6e 5f 65 72 72 6f 72 28 69 6e 74 65 72 70 2c 20  n_error(interp, 
2560: 72 63 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 53  rc);.  }.  Tcl_S
2570: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
2580: 72 70 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41  rp, Tcl_NewByteA
2590: 72 72 61 79 4f 62 6a 28 28 75 6e 73 69 67 6e 65  rrayObj((unsigne
25a0: 64 20 63 68 61 72 20 2a 29 61 4f 75 74 2c 20 6e  d char *)aOut, n
25b0: 4f 75 74 29 29 3b 0a 20 20 73 71 6c 69 74 65 33  Out));.  sqlite3
25c0: 5f 66 72 65 65 28 61 4f 75 74 29 3b 0a 20 20 72  _free(aOut);.  r
25d0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
25e0: 0a 2f 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 73 65  ./*.** sqlite3se
25f0: 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 20 56 41  ssion_foreach VA
2600: 52 4e 41 4d 45 20 43 48 41 4e 47 45 53 45 54 20  RNAME CHANGESET 
2610: 53 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74 69 63  SCRIPT.*/.static
2620: 20 69 6e 74 20 74 65 73 74 5f 73 71 6c 69 74 65   int test_sqlite
2630: 33 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68  3session_foreach
2640: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
2650: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
2660: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
2670: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
2680: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
2690: 0a 29 7b 0a 20 20 76 6f 69 64 20 2a 70 43 68 61  .){.  void *pCha
26a0: 6e 67 65 53 65 74 3b 0a 20 20 69 6e 74 20 6e 43  ngeSet;.  int nC
26b0: 68 61 6e 67 65 53 65 74 3b 0a 20 20 73 71 6c 69  hangeSet;.  sqli
26c0: 74 65 33 5f 63 68 61 6e 67 65 73 65 74 5f 69 74  te3_changeset_it
26d0: 65 72 20 2a 70 49 74 65 72 3b 0a 20 20 69 6e 74  er *pIter;.  int
26e0: 20 72 63 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63   rc;..  if( objc
26f0: 21 3d 34 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=4 ){.    Tcl_W
2700: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
2710: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 56 41  rp, 1, objv, "VA
2720: 52 4e 41 4d 45 20 43 48 41 4e 47 45 53 45 54 20  RNAME CHANGESET 
2730: 53 43 52 49 50 54 22 29 3b 0a 20 20 20 20 72 65  SCRIPT");.    re
2740: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
2750: 20 20 7d 0a 0a 20 20 70 43 68 61 6e 67 65 53 65    }..  pChangeSe
2760: 74 20 3d 20 28 76 6f 69 64 20 2a 29 54 63 6c 5f  t = (void *)Tcl_
2770: 47 65 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d  GetByteArrayFrom
2780: 4f 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26 6e 43  Obj(objv[2], &nC
2790: 68 61 6e 67 65 53 65 74 29 3b 0a 20 20 72 63 20  hangeSet);.  rc 
27a0: 3d 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73  = sqlite3changes
27b0: 65 74 5f 73 74 61 72 74 28 26 70 49 74 65 72 2c  et_start(&pIter,
27c0: 20 6e 43 68 61 6e 67 65 53 65 74 2c 20 70 43 68   nChangeSet, pCh
27d0: 61 6e 67 65 53 65 74 29 3b 0a 20 20 69 66 28 20  angeSet);.  if( 
27e0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
27f0: 0a 20 20 20 20 72 65 74 75 72 6e 20 74 65 73 74  .    return test
2800: 5f 73 65 73 73 69 6f 6e 5f 65 72 72 6f 72 28 69  _session_error(i
2810: 6e 74 65 72 70 2c 20 72 63 29 3b 0a 20 20 7d 0a  nterp, rc);.  }.
2820: 0a 20 20 77 68 69 6c 65 28 20 53 51 4c 49 54 45  .  while( SQLITE
2830: 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 63 68 61  _ROW==sqlite3cha
2840: 6e 67 65 73 65 74 5f 6e 65 78 74 28 70 49 74 65  ngeset_next(pIte
2850: 72 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 43  r) ){.    int nC
2860: 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ol;             
2870: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2880: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
2890: 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74  table */.    int
28a0: 20 6f 70 3b 20 20 20 20 20 20 20 20 20 20 20 20   op;            
28b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51             /* SQ
28c0: 4c 49 54 45 5f 49 4e 53 45 52 54 2c 20 55 50 44  LITE_INSERT, UPD
28d0: 41 54 45 20 6f 72 20 44 45 4c 45 54 45 20 2a 2f  ATE or DELETE */
28e0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
28f0: 2a 7a 54 61 62 3b 20 20 20 20 20 20 20 20 20 20  *zTab;          
2900: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61     /* Name of ta
2910: 62 6c 65 20 63 68 61 6e 67 65 20 61 70 70 6c 69  ble change appli
2920: 65 73 20 74 6f 20 2a 2f 0a 20 20 20 20 54 63 6c  es to */.    Tcl
2930: 5f 4f 62 6a 20 2a 70 56 61 72 3b 20 20 20 20 20  _Obj *pVar;     
2940: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 63             /* Tc
2950: 6c 20 76 61 6c 75 65 20 74 6f 20 73 65 74 20 24  l value to set $
2960: 56 41 52 4e 41 4d 45 20 74 6f 20 2a 2f 0a 20 20  VARNAME to */.  
2970: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f 6c 64 3b    Tcl_Obj *pOld;
2980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2990: 2f 2a 20 56 65 63 74 6f 72 20 6f 66 20 6f 6c 64  /* Vector of old
29a0: 2e 2a 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 20  .* values */.   
29b0: 20 54 63 6c 5f 4f 62 6a 20 2a 70 4e 65 77 3b 20   Tcl_Obj *pNew; 
29c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
29d0: 2a 20 56 65 63 74 6f 72 20 6f 66 20 6e 65 77 2e  * Vector of new.
29e0: 2a 20 76 61 6c 75 65 73 20 2a 2f 0a 0a 20 20 20  * values */..   
29f0: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
2a00: 74 5f 6f 70 28 70 49 74 65 72 2c 20 26 7a 54 61  t_op(pIter, &zTa
2a10: 62 2c 20 26 6e 43 6f 6c 2c 20 26 6f 70 29 3b 0a  b, &nCol, &op);.
2a20: 20 20 20 20 70 56 61 72 20 3d 20 54 63 6c 5f 4e      pVar = Tcl_N
2a30: 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 54 63 6c  ewObj();.    Tcl
2a40: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
2a50: 65 6d 65 6e 74 28 30 2c 20 70 56 61 72 2c 20 54  ement(0, pVar, T
2a60: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2a70: 0a 20 20 20 20 20 20 20 20 20 20 6f 70 3d 3d 53  .          op==S
2a80: 51 4c 49 54 45 5f 49 4e 53 45 52 54 20 3f 20 22  QLITE_INSERT ? "
2a90: 49 4e 53 45 52 54 22 20 3a 0a 20 20 20 20 20 20  INSERT" :.      
2aa0: 20 20 20 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 55      op==SQLITE_U
2ab0: 50 44 41 54 45 20 3f 20 22 55 50 44 41 54 45 22  PDATE ? "UPDATE"
2ac0: 20 3a 20 0a 20 20 20 20 20 20 20 20 20 20 22 44   : .          "D
2ad0: 45 4c 45 54 45 22 2c 20 2d 31 0a 20 20 20 20 29  ELETE", -1.    )
2ae0: 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f  );.    Tcl_ListO
2af0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2b00: 30 2c 20 70 56 61 72 2c 20 54 63 6c 5f 4e 65 77  0, pVar, Tcl_New
2b10: 53 74 72 69 6e 67 4f 62 6a 28 7a 54 61 62 2c 20  StringObj(zTab, 
2b20: 2d 31 29 29 3b 0a 0a 20 20 20 20 70 4f 6c 64 20  -1));..    pOld 
2b30: 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a  = Tcl_NewObj();.
2b40: 20 20 20 20 69 66 28 20 6f 70 21 3d 53 51 4c 49      if( op!=SQLI
2b50: 54 45 5f 49 4e 53 45 52 54 20 29 7b 0a 20 20 20  TE_INSERT ){.   
2b60: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
2b70: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b  for(i=0; i<nCol;
2b80: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 73   i++){.        s
2b90: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
2ba0: 61 6c 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  al;.        sqli
2bb0: 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6f 6c 64  te3changeset_old
2bc0: 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56 61 6c  (pIter, i, &pVal
2bd0: 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74 5f  );.        test_
2be0: 61 70 70 65 6e 64 5f 76 61 6c 75 65 28 70 4f 6c  append_value(pOl
2bf0: 64 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 20 20  d, pVal);.      
2c00: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 77  }.    }.    pNew
2c10: 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b   = Tcl_NewObj();
2c20: 0a 20 20 20 20 69 66 28 20 6f 70 21 3d 53 51 4c  .    if( op!=SQL
2c30: 49 54 45 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20  ITE_DELETE ){.  
2c40: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20      int i;.     
2c50: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c   for(i=0; i<nCol
2c60: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
2c70: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
2c80: 56 61 6c 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  Val;.        sql
2c90: 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 6e 65  ite3changeset_ne
2ca0: 77 28 70 49 74 65 72 2c 20 69 2c 20 26 70 56 61  w(pIter, i, &pVa
2cb0: 6c 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74  l);.        test
2cc0: 5f 61 70 70 65 6e 64 5f 76 61 6c 75 65 28 70 4e  _append_value(pN
2cd0: 65 77 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 20  ew, pVal);.     
2ce0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 54 63 6c   }.    }.    Tcl
2cf0: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
2d00: 65 6d 65 6e 74 28 30 2c 20 70 56 61 72 2c 20 70  ement(0, pVar, p
2d10: 4f 6c 64 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69  Old);.    Tcl_Li
2d20: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
2d30: 6e 74 28 30 2c 20 70 56 61 72 2c 20 70 4e 65 77  nt(0, pVar, pNew
2d40: 29 3b 0a 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 53  );..    Tcl_ObjS
2d50: 65 74 56 61 72 32 28 69 6e 74 65 72 70 2c 20 6f  etVar2(interp, o
2d60: 62 6a 76 5b 31 5d 2c 20 30 2c 20 70 56 61 72 2c  bjv[1], 0, pVar,
2d70: 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20 54 63   0);.    rc = Tc
2d80: 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 69 6e 74 65  l_EvalObjEx(inte
2d90: 72 70 2c 20 6f 62 6a 76 5b 33 5d 2c 20 30 29 3b  rp, objv[3], 0);
2da0: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 54 43 4c  .    if( rc!=TCL
2db0: 5f 4f 4b 20 26 26 20 72 63 21 3d 54 43 4c 5f 43  _OK && rc!=TCL_C
2dc0: 4f 4e 54 49 4e 55 45 20 29 7b 0a 20 20 20 20 20  ONTINUE ){.     
2dd0: 20 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65   sqlite3changese
2de0: 74 5f 66 69 6e 61 6c 69 7a 65 28 70 49 74 65 72  t_finalize(pIter
2df0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
2e00: 72 63 3d 3d 54 43 4c 5f 42 52 45 41 4b 20 3f 20  rc==TCL_BREAK ? 
2e10: 54 43 4c 5f 4f 4b 20 3a 20 72 63 3b 0a 20 20 20  TCL_OK : rc;.   
2e20: 20 7d 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71   }.  }.  rc = sq
2e30: 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f 66  lite3changeset_f
2e40: 69 6e 61 6c 69 7a 65 28 70 49 74 65 72 29 3b 0a  inalize(pIter);.
2e50: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
2e60: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72  _OK ){.    retur
2e70: 6e 20 74 65 73 74 5f 73 65 73 73 69 6f 6e 5f 65  n test_session_e
2e80: 72 72 6f 72 28 69 6e 74 65 72 70 2c 20 72 63 29  rror(interp, rc)
2e90: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
2ea0: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74 20 54  TCL_OK;.}..int T
2eb0: 65 73 74 53 65 73 73 69 6f 6e 5f 49 6e 69 74 28  estSession_Init(
2ec0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
2ed0: 72 70 29 7b 0a 20 20 54 63 6c 5f 43 72 65 61 74  rp){.  Tcl_Creat
2ee0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
2ef0: 72 70 2c 20 22 73 71 6c 69 74 65 33 73 65 73 73  rp, "sqlite3sess
2f00: 69 6f 6e 22 2c 20 74 65 73 74 5f 73 71 6c 69 74  ion", test_sqlit
2f10: 65 33 73 65 73 73 69 6f 6e 2c 20 30 2c 20 30 29  e3session, 0, 0)
2f20: 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62  ;.  Tcl_CreateOb
2f30: 6a 43 6f 6d 6d 61 6e 64 28 0a 20 20 20 20 20 20  jCommand(.      
2f40: 69 6e 74 65 72 70 2c 20 22 73 71 6c 69 74 65 33  interp, "sqlite3
2f50: 73 65 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 22  session_foreach"
2f60: 2c 20 74 65 73 74 5f 73 71 6c 69 74 65 33 73 65  , test_sqlite3se
2f70: 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 2c 20 30  ssion_foreach, 0
2f80: 2c 20 30 0a 20 20 29 3b 0a 20 20 54 63 6c 5f 43  , 0.  );.  Tcl_C
2f90: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
2fa0: 0a 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 22  .      interp, "
2fb0: 73 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74  sqlite3changeset
2fc0: 5f 69 6e 76 65 72 74 22 2c 20 74 65 73 74 5f 73  _invert", test_s
2fd0: 71 6c 69 74 65 33 63 68 61 6e 67 65 73 65 74 5f  qlite3changeset_
2fe0: 69 6e 76 65 72 74 2c 20 30 2c 20 30 0a 20 20 29  invert, 0, 0.  )
2ff0: 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62  ;.  Tcl_CreateOb
3000: 6a 43 6f 6d 6d 61 6e 64 28 0a 20 20 20 20 20 20  jCommand(.      
3010: 69 6e 74 65 72 70 2c 20 22 73 71 6c 69 74 65 33  interp, "sqlite3
3020: 63 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 22  changeset_apply"
3030: 2c 20 74 65 73 74 5f 73 71 6c 69 74 65 33 63 68  , test_sqlite3ch
3040: 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 2c 20 30  angeset_apply, 0
3050: 2c 20 30 0a 20 20 29 3b 0a 20 20 72 65 74 75 72  , 0.  );.  retur
3060: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e  n TCL_OK;.}..#en
3070: 64 69 66 0a 0a                                   dif..