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

📄 test8.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 3 页
字号:
  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);    pIdxInfo->orderByConsumed = 1;  }  appendToEchoModule(pVtab->interp, "xBestIndex");;  appendToEchoModule(pVtab->interp, zQuery);  pIdxInfo->idxNum = hashString(zQuery);  pIdxInfo->idxStr = zQuery;  pIdxInfo->needToFreeIdxStr = 1;  if (useCost) {    pIdxInfo->estimatedCost = cost;  } else if( useIdx ){    /* Approximation of log2(nRow). */    for( ii=0; ii<(sizeof(int)*8); ii++ ){      if( nRow & (1<<ii) ){        pIdxInfo->estimatedCost = (double)ii;      }    }  } else {    pIdxInfo->estimatedCost = (double)nRow;  }  return rc;}/*** The xUpdate method for echo module virtual tables.** **    apData[0]  apData[1]  apData[2..]****    INTEGER                              DELETE            ****    INTEGER    NULL       (nCol args)    UPDATE (do not set rowid)**    INTEGER    INTEGER    (nCol args)    UPDATE (with SET rowid = <arg1>)****    NULL       NULL       (nCol args)    INSERT INTO (automatic rowid value)**    NULL       INTEGER    (nCol args)    INSERT (incl. rowid value)***/int echoUpdate(  sqlite3_vtab *tab,   int nData,   sqlite3_value **apData,   sqlite_int64 *pRowid){  echo_vtab *pVtab = (echo_vtab *)tab;  sqlite3 *db = pVtab->db;  int rc = SQLITE_OK;  sqlite3_stmt *pStmt;  char *z = 0;               /* SQL statement to execute */  int bindArgZero = 0;       /* True to bind apData[0] to sql var no. nData */  int bindArgOne = 0;        /* True to bind apData[1] to sql var no. 1 */  int i;                     /* Counter variable used by for loops */  assert( nData==pVtab->nCol+2 || nData==1 );  /* If apData[0] is an integer and nData>1 then do an UPDATE */  if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){    char *zSep = " SET";    z = sqlite3_mprintf("UPDATE %Q", pVtab->zTableName);    bindArgOne = (apData[1] && sqlite3_value_type(apData[1])==SQLITE_INTEGER);    bindArgZero = 1;    if( bindArgOne ){       string_concat(&z, " SET rowid=?1 ", 0);       zSep = ",";    }    for(i=2; i<nData; i++){      if( apData[i]==0 ) continue;      string_concat(&z, sqlite3_mprintf(          "%s %Q=?%d", zSep, pVtab->aCol[i-2], i), 1);      zSep = ",";    }    string_concat(&z, sqlite3_mprintf(" WHERE rowid=?%d", nData), 0);  }  /* If apData[0] is an integer and nData==1 then do a DELETE */  else if( nData==1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){    z = sqlite3_mprintf("DELETE FROM %Q WHERE rowid = ?1", pVtab->zTableName);    bindArgZero = 1;  }  /* If the first argument is NULL and there are more than two args, INSERT */  else if( nData>2 && sqlite3_value_type(apData[0])==SQLITE_NULL ){    int ii;    char *zInsert = 0;    char *zValues = 0;      zInsert = sqlite3_mprintf("INSERT INTO %Q (", pVtab->zTableName);    if( sqlite3_value_type(apData[1])==SQLITE_INTEGER ){      bindArgOne = 1;      zValues = sqlite3_mprintf("?");      string_concat(&zInsert, "rowid", 0);    }    assert((pVtab->nCol+2)==nData);    for(ii=2; ii<nData; ii++){      string_concat(&zInsert,           sqlite3_mprintf("%s%Q", zValues?", ":"", pVtab->aCol[ii-2]), 1);      string_concat(&zValues,           sqlite3_mprintf("%s?%d", zValues?", ":"", ii), 1);    }    string_concat(&z, zInsert, 1);    string_concat(&z, ") VALUES(", 0);    string_concat(&z, zValues, 1);    string_concat(&z, ")", 0);  }  /* Anything else is an error */  else{    assert(0);    return SQLITE_ERROR;  }  rc = sqlite3_prepare(db, z, -1, &pStmt, 0);  assert( rc!=SQLITE_OK || pStmt );  sqlite3_free(z);  if( rc==SQLITE_OK ) {    if( bindArgZero ){      sqlite3_bind_value(pStmt, nData, apData[0]);    }    if( bindArgOne ){      sqlite3_bind_value(pStmt, 1, apData[1]);    }    for(i=2; i<nData; i++){      if( apData[i] ) sqlite3_bind_value(pStmt, i, apData[i]);    }    sqlite3_step(pStmt);    rc = sqlite3_finalize(pStmt);  }  if( pRowid && rc==SQLITE_OK ){    *pRowid = sqlite3_last_insert_rowid(db);  }  return rc;}/*** xBegin, xSync, xCommit and xRollback callbacks for echo module** virtual tables. Do nothing other than add the name of the callback** to the $::echo_module Tcl variable.*/static int echoTransactionCall(sqlite3_vtab *tab, const char *zCall){  char *z;  echo_vtab *pVtab = (echo_vtab *)tab;  z = sqlite3_mprintf("echo(%s)", pVtab->zTableName);  appendToEchoModule(pVtab->interp, zCall);  appendToEchoModule(pVtab->interp, z);  sqlite3_free(z);  return SQLITE_OK;}static int echoBegin(sqlite3_vtab *tab){  echo_vtab *pVtab = (echo_vtab *)tab;  Tcl_Interp *interp = pVtab->interp;  const char *zVal;   echoTransactionCall(tab, "xBegin");  /* Check if the $::echo_module_begin_fail variable is defined. If it is,  ** and it is set to the name of the real table underlying this virtual  ** echo module table, then cause this xSync operation to fail.  */  zVal = Tcl_GetVar(interp, "echo_module_begin_fail", TCL_GLOBAL_ONLY);  if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){    return SQLITE_ERROR;  }  return SQLITE_OK;}static int echoSync(sqlite3_vtab *tab){  echo_vtab *pVtab = (echo_vtab *)tab;  Tcl_Interp *interp = pVtab->interp;  const char *zVal;   echoTransactionCall(tab, "xSync");  /* Check if the $::echo_module_sync_fail variable is defined. If it is,  ** and it is set to the name of the real table underlying this virtual  ** echo module table, then cause this xSync operation to fail.  */  zVal = Tcl_GetVar(interp, "echo_module_sync_fail", TCL_GLOBAL_ONLY);  if( zVal && 0==strcmp(zVal, pVtab->zTableName) ){    return -1;  }  return SQLITE_OK;}static int echoCommit(sqlite3_vtab *tab){  return echoTransactionCall(tab, "xCommit");}static int echoRollback(sqlite3_vtab *tab){  return echoTransactionCall(tab, "xRollback");}/*** Implementation of "GLOB" function on the echo module.  Pass** all arguments to the ::echo_glob_overload procedure of TCL** and return the result of that procedure as a string.*/static void overloadedGlobFunction(  sqlite3_context *pContext,  int nArg,  sqlite3_value **apArg){  Tcl_Interp *interp = sqlite3_user_data(pContext);  Tcl_DString str;  int i;  int rc;  Tcl_DStringInit(&str);  Tcl_DStringAppendElement(&str, "::echo_glob_overload");  for(i=0; i<nArg; i++){    Tcl_DStringAppendElement(&str, (char*)sqlite3_value_text(apArg[i]));  }  rc = Tcl_Eval(interp, Tcl_DStringValue(&str));  Tcl_DStringFree(&str);  if( rc ){    sqlite3_result_error(pContext, Tcl_GetStringResult(interp), -1);  }else{    sqlite3_result_text(pContext, Tcl_GetStringResult(interp),                        -1, SQLITE_TRANSIENT);  }  Tcl_ResetResult(interp);}/*** This is the xFindFunction implementation for the echo module.** SQLite calls this routine when the first argument of a function** is a column of an echo virtual table.  This routine can optionally** override the implementation of that function.  It will choose to** do so if the function is named "glob", and a TCL command named** ::echo_glob_overload exists.*/static int echoFindFunction(  sqlite3_vtab *vtab,  int nArg,  const char *zFuncName,  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),  void **ppArg){  echo_vtab *pVtab = (echo_vtab *)vtab;  Tcl_Interp *interp = pVtab->interp;  Tcl_CmdInfo info;  if( strcmp(zFuncName,"glob")!=0 ){    return 0;  }  if( Tcl_GetCommandInfo(interp, "::echo_glob_overload", &info)==0 ){    return 0;  }  *pxFunc = overloadedGlobFunction;  *ppArg = interp;  return 1;}static int echoRename(sqlite3_vtab *vtab, const char *zNewName){  int rc = SQLITE_OK;  echo_vtab *p = (echo_vtab *)vtab;  if( p->isPattern ){    int nThis = strlen(p->zThis);    char *zSql = sqlite3MPrintf("ALTER TABLE %s RENAME TO %s%s",         p->zTableName, zNewName, &p->zTableName[nThis]    );    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);    sqliteFree(zSql);  }  return rc;}/*** A virtual table module that merely "echos" the contents of another** table (like an SQL VIEW).*/static sqlite3_module echoModule = {  0,                         /* iVersion */  echoCreate,  echoConnect,  echoBestIndex,  echoDisconnect,   echoDestroy,  echoOpen,                  /* xOpen - open a cursor */  echoClose,                 /* xClose - close a cursor */  echoFilter,                /* xFilter - configure scan constraints */  echoNext,                  /* xNext - advance a cursor */  echoEof,                   /* xEof */  echoColumn,                /* xColumn - read data */  echoRowid,                 /* xRowid - read data */  echoUpdate,                /* xUpdate - write data */  echoBegin,                 /* xBegin - begin transaction */  echoSync,                  /* xSync - sync transaction */  echoCommit,                /* xCommit - commit transaction */  echoRollback,              /* xRollback - rollback transaction */  echoFindFunction,          /* xFindFunction - function overloading */  echoRename,                /* xRename - rename the table */};/*** Decode a pointer to an sqlite3 object.*/static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){  *ppDb = (sqlite3*)sqlite3TextToPtr(zA);  return TCL_OK;}/*** Register the echo virtual table module.*/static int register_echo_module(  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int objc,              /* Number of arguments */  Tcl_Obj *CONST objv[]  /* Command arguments */){  sqlite3 *db;  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "DB");    return TCL_ERROR;  }  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;  sqlite3_create_module(db, "echo", &echoModule, (void *)interp);  return TCL_OK;}/*** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl:**** sqlite3_declare_vtab DB SQL*/static int declare_vtab(  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int objc,              /* Number of arguments */  Tcl_Obj *CONST objv[]  /* Command arguments */){  sqlite3 *db;  int rc;  if( objc!=3 ){    Tcl_WrongNumArgs(interp, 1, objv, "DB SQL");    return TCL_ERROR;  }  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;  rc = sqlite3_declare_vtab(db, Tcl_GetString(objv[2]));  if( rc!=SQLITE_OK ){    Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);    return TCL_ERROR;  }  return TCL_OK;}#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE *//*** Register commands with the TCL interpreter.*/int Sqlitetest8_Init(Tcl_Interp *interp){  static struct {     char *zName;     Tcl_ObjCmdProc *xProc;     void *clientData;  } aObjCmd[] = {#ifndef SQLITE_OMIT_VIRTUALTABLE     { "register_echo_module",   register_echo_module, 0 },     { "sqlite3_declare_vtab",   declare_vtab, 0 },#endif  };  int i;  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){    Tcl_CreateObjCommand(interp, aObjCmd[i].zName,         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);  }  return TCL_OK;}

⌨️ 快捷键说明

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