Fossil SCM

Added th1 query_bind functions.

stephan 2012-07-14 02:13 th1-query-api
Commit e30002440a9280e8fb560487affd621425995166
2 files changed +216 -12 +27 -6
+216 -12
--- src/th_main.c
+++ src/th_main.c
@@ -472,10 +472,20 @@
472472
assert( rc >= 0 && "AddStmt failed.");
473473
Th_SetResultInt( interp, rc );
474474
return TH_OK;
475475
}
476476
477
+/*
478
+** Tries to convert arg, which must be argLen bytes long, to a
479
+** statement handle id and, in turn, to a sqlite3_stmt. On success
480
+** (the argument references a prepared statement) it returns the
481
+** handle and stmtId (if not NULL) is assigned to the integer value of
482
+** arg. On error NULL is returned and stmtId might be modified (if not
483
+** NULL). If stmtId is unmodified after an error then it is not a
484
+** number, else it is a number but does not reference an opened
485
+** statement.
486
+*/
477487
static sqlite3_stmt * queryStmtHandle(Th_Interp *interp, char const * arg, int argLen, int * stmtId ){
478488
int rc = 0;
479489
sqlite3_stmt * pStmt = NULL;
480490
if( 0 == Th_ToInt( interp, arg, argLen, &rc ) ){
481491
if(stmtId){
@@ -513,15 +523,29 @@
513523
rc = Th_FinalizeStmt( interp, rc );
514524
Th_SetResultInt( interp, rc );
515525
return TH_OK;
516526
}
517527
518
-static void queryReportDbErr( Th_Interp * interp, int rc ){
528
+static int queryReportDbErr( Th_Interp * interp ){
519529
char const * msg = sqlite3_errmsg( g.db );
520530
Th_ErrorMessage(interp, "db error:", msg, -1);
531
+ return TH_ERROR;
521532
}
522533
534
+/*
535
+** Internal helper for fetching statement handle and index parameters.
536
+** The first 4 args should be the args passed to the TH1 callback.
537
+** pStmt must be a pointer to a NULL pointer. pIndex may be NULL or
538
+** a pointer to store the statement index argument in. If pIndex is
539
+** NULL then argc is asserted to be at least 2, else it must be at
540
+** least 3.
541
+**
542
+** On success it returns 0, sets *pStmt to the referenced statement
543
+** handle, and pIndex (if not NULL) to the integer value of argv[2]
544
+** argument. On error it reports the error via TH, returns non-0, and
545
+** modifies neither pStmt not pIndex.
546
+*/
523547
static int queryStmtIndexArgs(
524548
Th_Interp * interp,
525549
int argc,
526550
char const ** argv,
527551
int *argl,
@@ -566,21 +590,21 @@
566590
return Th_WrongNumArgs(interp, "query_step StmtHandle");
567591
}
568592
if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, NULL)){
569593
return TH_ERROR;
570594
}
595
+ assert(NULL != pStmt);
571596
rc = sqlite3_step( pStmt );
572597
switch(rc){
573598
case SQLITE_ROW:
574599
rc = 1;
575600
break;
576601
case SQLITE_DONE:
577602
rc = 0;
578603
break;
579604
default:
580
- queryReportDbErr( interp, rc );
581
- return TH_ERROR;
605
+ return queryReportDbErr( interp );
582606
}
583607
Th_SetResultInt( interp, rc );
584608
return TH_OK;
585609
}
586610
@@ -591,16 +615,17 @@
591615
const char **argv,
592616
int *argl
593617
){
594618
sqlite3_stmt * pStmt = NULL;
595619
char const * val;
596
- int index;
620
+ int index = -1;
597621
int valLen;
598622
if( argc!=3 ){
599623
return Th_WrongNumArgs(interp, "query_col_string StmtHandle Index");
600624
}
601
- if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
625
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
626
+ if(index < 0){
602627
return TH_ERROR;
603628
}
604629
val = sqlite3_column_text( pStmt, index );
605630
valLen = val ? sqlite3_column_bytes( pStmt, index ) : 0;
606631
Th_SetResult( interp, val, valLen );
@@ -614,15 +639,16 @@
614639
const char **argv,
615640
int *argl
616641
){
617642
sqlite3_stmt * pStmt = NULL;
618643
int rc = 0;
619
- int index = 0;
644
+ int index = -1;
620645
if( argc!=3 ){
621646
return Th_WrongNumArgs(interp, "query_col_int StmtHandle Index");
622647
}
623
- if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
648
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
649
+ if(index < 0){
624650
return TH_ERROR;
625651
}
626652
Th_SetResultInt( interp, sqlite3_column_int( pStmt, index ) );
627653
return TH_OK;
628654
}
@@ -638,17 +664,59 @@
638664
double rc = 0;
639665
int index = -1;
640666
if( argc!=3 ){
641667
return Th_WrongNumArgs(interp, "query_col_double StmtHandle Index");
642668
}
643
- if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
669
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
670
+ if(index < 0){
644671
return TH_ERROR;
645672
}
646673
Th_SetResultDouble( interp, sqlite3_column_double( pStmt, index ) );
647674
return TH_OK;
648675
}
649676
677
+static int queryColIsNullCmd(
678
+ Th_Interp *interp,
679
+ void *p,
680
+ int argc,
681
+ const char **argv,
682
+ int *argl
683
+){
684
+ sqlite3_stmt * pStmt = NULL;
685
+ double rc = 0;
686
+ int index = -1;
687
+ if( argc!=3 ){
688
+ return Th_WrongNumArgs(interp, "query_col_is_null StmtHandle Index");
689
+ }
690
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
691
+ if(index < 0){
692
+ return TH_ERROR;
693
+ }
694
+ Th_SetResultInt( interp, SQLITE_NULL==sqlite3_column_type( pStmt, index ) );
695
+ return TH_OK;
696
+}
697
+
698
+static int queryColTypeCmd(
699
+ Th_Interp *interp,
700
+ void *p,
701
+ int argc,
702
+ const char **argv,
703
+ int *argl
704
+){
705
+ sqlite3_stmt * pStmt = NULL;
706
+ double rc = 0;
707
+ int index = -1;
708
+ if( argc!=3 ){
709
+ return Th_WrongNumArgs(interp, "query_col_type StmtHandle Index");
710
+ }
711
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
712
+ if(index < 0){
713
+ return TH_ERROR;
714
+ }
715
+ Th_SetResultInt( interp, sqlite3_column_type( pStmt, index ) );
716
+ return TH_OK;
717
+}
650718
651719
static int queryColCountCmd(
652720
Th_Interp *interp,
653721
void *p,
654722
int argc,
@@ -698,10 +766,121 @@
698766
}else{
699767
Th_SetResult( interp, val, strlen( val ) );
700768
return TH_OK;
701769
}
702770
}
771
+
772
+static int queryBindNullCmd(
773
+ Th_Interp *interp,
774
+ void *p,
775
+ int argc,
776
+ const char **argv,
777
+ int *argl
778
+){
779
+ sqlite3_stmt * pStmt = NULL;
780
+ int rc;
781
+ int index = 0;
782
+ if( argc!=3 ){
783
+ return Th_WrongNumArgs(interp, "query_bind_null StmtHandle Index");
784
+ }
785
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
786
+ if(index < 1){
787
+ return TH_ERROR;
788
+ }
789
+ rc = sqlite3_bind_null( pStmt, index );
790
+ if(rc){
791
+ return queryReportDbErr( interp );
792
+ }
793
+ Th_SetResultInt( interp, 0 );
794
+ return TH_OK;
795
+}
796
+
797
+
798
+static int queryBindStringCmd(
799
+ Th_Interp *interp,
800
+ void *p,
801
+ int argc,
802
+ const char **argv,
803
+ int *argl
804
+){
805
+ sqlite3_stmt * pStmt = NULL;
806
+ int rc;
807
+ int index = 0;
808
+ if( argc!=4 ){
809
+ return Th_WrongNumArgs(interp, "query_bind_string StmtHandle Index val");
810
+ }
811
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
812
+ if(index < 1){
813
+ return TH_ERROR;
814
+ }
815
+ rc = sqlite3_bind_text( pStmt, index, argv[3], argl[3], SQLITE_TRANSIENT );
816
+ if(rc){
817
+ return queryReportDbErr( interp );
818
+ }
819
+ Th_SetResultInt( interp, 0 );
820
+ return TH_OK;
821
+}
822
+
823
+static int queryBindIntCmd(
824
+ Th_Interp *interp,
825
+ void *p,
826
+ int argc,
827
+ const char **argv,
828
+ int *argl
829
+){
830
+ sqlite3_stmt * pStmt = NULL;
831
+ int rc;
832
+ int val;
833
+ int index = 0;
834
+ if( argc!=4 ){
835
+ return Th_WrongNumArgs(interp, "query_bind_int StmtHandle Index val");
836
+ }
837
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
838
+ if(index < 1){
839
+ return TH_ERROR;
840
+ }
841
+ if( 0 != Th_ToInt( interp, argv[3], argl[3], &val ) ){
842
+ return TH_ERROR;
843
+ }
844
+
845
+ rc = sqlite3_bind_int( pStmt, index, val );
846
+ if(rc){
847
+ return queryReportDbErr( interp );
848
+ }
849
+ Th_SetResultInt( interp, 0 );
850
+ return TH_OK;
851
+}
852
+
853
+static int queryBindDoubleCmd(
854
+ Th_Interp *interp,
855
+ void *p,
856
+ int argc,
857
+ const char **argv,
858
+ int *argl
859
+){
860
+ sqlite3_stmt * pStmt = NULL;
861
+ int rc;
862
+ double val;
863
+ int index = 0;
864
+ if( argc!=4 ){
865
+ return Th_WrongNumArgs(interp, "query_bind_double StmtHandle Index val");
866
+ }
867
+ queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
868
+ if(index < 1){
869
+ return TH_ERROR;
870
+ }
871
+ if( 0 != Th_ToDouble( interp, argv[3], argl[3], &val ) ){
872
+ return TH_ERROR;
873
+ }
874
+
875
+ rc = sqlite3_bind_double( pStmt, index, val );
876
+ if(rc){
877
+ return queryReportDbErr( interp );
878
+ }
879
+ Th_SetResultInt( interp, 0 );
880
+ return TH_OK;
881
+}
703882
704883
#endif
705884
/* end TH_USE_SQLITE */
706885
707886
/*
@@ -728,22 +907,28 @@
728907
{"htmlize", htmlizeCmd, 0},
729908
{"date", dateCmd, 0},
730909
{"html", putsCmd, &puts_Html},
731910
{"puts", putsCmd, &puts_Normal},
732911
{"putsl", putsCmd, &puts_Ext},
912
+ {"wiki", wikiCmd, 0},
913
+ {"repository", repositoryCmd, 0},
733914
#ifdef TH_USE_SQLITE
915
+ {"query_bind_int", queryBindIntCmd, 0},
916
+ {"query_bind_double", queryBindDoubleCmd,0},
917
+ {"query_bind_null", queryBindNullCmd, 0},
918
+ {"query_bind_string", queryBindStringCmd,0},
734919
{"query_col_count", queryColCountCmd, 0},
920
+ {"query_col_double", queryColDoubleCmd, 0},
921
+ {"query_col_int", queryColIntCmd, 0},
922
+ {"query_col_is_null", queryColIsNullCmd, 0},
735923
{"query_col_name", queryColNameCmd, 0},
736924
{"query_col_string", queryColStringCmd, 0},
737
- {"query_col_int", queryColIntCmd, 0},
738
- {"query_col_double", queryColDoubleCmd, 0},
925
+ {"query_col_type", queryColTypeCmd, 0},
739926
{"query_finalize", queryFinalizeCmd, 0},
740927
{"query_prepare", queryPrepareCmd, 0},
741928
{"query_step", queryStepCmd, 0},
742929
#endif
743
- {"wiki", wikiCmd, 0},
744
- {"repository", repositoryCmd, 0},
745930
{0, 0, 0}
746931
};
747932
if( g.interp==0 ){
748933
int i;
749934
g.interp = Th_CreateInterp(&vtab);
@@ -756,10 +941,29 @@
756941
for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
757942
if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
758943
Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
759944
aCommand[i].pContext, 0);
760945
}
946
+#ifdef TH_USE_SQLITE
947
+ {
948
+ enum { BufLen = 100 };
949
+ char buf[BufLen];
950
+ int i;
951
+#define SET(K) i = snprintf(buf, BufLen, "%d", K); \
952
+ Th_SetVar( g.interp, #K, strlen(#K), buf, i );
953
+ SET(SQLITE_BLOB);
954
+ SET(SQLITE_DONE);
955
+ SET(SQLITE_ERROR);
956
+ SET(SQLITE_FLOAT);
957
+ SET(SQLITE_INTEGER);
958
+ SET(SQLITE_NULL);
959
+ SET(SQLITE_OK);
960
+ SET(SQLITE_ROW);
961
+ SET(SQLITE_TEXT);
962
+#undef SET
963
+ }
964
+#endif
761965
}
762966
}
763967
764968
/*
765969
** Store a string value in a variable in the interpreter.
766970
--- src/th_main.c
+++ src/th_main.c
@@ -472,10 +472,20 @@
472 assert( rc >= 0 && "AddStmt failed.");
473 Th_SetResultInt( interp, rc );
474 return TH_OK;
475 }
476
 
 
 
 
 
 
 
 
 
 
477 static sqlite3_stmt * queryStmtHandle(Th_Interp *interp, char const * arg, int argLen, int * stmtId ){
478 int rc = 0;
479 sqlite3_stmt * pStmt = NULL;
480 if( 0 == Th_ToInt( interp, arg, argLen, &rc ) ){
481 if(stmtId){
@@ -513,15 +523,29 @@
513 rc = Th_FinalizeStmt( interp, rc );
514 Th_SetResultInt( interp, rc );
515 return TH_OK;
516 }
517
518 static void queryReportDbErr( Th_Interp * interp, int rc ){
519 char const * msg = sqlite3_errmsg( g.db );
520 Th_ErrorMessage(interp, "db error:", msg, -1);
 
521 }
522
 
 
 
 
 
 
 
 
 
 
 
 
 
523 static int queryStmtIndexArgs(
524 Th_Interp * interp,
525 int argc,
526 char const ** argv,
527 int *argl,
@@ -566,21 +590,21 @@
566 return Th_WrongNumArgs(interp, "query_step StmtHandle");
567 }
568 if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, NULL)){
569 return TH_ERROR;
570 }
 
571 rc = sqlite3_step( pStmt );
572 switch(rc){
573 case SQLITE_ROW:
574 rc = 1;
575 break;
576 case SQLITE_DONE:
577 rc = 0;
578 break;
579 default:
580 queryReportDbErr( interp, rc );
581 return TH_ERROR;
582 }
583 Th_SetResultInt( interp, rc );
584 return TH_OK;
585 }
586
@@ -591,16 +615,17 @@
591 const char **argv,
592 int *argl
593 ){
594 sqlite3_stmt * pStmt = NULL;
595 char const * val;
596 int index;
597 int valLen;
598 if( argc!=3 ){
599 return Th_WrongNumArgs(interp, "query_col_string StmtHandle Index");
600 }
601 if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
 
602 return TH_ERROR;
603 }
604 val = sqlite3_column_text( pStmt, index );
605 valLen = val ? sqlite3_column_bytes( pStmt, index ) : 0;
606 Th_SetResult( interp, val, valLen );
@@ -614,15 +639,16 @@
614 const char **argv,
615 int *argl
616 ){
617 sqlite3_stmt * pStmt = NULL;
618 int rc = 0;
619 int index = 0;
620 if( argc!=3 ){
621 return Th_WrongNumArgs(interp, "query_col_int StmtHandle Index");
622 }
623 if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
 
624 return TH_ERROR;
625 }
626 Th_SetResultInt( interp, sqlite3_column_int( pStmt, index ) );
627 return TH_OK;
628 }
@@ -638,17 +664,59 @@
638 double rc = 0;
639 int index = -1;
640 if( argc!=3 ){
641 return Th_WrongNumArgs(interp, "query_col_double StmtHandle Index");
642 }
643 if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index)){
 
644 return TH_ERROR;
645 }
646 Th_SetResultDouble( interp, sqlite3_column_double( pStmt, index ) );
647 return TH_OK;
648 }
649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
651 static int queryColCountCmd(
652 Th_Interp *interp,
653 void *p,
654 int argc,
@@ -698,10 +766,121 @@
698 }else{
699 Th_SetResult( interp, val, strlen( val ) );
700 return TH_OK;
701 }
702 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
704 #endif
705 /* end TH_USE_SQLITE */
706
707 /*
@@ -728,22 +907,28 @@
728 {"htmlize", htmlizeCmd, 0},
729 {"date", dateCmd, 0},
730 {"html", putsCmd, &puts_Html},
731 {"puts", putsCmd, &puts_Normal},
732 {"putsl", putsCmd, &puts_Ext},
 
 
733 #ifdef TH_USE_SQLITE
 
 
 
 
734 {"query_col_count", queryColCountCmd, 0},
 
 
 
735 {"query_col_name", queryColNameCmd, 0},
736 {"query_col_string", queryColStringCmd, 0},
737 {"query_col_int", queryColIntCmd, 0},
738 {"query_col_double", queryColDoubleCmd, 0},
739 {"query_finalize", queryFinalizeCmd, 0},
740 {"query_prepare", queryPrepareCmd, 0},
741 {"query_step", queryStepCmd, 0},
742 #endif
743 {"wiki", wikiCmd, 0},
744 {"repository", repositoryCmd, 0},
745 {0, 0, 0}
746 };
747 if( g.interp==0 ){
748 int i;
749 g.interp = Th_CreateInterp(&vtab);
@@ -756,10 +941,29 @@
756 for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
757 if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
758 Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
759 aCommand[i].pContext, 0);
760 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761 }
762 }
763
764 /*
765 ** Store a string value in a variable in the interpreter.
766
--- src/th_main.c
+++ src/th_main.c
@@ -472,10 +472,20 @@
472 assert( rc >= 0 && "AddStmt failed.");
473 Th_SetResultInt( interp, rc );
474 return TH_OK;
475 }
476
477 /*
478 ** Tries to convert arg, which must be argLen bytes long, to a
479 ** statement handle id and, in turn, to a sqlite3_stmt. On success
480 ** (the argument references a prepared statement) it returns the
481 ** handle and stmtId (if not NULL) is assigned to the integer value of
482 ** arg. On error NULL is returned and stmtId might be modified (if not
483 ** NULL). If stmtId is unmodified after an error then it is not a
484 ** number, else it is a number but does not reference an opened
485 ** statement.
486 */
487 static sqlite3_stmt * queryStmtHandle(Th_Interp *interp, char const * arg, int argLen, int * stmtId ){
488 int rc = 0;
489 sqlite3_stmt * pStmt = NULL;
490 if( 0 == Th_ToInt( interp, arg, argLen, &rc ) ){
491 if(stmtId){
@@ -513,15 +523,29 @@
523 rc = Th_FinalizeStmt( interp, rc );
524 Th_SetResultInt( interp, rc );
525 return TH_OK;
526 }
527
528 static int queryReportDbErr( Th_Interp * interp ){
529 char const * msg = sqlite3_errmsg( g.db );
530 Th_ErrorMessage(interp, "db error:", msg, -1);
531 return TH_ERROR;
532 }
533
534 /*
535 ** Internal helper for fetching statement handle and index parameters.
536 ** The first 4 args should be the args passed to the TH1 callback.
537 ** pStmt must be a pointer to a NULL pointer. pIndex may be NULL or
538 ** a pointer to store the statement index argument in. If pIndex is
539 ** NULL then argc is asserted to be at least 2, else it must be at
540 ** least 3.
541 **
542 ** On success it returns 0, sets *pStmt to the referenced statement
543 ** handle, and pIndex (if not NULL) to the integer value of argv[2]
544 ** argument. On error it reports the error via TH, returns non-0, and
545 ** modifies neither pStmt not pIndex.
546 */
547 static int queryStmtIndexArgs(
548 Th_Interp * interp,
549 int argc,
550 char const ** argv,
551 int *argl,
@@ -566,21 +590,21 @@
590 return Th_WrongNumArgs(interp, "query_step StmtHandle");
591 }
592 if(0 != queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, NULL)){
593 return TH_ERROR;
594 }
595 assert(NULL != pStmt);
596 rc = sqlite3_step( pStmt );
597 switch(rc){
598 case SQLITE_ROW:
599 rc = 1;
600 break;
601 case SQLITE_DONE:
602 rc = 0;
603 break;
604 default:
605 return queryReportDbErr( interp );
 
606 }
607 Th_SetResultInt( interp, rc );
608 return TH_OK;
609 }
610
@@ -591,16 +615,17 @@
615 const char **argv,
616 int *argl
617 ){
618 sqlite3_stmt * pStmt = NULL;
619 char const * val;
620 int index = -1;
621 int valLen;
622 if( argc!=3 ){
623 return Th_WrongNumArgs(interp, "query_col_string StmtHandle Index");
624 }
625 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
626 if(index < 0){
627 return TH_ERROR;
628 }
629 val = sqlite3_column_text( pStmt, index );
630 valLen = val ? sqlite3_column_bytes( pStmt, index ) : 0;
631 Th_SetResult( interp, val, valLen );
@@ -614,15 +639,16 @@
639 const char **argv,
640 int *argl
641 ){
642 sqlite3_stmt * pStmt = NULL;
643 int rc = 0;
644 int index = -1;
645 if( argc!=3 ){
646 return Th_WrongNumArgs(interp, "query_col_int StmtHandle Index");
647 }
648 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
649 if(index < 0){
650 return TH_ERROR;
651 }
652 Th_SetResultInt( interp, sqlite3_column_int( pStmt, index ) );
653 return TH_OK;
654 }
@@ -638,17 +664,59 @@
664 double rc = 0;
665 int index = -1;
666 if( argc!=3 ){
667 return Th_WrongNumArgs(interp, "query_col_double StmtHandle Index");
668 }
669 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
670 if(index < 0){
671 return TH_ERROR;
672 }
673 Th_SetResultDouble( interp, sqlite3_column_double( pStmt, index ) );
674 return TH_OK;
675 }
676
677 static int queryColIsNullCmd(
678 Th_Interp *interp,
679 void *p,
680 int argc,
681 const char **argv,
682 int *argl
683 ){
684 sqlite3_stmt * pStmt = NULL;
685 double rc = 0;
686 int index = -1;
687 if( argc!=3 ){
688 return Th_WrongNumArgs(interp, "query_col_is_null StmtHandle Index");
689 }
690 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
691 if(index < 0){
692 return TH_ERROR;
693 }
694 Th_SetResultInt( interp, SQLITE_NULL==sqlite3_column_type( pStmt, index ) );
695 return TH_OK;
696 }
697
698 static int queryColTypeCmd(
699 Th_Interp *interp,
700 void *p,
701 int argc,
702 const char **argv,
703 int *argl
704 ){
705 sqlite3_stmt * pStmt = NULL;
706 double rc = 0;
707 int index = -1;
708 if( argc!=3 ){
709 return Th_WrongNumArgs(interp, "query_col_type StmtHandle Index");
710 }
711 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
712 if(index < 0){
713 return TH_ERROR;
714 }
715 Th_SetResultInt( interp, sqlite3_column_type( pStmt, index ) );
716 return TH_OK;
717 }
718
719 static int queryColCountCmd(
720 Th_Interp *interp,
721 void *p,
722 int argc,
@@ -698,10 +766,121 @@
766 }else{
767 Th_SetResult( interp, val, strlen( val ) );
768 return TH_OK;
769 }
770 }
771
772 static int queryBindNullCmd(
773 Th_Interp *interp,
774 void *p,
775 int argc,
776 const char **argv,
777 int *argl
778 ){
779 sqlite3_stmt * pStmt = NULL;
780 int rc;
781 int index = 0;
782 if( argc!=3 ){
783 return Th_WrongNumArgs(interp, "query_bind_null StmtHandle Index");
784 }
785 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
786 if(index < 1){
787 return TH_ERROR;
788 }
789 rc = sqlite3_bind_null( pStmt, index );
790 if(rc){
791 return queryReportDbErr( interp );
792 }
793 Th_SetResultInt( interp, 0 );
794 return TH_OK;
795 }
796
797
798 static int queryBindStringCmd(
799 Th_Interp *interp,
800 void *p,
801 int argc,
802 const char **argv,
803 int *argl
804 ){
805 sqlite3_stmt * pStmt = NULL;
806 int rc;
807 int index = 0;
808 if( argc!=4 ){
809 return Th_WrongNumArgs(interp, "query_bind_string StmtHandle Index val");
810 }
811 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
812 if(index < 1){
813 return TH_ERROR;
814 }
815 rc = sqlite3_bind_text( pStmt, index, argv[3], argl[3], SQLITE_TRANSIENT );
816 if(rc){
817 return queryReportDbErr( interp );
818 }
819 Th_SetResultInt( interp, 0 );
820 return TH_OK;
821 }
822
823 static int queryBindIntCmd(
824 Th_Interp *interp,
825 void *p,
826 int argc,
827 const char **argv,
828 int *argl
829 ){
830 sqlite3_stmt * pStmt = NULL;
831 int rc;
832 int val;
833 int index = 0;
834 if( argc!=4 ){
835 return Th_WrongNumArgs(interp, "query_bind_int StmtHandle Index val");
836 }
837 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
838 if(index < 1){
839 return TH_ERROR;
840 }
841 if( 0 != Th_ToInt( interp, argv[3], argl[3], &val ) ){
842 return TH_ERROR;
843 }
844
845 rc = sqlite3_bind_int( pStmt, index, val );
846 if(rc){
847 return queryReportDbErr( interp );
848 }
849 Th_SetResultInt( interp, 0 );
850 return TH_OK;
851 }
852
853 static int queryBindDoubleCmd(
854 Th_Interp *interp,
855 void *p,
856 int argc,
857 const char **argv,
858 int *argl
859 ){
860 sqlite3_stmt * pStmt = NULL;
861 int rc;
862 double val;
863 int index = 0;
864 if( argc!=4 ){
865 return Th_WrongNumArgs(interp, "query_bind_double StmtHandle Index val");
866 }
867 queryStmtIndexArgs(interp, argc, argv, argl, &pStmt, &index);
868 if(index < 1){
869 return TH_ERROR;
870 }
871 if( 0 != Th_ToDouble( interp, argv[3], argl[3], &val ) ){
872 return TH_ERROR;
873 }
874
875 rc = sqlite3_bind_double( pStmt, index, val );
876 if(rc){
877 return queryReportDbErr( interp );
878 }
879 Th_SetResultInt( interp, 0 );
880 return TH_OK;
881 }
882
883 #endif
884 /* end TH_USE_SQLITE */
885
886 /*
@@ -728,22 +907,28 @@
907 {"htmlize", htmlizeCmd, 0},
908 {"date", dateCmd, 0},
909 {"html", putsCmd, &puts_Html},
910 {"puts", putsCmd, &puts_Normal},
911 {"putsl", putsCmd, &puts_Ext},
912 {"wiki", wikiCmd, 0},
913 {"repository", repositoryCmd, 0},
914 #ifdef TH_USE_SQLITE
915 {"query_bind_int", queryBindIntCmd, 0},
916 {"query_bind_double", queryBindDoubleCmd,0},
917 {"query_bind_null", queryBindNullCmd, 0},
918 {"query_bind_string", queryBindStringCmd,0},
919 {"query_col_count", queryColCountCmd, 0},
920 {"query_col_double", queryColDoubleCmd, 0},
921 {"query_col_int", queryColIntCmd, 0},
922 {"query_col_is_null", queryColIsNullCmd, 0},
923 {"query_col_name", queryColNameCmd, 0},
924 {"query_col_string", queryColStringCmd, 0},
925 {"query_col_type", queryColTypeCmd, 0},
 
926 {"query_finalize", queryFinalizeCmd, 0},
927 {"query_prepare", queryPrepareCmd, 0},
928 {"query_step", queryStepCmd, 0},
929 #endif
 
 
930 {0, 0, 0}
931 };
932 if( g.interp==0 ){
933 int i;
934 g.interp = Th_CreateInterp(&vtab);
@@ -756,10 +941,29 @@
941 for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
942 if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
943 Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
944 aCommand[i].pContext, 0);
945 }
946 #ifdef TH_USE_SQLITE
947 {
948 enum { BufLen = 100 };
949 char buf[BufLen];
950 int i;
951 #define SET(K) i = snprintf(buf, BufLen, "%d", K); \
952 Th_SetVar( g.interp, #K, strlen(#K), buf, i );
953 SET(SQLITE_BLOB);
954 SET(SQLITE_DONE);
955 SET(SQLITE_ERROR);
956 SET(SQLITE_FLOAT);
957 SET(SQLITE_INTEGER);
958 SET(SQLITE_NULL);
959 SET(SQLITE_OK);
960 SET(SQLITE_ROW);
961 SET(SQLITE_TEXT);
962 #undef SET
963 }
964 #endif
965 }
966 }
967
968 /*
969 ** Store a string value in a variable in the interpreter.
970
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -28,11 +28,11 @@
2828
set colCount [query_col_count $stmt]
2929
puts "query column count: ${colCount}\n"
3030
#set stmt2 [query_prepare {SELECT cap, login FROM user}]
3131
#puts "stmt=${stmt} stmt2=${stmt2}\n"
3232
#putsl "step =" [query_step $stmt]
33
-#putsl "val =" [query_col_string $stmt 1]
33
+#putsl "cap =" [query_col_string $stmt 1]
3434
3535
proc noop {} {}
3636
proc incr {name {step 1}} {
3737
upvar $name x
3838
set x [expr $x+$step]
@@ -42,10 +42,11 @@
4242
set sep " "
4343
set i 0
4444
set colNames(0) 0
4545
for {set i 0} {$i < $colCount} {incr i} {
4646
set colNames($i) [query_col_name $stmt $i]
47
+ puts "colNames($i)=" $colNames($i) "\n"
4748
}
4849
4950
for {set row 0} {0 < [query_step $stmt]} {incr row} {
5051
for {set i 0} {$i < $colCount} {incr i} {
5152
if {$i > 0} {
@@ -74,19 +75,30 @@
7475
#puts "Calling callback: $stmt $colCount colNames\n"
7576
$callback $stmt $colCount
7677
}
7778
}
7879
79
-
80
-set stmt [query_prepare {SELECT uid, login FROM user}]
80
+set sql {SELECT uid, login FROM user WHERE uid!=?}
81
+#set sql {SELECT uid, login FROM user WHERE login=?}
82
+#set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
83
+set stmt [query_prepare $sql]
84
+puts "stmt ID=" $stmt "\n"
85
+query_bind_int $stmt 1 3
86
+#set stmt [query_prepare $sql]
87
+#query_bind_string $stmt 1 stephan
88
+#set stmt [query_prepare $sql]
89
+#query_bind_null $stmt 1
8190
set rc 0
91
+puts "USER LIST:\n"
8292
catch {
8393
proc my_each {stmt colCount} {
8494
upvar 2 sep sep
85
- puts [query_col_int $stmt 0] $sep
95
+ puts [query_col_int $stmt 0] " (type=" [query_col_type $stmt 0] ")" $sep
8696
puts [query_col_double $stmt 0] $sep
87
- puts [query_col_string $stmt 1]
97
+ puts [query_col_string $stmt 1] " (type=" [query_col_type $stmt 1] ")" $sep
98
+ puts "isnull 0 ?= " [query_col_is_null $stmt 0] $sep
99
+ puts "isnull 2 ?= " [query_col_is_null $stmt 2]
88100
# for {set i 0} {$i < $colCount} {incr i} {
89101
# if {$i > 0} { puts $sep }
90102
# }
91103
puts "\n"
92104
# error "hi!"
@@ -95,8 +107,17 @@
95107
# query_step_each $stmt {
96108
# proc each {stmt cc} { puts hi "\n" }
97109
# }
98110
} rc
99111
query_finalize $stmt
100
-puts rc = $rc
112
+puts rc = $rc "\n"
113
+
114
+set consts [list SQLITE_BLOB SQLITE_DONE SQLITE_ERROR SQLITE_FLOAT SQLITE_INTEGER SQLITE_NULL SQLITE_OK SQLITE_ROW SQLITE_TEXT]
115
+#set consts $SQLITE_CONSTANTS
116
+puts consts = $consts "\n"
117
+for {set i 0} {$i < [llength $consts]} {incr i} {
118
+ set x [lindex $consts $i]
119
+ puts \$$x = [expr \$$x] "\n"
120
+}
101121
122
+puts "If you got this far, you win!\n"
102123
</th1>
103124
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -28,11 +28,11 @@
28 set colCount [query_col_count $stmt]
29 puts "query column count: ${colCount}\n"
30 #set stmt2 [query_prepare {SELECT cap, login FROM user}]
31 #puts "stmt=${stmt} stmt2=${stmt2}\n"
32 #putsl "step =" [query_step $stmt]
33 #putsl "val =" [query_col_string $stmt 1]
34
35 proc noop {} {}
36 proc incr {name {step 1}} {
37 upvar $name x
38 set x [expr $x+$step]
@@ -42,10 +42,11 @@
42 set sep " "
43 set i 0
44 set colNames(0) 0
45 for {set i 0} {$i < $colCount} {incr i} {
46 set colNames($i) [query_col_name $stmt $i]
 
47 }
48
49 for {set row 0} {0 < [query_step $stmt]} {incr row} {
50 for {set i 0} {$i < $colCount} {incr i} {
51 if {$i > 0} {
@@ -74,19 +75,30 @@
74 #puts "Calling callback: $stmt $colCount colNames\n"
75 $callback $stmt $colCount
76 }
77 }
78
79
80 set stmt [query_prepare {SELECT uid, login FROM user}]
 
 
 
 
 
 
 
 
81 set rc 0
 
82 catch {
83 proc my_each {stmt colCount} {
84 upvar 2 sep sep
85 puts [query_col_int $stmt 0] $sep
86 puts [query_col_double $stmt 0] $sep
87 puts [query_col_string $stmt 1]
 
 
88 # for {set i 0} {$i < $colCount} {incr i} {
89 # if {$i > 0} { puts $sep }
90 # }
91 puts "\n"
92 # error "hi!"
@@ -95,8 +107,17 @@
95 # query_step_each $stmt {
96 # proc each {stmt cc} { puts hi "\n" }
97 # }
98 } rc
99 query_finalize $stmt
100 puts rc = $rc
 
 
 
 
 
 
 
 
101
 
102 </th1>
103
--- test/th1-query-api-1.th1
+++ test/th1-query-api-1.th1
@@ -28,11 +28,11 @@
28 set colCount [query_col_count $stmt]
29 puts "query column count: ${colCount}\n"
30 #set stmt2 [query_prepare {SELECT cap, login FROM user}]
31 #puts "stmt=${stmt} stmt2=${stmt2}\n"
32 #putsl "step =" [query_step $stmt]
33 #putsl "cap =" [query_col_string $stmt 1]
34
35 proc noop {} {}
36 proc incr {name {step 1}} {
37 upvar $name x
38 set x [expr $x+$step]
@@ -42,10 +42,11 @@
42 set sep " "
43 set i 0
44 set colNames(0) 0
45 for {set i 0} {$i < $colCount} {incr i} {
46 set colNames($i) [query_col_name $stmt $i]
47 puts "colNames($i)=" $colNames($i) "\n"
48 }
49
50 for {set row 0} {0 < [query_step $stmt]} {incr row} {
51 for {set i 0} {$i < $colCount} {incr i} {
52 if {$i > 0} {
@@ -74,19 +75,30 @@
75 #puts "Calling callback: $stmt $colCount colNames\n"
76 $callback $stmt $colCount
77 }
78 }
79
80 set sql {SELECT uid, login FROM user WHERE uid!=?}
81 #set sql {SELECT uid, login FROM user WHERE login=?}
82 #set sql {SELECT tagid, value, null FROM tagxref WHERE value IS ? LIMIT 3}
83 set stmt [query_prepare $sql]
84 puts "stmt ID=" $stmt "\n"
85 query_bind_int $stmt 1 3
86 #set stmt [query_prepare $sql]
87 #query_bind_string $stmt 1 stephan
88 #set stmt [query_prepare $sql]
89 #query_bind_null $stmt 1
90 set rc 0
91 puts "USER LIST:\n"
92 catch {
93 proc my_each {stmt colCount} {
94 upvar 2 sep sep
95 puts [query_col_int $stmt 0] " (type=" [query_col_type $stmt 0] ")" $sep
96 puts [query_col_double $stmt 0] $sep
97 puts [query_col_string $stmt 1] " (type=" [query_col_type $stmt 1] ")" $sep
98 puts "isnull 0 ?= " [query_col_is_null $stmt 0] $sep
99 puts "isnull 2 ?= " [query_col_is_null $stmt 2]
100 # for {set i 0} {$i < $colCount} {incr i} {
101 # if {$i > 0} { puts $sep }
102 # }
103 puts "\n"
104 # error "hi!"
@@ -95,8 +107,17 @@
107 # query_step_each $stmt {
108 # proc each {stmt cc} { puts hi "\n" }
109 # }
110 } rc
111 query_finalize $stmt
112 puts rc = $rc "\n"
113
114 set consts [list SQLITE_BLOB SQLITE_DONE SQLITE_ERROR SQLITE_FLOAT SQLITE_INTEGER SQLITE_NULL SQLITE_OK SQLITE_ROW SQLITE_TEXT]
115 #set consts $SQLITE_CONSTANTS
116 puts consts = $consts "\n"
117 for {set i 0} {$i < [llength $consts]} {incr i} {
118 set x [lindex $consts $i]
119 puts \$$x = [expr \$$x] "\n"
120 }
121
122 puts "If you got this far, you win!\n"
123 </th1>
124

Keyboard Shortcuts

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