/ Hex Artifact Content
Login

Artifact ee925e0d233677e45e395fb1f559b84068ce7baa8aa1034441739d3e87ee249c:


0000: 0a 70 72 6f 63 20 64 6f 5f 63 68 61 6e 67 65 73  .proc do_changes
0010: 65 74 5f 74 65 73 74 20 7b 74 6e 20 73 65 73 73  et_test {tn sess
0020: 69 6f 6e 20 72 65 73 7d 20 7b 0a 20 20 73 65 74  ion res} {.  set
0030: 20 72 20 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65   r [list].  fore
0040: 61 63 68 20 78 20 24 72 65 73 20 7b 6c 61 70 70  ach x $res {lapp
0050: 65 6e 64 20 72 20 24 78 7d 0a 20 20 75 70 6c 65  end r $x}.  uple
0060: 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 74 6e 20  vel do_test $tn 
0070: 5b 6c 69 73 74 20 5b 73 75 62 73 74 20 2d 6e 6f  [list [subst -no
0080: 63 6f 6d 6d 61 6e 64 73 20 7b 0a 20 20 20 20 73  commands {.    s
0090: 65 74 20 78 20 5b 6c 69 73 74 5d 0a 20 20 20 20  et x [list].    
00a0: 73 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 66  sqlite3session_f
00b0: 6f 72 65 61 63 68 20 63 20 5b 24 73 65 73 73 69  oreach c [$sessi
00c0: 6f 6e 20 63 68 61 6e 67 65 73 65 74 5d 20 7b 20  on changeset] { 
00d0: 6c 61 70 70 65 6e 64 20 78 20 5b 73 65 74 20 63  lappend x [set c
00e0: 5d 20 7d 0a 20 20 20 20 73 65 74 20 78 0a 20 20  ] }.    set x.  
00f0: 7d 5d 5d 20 5b 6c 69 73 74 20 24 72 5d 0a 7d 0a  }]] [list $r].}.
0100: 0a 70 72 6f 63 20 64 6f 5f 70 61 74 63 68 73 65  .proc do_patchse
0110: 74 5f 74 65 73 74 20 7b 74 6e 20 73 65 73 73 69  t_test {tn sessi
0120: 6f 6e 20 72 65 73 7d 20 7b 0a 20 20 73 65 74 20  on res} {.  set 
0130: 72 20 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61  r [list].  forea
0140: 63 68 20 78 20 24 72 65 73 20 7b 6c 61 70 70 65  ch x $res {lappe
0150: 6e 64 20 72 20 24 78 7d 0a 20 20 75 70 6c 65 76  nd r $x}.  uplev
0160: 65 6c 20 64 6f 5f 74 65 73 74 20 24 74 6e 20 5b  el do_test $tn [
0170: 6c 69 73 74 20 5b 73 75 62 73 74 20 2d 6e 6f 63  list [subst -noc
0180: 6f 6d 6d 61 6e 64 73 20 7b 0a 20 20 20 20 73 65  ommands {.    se
0190: 74 20 78 20 5b 6c 69 73 74 5d 0a 20 20 20 20 73  t x [list].    s
01a0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f  qlite3session_fo
01b0: 72 65 61 63 68 20 63 20 5b 24 73 65 73 73 69 6f  reach c [$sessio
01c0: 6e 20 70 61 74 63 68 73 65 74 5d 20 7b 20 6c 61  n patchset] { la
01d0: 70 70 65 6e 64 20 78 20 5b 73 65 74 20 63 5d 20  ppend x [set c] 
01e0: 7d 0a 20 20 20 20 73 65 74 20 78 0a 20 20 7d 5d  }.    set x.  }]
01f0: 5d 20 5b 6c 69 73 74 20 24 72 5d 0a 7d 0a 0a 0a  ] [list $r].}...
0200: 70 72 6f 63 20 64 6f 5f 63 68 61 6e 67 65 73 65  proc do_changese
0210: 74 5f 69 6e 76 65 72 74 5f 74 65 73 74 20 7b 74  t_invert_test {t
0220: 6e 20 73 65 73 73 69 6f 6e 20 72 65 73 7d 20 7b  n session res} {
0230: 0a 20 20 73 65 74 20 72 20 5b 6c 69 73 74 5d 0a  .  set r [list].
0240: 20 20 66 6f 72 65 61 63 68 20 78 20 24 72 65 73    foreach x $res
0250: 20 7b 6c 61 70 70 65 6e 64 20 72 20 24 78 7d 0a   {lappend r $x}.
0260: 20 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73    uplevel do_tes
0270: 74 20 24 74 6e 20 5b 6c 69 73 74 20 5b 73 75 62  t $tn [list [sub
0280: 73 74 20 2d 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b  st -nocommands {
0290: 0a 20 20 20 20 73 65 74 20 78 20 5b 6c 69 73 74  .    set x [list
02a0: 5d 0a 20 20 20 20 73 65 74 20 63 68 61 6e 67 65  ].    set change
02b0: 73 65 74 20 5b 73 71 6c 69 74 65 33 63 68 61 6e  set [sqlite3chan
02c0: 67 65 73 65 74 5f 69 6e 76 65 72 74 20 5b 24 73  geset_invert [$s
02d0: 65 73 73 69 6f 6e 20 63 68 61 6e 67 65 73 65 74  ession changeset
02e0: 5d 5d 0a 20 20 20 20 73 71 6c 69 74 65 33 73 65  ]].    sqlite3se
02f0: 73 73 69 6f 6e 5f 66 6f 72 65 61 63 68 20 63 20  ssion_foreach c 
0300: 5b 73 65 74 20 63 68 61 6e 67 65 73 65 74 5d 20  [set changeset] 
0310: 7b 20 6c 61 70 70 65 6e 64 20 78 20 5b 73 65 74  { lappend x [set
0320: 20 63 5d 20 7d 0a 20 20 20 20 73 65 74 20 78 0a   c] }.    set x.
0330: 20 20 7d 5d 5d 20 5b 6c 69 73 74 20 24 72 5d 0a    }]] [list $r].
0340: 7d 0a 0a 0a 70 72 6f 63 20 64 6f 5f 63 6f 6e 66  }...proc do_conf
0350: 6c 69 63 74 5f 74 65 73 74 20 7b 74 6e 20 61 72  lict_test {tn ar
0360: 67 73 7d 20 7b 0a 0a 20 20 73 65 74 20 4f 28 2d  gs} {..  set O(-
0370: 74 61 62 6c 65 73 29 20 20 20 20 5b 6c 69 73 74  tables)    [list
0380: 5d 0a 20 20 73 65 74 20 4f 28 2d 73 71 6c 29 20  ].  set O(-sql) 
0390: 20 20 20 20 20 20 5b 6c 69 73 74 5d 0a 20 20 73        [list].  s
03a0: 65 74 20 4f 28 2d 63 6f 6e 66 6c 69 63 74 73 29  et O(-conflicts)
03b0: 20 5b 6c 69 73 74 5d 0a 20 20 73 65 74 20 4f 28   [list].  set O(
03c0: 2d 70 6f 6c 69 63 79 29 20 20 20 20 22 4f 4d 49  -policy)    "OMI
03d0: 54 22 0a 0a 20 20 61 72 72 61 79 20 73 65 74 20  T"..  array set 
03e0: 56 20 24 61 72 67 73 0a 20 20 66 6f 72 65 61 63  V $args.  foreac
03f0: 68 20 6b 65 79 20 5b 61 72 72 61 79 20 6e 61 6d  h key [array nam
0400: 65 73 20 56 5d 20 7b 0a 20 20 20 20 69 66 20 7b  es V] {.    if {
0410: 21 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 4f 28  ![info exists O(
0420: 24 6b 65 79 29 5d 7d 20 7b 65 72 72 6f 72 20 22  $key)]} {error "
0430: 6e 6f 20 73 75 63 68 20 6f 70 74 69 6f 6e 3a 20  no such option: 
0440: 24 6b 65 79 22 7d 0a 20 20 7d 0a 20 20 61 72 72  $key"}.  }.  arr
0450: 61 79 20 73 65 74 20 4f 20 24 61 72 67 73 0a 0a  ay set O $args..
0460: 20 20 70 72 6f 63 20 78 43 6f 6e 66 6c 69 63 74    proc xConflict
0470: 20 7b 61 72 67 73 7d 20 5b 73 75 62 73 74 20 2d   {args} [subst -
0480: 6e 6f 63 6f 6d 6d 61 6e 64 73 20 7b 20 0a 20 20  nocommands { .  
0490: 20 20 6c 61 70 70 65 6e 64 20 3a 3a 78 43 6f 6e    lappend ::xCon
04a0: 66 6c 69 63 74 20 5b 73 65 74 20 61 72 67 73 5d  flict [set args]
04b0: 0a 20 20 20 20 72 65 74 75 72 6e 20 24 4f 28 2d  .    return $O(-
04c0: 70 6f 6c 69 63 79 29 20 0a 20 20 7d 5d 0a 20 20  policy) .  }].  
04d0: 70 72 6f 63 20 62 67 65 72 72 6f 72 20 7b 61 72  proc bgerror {ar
04e0: 67 73 7d 20 7b 20 73 65 74 20 3a 3a 62 61 63 6b  gs} { set ::back
04f0: 67 72 6f 75 6e 64 5f 65 72 72 6f 72 20 24 61 72  ground_error $ar
0500: 67 73 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 73  gs }..  sqlite3s
0510: 65 73 73 69 6f 6e 20 53 20 64 62 20 6d 61 69 6e  ession S db main
0520: 0a 20 20 66 6f 72 65 61 63 68 20 74 20 24 4f 28  .  foreach t $O(
0530: 2d 74 61 62 6c 65 73 29 20 7b 20 53 20 61 74 74  -tables) { S att
0540: 61 63 68 20 24 74 20 7d 0a 20 20 65 78 65 63 73  ach $t }.  execs
0550: 71 6c 20 24 4f 28 2d 73 71 6c 29 0a 0a 20 20 73  ql $O(-sql)..  s
0560: 65 74 20 3a 3a 78 43 6f 6e 66 6c 69 63 74 20 5b  et ::xConflict [
0570: 6c 69 73 74 5d 0a 20 20 73 71 6c 69 74 65 33 63  list].  sqlite3c
0580: 68 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 20 64  hangeset_apply d
0590: 62 32 20 5b 53 20 63 68 61 6e 67 65 73 65 74 5d  b2 [S changeset]
05a0: 20 78 43 6f 6e 66 6c 69 63 74 0a 0a 20 20 73 65   xConflict..  se
05b0: 74 20 63 6f 6e 66 6c 69 63 74 73 20 5b 6c 69 73  t conflicts [lis
05c0: 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 63 20 24  t].  foreach c $
05d0: 4f 28 2d 63 6f 6e 66 6c 69 63 74 73 29 20 7b 0a  O(-conflicts) {.
05e0: 20 20 20 20 6c 61 70 70 65 6e 64 20 63 6f 6e 66      lappend conf
05f0: 6c 69 63 74 73 20 24 63 0a 20 20 7d 0a 0a 20 20  licts $c.  }..  
0600: 61 66 74 65 72 20 31 20 7b 73 65 74 20 67 6f 20  after 1 {set go 
0610: 31 7d 0a 20 20 76 77 61 69 74 20 67 6f 0a 0a 20  1}.  vwait go.. 
0620: 20 75 70 6c 65 76 65 6c 20 64 6f 5f 74 65 73 74   uplevel do_test
0630: 20 24 74 6e 20 5b 6c 69 73 74 20 7b 20 73 65 74   $tn [list { set
0640: 20 3a 3a 78 43 6f 6e 66 6c 69 63 74 20 7d 5d 20   ::xConflict }] 
0650: 5b 6c 69 73 74 20 24 63 6f 6e 66 6c 69 63 74 73  [list $conflicts
0660: 5d 0a 20 20 53 20 64 65 6c 65 74 65 0a 7d 0a 0a  ].  S delete.}..
0670: 70 72 6f 63 20 64 6f 5f 63 6f 6d 6d 6f 6e 5f 73  proc do_common_s
0680: 71 6c 20 7b 73 71 6c 7d 20 7b 0a 20 20 65 78 65  ql {sql} {.  exe
0690: 63 73 71 6c 20 24 73 71 6c 20 64 62 0a 20 20 65  csql $sql db.  e
06a0: 78 65 63 73 71 6c 20 24 73 71 6c 20 64 62 32 0a  xecsql $sql db2.
06b0: 7d 0a 0a 70 72 6f 63 20 63 68 61 6e 67 65 73 65  }..proc changese
06c0: 74 5f 66 72 6f 6d 5f 73 71 6c 20 7b 73 71 6c 20  t_from_sql {sql 
06d0: 7b 64 62 6e 61 6d 65 20 6d 61 69 6e 7d 7d 20 7b  {dbname main}} {
06e0: 0a 20 20 69 66 20 7b 24 64 62 6e 61 6d 65 20 3d  .  if {$dbname =
06f0: 3d 20 22 6d 61 69 6e 22 7d 20 7b 0a 20 20 20 20  = "main"} {.    
0700: 72 65 74 75 72 6e 20 5b 73 71 6c 5f 65 78 65 63  return [sql_exec
0710: 5f 63 68 61 6e 67 65 73 65 74 20 64 62 20 24 73  _changeset db $s
0720: 71 6c 5d 0a 20 20 7d 0a 20 20 73 65 74 20 72 63  ql].  }.  set rc
0730: 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 73 71   [catch {.    sq
0740: 6c 69 74 65 33 73 65 73 73 69 6f 6e 20 53 20 64  lite3session S d
0750: 62 20 24 64 62 6e 61 6d 65 0a 20 20 20 20 64 62  b $dbname.    db
0760: 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 6e 61   eval "SELECT na
0770: 6d 65 20 46 52 4f 4d 20 24 64 62 6e 61 6d 65 2e  me FROM $dbname.
0780: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
0790: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
07a0: 65 27 22 20 7b 0a 20 20 20 20 20 20 53 20 61 74  e'" {.      S at
07b0: 74 61 63 68 20 24 6e 61 6d 65 0a 20 20 20 20 7d  tach $name.    }
07c0: 0a 20 20 20 20 64 62 20 65 76 61 6c 20 24 73 71  .    db eval $sq
07d0: 6c 0a 20 20 20 20 53 20 63 68 61 6e 67 65 73 65  l.    S changese
07e0: 74 0a 20 20 7d 20 63 68 61 6e 67 65 73 65 74 5d  t.  } changeset]
07f0: 0a 20 20 63 61 74 63 68 20 7b 20 53 20 64 65 6c  .  catch { S del
0800: 65 74 65 20 7d 0a 0a 20 20 69 66 20 7b 24 72 63  ete }..  if {$rc
0810: 7d 20 7b 0a 20 20 20 20 65 72 72 6f 72 20 24 63  } {.    error $c
0820: 68 61 6e 67 65 73 65 74 0a 20 20 7d 0a 20 20 72  hangeset.  }.  r
0830: 65 74 75 72 6e 20 24 63 68 61 6e 67 65 73 65 74  eturn $changeset
0840: 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 74 68 65 6e  .}..proc do_then
0850: 5f 61 70 70 6c 79 5f 73 71 6c 20 7b 73 71 6c 20  _apply_sql {sql 
0860: 7b 64 62 6e 61 6d 65 20 6d 61 69 6e 7d 7d 20 7b  {dbname main}} {
0870: 0a 20 20 70 72 6f 63 20 78 43 6f 6e 66 6c 69 63  .  proc xConflic
0880: 74 20 61 72 67 73 20 7b 20 72 65 74 75 72 6e 20  t args { return 
0890: 22 4f 4d 49 54 22 20 7d 0a 20 20 73 65 74 20 72  "OMIT" }.  set r
08a0: 63 20 5b 63 61 74 63 68 20 7b 0a 20 20 20 20 73  c [catch {.    s
08b0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 20 53 20  qlite3session S 
08c0: 64 62 20 24 64 62 6e 61 6d 65 0a 20 20 20 20 64  db $dbname.    d
08d0: 62 20 65 76 61 6c 20 22 53 45 4c 45 43 54 20 6e  b eval "SELECT n
08e0: 61 6d 65 20 46 52 4f 4d 20 24 64 62 6e 61 6d 65  ame FROM $dbname
08f0: 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57  .sqlite_master W
0900: 48 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62  HERE type = 'tab
0910: 6c 65 27 22 20 7b 0a 20 20 20 20 20 20 53 20 61  le'" {.      S a
0920: 74 74 61 63 68 20 24 6e 61 6d 65 0a 20 20 20 20  ttach $name.    
0930: 7d 0a 20 20 20 20 64 62 20 65 76 61 6c 20 24 73  }.    db eval $s
0940: 71 6c 0a 20 20 20 20 73 71 6c 69 74 65 33 63 68  ql.    sqlite3ch
0950: 61 6e 67 65 73 65 74 5f 61 70 70 6c 79 20 64 62  angeset_apply db
0960: 32 20 5b 53 20 63 68 61 6e 67 65 73 65 74 5d 20  2 [S changeset] 
0970: 78 43 6f 6e 66 6c 69 63 74 0a 20 20 7d 20 6d 73  xConflict.  } ms
0980: 67 5d 0a 0a 20 20 63 61 74 63 68 20 7b 20 53 20  g]..  catch { S 
0990: 64 65 6c 65 74 65 20 7d 0a 0a 20 20 69 66 20 7b  delete }..  if {
09a0: 24 72 63 7d 20 7b 65 72 72 6f 72 20 24 6d 73 67  $rc} {error $msg
09b0: 7d 0a 7d 0a 0a 70 72 6f 63 20 64 6f 5f 69 74 65  }.}..proc do_ite
09c0: 72 61 74 6f 72 5f 74 65 73 74 20 7b 74 6e 20 74  rator_test {tn t
09d0: 62 6c 5f 6c 69 73 74 20 73 71 6c 20 72 65 73 7d  bl_list sql res}
09e0: 20 7b 0a 20 20 73 71 6c 69 74 65 33 73 65 73 73   {.  sqlite3sess
09f0: 69 6f 6e 20 53 20 64 62 20 6d 61 69 6e 0a 20 20  ion S db main.  
0a00: 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24 74 62  if {[llength $tb
0a10: 6c 5f 6c 69 73 74 5d 3d 3d 30 7d 20 7b 20 53 20  l_list]==0} { S 
0a20: 61 74 74 61 63 68 20 2a 20 7d 0a 20 20 66 6f 72  attach * }.  for
0a30: 65 61 63 68 20 74 20 24 74 62 6c 5f 6c 69 73 74  each t $tbl_list
0a40: 20 7b 53 20 61 74 74 61 63 68 20 24 74 7d 0a 0a   {S attach $t}..
0a50: 20 20 65 78 65 63 73 71 6c 20 24 73 71 6c 0a 0a    execsql $sql..
0a60: 20 20 73 65 74 20 72 20 5b 6c 69 73 74 5d 0a 20    set r [list]. 
0a70: 20 66 6f 72 65 61 63 68 20 76 20 24 72 65 73 20   foreach v $res 
0a80: 7b 20 6c 61 70 70 65 6e 64 20 72 20 24 76 20 7d  { lappend r $v }
0a90: 0a 0a 20 20 73 65 74 20 78 20 5b 6c 69 73 74 5d  ..  set x [list]
0aa0: 0a 20 20 73 71 6c 69 74 65 33 73 65 73 73 69 6f  .  sqlite3sessio
0ab0: 6e 5f 66 6f 72 65 61 63 68 20 63 20 5b 53 20 63  n_foreach c [S c
0ac0: 68 61 6e 67 65 73 65 74 5d 20 7b 20 6c 61 70 70  hangeset] { lapp
0ad0: 65 6e 64 20 78 20 24 63 20 7d 0a 20 20 75 70 6c  end x $c }.  upl
0ae0: 65 76 65 6c 20 64 6f 5f 74 65 73 74 20 24 74 6e  evel do_test $tn
0af0: 20 5b 6c 69 73 74 20 5b 6c 69 73 74 20 73 65 74   [list [list set
0b00: 20 7b 7d 20 24 78 5d 5d 20 5b 6c 69 73 74 20 24   {} $x]] [list $
0b10: 72 5d 0a 0a 20 20 53 20 64 65 6c 65 74 65 0a 7d  r]..  S delete.}
0b20: 0a 0a 23 20 43 6f 6d 70 61 72 65 20 74 68 65 20  ..# Compare the 
0b30: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6c 6c 20  contents of all 
0b40: 74 61 62 6c 65 73 20 69 6e 20 5b 64 62 31 5d 20  tables in [db1] 
0b50: 61 6e 64 20 5b 64 62 32 5d 2e 20 54 68 72 6f 77  and [db2]. Throw
0b60: 20 61 6e 20 65 72 72 6f 72 20 69 66 20 0a 23 20   an error if .# 
0b70: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 69 64 65  they are not ide
0b80: 6e 74 69 63 61 6c 2c 20 6f 72 20 72 65 74 75 72  ntical, or retur
0b90: 6e 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e  n an empty strin
0ba0: 67 20 69 66 20 74 68 65 79 20 61 72 65 2e 0a 23  g if they are..#
0bb0: 0a 70 72 6f 63 20 63 6f 6d 70 61 72 65 5f 64 62  .proc compare_db
0bc0: 20 7b 64 62 31 20 64 62 32 7d 20 7b 0a 0a 20 20   {db1 db2} {..  
0bd0: 73 65 74 20 73 71 6c 20 7b 53 45 4c 45 43 54 20  set sql {SELECT 
0be0: 6e 61 6d 65 20 46 52 4f 4d 20 73 71 6c 69 74 65  name FROM sqlite
0bf0: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
0c00: 70 65 20 3d 20 27 74 61 62 6c 65 27 20 4f 52 44  pe = 'table' ORD
0c10: 45 52 20 42 59 20 6e 61 6d 65 7d 0a 20 20 73 65  ER BY name}.  se
0c20: 74 20 6c 6f 74 31 20 5b 24 64 62 31 20 65 76 61  t lot1 [$db1 eva
0c30: 6c 20 24 73 71 6c 5d 0a 20 20 73 65 74 20 6c 6f  l $sql].  set lo
0c40: 74 32 20 5b 24 64 62 32 20 65 76 61 6c 20 24 73  t2 [$db2 eval $s
0c50: 71 6c 5d 0a 0a 20 20 69 66 20 7b 24 6c 6f 74 31  ql]..  if {$lot1
0c60: 20 21 3d 20 24 6c 6f 74 32 7d 20 7b 20 0a 20 20   != $lot2} { .  
0c70: 20 20 70 75 74 73 20 24 6c 6f 74 31 0a 20 20 20    puts $lot1.   
0c80: 20 70 75 74 73 20 24 6c 6f 74 32 0a 20 20 20 20   puts $lot2.    
0c90: 65 72 72 6f 72 20 22 64 61 74 61 62 61 73 65 73  error "databases
0ca0: 20 63 6f 6e 74 61 69 6e 20 64 69 66 66 65 72 65   contain differe
0cb0: 6e 74 20 74 61 62 6c 65 73 22 20 0a 20 20 7d 0a  nt tables" .  }.
0cc0: 0a 20 20 66 6f 72 65 61 63 68 20 74 62 6c 20 24  .  foreach tbl $
0cd0: 6c 6f 74 31 20 7b 0a 20 20 20 20 73 65 74 20 63  lot1 {.    set c
0ce0: 6f 6c 31 20 5b 6c 69 73 74 5d 0a 20 20 20 20 73  ol1 [list].    s
0cf0: 65 74 20 63 6f 6c 32 20 5b 6c 69 73 74 5d 0a 0a  et col2 [list]..
0d00: 20 20 20 20 24 64 62 31 20 65 76 61 6c 20 22 50      $db1 eval "P
0d10: 52 41 47 4d 41 20 74 61 62 6c 65 5f 69 6e 66 6f  RAGMA table_info
0d20: 20 3d 20 24 74 62 6c 22 20 7b 20 6c 61 70 70 65   = $tbl" { lappe
0d30: 6e 64 20 63 6f 6c 31 20 24 6e 61 6d 65 20 7d 0a  nd col1 $name }.
0d40: 20 20 20 20 24 64 62 32 20 65 76 61 6c 20 22 50      $db2 eval "P
0d50: 52 41 47 4d 41 20 74 61 62 6c 65 5f 69 6e 66 6f  RAGMA table_info
0d60: 20 3d 20 24 74 62 6c 22 20 7b 20 6c 61 70 70 65   = $tbl" { lappe
0d70: 6e 64 20 63 6f 6c 32 20 24 6e 61 6d 65 20 7d 0a  nd col2 $name }.
0d80: 20 20 20 20 69 66 20 7b 24 63 6f 6c 31 20 21 3d      if {$col1 !=
0d90: 20 24 63 6f 6c 32 7d 20 7b 20 65 72 72 6f 72 20   $col2} { error 
0da0: 22 74 61 62 6c 65 20 24 74 62 6c 20 73 63 68 65  "table $tbl sche
0db0: 6d 61 20 6d 69 73 6d 61 74 63 68 22 20 7d 0a 0a  ma mismatch" }..
0dc0: 20 20 20 20 73 65 74 20 73 71 6c 20 22 53 45 4c      set sql "SEL
0dd0: 45 43 54 20 2a 20 46 52 4f 4d 20 24 74 62 6c 20  ECT * FROM $tbl 
0de0: 4f 52 44 45 52 20 42 59 20 5b 6a 6f 69 6e 20 24  ORDER BY [join $
0df0: 63 6f 6c 31 20 2c 5d 22 0a 20 20 20 20 73 65 74  col1 ,]".    set
0e00: 20 64 61 74 61 31 20 5b 24 64 62 31 20 65 76 61   data1 [$db1 eva
0e10: 6c 20 24 73 71 6c 5d 0a 20 20 20 20 73 65 74 20  l $sql].    set 
0e20: 64 61 74 61 32 20 5b 24 64 62 32 20 65 76 61 6c  data2 [$db2 eval
0e30: 20 24 73 71 6c 5d 0a 20 20 20 20 69 66 20 7b 24   $sql].    if {$
0e40: 64 61 74 61 31 20 21 3d 20 24 64 61 74 61 32 7d  data1 != $data2}
0e50: 20 7b 20 0a 20 20 20 20 20 20 70 75 74 73 20 22   { .      puts "
0e60: 24 64 61 74 61 31 22 0a 20 20 20 20 20 20 70 75  $data1".      pu
0e70: 74 73 20 22 24 64 61 74 61 32 22 0a 20 20 20 20  ts "$data2".    
0e80: 20 20 65 72 72 6f 72 20 22 74 61 62 6c 65 20 24    error "table $
0e90: 74 62 6c 20 64 61 74 61 20 6d 69 73 6d 61 74 63  tbl data mismatc
0ea0: 68 22 20 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  h" .    }.  }.. 
0eb0: 20 72 65 74 75 72 6e 20 22 22 0a 7d 0a 0a 70 72   return "".}..pr
0ec0: 6f 63 20 63 68 61 6e 67 65 73 65 74 5f 74 6f 5f  oc changeset_to_
0ed0: 6c 69 73 74 20 7b 63 7d 20 7b 0a 20 20 73 65 74  list {c} {.  set
0ee0: 20 6c 69 73 74 20 5b 6c 69 73 74 5d 0a 20 20 73   list [list].  s
0ef0: 71 6c 69 74 65 33 73 65 73 73 69 6f 6e 5f 66 6f  qlite3session_fo
0f00: 72 65 61 63 68 20 65 6c 65 6d 20 24 63 20 7b 20  reach elem $c { 
0f10: 6c 61 70 70 65 6e 64 20 6c 69 73 74 20 24 65 6c  lappend list $el
0f20: 65 6d 20 7d 0a 20 20 6c 73 6f 72 74 20 24 6c 69  em }.  lsort $li
0f30: 73 74 0a 7d 0a 0a 73 65 74 20 6f 6e 65 73 20 7b  st.}..set ones {
0f40: 7a 65 72 6f 20 6f 6e 65 20 74 77 6f 20 74 68 72  zero one two thr
0f50: 65 65 20 66 6f 75 72 20 66 69 76 65 20 73 69 78  ee four five six
0f60: 20 73 65 76 65 6e 20 65 69 67 68 74 20 6e 69 6e   seven eight nin
0f70: 65 0a 20 20 20 20 20 20 20 20 20 20 74 65 6e 20  e.          ten 
0f80: 65 6c 65 76 65 6e 20 74 77 65 6c 76 65 20 74 68  eleven twelve th
0f90: 69 72 74 65 65 6e 20 66 6f 75 72 74 65 65 6e 20  irteen fourteen 
0fa0: 66 69 66 74 65 65 6e 20 73 69 78 74 65 65 6e 20  fifteen sixteen 
0fb0: 73 65 76 65 6e 74 65 65 6e 0a 20 20 20 20 20 20  seventeen.      
0fc0: 20 20 20 20 65 69 67 68 74 65 65 6e 20 6e 69 6e      eighteen nin
0fd0: 65 74 65 65 6e 7d 0a 73 65 74 20 74 65 6e 73 20  eteen}.set tens 
0fe0: 7b 7b 7d 20 74 65 6e 20 74 77 65 6e 74 79 20 74  {{} ten twenty t
0ff0: 68 69 72 74 79 20 66 6f 72 74 79 20 66 69 66 74  hirty forty fift
1000: 79 20 73 69 78 74 79 20 73 65 76 65 6e 74 79 20  y sixty seventy 
1010: 65 69 67 68 74 79 20 6e 69 6e 65 74 79 7d 0a 70  eighty ninety}.p
1020: 72 6f 63 20 6e 75 6d 62 65 72 5f 6e 61 6d 65 20  roc number_name 
1030: 7b 6e 7d 20 7b 0a 20 20 69 66 20 7b 24 6e 3e 3d  {n} {.  if {$n>=
1040: 31 30 30 30 7d 20 7b 0a 20 20 20 20 73 65 74 20  1000} {.    set 
1050: 74 78 74 20 22 5b 6e 75 6d 62 65 72 5f 6e 61 6d  txt "[number_nam
1060: 65 20 5b 65 78 70 72 20 7b 24 6e 2f 31 30 30 30  e [expr {$n/1000
1070: 7d 5d 5d 20 74 68 6f 75 73 61 6e 64 22 0a 20 20  }]] thousand".  
1080: 20 20 73 65 74 20 6e 20 5b 65 78 70 72 20 7b 24    set n [expr {$
1090: 6e 25 31 30 30 30 7d 5d 0a 20 20 7d 20 65 6c 73  n%1000}].  } els
10a0: 65 20 7b 0a 20 20 20 20 73 65 74 20 74 78 74 20  e {.    set txt 
10b0: 7b 7d 0a 20 20 7d 0a 20 20 69 66 20 7b 24 6e 3e  {}.  }.  if {$n>
10c0: 3d 31 30 30 7d 20 7b 0a 20 20 20 20 61 70 70 65  =100} {.    appe
10d0: 6e 64 20 74 78 74 20 22 20 5b 6c 69 6e 64 65 78  nd txt " [lindex
10e0: 20 24 3a 3a 6f 6e 65 73 20 5b 65 78 70 72 20 7b   $::ones [expr {
10f0: 24 6e 2f 31 30 30 7d 5d 5d 20 68 75 6e 64 72 65  $n/100}]] hundre
1100: 64 22 0a 20 20 20 20 73 65 74 20 6e 20 5b 65 78  d".    set n [ex
1110: 70 72 20 7b 24 6e 25 31 30 30 7d 5d 0a 20 20 7d  pr {$n%100}].  }
1120: 0a 20 20 69 66 20 7b 24 6e 3e 3d 32 30 7d 20 7b  .  if {$n>=20} {
1130: 0a 20 20 20 20 61 70 70 65 6e 64 20 74 78 74 20  .    append txt 
1140: 22 20 5b 6c 69 6e 64 65 78 20 24 3a 3a 74 65 6e  " [lindex $::ten
1150: 73 20 5b 65 78 70 72 20 7b 24 6e 2f 31 30 7d 5d  s [expr {$n/10}]
1160: 5d 22 0a 20 20 20 20 73 65 74 20 6e 20 5b 65 78  ]".    set n [ex
1170: 70 72 20 7b 24 6e 25 31 30 7d 5d 0a 20 20 7d 0a  pr {$n%10}].  }.
1180: 20 20 69 66 20 7b 24 6e 3e 30 7d 20 7b 0a 20 20    if {$n>0} {.  
1190: 20 20 61 70 70 65 6e 64 20 74 78 74 20 22 20 5b    append txt " [
11a0: 6c 69 6e 64 65 78 20 24 3a 3a 6f 6e 65 73 20 24  lindex $::ones $
11b0: 6e 5d 22 0a 20 20 7d 0a 20 20 73 65 74 20 74 78  n]".  }.  set tx
11c0: 74 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24  t [string trim $
11d0: 74 78 74 5d 0a 20 20 69 66 20 7b 24 74 78 74 3d  txt].  if {$txt=
11e0: 3d 22 22 7d 20 7b 73 65 74 20 74 78 74 20 7a 65  =""} {set txt ze
11f0: 72 6f 7d 0a 20 20 72 65 74 75 72 6e 20 24 74 78  ro}.  return $tx
1200: 74 0a 7d 0a                                      t.}.