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

📄 pragma.c

📁 sqlite 嵌入式数据库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* Code that appears at the end of the integrity check.  If no error    ** messages have been generated, output OK.  Otherwise output the    ** error message    */    static const VdbeOpList endCode[] = {      { OP_MemLoad,     0, 0,        0},      { OP_Integer,     0, 0,        0},      { OP_Ne,          0, 0,        0},    /* 2 */      { OP_String8,     0, 0,        "ok"},      { OP_Callback,    1, 0,        0},    };    /* Initialize the VDBE program */    if( sqlite3ReadSchema(pParse) ) goto pragma_out;    sqlite3VdbeSetNumCols(v, 1);    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);    sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);    /* Do an integrity check on each database file */    for(i=0; i<db->nDb; i++){      HashElem *x;      int cnt = 0;      if( OMIT_TEMPDB && i==1 ) continue;      sqlite3CodeVerifySchema(pParse, i);      /* Do an integrity check of the B-Tree      */      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){        Table *pTab = sqliteHashData(x);        Index *pIdx;        sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);        cnt++;        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);          cnt++;        }      }      assert( cnt>0 );      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);      sqlite3VdbeOp3(v, OP_String8, 0, 0,         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),         P3_DYNAMIC);      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);      /* Make sure all the indices are constructed correctly.      */      sqlite3CodeVerifySchema(pParse, i);      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){        Table *pTab = sqliteHashData(x);        Index *pIdx;        int loopTop;        if( pTab->pIndex==0 ) continue;        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);        sqlite3VdbeAddOp(v, OP_Integer, 0, 0);        sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);        loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){          int jmp2;          static const VdbeOpList idxErr[] = {            { OP_MemIncr,     0,  0,  0},            { OP_String8,     0,  0,  "rowid "},            { OP_Rowid,       1,  0,  0},            { OP_String8,     0,  0,  " missing from index "},            { OP_String8,     0,  0,  0},    /* 4 */            { OP_Concat,      2,  0,  0},            { OP_Callback,    1,  0,  0},          };          sqlite3GenerateIndexKey(v, pIdx, 1);          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));        }        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);        sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){          static const VdbeOpList cntIdx[] = {             { OP_Integer,      0,  0,  0},             { OP_MemStore,     2,  1,  0},             { OP_Rewind,       0,  0,  0},  /* 2 */             { OP_MemIncr,      2,  0,  0},             { OP_Next,         0,  0,  0},  /* 4 */             { OP_MemLoad,      1,  0,  0},             { OP_MemLoad,      2,  0,  0},             { OP_Eq,           0,  0,  0},  /* 7 */             { OP_MemIncr,      0,  0,  0},             { OP_String8,      0,  0,  "wrong # of entries in index "},             { OP_String8,      0,  0,  0},  /* 10 */             { OP_Concat,       0,  0,  0},             { OP_Callback,     1,  0,  0},          };          if( pIdx->tnum==0 ) continue;          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);          sqlite3VdbeChangeP1(v, addr+2, j+2);          sqlite3VdbeChangeP2(v, addr+2, addr+5);          sqlite3VdbeChangeP1(v, addr+4, j+2);          sqlite3VdbeChangeP2(v, addr+4, addr+3);          sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));          sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);        }      }     }    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);    sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));  }else#endif /* SQLITE_OMIT_INTEGRITY_CHECK */#ifndef SQLITE_OMIT_UTF16  /*  **   PRAGMA encoding  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"  **  ** In it's first form, this pragma returns the encoding of the main  ** database. If the database is not initialized, it is initialized now.  **  ** The second form of this pragma is a no-op if the main database file  ** has not already been initialized. In this case it sets the default  ** encoding that will be used for the main database file if a new file  ** is created. If an existing main database file is opened, then the  ** default text encoding for the existing database is used.  **   ** In all cases new databases created using the ATTACH command are  ** created to use the same default text encoding as the main database. If  ** the main database has not been initialized and/or created when ATTACH  ** is executed, this is done before the ATTACH operation.  **  ** In the second form this pragma sets the text encoding to be used in  ** new database files created using this database handle. It is only  ** useful if invoked immediately after the main database i  */  if( sqlite3StrICmp(zLeft, "encoding")==0 ){    static struct EncName {      char *zName;      u8 enc;    } encnames[] = {      { "UTF-8",    SQLITE_UTF8        },      { "UTF8",     SQLITE_UTF8        },      { "UTF-16le", SQLITE_UTF16LE     },      { "UTF16le",  SQLITE_UTF16LE     },      { "UTF-16be", SQLITE_UTF16BE     },      { "UTF16be",  SQLITE_UTF16BE     },      { "UTF-16",   0 /* Filled in at run-time */ },      { "UTF16",    0 /* Filled in at run-time */ },      { 0, 0 }    };    struct EncName *pEnc;    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;    if( !zRight ){    /* "PRAGMA encoding" */      if( sqlite3ReadSchema(pParse) ) goto pragma_out;      sqlite3VdbeSetNumCols(v, 1);      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);      sqlite3VdbeAddOp(v, OP_String8, 0, 0);      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){        if( pEnc->enc==pParse->db->enc ){          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);          break;        }      }      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);    }else{                        /* "PRAGMA encoding = XXX" */      /* Only change the value of sqlite.enc if the database handle is not      ** initialized. If the main database exists, the new sqlite.enc value      ** will be overwritten when the schema is next loaded. If it does not      ** already exists, it will be created to use the new encoding value.      */      if( !(pParse->db->flags&SQLITE_Initialized) ){        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){            pParse->db->enc = pEnc->enc;            break;          }        }        if( !pEnc->zName ){          sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);        }      }    }  }else#endif /* SQLITE_OMIT_UTF16 */#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS  /*  **   PRAGMA [database.]schema_version  **   PRAGMA [database.]schema_version = <integer>  **  **   PRAGMA [database.]user_version  **   PRAGMA [database.]user_version = <integer>  **  ** The pragma's schema_version and user_version are used to set or get  ** the value of the schema-version and user-version, respectively. Both  ** the schema-version and the user-version are 32-bit signed integers  ** stored in the database header.  **  ** The schema-cookie is usually only manipulated internally by SQLite. It  ** is incremented by SQLite whenever the database schema is modified (by  ** creating or dropping a table or index). The schema version is used by  ** SQLite each time a query is executed to ensure that the internal cache  ** of the schema used when compiling the SQL query matches the schema of  ** the database against which the compiled query is actually executed.  ** Subverting this mechanism by using "PRAGMA schema_version" to modify  ** the schema-version is potentially dangerous and may lead to program  ** crashes or database corruption. Use with caution!  **  ** The user-version is not used internally by SQLite. It may be used by  ** applications for any purpose.  */  if( sqlite3StrICmp(zLeft, "schema_version")==0 ||      sqlite3StrICmp(zLeft, "user_version")==0 ){    int iCookie;   /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */    if( zLeft[0]=='s' || zLeft[0]=='S' ){      iCookie = 0;    }else{      iCookie = 5;    }    if( zRight ){      /* Write the specified cookie value */      static const VdbeOpList setCookie[] = {        { OP_Transaction,    0,  1,  0},    /* 0 */        { OP_Integer,        0,  0,  0},    /* 1 */        { OP_SetCookie,      0,  0,  0},    /* 2 */      };      int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);      sqlite3VdbeChangeP1(v, addr, iDb);      sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));      sqlite3VdbeChangeP1(v, addr+2, iDb);      sqlite3VdbeChangeP2(v, addr+2, iCookie);    }else{      /* Read the specified cookie value */      static const VdbeOpList readCookie[] = {        { OP_ReadCookie,      0,  0,  0},    /* 0 */        { OP_Callback,        1,  0,  0}      };      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);      sqlite3VdbeChangeP1(v, addr, iDb);      sqlite3VdbeChangeP2(v, addr, iCookie);      sqlite3VdbeSetNumCols(v, 1);    }  }#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)  /*  ** Report the current state of file logs for all databases  */  if( sqlite3StrICmp(zLeft, "lock_status")==0 ){    static const char *const azLockName[] = {      "unlocked", "shared", "reserved", "pending", "exclusive"    };    int i;    Vdbe *v = sqlite3GetVdbe(pParse);    sqlite3VdbeSetNumCols(v, 2);    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);    for(i=0; i<db->nDb; i++){      Btree *pBt;      Pager *pPager;      if( db->aDb[i].zName==0 ) continue;      sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);      pBt = db->aDb[i].pBt;      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){        sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);      }else{        int j = sqlite3pager_lockstate(pPager);        sqlite3VdbeOp3(v, OP_String, 0, 0,             (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);      }      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);    }  }else#endif#ifdef SQLITE_SSE  /*  ** Check to see if the sqlite_statements table exists.  Create it  ** if it does not.  */  if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){    extern int sqlite3CreateStatementsTable(Parse*);    sqlite3CreateStatementsTable(pParse);  }else#endif  {}  if( v ){    /* Code an OP_Expire at the end of each PRAGMA program to cause    ** the VDBE implementing the pragma to expire. Most (all?) pragmas    ** are only valid for a single execution.    */    sqlite3VdbeAddOp(v, OP_Expire, 1, 0);  }pragma_out:  sqliteFree(zLeft);  sqliteFree(zRight);}#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */

⌨️ 快捷键说明

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