Fossil

Check-in [8260fdc9]
Login

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

Overview
Comment:Refactored th1 query API col_xxx and bind_xxx to (col xxx) and (bind xxx).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | th1-query-api
Files: files | file ages | folders
SHA1: 8260fdc99a96478aef82695cbfc285c697f243fa
User & Date: stephan 2012-07-14 20:59:11.718
Context
2012-07-14
21:13
Refactored th1 argv_xxx to (argv xxx). Added th1_argv.wiki doc. ... (check-in: 615ee717 user: stephan tags: th1-query-api)
20:59
Refactored th1 query API col_xxx and bind_xxx to (col xxx) and (bind xxx). ... (check-in: 8260fdc9 user: stephan tags: th1-query-api)
20:45
Refactored th1 query API to use (query foo) instead of query_foo. Added th1_query.wiki doc page. ... (check-in: bd98f0f4 user: stephan tags: th1-query-api)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/th_main.c.
1322
1323
1324
1325
1326
1327
1328






































1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
  rc = sqlite3_bind_double( pStmt, index, val );
  if(rc){
    return queryReportDbErr( interp );
  }
  Th_SetResultInt( interp, 0 );
  return TH_OK;
}







































static int queryTopLevelCmd(
  Th_Interp *interp,
  void *ctx, 
  int argc, 
  const char **argv, 
  int *argl
){
  static Th_SubCommand aSub[] = {
    {"bind_int",    queryBindIntCmd},
    {"bind_double", queryBindDoubleCmd},
    {"bind_null",   queryBindNullCmd},
    {"bind_string", queryBindStringCmd},
    {"col_count",   queryColCountCmd},
    {"col_double",  queryColDoubleCmd},
    {"col_int",     queryColIntCmd},
    {"col_is_null", queryColIsNullCmd},
    {"col_name",    queryColNameCmd},
    {"col_string",  queryColStringCmd},
    {"col_type",    queryColTypeCmd},
    {"step",        queryStepCmd},
    {"finalize",    queryFinalizeCmd},
    {"prepare",     queryPrepareCmd},
    {0, 0}
  };
  Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
<
<
<
<
<
<
<
<
<
|







1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376









1377
1378
1379
1380
1381
1382
1383
1384
  rc = sqlite3_bind_double( pStmt, index, val );
  if(rc){
    return queryReportDbErr( interp );
  }
  Th_SetResultInt( interp, 0 );
  return TH_OK;
}

static int queryBindTopLevelCmd(
  Th_Interp *interp,
  void *ctx, 
  int argc, 
  const char **argv, 
  int *argl
){
  static Th_SubCommand aSub[] = {
    {"int",    queryBindIntCmd},
    {"double", queryBindDoubleCmd},
    {"null",   queryBindNullCmd},
    {"string", queryBindStringCmd},
    {0, 0}
  };
  Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
}

static int queryColTopLevelCmd(
  Th_Interp *interp,
  void *ctx, 
  int argc, 
  const char **argv, 
  int *argl
){
  static Th_SubCommand aSub[] = {
    {"count",   queryColCountCmd},
    {"is_null", queryColIsNullCmd},
    {"name",    queryColNameCmd},
    {"double",  queryColDoubleCmd},
    {"int",     queryColIntCmd},
    {"string",  queryColStringCmd},
    {"type",    queryColTypeCmd},
    {0, 0}
  };
  Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
}


static int queryTopLevelCmd(
  Th_Interp *interp,
  void *ctx, 
  int argc, 
  const char **argv, 
  int *argl
){
  static Th_SubCommand aSub[] = {
    {"bind",        queryBindTopLevelCmd},









    {"col",         queryColTopLevelCmd},
    {"step",        queryStepCmd},
    {"finalize",    queryFinalizeCmd},
    {"prepare",     queryPrepareCmd},
    {0, 0}
  };
  Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
}
Changes to test/th1-query-api-1.th1.
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
proc xyz {} {
        return 42
}
set a [xyz]
puts "a=${a}" ! \n

set stmt [query prepare {SELECT login, cap FROM user}]
set colCount [query col_count $stmt]
puts "query column count: ${colCount}\n"
puts "stmt id=${stmt}\n"

proc noop {} {}
proc incr {name {step 1}} {
    upvar $name x
    set x [expr $x+$step]
}


set sep "    "
set i 0
set colNames(0) 0
for {set i 0} {$i < $colCount} {incr i} {
    set colNames($i) [query col_name $stmt $i]
    puts "colNames($i)=" $colNames($i) "\n"
}

