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

📄 tclsqlite.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
          }else{            sqlite3_bind_null( pStmt, i );          }        }      }      /* Execute the SQL      */      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){	/* Compute column names. This must be done after the first successful	** call to sqlite3_step(), in case the query is recompiled and the        ** number or names of the returned columns changes.         */        assert(!pArray||pScript);        if (nCol < 0) {          Tcl_Obj ***ap = (pScript?&apColName:0);          nCol = computeColumnNames(interp, pStmt, ap, pArray);        }        for(i=0; i<nCol; i++){          Tcl_Obj *pVal;                    /* Set pVal to contain the i'th column of this row. */          switch( sqlite3_column_type(pStmt, i) ){            case SQLITE_BLOB: {              int bytes = sqlite3_column_bytes(pStmt, i);              const char *zBlob = sqlite3_column_blob(pStmt, i);              if( !zBlob ) bytes = 0;              pVal = Tcl_NewByteArrayObj((u8*)zBlob, bytes);              break;            }            case SQLITE_INTEGER: {              sqlite_int64 v = sqlite3_column_int64(pStmt, i);              if( v>=-2147483647 && v<=2147483647 ){                pVal = Tcl_NewIntObj(v);              }else{                pVal = Tcl_NewWideIntObj(v);              }              break;            }            case SQLITE_FLOAT: {              double r = sqlite3_column_double(pStmt, i);              pVal = Tcl_NewDoubleObj(r);              break;            }            case SQLITE_NULL: {              pVal = dbTextToObj(pDb->zNull);              break;            }            default: {              pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i));              break;            }          }            if( pScript ){            if( pArray==0 ){              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);            }else{              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);            }          }else if( choice==DB_ONECOLUMN ){            assert( pRet==0 );            if( pRet==0 ){              pRet = pVal;              Tcl_IncrRefCount(pRet);            }            rc = TCL_BREAK;            i = nCol;          }else if( choice==DB_EXISTS ){            Tcl_DecrRefCount(pRet);            pRet = Tcl_NewBooleanObj(1);            Tcl_IncrRefCount(pRet);            rc = TCL_BREAK;            i = nCol;          }else{            Tcl_ListObjAppendElement(interp, pRet, pVal);          }        }          if( pScript ){          rc = Tcl_EvalObjEx(interp, pScript, 0);          if( rc==TCL_CONTINUE ){            rc = TCL_OK;          }        }      }      if( rc==TCL_BREAK ){        rc = TCL_OK;      }      /* Free the column name objects */      if( pScript ){        /* If the query returned no rows, but an array variable was         ** specified, call computeColumnNames() now to populate the         ** arrayname(*) variable.        */        if (pArray && nCol < 0) {          Tcl_Obj ***ap = (pScript?&apColName:0);          nCol = computeColumnNames(interp, pStmt, ap, pArray);        }        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);      }      /* Reset the statement.  If the result code is SQLITE_SCHEMA, then      ** flush the statement cache and try the statement again.      */      rc2 = sqlite3_reset(pStmt);      if( SQLITE_OK!=rc2 ){        /* If a run-time error occurs, report the error and stop reading        ** the SQL        */        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));        sqlite3_finalize(pStmt);        rc = TCL_ERROR;        if( pPreStmt ) Tcl_Free((char*)pPreStmt);        break;      }else if( pDb->maxStmt<=0 ){        /* If the cache is turned off, deallocated the statement */        if( pPreStmt ) Tcl_Free((char*)pPreStmt);        sqlite3_finalize(pStmt);      }else{        /* Everything worked and the cache is operational.        ** Create a new SqlPreparedStmt structure if we need one.        ** (If we already have one we can just reuse it.)        */        if( pPreStmt==0 ){          len = zLeft - zSql;          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) );          if( pPreStmt==0 ) return TCL_ERROR;          pPreStmt->pStmt = pStmt;          pPreStmt->nSql = len;          pPreStmt->zSql = sqlite3_sql(pStmt);          assert( strlen(pPreStmt->zSql)==len );          assert( 0==memcmp(pPreStmt->zSql, zSql, len) );        }        /* Add the prepared statement to the beginning of the cache list        */        pPreStmt->pNext = pDb->stmtList;        pPreStmt->pPrev = 0;        if( pDb->stmtList ){         pDb->stmtList->pPrev = pPreStmt;        }        pDb->stmtList = pPreStmt;        if( pDb->stmtLast==0 ){          assert( pDb->nStmt==0 );          pDb->stmtLast = pPreStmt;        }else{          assert( pDb->nStmt>0 );        }        pDb->nStmt++;           /* If we have too many statement in cache, remove the surplus from the        ** end of the cache list.        */        while( pDb->nStmt>pDb->maxStmt ){          sqlite3_finalize(pDb->stmtLast->pStmt);          pDb->stmtLast = pDb->stmtLast->pPrev;          Tcl_Free((char*)pDb->stmtLast->pNext);          pDb->stmtLast->pNext = 0;          pDb->nStmt--;        }      }      /* Proceed to the next statement */      zSql = zLeft;    }    Tcl_DecrRefCount(objv[2]);    if( pRet ){      if( rc==TCL_OK ){        Tcl_SetObjResult(interp, pRet);      }      Tcl_DecrRefCount(pRet);    }else if( rc==TCL_OK ){      Tcl_ResetResult(interp);    }    break;  }  /*  **     $db function NAME SCRIPT  **  ** Create a new SQL function called NAME.  Whenever that function is  ** called, invoke SCRIPT to evaluate the function.  */  case DB_FUNCTION: {    SqlFunc *pFunc;    Tcl_Obj *pScript;    char *zName;    if( objc!=4 ){      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");      return TCL_ERROR;    }    zName = Tcl_GetStringFromObj(objv[2], 0);    pScript = objv[3];    pFunc = findSqlFunc(pDb, zName);    if( pFunc==0 ) return TCL_ERROR;    if( pFunc->pScript ){      Tcl_DecrRefCount(pFunc->pScript);    }    pFunc->pScript = pScript;    Tcl_IncrRefCount(pScript);    pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);    rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,        pFunc, tclSqlFunc, 0, 0);    if( rc!=SQLITE_OK ){      rc = TCL_ERROR;      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);    }    break;  }  /*  **     $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID  */  case DB_INCRBLOB: {#ifdef SQLITE_OMIT_INCRBLOB    Tcl_AppendResult(interp, "incrblob not available in this build", 0);    return TCL_ERROR;#else    int isReadonly = 0;    const char *zDb = "main";    const char *zTable;    const char *zColumn;    sqlite_int64 iRow;    /* Check for the -readonly option */    if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){      isReadonly = 1;    }    if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){      Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");      return TCL_ERROR;    }    if( objc==(6+isReadonly) ){      zDb = Tcl_GetString(objv[2]);    }    zTable = Tcl_GetString(objv[objc-3]);    zColumn = Tcl_GetString(objv[objc-2]);    rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);    if( rc==TCL_OK ){      rc = createIncrblobChannel(          interp, pDb, zDb, zTable, zColumn, iRow, isReadonly      );    }#endif    break;  }  /*  **     $db interrupt  **  ** Interrupt the execution of the inner-most SQL interpreter.  This  ** causes the SQL statement to return an error of SQLITE_INTERRUPT.  */  case DB_INTERRUPT: {    sqlite3_interrupt(pDb->db);    break;  }  /*  **     $db nullvalue ?STRING?  **  ** Change text used when a NULL comes back from the database. If ?STRING?  ** is not present, then the current string used for NULL is returned.  ** If STRING is present, then STRING is returned.  **  */  case DB_NULLVALUE: {    if( objc!=2 && objc!=3 ){      Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");      return TCL_ERROR;    }    if( objc==3 ){      int len;      char *zNull = Tcl_GetStringFromObj(objv[2], &len);      if( pDb->zNull ){        Tcl_Free(pDb->zNull);      }      if( zNull && len>0 ){        pDb->zNull = Tcl_Alloc( len + 1 );        strncpy(pDb->zNull, zNull, len);        pDb->zNull[len] = '\0';      }else{        pDb->zNull = 0;      }    }    Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));    break;  }  /*  **     $db last_insert_rowid   **  ** Return an integer which is the ROWID for the most recent insert.  */  case DB_LAST_INSERT_ROWID: {    Tcl_Obj *pResult;    Tcl_WideInt rowid;    if( objc!=2 ){      Tcl_WrongNumArgs(interp, 2, objv, "");      return TCL_ERROR;    }    rowid = sqlite3_last_insert_rowid(pDb->db);    pResult = Tcl_GetObjResult(interp);    Tcl_SetWideIntObj(pResult, rowid);    break;  }  /*  ** The DB_ONECOLUMN method is implemented together with DB_EVAL.  */  /*    $db progress ?N CALLBACK?  **   ** Invoke the given callback every N virtual machine opcodes while executing  ** queries.  */  case DB_PROGRESS: {    if( objc==2 ){      if( pDb->zProgress ){        Tcl_AppendResult(interp, pDb->zProgress, 0);      }    }else if( objc==4 ){      char *zProgress;      int len;      int N;      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){        return TCL_ERROR;      };      if( pDb->zProgress ){        Tcl_Free(pDb->zProgress);      }      zProgress = Tcl_GetStringFromObj(objv[3], &len);      if( zProgress && len>0 ){        pDb->zProgress = Tcl_Alloc( len + 1 );        memcpy(pDb->zProgress, zProgress, len+1);      }else{        pDb->zProgress = 0;      }#ifndef SQLITE_OMIT_PROGRESS_CALLBACK      if( pDb->zProgress ){        pDb->interp = interp;        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);      }else{        sqlite3_progress_handler(pDb->db, 0, 0, 0);      }#endif    }else{      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");      return TCL_ERROR;    }    break;  }  /*    $db profile ?CALLBACK?  **  ** Make arrangements to invoke the CALLBACK routine after each SQL statement  ** that has run.  The text of the SQL and the amount of elapse time are  ** appended to CALLBACK before the script is run.  */  case DB_PROFILE: {    if( objc>3 ){      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");      return TCL_ERROR;    }else if( objc==2 ){      if( pDb->zProfile ){        Tcl_AppendResult(interp, pDb->zProfile, 0);      }    }else{      char *zProfile;      int len;      if( pDb->zProfile ){        Tcl_Free(pDb->zProfile);      }      zProfile = Tcl_GetStringFromObj(objv[2], &len);      if( zProfile && len>0 ){        pDb->zProfile = Tcl_Alloc( len + 1 );        memcpy(pDb->zProfile, zProfile, len+1);      }else{        pDb->zProfile = 0;      }#ifndef SQLITE_OMIT_TRACE      if( pDb->zProfile ){        pDb->interp = interp;        sqlite3_profile(pDb->db, DbProfileHandler, pDb);      }else{        sqlite3_profile(pDb->db, 0, 0);      }#endif    }    break;  }  /*  **     $db rekey KEY  **  ** Change the encryption key on the currently open database.  */  case DB_REKEY: {

⌨️ 快捷键说明

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