SQLite

Check-in [f3c4aa97d8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More work on the Tcl interface and tests for the sqlite3_trace_v2() API.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sqlite3_trace_v2
Files: files | file ages | folders
SHA1: f3c4aa97d8c10fdb69efc6405b5fa45781f45a61
User & Date: mistachkin 2016-07-14 23:17:03.656
Context
2016-07-15
00:07
Add tests, including some for the sqlite3_expanded_sql() API. (check-in: 8b8c0b749a user: mistachkin tags: sqlite3_trace_v2)
2016-07-14
23:17
More work on the Tcl interface and tests for the sqlite3_trace_v2() API. (check-in: f3c4aa97d8 user: mistachkin tags: sqlite3_trace_v2)
21:26
Initial work on the Tcl API interface to the new sqlite3_trace_v2() function. (check-in: 7b59fa40a0 user: mistachkin tags: sqlite3_trace_v2)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/tclsqlite.c.
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944

2945





















2946





2947
2948
2949









2950
2951
2952
2953
2954
2955
2956
2957
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zTraceV2 ){
        Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
      }
    }else{
      Tcl_WideInt wMask;
      char *zTraceV2;
      int len;

      if( objc==4 ){





















        if( TCL_OK!=Tcl_GetWideIntFromObj(interp, objv[3], &wMask) ){





          return TCL_ERROR;
        }
      }else{









        wMask = SQLITE_TRACE_STMT;
      }
      if( pDb->zTraceV2 ){
        Tcl_Free(pDb->zTraceV2);
      }
      zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
      if( zTraceV2 && len>0 ){
        pDb->zTraceV2 = Tcl_Alloc( len + 1 );







<


>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
|







2935
2936
2937
2938
2939
2940
2941

2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zTraceV2 ){
        Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
      }
    }else{

      char *zTraceV2;
      int len;
      Tcl_WideInt wMask = 0;
      if( objc==4 ){
        static const char *TTYPE_strs[] = {
          "statement", "profile", "row", "close", 0
        };
        enum TTYPE_enum {
          TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
        };
        int i;
        if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
          return TCL_ERROR;
        }
        for(i=0; i<len; i++){
          Tcl_Obj *pObj;
          int ttype;
          if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
            return TCL_ERROR;
          }
          if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
                                  0, &ttype)!=TCL_OK ){
            Tcl_WideInt wType;
            Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
            Tcl_IncrRefCount(pError);
            if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
              Tcl_DecrRefCount(pError);
              wMask |= wType;
            }else{
              Tcl_SetObjResult(interp, pError);
              Tcl_DecrRefCount(pError);
              return TCL_ERROR;
            }
          }else{
            switch( (enum TTYPE_enum)ttype ){
              case TTYPE_STMT:    wMask |= SQLITE_TRACE_STMT;    break;
              case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
              case TTYPE_ROW:     wMask |= SQLITE_TRACE_ROW;     break;
              case TTYPE_CLOSE:   wMask |= SQLITE_TRACE_CLOSE;   break;
            }
          }
        }
      }else{
        wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
      }
      if( pDb->zTraceV2 ){
        Tcl_Free(pDb->zTraceV2);
      }
      zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
      if( zTraceV2 && len>0 ){
        pDb->zTraceV2 = Tcl_Alloc( len + 1 );
Added test/trace3.test.
























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 2016 July 14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus
# of this test file is the "sqlite3_trace_v2()" API.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !trace { finish_test ; return }
set ::testprefix trace3

proc trace_v2_error { args } {
  lappend ::stmtlist(error) [string trim $args]
  error "trace error"; # this will be ignored.
}
proc trace_v2_record { args } {
  lappend ::stmtlist(record) [string trim $args]
}
proc trace_v2_nop { args } {}; # do nothing.

do_test trace3-1.0 {
  execsql {
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,NULL);
    INSERT INTO t1 VALUES(2,-1);
    INSERT INTO t1 VALUES(3,0);
    INSERT INTO t1 VALUES(4,1);
    INSERT INTO t1 VALUES(5,-2147483648);
    INSERT INTO t1 VALUES(6,2147483647);
    INSERT INTO t1 VALUES(7,-9223372036854775808);
    INSERT INTO t1 VALUES(8,9223372036854775807);
    INSERT INTO t1 VALUES(9,-1.0);
    INSERT INTO t1 VALUES(10,0.0);
    INSERT INTO t1 VALUES(11,1.0);
    INSERT INTO t1 VALUES(12,'');
    INSERT INTO t1 VALUES(13,'1');
    INSERT INTO t1 VALUES(14,'one');
    INSERT INTO t1 VALUES(15,x'abcd0123');
    INSERT INTO t1 VALUES(16,x'4567cdef');
  }
} {}

do_test trace3-1.1 {
  set rc [catch {db trace_v2 1 2 3} msg]
  lappend rc $msg
} {1 {wrong # args: should be "db trace_v2 ?CALLBACK? ?MASK?"}}
do_test trace3-1.2 {
  set rc [catch {db trace_v2 1 bad} msg]
  lappend rc $msg
} {1 {bad trace type "bad": must be statement, profile, row, or close}}

do_test trace3-2.1 {
  db trace_v2 trace_v2_nop
  db trace_v2
} {trace_v2_nop}

do_test trace3-3.1 {
  unset -nocomplain ::stmtlist
  db trace_v2 trace_v2_nop
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  array get ::stmtlist
} {}
do_test trace3-3.2 {
  set ::stmtlist(error) {}
  db trace_v2 trace_v2_error
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  set ::stmtlist(error)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}
do_test trace3-3.3 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  set ::stmtlist(record)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}

do_test trace3-4.1 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record profile
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  set ::stmtlist(record)
} {/^\{-?\d+ -?\d+\}$/}

do_test trace3-5.1 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record row
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  set ::stmtlist(record)
} "/^[string trim [string repeat {\d+ } 16]]\$/"

do_test trace3-6.1 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record {profile row}
  execsql {
    SELECT a, b FROM t1 ORDER BY a;
  }
  set ::stmtlist(record)
} "/^[string trim [string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/"

do_test trace3-7.1 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record close
  db close
  set ::stmtlist(record)
} {/^-?\d+$/}

finish_test