for {set row 0} {0 < [query step $stmt]} {incr row} {
    for {set i 0} {$i < $colCount} {incr i} {
        if {$i > 0} {
            puts $sep
        } else {
            puts "#$row: $sep"
        }
        puts $colNames($i) = [query col_string $stmt $i]
    }
    puts "\n"
}
unset row

query finalize $stmt


proc query_step_each {{stmt} {callback}} {
    set colNames(0) 0
    set colCount [query col_count $stmt]
    for {set i 0} {$i < $colCount} {incr i} {
        set colNames($i) [query col_name $stmt $i]
    }
    upvar cb $callback
    for {set row 0} {0 < [query step $stmt]} {incr row} {
        #puts "Calling callback: $stmt $colCount colNames\n"
        $callback $stmt $colCount
    }
}

set sql {SELECT uid, login FROM user WHERE uid!=?}
#set sql {SELECT uid, login FROM user WHERE login=?}
#set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
set stmt [query prepare $sql]
puts "stmt ID=" $stmt "\n"
query bind_int $stmt 1 3
#set stmt [query prepare $sql]
#query bind_string $stmt 1 stephan
#set stmt [query prepare $sql]
#query bind_null $stmt 1
set rc 0
puts "USER LIST:\n"
catch {
    proc my_each {stmt colCount} {
        upvar 2 sep sep
        puts [query col_int $stmt 0] " (type=" [query col_type $stmt 0] ")" $sep
        puts [query col_double $stmt 0] $sep
        puts [query col_string $stmt 1]  " (type=" [query col_type $stmt 1] ")" $sep
        puts "isnull 0 ?= " [query col_is_null $stmt 0] $sep
        puts "isnull 2 ?= " [query col_is_null $stmt 2]
#        for {set i 0} {$i < $colCount} {incr i} {
#            if {$i > 0} { puts $sep }
#        }
        puts "\n"
#        error "hi!"
    }
    query step_each $stmt my_each







|














|










|










|

|













|

|

|





|
|
|
|
|







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
proc xyz {} {
        return 42
}
set a [xyz]
puts "a=${a}" ! \n

set stmt [query prepare {SELECT login, cap FROM user}]
set colCount [query col count $stmt]
puts "query column count: ${colCount}\n"
puts "stmt id=${stmt}\n"

proc noop {} {}
proc incr {name {step 1}} {
    upvar $name x
    set x [expr $x+$step]
}


set sep "    "
set i 0
set colNames(0) 0
for {set i 0} {$i < $colCount} {incr i} {
    set colNames($i) [query col name $stmt $i]
    puts "colNames($i)=" $colNames($i) "\n"
}

for {set row 0} {0 < [query step $stmt]} {incr row} {
    for {set i 0} {$i < $colCount} {incr i} {
        if {$i > 0} {
            puts $sep
        } else {
            puts "#$row: $sep"
        }
        puts $colNames($i) = [query col string $stmt $i]
    }
    puts "\n"
}
unset row

query finalize $stmt


proc query_step_each {{stmt} {callback}} {
    set colNames(0) 0
    set colCount [query col count $stmt]
    for {set i 0} {$i < $colCount} {incr i} {
        set colNames($i) [query col name $stmt $i]
    }
    upvar cb $callback
    for {set row 0} {0 < [query step $stmt]} {incr row} {
        #puts "Calling callback: $stmt $colCount colNames\n"
        $callback $stmt $colCount
    }
}

set sql {SELECT uid, login FROM user WHERE uid!=?}
#set sql {SELECT uid, login FROM user WHERE login=?}
#set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
set stmt [query prepare $sql]
puts "stmt ID=" $stmt "\n"
query bind int $stmt 1 3
#set stmt [query prepare $sql]
#query bind string $stmt 1 stephan
#set stmt [query prepare $sql]
#query bind null $stmt 1
set rc 0
puts "USER LIST:\n"
catch {
    proc my_each {stmt colCount} {
        upvar 2 sep sep
        puts [query col int $stmt 0] " (type=" [query col type $stmt 0] ")" $sep
        puts [query col double $stmt 0] $sep
        puts [query col string $stmt 1]  " (type=" [query col type $stmt 1] ")" $sep
        puts "isnull 0 ?= " [query col is_null $stmt 0] $sep
        puts "isnull 2 ?= " [query col is_null $stmt 2]
#        for {set i 0} {$i < $colCount} {incr i} {
#            if {$i > 0} { puts $sep }
#        }
        puts "\n"
#        error "hi!"
    }
    query step_each $stmt my_each
Changes to www/th1_query.wiki.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<h1>TH1 "query" API</h1>

The "query" API provides limited access to the fossil database.
It restricts usage to queries which return result columns (i.e.
<tt>SELECT</tt> and friends).
Example usage:

<nowiki><pre>
&lt;th1>
catch {
    set stmt [query prepare "SELECT login, cap FROM user"]
    puts "stmt ID=$stmt\n"
    for {} {0 < [query step $stmt]} {} {
        puts [query col_string $stmt 0] ": " [query col_string $stmt 1] "\n"
    }
    query finalize $stmt
    return 0
} rc
if {0 != $rc} {
    puts "ERROR: $rc\n"
}













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<h1>TH1 "query" API</h1>

The "query" API provides limited access to the fossil database.
It restricts usage to queries which return result columns (i.e.
<tt>SELECT</tt> and friends).
Example usage:

<nowiki><pre>
&lt;th1>
catch {
    set stmt [query prepare "SELECT login, cap FROM user"]
    puts "stmt ID=$stmt\n"
    for {} {0 < [query step $stmt]} {} {
        puts [query col string $stmt 0] ": " [query col string $stmt 1] "\n"
    }
    query finalize $stmt
    return 0
} rc
if {0 != $rc} {
    puts "ERROR: $rc\n"
}
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

This subcommand steps the result set by one row. It returns 0
at the end of the set, a positive value if a new row is available,
and throws for any other condition.

<nowiki><pre>
for {} {0 &lt; [query step $stmt]} {} {
   puts [query col_string $stmt 0] "\n"
}
</pre></nowiki>


<h2>bind_xxx</h2>

The <tt>bind_xxx</tt> family of subcommands attach values to queries
before stepping through them. The subcommands include:

   *  <tt>bind_int StmtId Index Value</tt>
   *  <tt>bind_double StmtId Index Value</tt>
   *  <tt>bind_null StmtId Index</tt>
   *  <tt>bind_string StmtId Index Value</tt>

Achtung: the bind API uses 1-based indexes, just like SQL does.

TODO: split bind_xxx into "bind xxx".

<nowiki><pre>
set stmt [query prepare "SELECT ... WHERE user=?"]
query bind_int $stmt 1 drh
if {0 &lt; [query step $stmt]} {
   puts [query col_string $stmt 0] "\n"
}
query finalize $stmt
</pre></nowiki>


<h2>col_xxx</h2>

The <tt>col_xxx</tt> familys of subcommands are for fetching
values and metadata from result rows.

   *  <tt>col_count StmtId</tt> Returns the number of result columns in the statement.
   *  <tt>col_is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
   *  <tt>col_double StmtId Index</tt>
   *  <tt>col_int StmtId Index</tt>
   *  <tt>col_string StmtId Index</tt>
   *  <tt>col_type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.

TODO: split col_xxx into "col xxx".

Achtung: the col API uses 0-based indexes, just like SQL does.







|




|

|


|
|
|
|



<
<




|





|

|


|
|
|
|
|
|

<
<

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

This subcommand steps the result set by one row. It returns 0
at the end of the set, a positive value if a new row is available,
and throws for any other condition.

<nowiki><pre>
for {} {0 &lt; [query step $stmt]} {} {
   puts [query col string $stmt 0] "\n"
}
</pre></nowiki>


<h2>bind xxx</h2>

The <tt>bind xxx</tt> family of subcommands attach values to queries
before stepping through them. The subcommands include:

   *  <tt>bind int StmtId Index Value</tt>
   *  <tt>bind double StmtId Index Value</tt>
   *  <tt>bind null StmtId Index</tt>
   *  <tt>bind string StmtId Index Value</tt>

Achtung: the bind API uses 1-based indexes, just like SQL does.



<nowiki><pre>
set stmt [query prepare "SELECT ... WHERE user=?"]
query bind_int $stmt 1 drh
if {0 &lt; [query step $stmt]} {
   puts [query col string $stmt 0] "\n"
}
query finalize $stmt
</pre></nowiki>


<h2>col xxx</h2>

The <tt>col xxx</tt> familys of subcommands are for fetching
values and metadata from result rows.

   *  <tt>col count StmtId</tt> Returns the number of result columns in the statement.
   *  <tt>col is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
   *  <tt>col double StmtId Index</tt>
   *  <tt>col int StmtId Index</tt>
   *  <tt>col string StmtId Index</tt>
   *  <tt>col type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.



Achtung: the col API uses 0-based indexes, just like SQL does.