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

📄 test8.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 3 页
字号:
      char *z = sqlite3MPrintf("%s%s", argv[2], &(pVtab->zTableName[1]));      sqliteFree(pVtab->zTableName);      pVtab->zTableName = z;      pVtab->isPattern = 1;    }    if( !pVtab->zTableName ){      echoDestructor((sqlite3_vtab *)pVtab);      return SQLITE_NOMEM;    }  }  /* Log the arguments to this function to Tcl var ::echo_module */  for(i=0; i<argc; i++){    appendToEchoModule(pVtab->interp, argv[i]);  }  /* Invoke sqlite3_declare_vtab and set up other members of the echo_vtab  ** structure. If an error occurs, delete the sqlite3_vtab structure and  ** return an error code.  */  if( echoDeclareVtab(pVtab, db) ){    echoDestructor((sqlite3_vtab *)pVtab);    return SQLITE_ERROR;  }  /* 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((Tcl_Interp *)(pAux), "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("%s", argv[4]);    zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName);    rc = sqlite3_exec(db, zSql, 0, 0, 0);    sqliteFree(zSql);  }  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((Tcl_Interp *)(pAux), "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("DROP TABLE %Q", p->zLogName);    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);    sqliteFree(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;  pCur = sqliteMalloc(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;  sqliteFree(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;  echo_cursor *pCur = (echo_cursor *)cur;  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( !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;  *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;  /* 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){  char *zIn = *pzStr;  if( zIn ){    char *zTemp = zIn;    zIn = sqlite3_mprintf("%s%s", zIn, zAppend);    sqlite3_free(zTemp);  }else{    zIn = sqlite3_mprintf("%s", zAppend);  }  *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 it's 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;  /* 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);    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);  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];    iCol = pConstraint->iColumn;    if( pVtab->aIndex[iCol] ){      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);      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.  */

⌨️ 快捷键说明

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