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

📄 tclsqlite.c

📁 sqlite嵌入式数据库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
          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) ||          (c=='i' && strcmp(zType,"int")==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 ){      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;    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.**** copied from shell.c from '.import' command*/static char *local_getline(char *zPrompt, FILE *in){  char *zLine;  int nLine;  int n;  int eol;  nLine = 100;  zLine = malloc( nLine );  if( zLine==0 ) return 0;  n = 0;  eol = 0;  while( !eol ){    if( n+100>nLine ){      nLine = nLine*2 + 100;      zLine = realloc(zLine, nLine);      if( zLine==0 ) return 0;    }    if( fgets(&zLine[n], nLine - n, in)==0 ){      if( n==0 ){        free(zLine);        return 0;      }      zLine[n] = 0;      eol = 1;      break;    }    while( zLine[n] ){ n++; }    if( n>0 && zLine[n-1]=='\n' ){      n--;      zLine[n] = 0;      eol = 1;    }  }  zLine = realloc( zLine, n+1 );  return zLine;}/*** The "sqlite" command below creates a new Tcl command for each** connection it opens to an SQLite database.  This routine is invoked** whenever one of those connection-specific commands is executed** in Tcl.  For example, if you run Tcl code like this:****       sqlite3 db1  "my_database"**       db1 close**** The first command opens a connection to the "my_database" database** and calls that connection "db1".  The second command causes this** subroutine to be invoked.*/static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){  SqliteDb *pDb = (SqliteDb*)cd;  int choice;  int rc = TCL_OK;  static const char *DB_strs[] = {    "authorizer",         "busy",              "cache",    "changes",            "close",             "collate",    "collation_needed",   "commit_hook",       "complete",    "copy",               "enable_load_extension","errorcode",    "eval",               "exists",            "function",    "interrupt",          "last_insert_rowid", "nullvalue",    "onecolumn",          "profile",           "progress",    "rekey",              "rollback_hook",     "timeout",    "total_changes",      "trace",             "transaction",    "update_hook",        "version",           0  };  enum DB_enum {    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,    DB_COPY,              DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,    DB_EVAL,              DB_EXISTS,           DB_FUNCTION,    DB_INTERRUPT,         DB_LAST_INSERT_ROWID,DB_NULLVALUE,    DB_ONECOLUMN,         DB_PROFILE,          DB_PROGRESS,    DB_REKEY,             DB_ROLLBACK_HOOK,    DB_TIMEOUT,    DB_TOTAL_CHANGES,     DB_TRACE,            DB_TRANSACTION,    DB_UPDATE_HOOK,       DB_VERSION,            };  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */  if( objc<2 ){    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");    return TCL_ERROR;  }  if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){    return TCL_ERROR;  }  switch( (enum DB_enum)choice ){  /*    $db authorizer ?CALLBACK?  **  ** Invoke the given callback to authorize each SQL operation as it is  ** compiled.  5 arguments are appended to the callback before it is  ** invoked:  **  **   (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)  **   (2) First descriptive name (depends on authorization type)  **   (3) Second descriptive name  **   (4) Name of the database (ex: "main", "temp")  **   (5) Name of trigger that is doing the access  **  ** The callback should return on of the following strings: SQLITE_OK,  ** SQLITE_IGNORE, or SQLITE_DENY.  Any other return value is an error.  **  ** If this method is invoked with no arguments, the current authorization  ** callback string is returned.  */  case DB_AUTHORIZER: {#ifdef SQLITE_OMIT_AUTHORIZATION    Tcl_AppendResult(interp, "authorization not available in this build", 0);    return TCL_ERROR;#else    if( objc>3 ){      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");      return TCL_ERROR;    }else if( objc==2 ){      if( pDb->zAuth ){        Tcl_AppendResult(interp, pDb->zAuth, 0);      }    }else{      char *zAuth;      int len;      if( pDb->zAuth ){        Tcl_Free(pDb->zAuth);      }      zAuth = Tcl_GetStringFromObj(objv[2], &len);      if( zAuth && len>0 ){        pDb->zAuth = Tcl_Alloc( len + 1 );        strcpy(pDb->zAuth, zAuth);      }else{        pDb->zAuth = 0;      }      if( pDb->zAuth ){        pDb->interp = interp;        sqlite3_set_authorizer(pDb->db, auth_callback, pDb);      }else{        sqlite3_set_authorizer(pDb->db, 0, 0);      }    }#endif    break;  }  /*    $db busy ?CALLBACK?  **  ** Invoke the given callback if an SQL statement attempts to open  ** a locked database file.  */  case DB_BUSY: {    if( objc>3 ){      Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");      return TCL_ERROR;    }else if( objc==2 ){      if( pDb->zBusy ){        Tcl_AppendResult(interp, pDb->zBusy, 0);      }    }else{      char *zBusy;      int len;      if( pDb->zBusy ){        Tcl_Free(pDb->zBusy);      }      zBusy = Tcl_GetStringFromObj(objv[2], &len);      if( zBusy && len>0 ){        pDb->zBusy = Tcl_Alloc( len + 1 );        strcpy(pDb->zBusy, zBusy);      }else{        pDb->zBusy = 0;      }      if( pDb->zBusy ){        pDb->interp = interp;        sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);      }else{        sqlite3_busy_handler(pDb->db, 0, 0);      }    }    break;  }  /*     $db cache flush  **     $db cache size n  **  ** Flush the prepared statement cache, or set the maximum number of  ** cached statements.  */  case DB_CACHE: {    char *subCmd;    int n;    if( objc<=2 ){      Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");      return TCL_ERROR;    }    subCmd = Tcl_GetStringFromObj( objv[2], 0 );    if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){      if( objc!=3 ){        Tcl_WrongNumArgs(interp, 2, objv, "flush");        return TCL_ERROR;      }else{        flushStmtCache( pDb );      }    }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){      if( objc!=4 ){        Tcl_WrongNumArgs(interp, 2, objv, "size n");        return TCL_ERROR;      }else{        if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){          Tcl_AppendResult( interp, "cannot convert \"",                Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);          return TCL_ERROR;        }else{          if( n<0 ){            flushStmtCache( pDb );            n = 0;          }else if( n>MAX_PREPARED_STMTS ){            n = MAX_PREPARED_STMTS;          }          pDb->maxStmt = n;        }      }    }else{      Tcl_AppendResult( interp, "bad option \"",           Tcl_GetStringFromObj(objv[0],0), "\": must be flush or size", 0);      return TCL_ERROR;    }    break;  }  /*     $db changes  **  ** Return the number of rows that were modified, inserted, or deleted by  ** the most recent INSERT, UPDATE or DELETE statement, not including   ** any changes made by trigger programs.  */  case DB_CHANGES: {    Tcl_Obj *pResult;    if( objc!=2 ){      Tcl_WrongNumArgs(interp, 2, objv, "");      return TCL_ERROR;    }    pResult = Tcl_GetObjResult(interp);    Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));

⌨️ 快捷键说明

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