modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/session/session5.test (about)

     1  # 2011 April 13
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     6  #    May you do good and not evil.
     7  #    May you find forgiveness for yourself and forgive others.
     8  #    May you share freely, never taking more than you give.
     9  #
    10  #***********************************************************************
    11  # This file implements regression tests for the session module. 
    12  # Specifically, for the sqlite3changeset_concat() command.
    13  # 
    14  
    15  if {![info exists testdir]} {
    16    set testdir [file join [file dirname [info script]] .. .. test]
    17  } 
    18  source [file join [file dirname [info script]] session_common.tcl]
    19  source $testdir/tester.tcl
    20  ifcapable !session {finish_test; return}
    21  
    22  set testprefix session5
    23  
    24  # Organization of tests:
    25  #
    26  #   session5-1.*: Simple tests to check the concat() function produces 
    27  #                 correct results.
    28  #
    29  #   session5-2.*: More complicated tests.
    30  #   
    31  #   session5-3.*: Schema mismatch errors.
    32  #
    33  #   session5-4.*: Test the concat cases that indicate that the database
    34  #                 was modified in between recording of the two changesets
    35  #                 being concatenated (i.e. two changesets that INSERT rows
    36  #                 with the same PK values).
    37  #
    38  
    39  proc do_concat_test {tn args} {
    40  
    41    set subtest 0
    42    foreach sql $args {
    43      incr subtest
    44      sqlite3session S db main ; S attach *
    45      execsql $sql
    46  
    47      set c [S changeset]
    48      if {[info commands s_prev] != ""} {
    49        set c_concat [sqlite3changeset_concat $c_prev $c]
    50        set c_two [s_prev changeset]
    51        s_prev delete
    52  
    53        set h_concat [changeset_to_list $c_concat]
    54        set h_two [changeset_to_list $c_two]
    55  
    56        do_test $tn.$subtest [list set {} $h_concat] $h_two
    57      }
    58      set c_prev $c
    59      rename S s_prev
    60    }
    61  
    62    catch { s_prev delete }
    63  }
    64  
    65  #-------------------------------------------------------------------------
    66  # Test cases session5-1.* - simple tests.
    67  #
    68  do_execsql_test 1.0 {
    69    CREATE TABLE t1(a PRIMARY KEY, b);
    70  }
    71  
    72  do_concat_test 1.1.1 {
    73    INSERT INTO t1 VALUES(1, 'one');
    74  } {
    75    INSERT INTO t1 VALUES(2, 'two');
    76  }
    77  
    78  do_concat_test 1.1.2 {
    79    UPDATE t1 SET b = 'five' WHERE a = 1;
    80  } {
    81    UPDATE t1 SET b = 'six' WHERE a = 2;
    82  }
    83  
    84  do_concat_test 1.1.3 {
    85    DELETE FROM t1 WHERE a = 1;
    86  } {
    87    DELETE FROM t1 WHERE a = 2;
    88  }
    89  
    90  
    91  # 1.2.1:    INSERT + DELETE                     -> (none)
    92  # 1.2.2:    INSERT + UPDATE                     -> INSERT
    93  #
    94  # 1.2.3:    DELETE + INSERT (matching data)     -> (none)
    95  # 1.2.4:    DELETE + INSERT (non-matching data) -> UPDATE
    96  #
    97  # 1.2.5:    UPDATE + UPDATE (matching data)     -> (none)
    98  # 1.2.6:    UPDATE + UPDATE (non-matching data) -> UPDATE
    99  # 1.2.7:    UPDATE + DELETE                     -> DELETE
   100  #
   101  do_concat_test 1.2.1 {
   102    INSERT INTO t1 VALUES('x', 'y');
   103  } {
   104    DELETE FROM t1 WHERE a = 'x';
   105  }
   106  do_concat_test 1.2.2 {
   107    INSERT INTO t1 VALUES(5.0, 'five');
   108  } {
   109    UPDATE t1 SET b = 'six' WHERE a = 5.0;
   110  }
   111  
   112  do_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')"
   113  do_concat_test 1.2.3.2 {
   114    DELETE FROM t1 WHERE a = 'I';
   115  } {
   116    INSERT INTO t1 VALUES('I', 'one');
   117  }
   118  do_concat_test 1.2.4 {
   119    DELETE FROM t1 WHERE a = 'I';
   120  } {
   121    INSERT INTO t1 VALUES('I', 'two');
   122  }
   123  do_concat_test 1.2.5 {
   124    UPDATE t1 SET b = 'five' WHERE a = 'I';
   125  } {
   126    UPDATE t1 SET b = 'two' WHERE a = 'I';
   127  }
   128  do_concat_test 1.2.6 {
   129    UPDATE t1 SET b = 'six' WHERE a = 'I';
   130  } {
   131    UPDATE t1 SET b = 'seven' WHERE a = 'I';
   132  }
   133  do_concat_test 1.2.7 {
   134    UPDATE t1 SET b = 'eight' WHERE a = 'I';
   135  } {
   136    DELETE FROM t1 WHERE a = 'I';
   137  }
   138  
   139  
   140  #-------------------------------------------------------------------------
   141  # Test cases session5-2.* - more complex tests.
   142  #
   143  db function indirect indirect 
   144  proc indirect {{x -1}} {
   145    S indirect $x
   146    s_prev indirect $x
   147  }
   148  do_concat_test 2.1 {
   149    CREATE TABLE abc(a, b, c PRIMARY KEY);
   150    INSERT INTO abc VALUES(NULL, NULL, 1);
   151    INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
   152  } {
   153    DELETE FROM abc WHERE c = 1;
   154    UPDATE abc SET c = 1 WHERE c = 2;
   155  } {
   156    INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
   157    INSERT INTO abc VALUES(1.0, 2.0, 3);
   158  } {
   159    UPDATE abc SET a = a-1;
   160  } {
   161    CREATE TABLE def(d, e, f, PRIMARY KEY(e, f));
   162    INSERT INTO def VALUES('x', randomblob(11000), 67);
   163    INSERT INTO def SELECT d, e, f+1 FROM def;
   164    INSERT INTO def SELECT d, e, f+2 FROM def;
   165    INSERT INTO def SELECT d, e, f+4 FROM def;
   166  } {
   167    DELETE FROM def WHERE rowid>4;
   168  } { 
   169    INSERT INTO def SELECT d, e, f+4 FROM def; 
   170  } {
   171    INSERT INTO abc VALUES(22, 44, -1);
   172  } { 
   173    UPDATE abc SET c=-2 WHERE c=-1;
   174    UPDATE abc SET c=-3 WHERE c=-2;
   175  } {
   176    UPDATE abc SET c=-4 WHERE c=-3;
   177  } {
   178    UPDATE abc SET a=a+1 WHERE c=-3;
   179    UPDATE abc SET a=a+1 WHERE c=-3;
   180  } {
   181    UPDATE abc SET a=a+1 WHERE c=-3;
   182    UPDATE abc SET a=a+1 WHERE c=-3;
   183  } {
   184    INSERT INTO abc VALUES('one', 'two', 'three');
   185  } {
   186    SELECT indirect(1);
   187    UPDATE abc SET a='one point five' WHERE c = 'three';
   188  } {
   189    SELECT indirect(0);
   190    UPDATE abc SET a='one point six' WHERE c = 'three';
   191  } {
   192    CREATE TABLE x1(a, b, PRIMARY KEY(a));
   193    SELECT indirect(1);
   194    INSERT INTO x1 VALUES(1, 2);
   195  } {
   196    SELECT indirect(1);
   197    UPDATE x1 SET b = 3 WHERE a = 1;
   198  }
   199  
   200  catch {db close}
   201  forcedelete test.db
   202  sqlite3 db test.db
   203  do_concat_test 2.2 {
   204    CREATE TABLE t1(a, b, PRIMARY KEY(b));
   205    CREATE TABLE t2(a PRIMARY KEY, b);
   206    INSERT INTO t1 VALUES('string', 1);
   207    INSERT INTO t1 VALUES(4, 2);
   208    INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
   209  } {
   210    INSERT INTO t2 VALUES('one', 'two');
   211    INSERT INTO t2 VALUES(1, NULL);
   212    UPDATE t1 SET a = 5 WHERE a = 2;
   213  } {
   214    DELETE FROM t2 WHERE a = 1;
   215    UPDATE t1 SET a = 4 WHERE a = 2;
   216    INSERT INTO t2 VALUES('x', 'y');
   217  }
   218  
   219  do_test 2.3.0 {
   220    catch {db close}
   221    forcedelete test.db
   222    sqlite3 db test.db
   223   
   224    set sql1 ""
   225    set sql2 ""
   226    for {set i 1} {$i < 120} {incr i} {
   227      append sql1 "INSERT INTO x1 VALUES($i*4, $i);"
   228    }
   229    for {set i 1} {$i < 120} {incr i} {
   230      append sql2 "DELETE FROM x1 WHERE a = $i*4;"
   231    }
   232    set {} {}
   233  } {}
   234  do_concat_test 2.3 {
   235    CREATE TABLE x1(a PRIMARY KEY, b)
   236  } $sql1 $sql2 $sql1 $sql2
   237  
   238  do_concat_test 2.4 {
   239    CREATE TABLE x2(a PRIMARY KEY, b);
   240    CREATE TABLE x3(a PRIMARY KEY, b);
   241  
   242    INSERT INTO x2 VALUES('a', 'b');
   243    INSERT INTO x2 VALUES('x', 'y');
   244    INSERT INTO x3 VALUES('a', 'b');
   245  } {
   246    INSERT INTO x2 VALUES('c', 'd');
   247    INSERT INTO x3 VALUES('e', 'f');
   248    INSERT INTO x3 VALUES('x', 'y');
   249  }
   250  
   251  do_concat_test 2.5 {
   252    UPDATE x3 SET b = 'Y' WHERE a = 'x'
   253  } {
   254    DELETE FROM x3 WHERE a = 'x'
   255  } {
   256    DELETE FROM x2 WHERE a = 'a'
   257  } {
   258    INSERT INTO x2 VALUES('a', 'B');
   259  }
   260  
   261  for {set k 1} {$k <=10} {incr k} {
   262    do_test 2.6.$k.1 {
   263      drop_all_tables
   264      set sql1 ""
   265      set sql2 ""
   266      for {set i 1} {$i < 120} {incr i} {
   267        append sql1 "INSERT INTO x1 VALUES(randomblob(20+(random()%10)), $i);"
   268      }
   269      for {set i 1} {$i < 120} {incr i} {
   270        append sql2 "DELETE FROM x1 WHERE rowid = $i;"
   271      }
   272      set {} {}
   273    } {}
   274    do_concat_test 2.6.$k {
   275      CREATE TABLE x1(a PRIMARY KEY, b)
   276    } $sql1 $sql2 $sql1 $sql2
   277  }
   278  
   279  for {set k 1} {$k <=10} {incr k} {
   280    do_test 2.7.$k.1 {
   281      drop_all_tables
   282      set sql1 ""
   283      set sql2 ""
   284      for {set i 1} {$i < 120} {incr i} {
   285        append sql1 {
   286          INSERT INTO x1 VALUES(
   287           CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END,
   288           CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END
   289          );
   290        }
   291      }
   292      for {set i 1} {$i < 120} {incr i} {
   293        append sql2 "DELETE FROM x1 WHERE rowid = $i;"
   294      }
   295      set {} {}
   296    } {}
   297    do_concat_test 2.7.$k {
   298      CREATE TABLE x1(a PRIMARY KEY, b)
   299    } $sql1 $sql2 $sql1 $sql2
   300  }
   301  
   302  
   303  #-------------------------------------------------------------------------
   304  # Test that schema incompatibilities are detected correctly.
   305  #
   306  #   session5-3.1: Incompatible number of columns.
   307  #   session5-3.2: Incompatible PK definition.
   308  #
   309  
   310  do_test 3.1 {
   311    db close
   312    forcedelete test.db
   313    sqlite3 db test.db
   314  
   315    execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
   316    set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
   317    execsql { 
   318      DROP TABLE t1;
   319      CREATE TABLE t1(a PRIMARY KEY, b, c);
   320    }
   321    set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }]
   322  
   323    list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
   324  } {1 SQLITE_SCHEMA}
   325  
   326  do_test 3.2 {
   327    db close
   328    forcedelete test.db
   329    sqlite3 db test.db
   330  
   331    execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
   332    set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
   333    execsql { 
   334      DROP TABLE t1;
   335      CREATE TABLE t1(a, b PRIMARY KEY);
   336    }
   337    set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }]
   338  
   339    list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
   340  } {1 SQLITE_SCHEMA}
   341  
   342  #-------------------------------------------------------------------------
   343  # Test that concat() handles these properly:
   344  #
   345  #   session5-4.1: INSERT + INSERT
   346  #   session5-4.2: UPDATE + INSERT
   347  #   session5-4.3: DELETE + UPDATE
   348  #   session5-4.4: DELETE + DELETE
   349  #
   350  
   351  proc do_concat_test2 {tn sql1 sqlX sql2 expected} {
   352    sqlite3session S db main ; S attach *
   353    execsql $sql1
   354    set ::c1 [S changeset]
   355    S delete
   356  
   357    execsql $sqlX
   358  
   359    sqlite3session S db main ; S attach *
   360    execsql $sql2
   361    set ::c2 [S changeset]
   362    S delete
   363  
   364    uplevel do_test $tn [list {
   365      changeset_to_list [sqlite3changeset_concat $::c1 $::c2]
   366    }] [list [normalize_list $expected]]
   367  }
   368  
   369  drop_all_tables db
   370  do_concat_test2 4.1 {
   371    CREATE TABLE t1(a PRIMARY KEY, b);
   372    INSERT INTO t1 VALUES('key', 'value');
   373  } {
   374    DELETE FROM t1 WHERE a = 'key';
   375  } {
   376    INSERT INTO t1 VALUES('key', 'xxx');
   377  } {
   378    {INSERT t1 0 X. {} {t key t value}}
   379  }
   380  do_concat_test2 4.2 {
   381    UPDATE t1 SET b = 'yyy';
   382  } {
   383    DELETE FROM t1 WHERE a = 'key';
   384  } {
   385    INSERT INTO t1 VALUES('key', 'value');
   386  } {
   387    {UPDATE t1 0 X. {t key t xxx} {{} {} t yyy}}
   388  }
   389  do_concat_test2 4.3 {
   390    DELETE FROM t1 WHERE a = 'key';
   391  } {
   392    INSERT INTO t1 VALUES('key', 'www');
   393  } {
   394    UPDATE t1 SET b = 'valueX' WHERE a = 'key';
   395  } {
   396    {DELETE t1 0 X. {t key t value} {}}
   397  }
   398  do_concat_test2 4.4 {
   399    DELETE FROM t1 WHERE a = 'key';
   400  } {
   401    INSERT INTO t1 VALUES('key', 'ttt');
   402  } {
   403    DELETE FROM t1 WHERE a = 'key';
   404  } {
   405    {DELETE t1 0 X. {t key t valueX} {}}
   406  }
   407  
   408  finish_test