⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclsqlite.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
  closeIncrblobChannels(pDb);  sqlite3_close(pDb->db);  while( pDb->pFunc ){    SqlFunc *pFunc = pDb->pFunc;    pDb->pFunc = pFunc->pNext;    Tcl_DecrRefCount(pFunc->pScript);    Tcl_Free((char*)pFunc);  }  while( pDb->pCollate ){    SqlCollate *pCollate = pDb->pCollate;    pDb->pCollate = pCollate->pNext;    Tcl_Free((char*)pCollate);  }  if( pDb->zBusy ){    Tcl_Free(pDb->zBusy);  }  if( pDb->zTrace ){    Tcl_Free(pDb->zTrace);  }  if( pDb->zProfile ){    Tcl_Free(pDb->zProfile);  }  if( pDb->zAuth ){    Tcl_Free(pDb->zAuth);  }  if( pDb->zNull ){    Tcl_Free(pDb->zNull);  }  if( pDb->pUpdateHook ){    Tcl_DecrRefCount(pDb->pUpdateHook);  }  if( pDb->pRollbackHook ){    Tcl_DecrRefCount(pDb->pRollbackHook);  }  if( pDb->pCollateNeeded ){    Tcl_DecrRefCount(pDb->pCollateNeeded);  }  Tcl_Free((char*)pDb);}/*** This routine is called when a database file is locked while trying** to execute SQL.*/static int DbBusyHandler(void *cd, int nTries){  SqliteDb *pDb = (SqliteDb*)cd;  int rc;  char zVal[30];  sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);  rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){    return 0;  }  return 1;}/*** This routine is invoked as the 'progress callback' for the database.*/static int DbProgressHandler(void *cd){  SqliteDb *pDb = (SqliteDb*)cd;  int rc;  assert( pDb->zProgress );  rc = Tcl_Eval(pDb->interp, pDb->zProgress);  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){    return 1;  }  return 0;}#ifndef SQLITE_OMIT_TRACE/*** This routine is called by the SQLite trace handler whenever a new** block of SQL is executed.  The TCL script in pDb->zTrace is executed.*/static void DbTraceHandler(void *cd, const char *zSql){  SqliteDb *pDb = (SqliteDb*)cd;  Tcl_DString str;  Tcl_DStringInit(&str);  Tcl_DStringAppend(&str, pDb->zTrace, -1);  Tcl_DStringAppendElement(&str, zSql);  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));  Tcl_DStringFree(&str);  Tcl_ResetResult(pDb->interp);}#endif#ifndef SQLITE_OMIT_TRACE/*** This routine is called by the SQLite profile handler after a statement** SQL has executed.  The TCL script in pDb->zProfile is evaluated.*/static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){  SqliteDb *pDb = (SqliteDb*)cd;  Tcl_DString str;  char zTm[100];  sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);  Tcl_DStringInit(&str);  Tcl_DStringAppend(&str, pDb->zProfile, -1);  Tcl_DStringAppendElement(&str, zSql);  Tcl_DStringAppendElement(&str, zTm);  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));  Tcl_DStringFree(&str);  Tcl_ResetResult(pDb->interp);}#endif/*** This routine is called when a transaction is committed.  The** TCL script in pDb->zCommit is executed.  If it returns non-zero or** if it throws an exception, the transaction is rolled back instead** of being committed.*/static int DbCommitHandler(void *cd){  SqliteDb *pDb = (SqliteDb*)cd;  int rc;  rc = Tcl_Eval(pDb->interp, pDb->zCommit);  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){    return 1;  }  return 0;}static void DbRollbackHandler(void *clientData){  SqliteDb *pDb = (SqliteDb*)clientData;  assert(pDb->pRollbackHook);  if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){    Tcl_BackgroundError(pDb->interp);  }}static void DbUpdateHandler(  void *p,   int op,  const char *zDb,   const char *zTbl,   sqlite_int64 rowid){  SqliteDb *pDb = (SqliteDb *)p;  Tcl_Obj *pCmd;  assert( pDb->pUpdateHook );  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );  pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);  Tcl_IncrRefCount(pCmd);  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(    ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);}static void tclCollateNeeded(  void *pCtx,  sqlite3 *db,  int enc,  const char *zName){  SqliteDb *pDb = (SqliteDb *)pCtx;  Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);  Tcl_IncrRefCount(pScript);  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));  Tcl_EvalObjEx(pDb->interp, pScript, 0);  Tcl_DecrRefCount(pScript);}/*** This routine is called to evaluate an SQL collation function implemented** using TCL script.*/static int tclSqlCollate(  void *pCtx,  int nA,  const void *zA,  int nB,  const void *zB){  SqlCollate *p = (SqlCollate *)pCtx;  Tcl_Obj *pCmd;  pCmd = Tcl_NewStringObj(p->zScript, -1);  Tcl_IncrRefCount(pCmd);  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));  Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);  Tcl_DecrRefCount(pCmd);  return (atoi(Tcl_GetStringResult(p->interp)));}/*** This routine is called to evaluate an SQL function implemented** using TCL script.*/static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){  SqlFunc *p = sqlite3_user_data(context);  Tcl_Obj *pCmd;  int i;  int rc;  if( argc==0 ){    /* If there are no arguments to the function, call Tcl_EvalObjEx on the    ** script object directly.  This allows the TCL compiler to generate    ** bytecode for the command on the first invocation and thus make    ** subsequent invocations much faster. */    pCmd = p->pScript;    Tcl_IncrRefCount(pCmd);    rc = Tcl_EvalObjEx(p->interp, pCmd, 0);    Tcl_DecrRefCount(pCmd);  }else{    /* If there are arguments to the function, make a shallow copy of the    ** script object, lappend the arguments, then evaluate the copy.    **    ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.    ** The new Tcl_Obj contains pointers to the original list elements.     ** That way, when Tcl_EvalObjv() is run and shimmers the first element    ** of the list to tclCmdNameType, that alternate representation will    ** be preserved and reused on the next invocation.    */    Tcl_Obj **aArg;    int nArg;    if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){      sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);       return;    }         pCmd = Tcl_NewListObj(nArg, aArg);    Tcl_IncrRefCount(pCmd);    for(i=0; i<argc; i++){      sqlite3_value *pIn = argv[i];      Tcl_Obj *pVal;                  /* Set pVal to contain the i'th column of this row. */      switch( sqlite3_value_type(pIn) ){        case SQLITE_BLOB: {          int bytes = sqlite3_value_bytes(pIn);          pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);          break;        }        case SQLITE_INTEGER: {          sqlite_int64 v = sqlite3_value_int64(pIn);          if( v>=-2147483647 && v<=2147483647 ){            pVal = Tcl_NewIntObj(v);          }else{            pVal = Tcl_NewWideIntObj(v);          }          break;        }        case SQLITE_FLOAT: {          double r = sqlite3_value_double(pIn);          pVal = Tcl_NewDoubleObj(r);          break;        }        case SQLITE_NULL: {          pVal = Tcl_NewStringObj("", 0);          break;        }        default: {          int bytes = sqlite3_value_bytes(pIn);          pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);          break;        }      }      rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);      if( rc ){        Tcl_DecrRefCount(pCmd);        sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);         return;      }    }    if( !p->useEvalObjv ){      /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd      ** is a list without a string representation.  To prevent this from      ** happening, make sure pCmd has a valid string representation */      Tcl_GetString(pCmd);    }    rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);    Tcl_DecrRefCount(pCmd);  }  if( rc && rc!=TCL_RETURN ){    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);   }else{    Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);    int n;    u8 *data;    char *zType = pVar->typePtr ? pVar->typePtr->name : "";    char c = zType[0];    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){      /* Only return a BLOB type if the Tcl variable is a bytearray and      ** has no string representation. */      data = Tcl_GetByteArrayFromObj(pVar, &n);      sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);    }else if( c=='b' && strcmp(zType,"boolean")==0 ){      Tcl_GetIntFromObj(0, pVar, &n);      sqlite3_result_int(context, n);    }else if( c=='d' && strcmp(zType,"double")==0 ){      double r;      Tcl_GetDoubleFromObj(0, pVar, &r);      sqlite3_result_double(context, r);    }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||          (c=='i' && strcmp(zType,"int")==0) ){      Tcl_WideInt v;      Tcl_GetWideIntFromObj(0, pVar, &v);      sqlite3_result_int64(context, v);    }else{      data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);      sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);    }  }}#ifndef SQLITE_OMIT_AUTHORIZATION/*** This is the authentication function.  It appends the authentication** type code and the two arguments to zCmd[] then invokes the result** on the interpreter.  The reply is examined to determine if the** authentication fails or succeeds.*/static int auth_callback(  void *pArg,  int code,  const char *zArg1,  const char *zArg2,  const char *zArg3,  const char *zArg4){  char *zCode;  Tcl_DString str;  int rc;  const char *zReply;  SqliteDb *pDb = (SqliteDb*)pArg;  switch( code ){    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;    case SQLITE_CREATE_TEMP_VIEW  : zCode="SQLITE_CREATE_TEMP_VIEW"; break;    case SQLITE_CREATE_TRIGGER    : zCode="SQLITE_CREATE_TRIGGER"; break;    case SQLITE_CREATE_VIEW       : zCode="SQLITE_CREATE_VIEW"; break;    case SQLITE_DELETE            : zCode="SQLITE_DELETE"; break;    case SQLITE_DROP_INDEX        : zCode="SQLITE_DROP_INDEX"; break;    case SQLITE_DROP_TABLE        : zCode="SQLITE_DROP_TABLE"; break;    case SQLITE_DROP_TEMP_INDEX   : zCode="SQLITE_DROP_TEMP_INDEX"; break;    case SQLITE_DROP_TEMP_TABLE   : zCode="SQLITE_DROP_TEMP_TABLE"; break;    case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;    case SQLITE_DROP_TEMP_VIEW    : zCode="SQLITE_DROP_TEMP_VIEW"; break;    case SQLITE_DROP_TRIGGER      : zCode="SQLITE_DROP_TRIGGER"; break;    case SQLITE_DROP_VIEW         : zCode="SQLITE_DROP_VIEW"; break;    case SQLITE_INSERT            : zCode="SQLITE_INSERT"; break;    case SQLITE_PRAGMA            : zCode="SQLITE_PRAGMA"; break;    case SQLITE_READ              : zCode="SQLITE_READ"; break;    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;    default                       : zCode="????"; break;  }  Tcl_DStringInit(&str);  Tcl_DStringAppend(&str, pDb->zAuth, -1);  Tcl_DStringAppendElement(&str, zCode);  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");  Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");  Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");  rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));  Tcl_DStringFree(&str);  zReply = Tcl_GetStringResult(pDb->interp);  if( strcmp(zReply,"SQLITE_OK")==0 ){    rc = SQLITE_OK;  }else if( strcmp(zReply,"SQLITE_DENY")==0 ){    rc = SQLITE_DENY;  }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){    rc = SQLITE_IGNORE;  }else{    rc = 999;  }  return rc;}#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()** fails.**** The interface is like "readline" but no command-line editing** is done.**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -