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

📄 vtab.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 2 页
字号:
      nType = strlen(zType);      if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){        for(i=0; i<nType; i++){          if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))           && (zType[i+7]=='\0' || zType[i+7]==' ')          ){            i++;            break;          }        }      }      if( i<nType ){        int j;        int nDel = 6 + (zType[i+6] ? 1 : 0);        for(j=i; (j+nDel)<=nType; j++){          zType[j] = zType[j+nDel];        }        if( zType[i]=='\0' && i>0 ){          assert(zType[i-1]==' ');          zType[i-1] = '\0';        }        pTab->aCol[iCol].isHidden = 1;      }    }  }  return rc;}/*** This function is invoked by the parser to call the xConnect() method** of the virtual table pTab. If an error occurs, an error code is returned ** and an error left in pParse.**** This call is a no-op if table pTab is not a virtual table.*/int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){  Module *pMod;  int rc = SQLITE_OK;  if( !pTab || !pTab->isVirtual || pTab->pVtab ){    return SQLITE_OK;  }  pMod = pTab->pMod;  if( !pMod ){    const char *zModule = pTab->azModuleArg[0];    sqlite3ErrorMsg(pParse, "no such module: %s", zModule);    rc = SQLITE_ERROR;  } else {    char *zErr = 0;    sqlite3 *db = pParse->db;    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);    if( rc!=SQLITE_OK ){      sqlite3ErrorMsg(pParse, "%s", zErr);    }    sqliteFree(zErr);  }  return rc;}/*** Add the virtual table pVtab to the array sqlite3.aVTrans[].*/static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){  const int ARRAY_INCR = 5;  /* Grow the sqlite3.aVTrans array if required */  if( (db->nVTrans%ARRAY_INCR)==0 ){    sqlite3_vtab **aVTrans;    int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);    aVTrans = sqliteRealloc((void *)db->aVTrans, nBytes);    if( !aVTrans ){      return SQLITE_NOMEM;    }    memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);    db->aVTrans = aVTrans;  }  /* Add pVtab to the end of sqlite3.aVTrans */  db->aVTrans[db->nVTrans++] = pVtab;  sqlite3VtabLock(pVtab);  return SQLITE_OK;}/*** This function is invoked by the vdbe to call the xCreate method** of the virtual table named zTab in database iDb. **** If an error occurs, *pzErr is set to point an an English language** description of the error and an SQLITE_XXX error code is returned.** In this case the caller must call sqliteFree() on *pzErr.*/int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){  int rc = SQLITE_OK;  Table *pTab;  Module *pMod;  const char *zModule;  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);  assert(pTab && pTab->isVirtual && !pTab->pVtab);  pMod = pTab->pMod;  zModule = pTab->azModuleArg[0];  /* If the module has been registered and includes a Create method,   ** invoke it now. If the module has not been registered, return an   ** error. Otherwise, do nothing.  */  if( !pMod ){    *pzErr = sqlite3MPrintf("no such module: %s", zModule);    rc = SQLITE_ERROR;  }else{    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);  }  if( rc==SQLITE_OK && pTab->pVtab ){      rc = addToVTrans(db, pTab->pVtab);  }  return rc;}/*** This function is used to set the schema of a virtual table.  It is only** valid to call this function from within the xCreate() or xConnect() of a** virtual table module.*/int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){  Parse sParse;  int rc = SQLITE_OK;  Table *pTab = db->pVTab;  char *zErr = 0;  if( !pTab ){    sqlite3Error(db, SQLITE_MISUSE, 0);    return SQLITE_MISUSE;  }  assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0);  memset(&sParse, 0, sizeof(Parse));  sParse.declareVtab = 1;  sParse.db = db;  if(       SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) &&       sParse.pNewTable &&       !sParse.pNewTable->pSelect &&       !sParse.pNewTable->isVirtual   ){    pTab->aCol = sParse.pNewTable->aCol;    pTab->nCol = sParse.pNewTable->nCol;    sParse.pNewTable->nCol = 0;    sParse.pNewTable->aCol = 0;    db->pVTab = 0;  } else {    sqlite3Error(db, SQLITE_ERROR, zErr);    sqliteFree(zErr);    rc = SQLITE_ERROR;  }  sParse.declareVtab = 0;  sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);  sqlite3DeleteTable(sParse.pNewTable);  sParse.pNewTable = 0;  assert( (rc&0xff)==rc );  return sqlite3ApiExit(db, rc);}/*** This function is invoked by the vdbe to call the xDestroy method** of the virtual table named zTab in database iDb. This occurs** when a DROP TABLE is mentioned.**** This call is a no-op if zTab is not a virtual table.*/int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){  int rc = SQLITE_OK;  Table *pTab;  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);  assert(pTab);  if( pTab->pVtab ){    int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;    rc = sqlite3SafetyOff(db);    assert( rc==SQLITE_OK );    if( xDestroy ){      rc = xDestroy(pTab->pVtab);    }    sqlite3SafetyOn(db);    if( rc==SQLITE_OK ){      pTab->pVtab = 0;    }  }  return rc;}/*** This function invokes either the xRollback or xCommit method** of each of the virtual tables in the sqlite3.aVTrans array. The method** called is identified by the second argument, "offset", which is** the offset of the method to call in the sqlite3_module structure.**** The array is cleared after invoking the callbacks. */static void callFinaliser(sqlite3 *db, int offset){  int i;  if( db->aVTrans ){    for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){      sqlite3_vtab *pVtab = db->aVTrans[i];      int (*x)(sqlite3_vtab *);      x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);      if( x ) x(pVtab);      sqlite3VtabUnlock(db, pVtab);    }    sqliteFree(db->aVTrans);    db->nVTrans = 0;    db->aVTrans = 0;  }}/*** If argument rc2 is not SQLITE_OK, then return it and do nothing. ** Otherwise, invoke the xSync method of all virtual tables in the ** sqlite3.aVTrans array. Return the error code for the first error ** that occurs, or SQLITE_OK if all xSync operations are successful.*/int sqlite3VtabSync(sqlite3 *db, int rc2){  int i;  int rc = SQLITE_OK;  int rcsafety;  sqlite3_vtab **aVTrans = db->aVTrans;  if( rc2!=SQLITE_OK ) return rc2;  rc = sqlite3SafetyOff(db);  db->aVTrans = 0;  for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){    sqlite3_vtab *pVtab = aVTrans[i];    int (*x)(sqlite3_vtab *);    x = pVtab->pModule->xSync;    if( x ){      rc = x(pVtab);    }  }  db->aVTrans = aVTrans;  rcsafety = sqlite3SafetyOn(db);  if( rc==SQLITE_OK ){    rc = rcsafety;  }  return rc;}/*** Invoke the xRollback method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself.*/int sqlite3VtabRollback(sqlite3 *db){  callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback));  return SQLITE_OK;}/*** Invoke the xCommit method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself.*/int sqlite3VtabCommit(sqlite3 *db){  callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit));  return SQLITE_OK;}/*** If the virtual table pVtab supports the transaction interface** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is** not currently open, invoke the xBegin method now.**** If the xBegin call is successful, place the sqlite3_vtab pointer** in the sqlite3.aVTrans array.*/int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){  int rc = SQLITE_OK;  const sqlite3_module *pModule;  /* Special case: If db->aVTrans is NULL and db->nVTrans is greater  ** than zero, then this function is being called from within a  ** virtual module xSync() callback. It is illegal to write to   ** virtual module tables in this case, so return SQLITE_LOCKED.  */  if( 0==db->aVTrans && db->nVTrans>0 ){    return SQLITE_LOCKED;  }  if( !pVtab ){    return SQLITE_OK;  }   pModule = pVtab->pModule;  if( pModule->xBegin ){    int i;    /* If pVtab is already in the aVTrans array, return early */    for(i=0; (i<db->nVTrans) && 0!=db->aVTrans[i]; i++){      if( db->aVTrans[i]==pVtab ){        return SQLITE_OK;      }    }    /* Invoke the xBegin method */    rc = pModule->xBegin(pVtab);    if( rc!=SQLITE_OK ){      return rc;    }    rc = addToVTrans(db, pVtab);  }  return rc;}/*** The first parameter (pDef) is a function implementation.  The** second parameter (pExpr) is the first argument to this function.** If pExpr is a column in a virtual table, then let the virtual** table implementation have an opportunity to overload the function.**** This routine is used to allow virtual table implementations to** overload MATCH, LIKE, GLOB, and REGEXP operators.**** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the** SQLITE_FUNC_EPHEM flag.*/FuncDef *sqlite3VtabOverloadFunction(  FuncDef *pDef,  /* Function to possibly overload */  int nArg,       /* Number of arguments to the function */  Expr *pExpr     /* First argument to the function */){  Table *pTab;  sqlite3_vtab *pVtab;  sqlite3_module *pMod;  void (*xFunc)(sqlite3_context*,int,sqlite3_value**);  void *pArg;  FuncDef *pNew;  int rc;  char *zLowerName;  unsigned char *z;  /* Check to see the left operand is a column in a virtual table */  if( pExpr==0 ) return pDef;  if( pExpr->op!=TK_COLUMN ) return pDef;  pTab = pExpr->pTab;  if( pTab==0 ) return pDef;  if( !pTab->isVirtual ) return pDef;  pVtab = pTab->pVtab;  assert( pVtab!=0 );  assert( pVtab->pModule!=0 );  pMod = (sqlite3_module *)pVtab->pModule;  if( pMod->xFindFunction==0 ) return pDef;   /* Call the xFuncFunction method on the virtual table implementation  ** to see if the implementation wants to overload this function   */  zLowerName = sqlite3StrDup(pDef->zName);  for(z=(unsigned char*)zLowerName; *z; z++){    *z = sqlite3UpperToLower[*z];  }  rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);  sqliteFree(zLowerName);  if( rc==0 ){    return pDef;  }  /* Create a new ephemeral function definition for the overloaded  ** function */  pNew = sqliteMalloc( sizeof(*pNew) + strlen(pDef->zName) );  if( pNew==0 ){    return pDef;  }  *pNew = *pDef;  memcpy(pNew->zName, pDef->zName, strlen(pDef->zName)+1);  pNew->xFunc = xFunc;  pNew->pUserData = pArg;  pNew->flags |= SQLITE_FUNC_EPHEM;  return pNew;}#endif /* SQLITE_OMIT_VIRTUALTABLE */

⌨️ 快捷键说明

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