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

📄 prepare.c

📁 sqlite 嵌入式数据库的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  ** file_format==1    Version 3.0.0.  ** file_format==2    Version 3.1.3.  ** file_format==3    Version 3.1.4.  **  ** Version 3.0 can only use files with file_format==1. Version 3.1.3  ** can read and write files with file_format==1 or file_format==2.  ** Version 3.1.4 can read and write file formats 1, 2 and 3.  */  if( meta[1]>3 ){    sqlite3BtreeCloseCursor(curMain);    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);    return SQLITE_ERROR;  }  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);  /* Read the schema information out of the schema tables  */  assert( db->init.busy );  if( rc==SQLITE_EMPTY ){    /* For an empty database, there is nothing to read */    rc = SQLITE_OK;  }else{    char *zSql;    zSql = sqlite3MPrintf(        "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",        zDbNum, db->aDb[iDb].zName, zMasterName);    sqlite3SafetyOff(db);    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);    sqlite3SafetyOn(db);    sqliteFree(zSql);    sqlite3BtreeCloseCursor(curMain);  }  if( sqlite3_malloc_failed ){    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);    rc = SQLITE_NOMEM;    sqlite3ResetInternalSchema(db, 0);  }  if( rc==SQLITE_OK ){    DbSetProperty(db, iDb, DB_SchemaLoaded);  }else{    sqlite3ResetInternalSchema(db, iDb);  }  return rc;}/*** Initialize all database files - the main database file, the file** used to store temporary tables, and any additional database files** created using ATTACH statements.  Return a success code.  If an** error occurs, write an error message into *pzErrMsg.**** After the database is initialized, the SQLITE_Initialized** bit is set in the flags field of the sqlite structure. */int sqlite3Init(sqlite3 *db, char **pzErrMsg){  int i, rc;    if( db->init.busy ) return SQLITE_OK;  assert( (db->flags & SQLITE_Initialized)==0 );  rc = SQLITE_OK;  db->init.busy = 1;  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;    rc = sqlite3InitOne(db, i, pzErrMsg);    if( rc ){      sqlite3ResetInternalSchema(db, i);    }  }  /* Once all the other databases have been initialised, load the schema  ** for the TEMP database. This is loaded last, as the TEMP database  ** schema may contain references to objects in other databases.  */#ifndef SQLITE_OMIT_TEMPDB  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){    rc = sqlite3InitOne(db, 1, pzErrMsg);    if( rc ){      sqlite3ResetInternalSchema(db, 1);    }  }#endif  db->init.busy = 0;  if( rc==SQLITE_OK ){    db->flags |= SQLITE_Initialized;    sqlite3CommitInternalChanges(db);  }  if( rc!=SQLITE_OK ){    db->flags &= ~SQLITE_Initialized;  }  return rc;}/*** This routine is a no-op if the database schema is already initialised.** Otherwise, the schema is loaded. An error code is returned.*/int sqlite3ReadSchema(Parse *pParse){  int rc = SQLITE_OK;  sqlite3 *db = pParse->db;  if( !db->init.busy ){    if( (db->flags & SQLITE_Initialized)==0 ){      rc = sqlite3Init(db, &pParse->zErrMsg);    }  }  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );  if( rc!=SQLITE_OK ){    pParse->rc = rc;    pParse->nErr++;  }  return rc;}/*** Check schema cookies in all databases.  If any cookie is out** of date, return 0.  If all schema cookies are current, return 1.*/static int schemaIsValid(sqlite3 *db){  int iDb;  int rc;  BtCursor *curTemp;  int cookie;  int allOk = 1;  for(iDb=0; allOk && iDb<db->nDb; iDb++){    Btree *pBt;    pBt = db->aDb[iDb].pBt;    if( pBt==0 ) continue;    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);    if( rc==SQLITE_OK ){      rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){        allOk = 0;      }      sqlite3BtreeCloseCursor(curTemp);    }  }  return allOk;}/*** Compile the UTF-8 encoded SQL statement zSql into a statement handle.*/int sqlite3_prepare(  sqlite3 *db,              /* Database handle. */  const char *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const char** pzTail       /* OUT: End of parsed string */){  Parse sParse;  char *zErrMsg = 0;  int rc = SQLITE_OK;  if( sqlite3_malloc_failed ){    return SQLITE_NOMEM;  }  assert( ppStmt );  *ppStmt = 0;  if( sqlite3SafetyOn(db) ){    return SQLITE_MISUSE;  }  memset(&sParse, 0, sizeof(sParse));  sParse.db = db;  sqlite3RunParser(&sParse, zSql, &zErrMsg);  if( sqlite3_malloc_failed ){    rc = SQLITE_NOMEM;    sqlite3RollbackAll(db);    sqlite3ResetInternalSchema(db, 0);    db->flags &= ~SQLITE_InTrans;    goto prepare_out;  }  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){    sParse.rc = SQLITE_SCHEMA;  }  if( sParse.rc==SQLITE_SCHEMA ){    sqlite3ResetInternalSchema(db, 0);  }  if( pzTail ) *pzTail = sParse.zTail;  rc = sParse.rc;#ifndef SQLITE_OMIT_EXPLAIN  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){    sqlite3VdbeSetNumCols(sParse.pVdbe, 5);    sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);    sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);    sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);    sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);    sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);  } #endifprepare_out:  if( sqlite3SafetyOff(db) ){    rc = SQLITE_MISUSE;  }  if( rc==SQLITE_OK ){    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;  }else if( sParse.pVdbe ){    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);  }  if( zErrMsg ){    sqlite3Error(db, rc, "%s", zErrMsg);    sqliteFree(zErrMsg);  }else{    sqlite3Error(db, rc, 0);  }  return rc;}#ifndef SQLITE_OMIT_UTF16/*** Compile the UTF-16 encoded SQL statement zSql into a statement handle.*/int sqlite3_prepare16(  sqlite3 *db,              /* Database handle. */   const void *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const void **pzTail       /* OUT: End of parsed string */){  /* This function currently works by first transforming the UTF-16  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The  ** tricky bit is figuring out the pointer to return in *pzTail.  */  char const *zSql8 = 0;  char const *zTail8 = 0;  int rc;  sqlite3_value *pTmp;  if( sqlite3SafetyCheck(db) ){    return SQLITE_MISUSE;  }  pTmp = sqlite3GetTransientValue(db);  sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);  zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);  if( !zSql8 ){    sqlite3Error(db, SQLITE_NOMEM, 0);    return SQLITE_NOMEM;  }  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);  if( zTail8 && pzTail ){    /* If sqlite3_prepare returns a tail pointer, we calculate the    ** equivalent pointer into the UTF-16 string by counting the unicode    ** characters between zSql8 and zTail8, and then returning a pointer    ** the same number of characters into the UTF-16 string.    */    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);  }   return rc;}#endif /* SQLITE_OMIT_UTF16 */

⌨️ 快捷键说明

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