aboutsummaryrefslogtreecommitdiff
path: root/src/tclsqlite.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2012-10-03 11:02:33 +0000
committerdrh <drh@noemail.net>2012-10-03 11:02:33 +0000
commitc45e67162de9ad08991b095db0f5ae6d089f3535 (patch)
tree35f41820f42d3cb6a8786a1e07cfc52d44b3242c /src/tclsqlite.c
parente7c54168faa48c0e589b5fbbe9fd96409801b177 (diff)
downloadsqlite-c45e67162de9ad08991b095db0f5ae6d089f3535.tar.gz
sqlite-c45e67162de9ad08991b095db0f5ae6d089f3535.zip
Fix the TCL interface so that SQL functions implemented in TCL honor the
"nullvalue" setting. Also remove from the TCL interface some unused legacy UTF8 translation code left over from SQLite2. FossilOrigin-Name: c1f10a2643179ec58f3879764e9e89676d4b5f91
Diffstat (limited to 'src/tclsqlite.c')
-rw-r--r--src/tclsqlite.c52
1 files changed, 14 insertions, 38 deletions
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 47110cb8d..5ea67782a 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -53,15 +53,8 @@
#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100
-/*
-** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
-** have to do a translation when going between the two. Set the
-** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
-** this translation.
-*/
-#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
-# define UTF_TRANSLATION_NEEDED 1
-#endif
+/* Forward declaration */
+typedef struct SqliteDb SqliteDb;
/*
** New SQL functions can be created as TCL scripts. Each such function
@@ -71,6 +64,7 @@ typedef struct SqlFunc SqlFunc;
struct SqlFunc {
Tcl_Interp *interp; /* The TCL interpret to execute the function */
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
+ SqliteDb *pDb; /* Database connection that owns this function */
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
char *zName; /* Name of this function */
SqlFunc *pNext; /* Next function on the list of them all */
@@ -113,7 +107,6 @@ typedef struct IncrblobChannel IncrblobChannel;
** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
*/
-typedef struct SqliteDb SqliteDb;
struct SqliteDb {
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
Tcl_Interp *interp; /* The interpreter used for this database */
@@ -431,6 +424,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
}
}
pNew->interp = pDb->interp;
+ pNew->pDb = pDb;
pNew->pScript = 0;
pNew->pNext = pDb->pFunc;
pDb->pFunc = pNew;
@@ -478,6 +472,7 @@ static void DbDeleteCmd(void *db){
while( pDb->pFunc ){
SqlFunc *pFunc = pDb->pFunc;
pDb->pFunc = pFunc->pNext;
+ assert( pFunc->pDb==pDb );
Tcl_DecrRefCount(pFunc->pScript);
Tcl_Free((char*)pFunc);
}
@@ -794,7 +789,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
break;
}
case SQLITE_NULL: {
- pVal = Tcl_NewStringObj("", 0);
+ pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
break;
}
default: {
@@ -934,26 +929,6 @@ static int auth_callback(
#endif /* SQLITE_OMIT_AUTHORIZATION */
/*
-** zText is a pointer to text obtained via an sqlite3_result_text()
-** or similar interface. This routine returns a Tcl string object,
-** reference count set to 0, containing the text. If a translation
-** between iso8859 and UTF-8 is required, it is preformed.
-*/
-static Tcl_Obj *dbTextToObj(char const *zText){
- Tcl_Obj *pVal;
-#ifdef UTF_TRANSLATION_NEEDED
- Tcl_DString dCol;
- Tcl_DStringInit(&dCol);
- Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
- pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
- Tcl_DStringFree(&dCol);
-#else
- pVal = Tcl_NewStringObj(zText, -1);
-#endif
- return pVal;
-}
-
-/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text. NULL is returned at end of file, or if malloc()
@@ -1140,13 +1115,13 @@ static int dbPrepareAndBind(
int nByte;
if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
- Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}
if( pStmt==0 ){
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
/* A compile-time error in the statement. */
- Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
/* The statement was a no-op. Continue to the next statement
@@ -1365,7 +1340,7 @@ static void dbEvalRowInfo(
if( nCol>0 && (papColName || p->pArray) ){
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
for(i=0; i<nCol; i++){
- apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
+ apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
Tcl_IncrRefCount(apColName[i]);
}
p->apColName = apColName;
@@ -1452,7 +1427,8 @@ static int dbEvalStep(DbEvalContext *p){
continue;
}
#endif
- Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
+ Tcl_SetObjResult(pDb->interp,
+ Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
dbReleaseStmt(pDb, pPreStmt, 0);
@@ -1509,11 +1485,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
}
case SQLITE_NULL: {
- return dbTextToObj(p->pDb->zNull);
+ return Tcl_NewStringObj(p->pDb->zNull, -1);
}
}
- return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
+ return Tcl_NewStringObj(sqlite3_column_text(pStmt, iCol), -1);
}
/*
@@ -2433,7 +2409,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pDb->zNull = 0;
}
}
- Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
break;
}