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

📄 test8.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    echoDestructor((sqlite3_vtab *)pVtab);    return rc;  }  /* Success. Set *ppVtab and return */  *ppVtab = &pVtab->base;  return SQLITE_OK;}/* ** Echo virtual table module xCreate method.*/static int echoCreate(  sqlite3 *db,  void *pAux,  int argc, const char *const*argv,  sqlite3_vtab **ppVtab,  char **pzErr){  int rc = SQLITE_OK;  appendToEchoModule(((EchoModule *)pAux)->interp, "xCreate");  rc = echoConstructor(db, pAux, argc, argv, ppVtab, pzErr);  /* If there were two arguments passed to the module at the SQL level   ** (i.e. "CREATE VIRTUAL TABLE tbl USING echo(arg1, arg2)"), then   ** the second argument is used as a table name. Attempt to create  ** such a table with a single column, "logmsg". This table will  ** be used to log calls to the xUpdate method. It will be deleted  ** when the virtual table is DROPed.  **  ** Note: The main point of this is to test that we can drop tables  ** from within an xDestroy method call.  */  if( rc==SQLITE_OK && argc==5 ){    char *zSql;    echo_vtab *pVtab = *(echo_vtab **)ppVtab;    pVtab->zLogName = sqlite3MPrintf(0, "%s", argv[4]);    zSql = sqlite3MPrintf(0, "CREATE TABLE %Q(logmsg)", pVtab->zLogName);    rc = sqlite3_exec(db, zSql, 0, 0, 0);    sqlite3_free(zSql);    if( rc!=SQLITE_OK ){      *pzErr = sqlite3DbStrDup(0, sqlite3_errmsg(db));    }  }  if( *ppVtab && rc!=SQLITE_OK ){    echoDestructor(*ppVtab);    *ppVtab = 0;  }  if( rc==SQLITE_OK ){    (*(echo_vtab**)ppVtab)->inTransaction = 1;  }  return rc;}/* ** Echo virtual table module xConnect method.*/static int echoConnect(  sqlite3 *db,  void *pAux,  int argc, const char *const*argv,  sqlite3_vtab **ppVtab,  char **pzErr){  appendToEchoModule(((EchoModule *)pAux)->interp, "xConnect");  return echoConstructor(db, pAux, argc, argv, ppVtab, pzErr);}/* ** Echo virtual table module xDisconnect method.*/static int echoDisconnect(sqlite3_vtab *pVtab){  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");  return echoDestructor(pVtab);}/* ** Echo virtual table module xDestroy method.*/static int echoDestroy(sqlite3_vtab *pVtab){  int rc = SQLITE_OK;  echo_vtab *p = (echo_vtab *)pVtab;  appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy");  /* Drop the "log" table, if one exists (see echoCreate() for details) */  if( p && p->zLogName ){    char *zSql;    zSql = sqlite3MPrintf(0, "DROP TABLE %Q", p->zLogName);    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);    sqlite3_free(zSql);  }  if( rc==SQLITE_OK ){    rc = echoDestructor(pVtab);  }  return rc;}/* ** Echo virtual table module xOpen method.*/static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){  echo_cursor *pCur;  if( simulateVtabError((echo_vtab *)pVTab, "xOpen") ){    return SQLITE_ERROR;  }  pCur = sqlite3MallocZero(sizeof(echo_cursor));  *ppCursor = (sqlite3_vtab_cursor *)pCur;  return (pCur ? SQLITE_OK : SQLITE_NOMEM);}/* ** Echo virtual table module xClose method.*/static int echoClose(sqlite3_vtab_cursor *cur){  int rc;  echo_cursor *pCur = (echo_cursor *)cur;  sqlite3_stmt *pStmt = pCur->pStmt;  pCur->pStmt = 0;  sqlite3_free(pCur);  rc = sqlite3_finalize(pStmt);  return rc;}/*** Return non-zero if the cursor does not currently point to a valid record** (i.e if the scan has finished), or zero otherwise.*/static int echoEof(sqlite3_vtab_cursor *cur){  return (((echo_cursor *)cur)->pStmt ? 0 : 1);}/* ** Echo virtual table module xNext method.*/static int echoNext(sqlite3_vtab_cursor *cur){  int rc = SQLITE_OK;  echo_cursor *pCur = (echo_cursor *)cur;  if( simulateVtabError((echo_vtab *)(cur->pVtab), "xNext") ){    return SQLITE_ERROR;  }  if( pCur->pStmt ){    rc = sqlite3_step(pCur->pStmt);    if( rc==SQLITE_ROW ){      rc = SQLITE_OK;    }else{      rc = sqlite3_finalize(pCur->pStmt);      pCur->pStmt = 0;    }  }  return rc;}/* ** Echo virtual table module xColumn method.*/static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){  int iCol = i + 1;  sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;  if( simulateVtabError((echo_vtab *)(cur->pVtab), "xColumn") ){    return SQLITE_ERROR;  }  if( !pStmt ){    sqlite3_result_null(ctx);  }else{    assert( sqlite3_data_count(pStmt)>iCol );    sqlite3_result_value(ctx, sqlite3_column_value(pStmt, iCol));  }  return SQLITE_OK;}/* ** Echo virtual table module xRowid method.*/static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){  sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;  if( simulateVtabError((echo_vtab *)(cur->pVtab), "xRowid") ){    return SQLITE_ERROR;  }  *pRowid = sqlite3_column_int64(pStmt, 0);  return SQLITE_OK;}/*** Compute a simple hash of the null terminated string zString.**** This module uses only sqlite3_index_info.idxStr, not ** sqlite3_index_info.idxNum. So to test idxNum, when idxStr is set** in echoBestIndex(), idxNum is set to the corresponding hash value.** In echoFilter(), code assert()s that the supplied idxNum value is** indeed the hash of the supplied idxStr.*/static int hashString(const char *zString){  int val = 0;  int ii;  for(ii=0; zString[ii]; ii++){    val = (val << 3) + (int)zString[ii];  }  return val;}/* ** Echo virtual table module xFilter method.*/static int echoFilter(  sqlite3_vtab_cursor *pVtabCursor,   int idxNum, const char *idxStr,  int argc, sqlite3_value **argv){  int rc;  int i;  echo_cursor *pCur = (echo_cursor *)pVtabCursor;  echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab;  sqlite3 *db = pVtab->db;  if( simulateVtabError(pVtab, "xFilter") ){    return SQLITE_ERROR;  }  /* Check that idxNum matches idxStr */  assert( idxNum==hashString(idxStr) );  /* Log arguments to the ::echo_module Tcl variable */  appendToEchoModule(pVtab->interp, "xFilter");  appendToEchoModule(pVtab->interp, idxStr);  for(i=0; i<argc; i++){    appendToEchoModule(pVtab->interp, (const char*)sqlite3_value_text(argv[i]));  }  sqlite3_finalize(pCur->pStmt);  pCur->pStmt = 0;  /* Prepare the SQL statement created by echoBestIndex and bind the  ** runtime parameters passed to this function to it.  */  rc = sqlite3_prepare(db, idxStr, -1, &pCur->pStmt, 0);  assert( pCur->pStmt || rc!=SQLITE_OK );  for(i=0; rc==SQLITE_OK && i<argc; i++){    sqlite3_bind_value(pCur->pStmt, i+1, argv[i]);  }  /* If everything was successful, advance to the first row of the scan */  if( rc==SQLITE_OK ){    rc = echoNext(pVtabCursor);  }  return rc;}/*** A helper function used by echoUpdate() and echoBestIndex() for** manipulating strings in concert with the sqlite3_mprintf() function.**** Parameter pzStr points to a pointer to a string allocated with** sqlite3_mprintf. The second parameter, zAppend, points to another** string. The two strings are concatenated together and *pzStr** set to point at the result. The initial buffer pointed to by *pzStr** is deallocated via sqlite3_free().**** If the third argument, doFree, is true, then sqlite3_free() is** also called to free the buffer pointed to by zAppend.*/static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){  char *zIn = *pzStr;  if( !zAppend && doFree && *pRc==SQLITE_OK ){    *pRc = SQLITE_NOMEM;  }  if( *pRc!=SQLITE_OK ){    sqlite3_free(zIn);    zIn = 0;  }else{    if( zIn ){      char *zTemp = zIn;      zIn = sqlite3_mprintf("%s%s", zIn, zAppend);      sqlite3_free(zTemp);    }else{      zIn = sqlite3_mprintf("%s", zAppend);    }    if( !zIn ){      *pRc = SQLITE_NOMEM;    }  }  *pzStr = zIn;  if( doFree ){    sqlite3_free(zAppend);  }}/*** The echo module implements the subset of query constraints and sort** orders that may take advantage of SQLite indices on the underlying** real table. For example, if the real table is declared as:****     CREATE TABLE real(a, b, c);**     CREATE INDEX real_index ON real(b);**** then the echo module handles WHERE or ORDER BY clauses that refer** to the column "b", but not "a" or "c". If a multi-column index is** present, only its left most column is considered. **** This xBestIndex method encodes the proposed search strategy as** an SQL query on the real table underlying the virtual echo module ** table and stores the query in sqlite3_index_info.idxStr. The SQL** statement is of the form:****   SELECT rowid, * FROM <real-table> ?<where-clause>? ?<order-by-clause>?**** where the <where-clause> and <order-by-clause> are determined** by the contents of the structure pointed to by the pIdxInfo argument.*/static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){  int ii;  char *zQuery = 0;  char *zNew;  int nArg = 0;  const char *zSep = "WHERE";  echo_vtab *pVtab = (echo_vtab *)tab;  sqlite3_stmt *pStmt = 0;  Tcl_Interp *interp = pVtab->interp;  int nRow;  int useIdx = 0;  int rc = SQLITE_OK;  int useCost = 0;  double cost;  int isIgnoreUsable = 0;  if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){    isIgnoreUsable = 1;  }  if( simulateVtabError(pVtab, "xBestIndex") ){    return SQLITE_ERROR;  }  /* Determine the number of rows in the table and store this value in local  ** variable nRow. The 'estimated-cost' of the scan will be the number of  ** rows in the table for a linear scan, or the log (base 2) of the   ** number of rows if the proposed scan uses an index.    */  if( Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY) ){    cost = atof(Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY));    useCost = 1;  } else {    zQuery = sqlite3_mprintf("SELECT count(*) FROM %Q", pVtab->zTableName);    if( !zQuery ){      return SQLITE_NOMEM;    }    rc = sqlite3_prepare(pVtab->db, zQuery, -1, &pStmt, 0);    sqlite3_free(zQuery);    if( rc!=SQLITE_OK ){      return rc;    }    sqlite3_step(pStmt);    nRow = sqlite3_column_int(pStmt, 0);    rc = sqlite3_finalize(pStmt);    if( rc!=SQLITE_OK ){      return rc;    }  }  zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName);  if( !zQuery ){    return SQLITE_NOMEM;  }  for(ii=0; ii<pIdxInfo->nConstraint; ii++){    const struct sqlite3_index_constraint *pConstraint;    struct sqlite3_index_constraint_usage *pUsage;    int iCol;    pConstraint = &pIdxInfo->aConstraint[ii];    pUsage = &pIdxInfo->aConstraintUsage[ii];    if( !isIgnoreUsable && !pConstraint->usable ) continue;    iCol = pConstraint->iColumn;    if( pVtab->aIndex[iCol] || iCol<0 ){      char *zCol = pVtab->aCol[iCol];      char *zOp = 0;      useIdx = 1;      if( iCol<0 ){        zCol = "rowid";      }      switch( pConstraint->op ){        case SQLITE_INDEX_CONSTRAINT_EQ:          zOp = "="; break;        case SQLITE_INDEX_CONSTRAINT_LT:          zOp = "<"; break;        case SQLITE_INDEX_CONSTRAINT_GT:          zOp = ">"; break;        case SQLITE_INDEX_CONSTRAINT_LE:          zOp = "<="; break;        case SQLITE_INDEX_CONSTRAINT_GE:          zOp = ">="; break;        case SQLITE_INDEX_CONSTRAINT_MATCH:          zOp = "LIKE"; break;      }      if( zOp[0]=='L' ){        zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')",                                zSep, zCol);      } else {        zNew = sqlite3_mprintf(" %s %s %s ?", zSep, zCol, zOp);      }      string_concat(&zQuery, zNew, 1, &rc);      zSep = "AND";      pUsage->argvIndex = ++nArg;      pUsage->omit = 1;    }  }  /* If there is only one term in the ORDER BY clause, and it is  ** on a column that this virtual table has an index for, then consume   ** the ORDER BY clause.  */  if( pIdxInfo->nOrderBy==1 && pVtab->aIndex[pIdxInfo->aOrderBy->iColumn] ){    int iCol = pIdxInfo->aOrderBy->iColumn;    char *zCol = pVtab->aCol[iCol];    char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC";    if( iCol<0 ){      zCol = "rowid";    }    zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir);    string_concat(&zQuery, zNew, 1, &rc);    pIdxInfo->orderByConsumed = 1;  }  appendToEchoModule(pVtab->interp, "xBestIndex");;  appendToEchoModule(pVtab->interp, zQuery);  if( !zQuery ){    return rc;  }  pIdxInfo->idxNum = hashString(zQuery);  pIdxInfo->idxStr = zQuery;  pIdxInfo->needToFreeIdxStr = 1;  if (useCost) {

⌨️ 快捷键说明

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