Fossil SCM

Refactored th1 query API col_xxx and bind_xxx to (col xxx) and (bind xxx).

stephan 2012-07-14 20:59 th1-query-api
Commit 8260fdc99a96478aef82695cbfc285c697f243fa
+40 -11
--- src/th_main.c
+++ src/th_main.c
@@ -1324,30 +1324,59 @@
13241324
return queryReportDbErr( interp );
13251325
}
13261326
Th_SetResultInt( interp, 0 );
13271327
return TH_OK;
13281328
}
1329
+
1330
+static int queryBindTopLevelCmd(
1331
+ Th_Interp *interp,
1332
+ void *ctx,
1333
+ int argc,
1334
+ const char **argv,
1335
+ int *argl
1336
+){
1337
+ static Th_SubCommand aSub[] = {
1338
+ {"int", queryBindIntCmd},
1339
+ {"double", queryBindDoubleCmd},
1340
+ {"null", queryBindNullCmd},
1341
+ {"string", queryBindStringCmd},
1342
+ {0, 0}
1343
+ };
1344
+ Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
1345
+}
1346
+
1347
+static int queryColTopLevelCmd(
1348
+ Th_Interp *interp,
1349
+ void *ctx,
1350
+ int argc,
1351
+ const char **argv,
1352
+ int *argl
1353
+){
1354
+ static Th_SubCommand aSub[] = {
1355
+ {"count", queryColCountCmd},
1356
+ {"is_null", queryColIsNullCmd},
1357
+ {"name", queryColNameCmd},
1358
+ {"double", queryColDoubleCmd},
1359
+ {"int", queryColIntCmd},
1360
+ {"string", queryColStringCmd},
1361
+ {"type", queryColTypeCmd},
1362
+ {0, 0}
1363
+ };
1364
+ Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
1365
+}
1366
+
13291367
13301368
static int queryTopLevelCmd(
13311369
Th_Interp *interp,
13321370
void *ctx,
13331371
int argc,
13341372
const char **argv,
13351373
int *argl
13361374
){
13371375
static Th_SubCommand aSub[] = {
1338
- {"bind_int", queryBindIntCmd},
1339
- {"bind_double", queryBindDoubleCmd},
1340
- {"bind_null", queryBindNullCmd},
1341
- {"bind_string", queryBindStringCmd},
1342
- {"col_count", queryColCountCmd},
1343
- {"col_double", queryColDoubleCmd},
1344
- {"col_int", queryColIntCmd},
1345
- {"col_is_null", queryColIsNullCmd},
1346
- {"col_name", queryColNameCmd},
1347
- {"col_string", queryColStringCmd},
1348
- {"col_type", queryColTypeCmd},
1376
+ {"bind", queryBindTopLevelCmd},
1377
+ {"col", queryColTopLevelCmd},
13491378
{"step", queryStepCmd},
13501379
{"finalize", queryFinalizeCmd},
13511380
{"prepare", queryPrepareCmd},
13521381
{0, 0}
13531382
};
13541383
--- src/th_main.c
+++ src/th_main.c
@@ -1324,30 +1324,59 @@
1324 return queryReportDbErr( interp );
1325 }
1326 Th_SetResultInt( interp, 0 );
1327 return TH_OK;
1328 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1329
1330 static int queryTopLevelCmd(
1331 Th_Interp *interp,
1332 void *ctx,
1333 int argc,
1334 const char **argv,
1335 int *argl
1336 ){
1337 static Th_SubCommand aSub[] = {
1338 {"bind_int", queryBindIntCmd},
1339 {"bind_double", queryBindDoubleCmd},
1340 {"bind_null", queryBindNullCmd},
1341 {"bind_string", queryBindStringCmd},
1342 {"col_count", queryColCountCmd},
1343 {"col_double", queryColDoubleCmd},
1344 {"col_int", queryColIntCmd},
1345 {"col_is_null", queryColIsNullCmd},
1346 {"col_name", queryColNameCmd},
1347 {"col_string", queryColStringCmd},
1348 {"col_type", queryColTypeCmd},
1349 {"step", queryStepCmd},
1350 {"finalize", queryFinalizeCmd},
1351 {"prepare", queryPrepareCmd},
1352 {0, 0}
1353 };
1354
--- src/th_main.c
+++ src/th_main.c
@@ -1324,30 +1324,59 @@
1324 return queryReportDbErr( interp );
1325 }
1326 Th_SetResultInt( interp, 0 );
1327 return TH_OK;
1328 }
1329
1330 static int queryBindTopLevelCmd(
1331 Th_Interp *interp,
1332 void *ctx,
1333 int argc,
1334 const char **argv,
1335 int *argl
1336 ){
1337 static Th_SubCommand aSub[] = {
1338 {"int", queryBindIntCmd},
1339 {"double", queryBindDoubleCmd},
1340 {"null", queryBindNullCmd},
1341 {"string", queryBindStringCmd},
1342 {0, 0}
1343 };
1344 Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
1345 }
1346
1347 static int queryColTopLevelCmd(
1348 Th_Interp *interp,
1349 void *ctx,
1350 int argc,
1351 const char **argv,
1352 int *argl
1353 ){
1354 static Th_SubCommand aSub[] = {
1355 {"count", queryColCountCmd},
1356 {"is_null", queryColIsNullCmd},
1357 {"name", queryColNameCmd},
1358 {"double", queryColDoubleCmd},
1359 {"int", queryColIntCmd},
1360 {"string", queryColStringCmd},
1361 {"type", queryColTypeCmd},
1362 {0, 0}
1363 };
1364 Th_CallSubCommand2( interp, ctx, argc, argv, argl, aSub );
1365 }
1366
1367
1368 static int queryTopLevelCmd(
1369 Th_Interp *interp,
1370 void *ctx,
1371 int argc,
1372 const char **argv,
1373 int *argl
1374 ){
1375 static Th_SubCommand aSub[] = {
1376 {"bind", queryBindTopLevelCmd},
1377 {"col", queryColTopLevelCmd},
 
 
 
 
 
 
 
 
 
1378 {"step", queryStepCmd},
1379 {"finalize", queryFinalizeCmd},
1380 {"prepare", queryPrepareCmd},
1381 {0, 0}
1382 };
1383
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -23,11 +23,11 @@
2323
}
2424
set a [xyz]
2525
puts "a=${a}" ! \n
2626
2727
set stmt [query prepare {SELECT login, cap FROM user}]
28
-set colCount [query col_count $stmt]
28
+set colCount [query col count $stmt]
2929
puts "query column count: ${colCount}\n"
3030
puts "stmt id=${stmt}\n"
3131
3232
proc noop {} {}
3333
proc incr {name {step 1}} {
@@ -38,11 +38,11 @@
3838
3939
set sep " "
4040
set i 0
4141
set colNames(0) 0
4242
for {set i 0} {$i < $colCount} {incr i} {
43
- set colNames($i) [query col_name $stmt $i]
43
+ set colNames($i) [query col name $stmt $i]
4444
puts "colNames($i)=" $colNames($i) "\n"
4545
}
4646
4747
for {set row 0} {0 < [query step $stmt]} {incr row} {
4848
for {set i 0} {$i < $colCount} {incr i} {
@@ -49,11 +49,11 @@
4949
if {$i > 0} {
5050
puts $sep
5151
} else {
5252
puts "#$row: $sep"
5353
}
54
- puts $colNames($i) = [query col_string $stmt $i]
54
+ puts $colNames($i) = [query col string $stmt $i]
5555
}
5656
puts "\n"
5757
}
5858
unset row
5959
@@ -60,13 +60,13 @@
6060
query finalize $stmt
6161
6262
6363
proc query_step_each {{stmt} {callback}} {
6464
set colNames(0) 0
65
- set colCount [query col_count $stmt]
65
+ set colCount [query col count $stmt]
6666
for {set i 0} {$i < $colCount} {incr i} {
67
- set colNames($i) [query col_name $stmt $i]
67
+ set colNames($i) [query col name $stmt $i]
6868
}
6969
upvar cb $callback
7070
for {set row 0} {0 < [query step $stmt]} {incr row} {
7171
#puts "Calling callback: $stmt $colCount colNames\n"
7272
$callback $stmt $colCount
@@ -76,25 +76,25 @@
7676
set sql {SELECT uid, login FROM user WHERE uid!=?}
7777
#set sql {SELECT uid, login FROM user WHERE login=?}
7878
#set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
7979
set stmt [query prepare $sql]
8080
puts "stmt ID=" $stmt "\n"
81
-query bind_int $stmt 1 3
81
+query bind int $stmt 1 3
8282
#set stmt [query prepare $sql]
83
-#query bind_string $stmt 1 stephan
83
+#query bind string $stmt 1 stephan
8484
#set stmt [query prepare $sql]
85
-#query bind_null $stmt 1
85
+#query bind null $stmt 1
8686
set rc 0
8787
puts "USER LIST:\n"
8888
catch {
8989
proc my_each {stmt colCount} {
9090
upvar 2 sep sep
91
- puts [query col_int $stmt 0] " (type=" [query col_type $stmt 0] ")" $sep
92
- puts [query col_double $stmt 0] $sep
93
- puts [query col_string $stmt 1] " (type=" [query col_type $stmt 1] ")" $sep
94
- puts "isnull 0 ?= " [query col_is_null $stmt 0] $sep
95
- puts "isnull 2 ?= " [query col_is_null $stmt 2]
91
+ puts [query col int $stmt 0] " (type=" [query col type $stmt 0] ")" $sep
92
+ puts [query col double $stmt 0] $sep
93
+ puts [query col string $stmt 1] " (type=" [query col type $stmt 1] ")" $sep
94
+ puts "isnull 0 ?= " [query col is_null $stmt 0] $sep
95
+ puts "isnull 2 ?= " [query col is_null $stmt 2]
9696
# for {set i 0} {$i < $colCount} {incr i} {
9797
# if {$i > 0} { puts $sep }
9898
# }
9999
puts "\n"
100100
# error "hi!"
101101
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -23,11 +23,11 @@
23 }
24 set a [xyz]
25 puts "a=${a}" ! \n
26
27 set stmt [query prepare {SELECT login, cap FROM user}]
28 set colCount [query col_count $stmt]
29 puts "query column count: ${colCount}\n"
30 puts "stmt id=${stmt}\n"
31
32 proc noop {} {}
33 proc incr {name {step 1}} {
@@ -38,11 +38,11 @@
38
39 set sep " "
40 set i 0
41 set colNames(0) 0
42 for {set i 0} {$i < $colCount} {incr i} {
43 set colNames($i) [query col_name $stmt $i]
44 puts "colNames($i)=" $colNames($i) "\n"
45 }
46
47 for {set row 0} {0 < [query step $stmt]} {incr row} {
48 for {set i 0} {$i < $colCount} {incr i} {
@@ -49,11 +49,11 @@
49 if {$i > 0} {
50 puts $sep
51 } else {
52 puts "#$row: $sep"
53 }
54 puts $colNames($i) = [query col_string $stmt $i]
55 }
56 puts "\n"
57 }
58 unset row
59
@@ -60,13 +60,13 @@
60 query finalize $stmt
61
62
63 proc query_step_each {{stmt} {callback}} {
64 set colNames(0) 0
65 set colCount [query col_count $stmt]
66 for {set i 0} {$i < $colCount} {incr i} {
67 set colNames($i) [query col_name $stmt $i]
68 }
69 upvar cb $callback
70 for {set row 0} {0 < [query step $stmt]} {incr row} {
71 #puts "Calling callback: $stmt $colCount colNames\n"
72 $callback $stmt $colCount
@@ -76,25 +76,25 @@
76 set sql {SELECT uid, login FROM user WHERE uid!=?}
77 #set sql {SELECT uid, login FROM user WHERE login=?}
78 #set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
79 set stmt [query prepare $sql]
80 puts "stmt ID=" $stmt "\n"
81 query bind_int $stmt 1 3
82 #set stmt [query prepare $sql]
83 #query bind_string $stmt 1 stephan
84 #set stmt [query prepare $sql]
85 #query bind_null $stmt 1
86 set rc 0
87 puts "USER LIST:\n"
88 catch {
89 proc my_each {stmt colCount} {
90 upvar 2 sep sep
91 puts [query col_int $stmt 0] " (type=" [query col_type $stmt 0] ")" $sep
92 puts [query col_double $stmt 0] $sep
93 puts [query col_string $stmt 1] " (type=" [query col_type $stmt 1] ")" $sep
94 puts "isnull 0 ?= " [query col_is_null $stmt 0] $sep
95 puts "isnull 2 ?= " [query col_is_null $stmt 2]
96 # for {set i 0} {$i < $colCount} {incr i} {
97 # if {$i > 0} { puts $sep }
98 # }
99 puts "\n"
100 # error "hi!"
101
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -23,11 +23,11 @@
23 }
24 set a [xyz]
25 puts "a=${a}" ! \n
26
27 set stmt [query prepare {SELECT login, cap FROM user}]
28 set colCount [query col count $stmt]
29 puts "query column count: ${colCount}\n"
30 puts "stmt id=${stmt}\n"
31
32 proc noop {} {}
33 proc incr {name {step 1}} {
@@ -38,11 +38,11 @@
38
39 set sep " "
40 set i 0
41 set colNames(0) 0
42 for {set i 0} {$i < $colCount} {incr i} {
43 set colNames($i) [query col name $stmt $i]
44 puts "colNames($i)=" $colNames($i) "\n"
45 }
46
47 for {set row 0} {0 < [query step $stmt]} {incr row} {
48 for {set i 0} {$i < $colCount} {incr i} {
@@ -49,11 +49,11 @@
49 if {$i > 0} {
50 puts $sep
51 } else {
52 puts "#$row: $sep"
53 }
54 puts $colNames($i) = [query col string $stmt $i]
55 }
56 puts "\n"
57 }
58 unset row
59
@@ -60,13 +60,13 @@
60 query finalize $stmt
61
62
63 proc query_step_each {{stmt} {callback}} {
64 set colNames(0) 0
65 set colCount [query col count $stmt]
66 for {set i 0} {$i < $colCount} {incr i} {
67 set colNames($i) [query col name $stmt $i]
68 }
69 upvar cb $callback
70 for {set row 0} {0 < [query step $stmt]} {incr row} {
71 #puts "Calling callback: $stmt $colCount colNames\n"
72 $callback $stmt $colCount
@@ -76,25 +76,25 @@
76 set sql {SELECT uid, login FROM user WHERE uid!=?}
77 #set sql {SELECT uid, login FROM user WHERE login=?}
78 #set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
79 set stmt [query prepare $sql]
80 puts "stmt ID=" $stmt "\n"
81 query bind int $stmt 1 3
82 #set stmt [query prepare $sql]
83 #query bind string $stmt 1 stephan
84 #set stmt [query prepare $sql]
85 #query bind null $stmt 1
86 set rc 0
87 puts "USER LIST:\n"
88 catch {
89 proc my_each {stmt colCount} {
90 upvar 2 sep sep
91 puts [query col int $stmt 0] " (type=" [query col type $stmt 0] ")" $sep
92 puts [query col double $stmt 0] $sep
93 puts [query col string $stmt 1] " (type=" [query col type $stmt 1] ")" $sep
94 puts "isnull 0 ?= " [query col is_null $stmt 0] $sep
95 puts "isnull 2 ?= " [query col is_null $stmt 2]
96 # for {set i 0} {$i < $colCount} {incr i} {
97 # if {$i > 0} { puts $sep }
98 # }
99 puts "\n"
100 # error "hi!"
101
+17 -21
--- www/th1_query.wiki
+++ www/th1_query.wiki
@@ -9,11 +9,11 @@
99
&lt;th1>
1010
catch {
1111
set stmt [query prepare "SELECT login, cap FROM user"]
1212
puts "stmt ID=$stmt\n"
1313
for {} {0 < [query step $stmt]} {} {
14
- puts [query col_string $stmt 0] ": " [query col_string $stmt 1] "\n"
14
+ puts [query col string $stmt 0] ": " [query col string $stmt 1] "\n"
1515
}
1616
query finalize $stmt
1717
return 0
1818
} rc
1919
if {0 != $rc} {
@@ -50,49 +50,45 @@
5050
at the end of the set, a positive value if a new row is available,
5151
and throws for any other condition.
5252
5353
<nowiki><pre>
5454
for {} {0 &lt; [query step $stmt]} {} {
55
- puts [query col_string $stmt 0] "\n"
55
+ puts [query col string $stmt 0] "\n"
5656
}
5757
</pre></nowiki>
5858
5959
60
-<h2>bind_xxx</h2>
60
+<h2>bind xxx</h2>
6161
62
-The <tt>bind_xxx</tt> family of subcommands attach values to queries
62
+The <tt>bind xxx</tt> family of subcommands attach values to queries
6363
before stepping through them. The subcommands include:
6464
65
- * <tt>bind_int StmtId Index Value</tt>
66
- * <tt>bind_double StmtId Index Value</tt>
67
- * <tt>bind_null StmtId Index</tt>
68
- * <tt>bind_string StmtId Index Value</tt>
65
+ * <tt>bind int StmtId Index Value</tt>
66
+ * <tt>bind double StmtId Index Value</tt>
67
+ * <tt>bind null StmtId Index</tt>
68
+ * <tt>bind string StmtId Index Value</tt>
6969
7070
Achtung: the bind API uses 1-based indexes, just like SQL does.
7171
72
-TODO: split bind_xxx into "bind xxx".
73
-
7472
<nowiki><pre>
7573
set stmt [query prepare "SELECT ... WHERE user=?"]
7674
query bind_int $stmt 1 drh
7775
if {0 &lt; [query step $stmt]} {
78
- puts [query col_string $stmt 0] "\n"
76
+ puts [query col string $stmt 0] "\n"
7977
}
8078
query finalize $stmt
8179
</pre></nowiki>
8280
8381
84
-<h2>col_xxx</h2>
82
+<h2>col xxx</h2>
8583
86
-The <tt>col_xxx</tt> familys of subcommands are for fetching
84
+The <tt>col xxx</tt> familys of subcommands are for fetching
8785
values and metadata from result rows.
8886
89
- * <tt>col_count StmtId</tt> Returns the number of result columns in the statement.
90
- * <tt>col_is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
91
- * <tt>col_double StmtId Index</tt>
92
- * <tt>col_int StmtId Index</tt>
93
- * <tt>col_string StmtId Index</tt>
94
- * <tt>col_type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.
95
-
96
-TODO: split col_xxx into "col xxx".
87
+ * <tt>col count StmtId</tt> Returns the number of result columns in the statement.
88
+ * <tt>col is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
89
+ * <tt>col double StmtId Index</tt>
90
+ * <tt>col int StmtId Index</tt>
91
+ * <tt>col string StmtId Index</tt>
92
+ * <tt>col type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.
9793
9894
Achtung: the col API uses 0-based indexes, just like SQL does.
9995
--- www/th1_query.wiki
+++ www/th1_query.wiki
@@ -9,11 +9,11 @@
9 &lt;th1>
10 catch {
11 set stmt [query prepare "SELECT login, cap FROM user"]
12 puts "stmt ID=$stmt\n"
13 for {} {0 < [query step $stmt]} {} {
14 puts [query col_string $stmt 0] ": " [query col_string $stmt 1] "\n"
15 }
16 query finalize $stmt
17 return 0
18 } rc
19 if {0 != $rc} {
@@ -50,49 +50,45 @@
50 at the end of the set, a positive value if a new row is available,
51 and throws for any other condition.
52
53 <nowiki><pre>
54 for {} {0 &lt; [query step $stmt]} {} {
55 puts [query col_string $stmt 0] "\n"
56 }
57 </pre></nowiki>
58
59
60 <h2>bind_xxx</h2>
61
62 The <tt>bind_xxx</tt> family of subcommands attach values to queries
63 before stepping through them. The subcommands include:
64
65 * <tt>bind_int StmtId Index Value</tt>
66 * <tt>bind_double StmtId Index Value</tt>
67 * <tt>bind_null StmtId Index</tt>
68 * <tt>bind_string StmtId Index Value</tt>
69
70 Achtung: the bind API uses 1-based indexes, just like SQL does.
71
72 TODO: split bind_xxx into "bind xxx".
73
74 <nowiki><pre>
75 set stmt [query prepare "SELECT ... WHERE user=?"]
76 query bind_int $stmt 1 drh
77 if {0 &lt; [query step $stmt]} {
78 puts [query col_string $stmt 0] "\n"
79 }
80 query finalize $stmt
81 </pre></nowiki>
82
83
84 <h2>col_xxx</h2>
85
86 The <tt>col_xxx</tt> familys of subcommands are for fetching
87 values and metadata from result rows.
88
89 * <tt>col_count StmtId</tt> Returns the number of result columns in the statement.
90 * <tt>col_is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
91 * <tt>col_double StmtId Index</tt>
92 * <tt>col_int StmtId Index</tt>
93 * <tt>col_string StmtId Index</tt>
94 * <tt>col_type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.
95
96 TODO: split col_xxx into "col xxx".
97
98 Achtung: the col API uses 0-based indexes, just like SQL does.
99
--- www/th1_query.wiki
+++ www/th1_query.wiki
@@ -9,11 +9,11 @@
9 &lt;th1>
10 catch {
11 set stmt [query prepare "SELECT login, cap FROM user"]
12 puts "stmt ID=$stmt\n"
13 for {} {0 < [query step $stmt]} {} {
14 puts [query col string $stmt 0] ": " [query col string $stmt 1] "\n"
15 }
16 query finalize $stmt
17 return 0
18 } rc
19 if {0 != $rc} {
@@ -50,49 +50,45 @@
50 at the end of the set, a positive value if a new row is available,
51 and throws for any other condition.
52
53 <nowiki><pre>
54 for {} {0 &lt; [query step $stmt]} {} {
55 puts [query col string $stmt 0] "\n"
56 }
57 </pre></nowiki>
58
59
60 <h2>bind xxx</h2>
61
62 The <tt>bind xxx</tt> family of subcommands attach values to queries
63 before stepping through them. The subcommands include:
64
65 * <tt>bind int StmtId Index Value</tt>
66 * <tt>bind double StmtId Index Value</tt>
67 * <tt>bind null StmtId Index</tt>
68 * <tt>bind string StmtId Index Value</tt>
69
70 Achtung: the bind API uses 1-based indexes, just like SQL does.
71
 
 
72 <nowiki><pre>
73 set stmt [query prepare "SELECT ... WHERE user=?"]
74 query bind_int $stmt 1 drh
75 if {0 &lt; [query step $stmt]} {
76 puts [query col string $stmt 0] "\n"
77 }
78 query finalize $stmt
79 </pre></nowiki>
80
81
82 <h2>col xxx</h2>
83
84 The <tt>col xxx</tt> familys of subcommands are for fetching
85 values and metadata from result rows.
86
87 * <tt>col count StmtId</tt> Returns the number of result columns in the statement.
88 * <tt>col is_null StmtId Index</tt> Returns non-0 if the given column contains an SQL NULL value.
89 * <tt>col double StmtId Index</tt>
90 * <tt>col int StmtId Index</tt>
91 * <tt>col string StmtId Index</tt>
92 * <tt>col type StmtId Index</tt> Return value corresponds to one of the <tt>SQLITE_TYPENAME</tt> family of constants.
 
 
93
94 Achtung: the col API uses 0-based indexes, just like SQL does.
95

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button