Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Protect Tcl_Obj pointers from change using Tcl_IncrRefCount() while executing SQL statements in the TCL bindings. (CVS 1903) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6199f2f243514bbd4befbf768a7e03ae |
User & Date: | drh 2004-08-26 00:56:05.000 |
Context
2004-08-26
| ||
01:12 | Update the TCL binding documentation to describe the newly added ability to specify TCL variable names in the body of an SQL statement. (CVS 1904) (check-in: b3b9e58103 user: drh tags: trunk) | |
00:56 | Protect Tcl_Obj pointers from change using Tcl_IncrRefCount() while executing SQL statements in the TCL bindings. (CVS 1903) (check-in: 6199f2f243 user: drh tags: trunk) | |
2004-08-25
| ||
04:07 | Host parameter names conform to SQL-2003. (CVS 1902) (check-in: fd584d1ccf user: drh tags: trunk) | |
Changes
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.103 2004/08/26 00:56:05 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | */ case DB_EVAL: { char const *zSql; /* Next SQL statement to execute */ char const *zLeft; /* What is left after first stmt in zSql */ sqlite3_stmt *pStmt; /* Compiled SQL statment */ Tcl_Obj *pArray; /* Name of array into which results are written */ Tcl_Obj *pScript; /* Script to run for each result set */ Tcl_Obj *pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); if( objc<3 || objc>5 ){ Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?"); return TCL_ERROR; } if( objc==3 ){ pArray = pScript = 0; }else if( objc==4 ){ pArray = 0; pScript = objv[3]; }else{ pArray = objv[3]; if( Tcl_GetString(pArray)[0]==0 ) pArray = 0; pScript = objv[4]; } zSql = Tcl_GetStringFromObj(objv[2], 0); while( zSql[0] ){ int i; /* Loop counter */ int nVar; /* Number of wildcards in the SQL */ int nCol; /* Number of columns in the result set */ Tcl_Obj **apColName = 0; /* Array of column names */ | > > > > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 | */ case DB_EVAL: { char const *zSql; /* Next SQL statement to execute */ char const *zLeft; /* What is left after first stmt in zSql */ sqlite3_stmt *pStmt; /* Compiled SQL statment */ Tcl_Obj *pArray; /* Name of array into which results are written */ Tcl_Obj *pScript; /* Script to run for each result set */ Tcl_Obj **apParm; /* Parameters that need a Tcl_DecrRefCount() */ int nParm; /* Number of entries used in apParm[] */ Tcl_Obj *aParm[10]; /* Static space for apParm[] in the common case */ Tcl_Obj *pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); if( objc<3 || objc>5 ){ Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?"); return TCL_ERROR; } if( objc==3 ){ pArray = pScript = 0; }else if( objc==4 ){ pArray = 0; pScript = objv[3]; }else{ pArray = objv[3]; if( Tcl_GetString(pArray)[0]==0 ) pArray = 0; pScript = objv[4]; } Tcl_IncrRefCount(objv[2]); zSql = Tcl_GetStringFromObj(objv[2], 0); while( zSql[0] ){ int i; /* Loop counter */ int nVar; /* Number of wildcards in the SQL */ int nCol; /* Number of columns in the result set */ Tcl_Obj **apColName = 0; /* Array of column names */ |
︙ | ︙ | |||
737 738 739 740 741 742 743 | break; }else{ zSql = zLeft; continue; } } | | > > > > > > > > > > | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 | break; }else{ zSql = zLeft; continue; } } /* Bind values to wildcards that begin with $ or : */ nVar = sqlite3_bind_parameter_count(pStmt); nParm = 0; if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){ apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0])); }else{ apParm = aParm; } for(i=1; i<=nVar; i++){ const char *zVar = sqlite3_bind_parameter_name(pStmt, i); if( zVar[0]=='$' || zVar[0]==':' ){ Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); if( pVar ){ int n; u8 *data; char *zType = pVar->typePtr ? pVar->typePtr->name : ""; char c = zType[0]; if( c=='b' && strcmp(zType,"bytearray")==0 ){ data = Tcl_GetByteArrayFromObj(pVar, &n); sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); apParm[nParm++] = pVar; }else if( (c=='b' && strcmp(zType,"boolean")==0) || (c=='i' && strcmp(zType,"int")==0) ){ Tcl_GetIntFromObj(interp, pVar, &n); sqlite3_bind_int(pStmt, i, n); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); }else{ data = Tcl_GetStringFromObj(pVar, &n); sqlite3_bind_text(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); apParm[nParm++] = pVar; } } } } /* Compute column names */ |
︙ | ︙ | |||
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | /* Free the column name objects */ if( pScript ){ for(i=0; i<nCol; i++){ Tcl_DecrRefCount(apColName[i]); } Tcl_Free((char*)apColName); } /* Finalize the statement. If the result code is SQLITE_SCHEMA, then ** try again to execute the same statement */ if( SQLITE_SCHEMA==sqlite3_finalize(pStmt) ){ continue; } if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); rc = TCL_ERROR; break; } zSql = zLeft; } if( rc==TCL_OK ){ Tcl_SetObjResult(interp, pRet); } Tcl_DecrRefCount(pRet); break; | > > > > > > > > > | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 | /* Free the column name objects */ if( pScript ){ for(i=0; i<nCol; i++){ Tcl_DecrRefCount(apColName[i]); } Tcl_Free((char*)apColName); } /* Free the bound string and blob parameters */ for(i=0; i<nParm; i++){ Tcl_DecrRefCount(apParm[i]); } if( apParm!=aParm ){ Tcl_Free((char*)apParm); } /* Finalize the statement. If the result code is SQLITE_SCHEMA, then ** try again to execute the same statement */ if( SQLITE_SCHEMA==sqlite3_finalize(pStmt) ){ continue; } if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); rc = TCL_ERROR; break; } zSql = zLeft; } Tcl_DecrRefCount(objv[2]); if( rc==TCL_OK ){ Tcl_SetObjResult(interp, pRet); } Tcl_DecrRefCount(pRet); break; |
︙ | ︙ |