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

📄 pragma.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*** 2003 April 6**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** This file contains code used to implement the PRAGMA command.**** $Id: pragma.c,v 1.184 2008/08/20 16:34:24 danielk1977 Exp $*/#include "sqliteInt.h"#include <ctype.h>/* Ignore this whole file if pragmas are disabled*/#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)/*** Interpret the given string as a safety level.  Return 0 for OFF,** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or ** unrecognized string argument.**** Note that the values returned are one less that the values that** should be passed into sqlite3BtreeSetSafetyLevel().  The is done** to support legacy SQL code.  The safety level used to be boolean** and older scripts may have used numbers 0 for OFF and 1 for ON.*/static int getSafetyLevel(const char *z){                             /* 123456789 123456789 */  static const char zText[] = "onoffalseyestruefull";  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};  int i, n;  if( isdigit(*z) ){    return atoi(z);  }  n = strlen(z);  for(i=0; i<sizeof(iLength); i++){    if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){      return iValue[i];    }  }  return 1;}/*** Interpret the given string as a boolean value.*/static int getBoolean(const char *z){  return getSafetyLevel(z)&1;}/*** Interpret the given string as a locking mode value.*/static int getLockingMode(const char *z){  if( z ){    if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE;    if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL;  }  return PAGER_LOCKINGMODE_QUERY;}#ifndef SQLITE_OMIT_AUTOVACUUM/*** Interpret the given string as an auto-vacuum mode value.**** The following strings, "none", "full" and "incremental" are ** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively.*/static int getAutoVacuum(const char *z){  int i;  if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;  if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;  if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;  i = atoi(z);  return ((i>=0&&i<=2)?i:0);}#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */#ifndef SQLITE_OMIT_PAGER_PRAGMAS/*** Interpret the given string as a temp db location. Return 1 for file** backed temporary databases, 2 for the Red-Black tree in memory database** and 0 to use the compile-time default.*/static int getTempStore(const char *z){  if( z[0]>='0' && z[0]<='2' ){    return z[0] - '0';  }else if( sqlite3StrICmp(z, "file")==0 ){    return 1;  }else if( sqlite3StrICmp(z, "memory")==0 ){    return 2;  }else{    return 0;  }}#endif /* SQLITE_PAGER_PRAGMAS */#ifndef SQLITE_OMIT_PAGER_PRAGMAS/*** Invalidate temp storage, either when the temp storage is changed** from default, or when 'file' and the temp_store_directory has changed*/static int invalidateTempStorage(Parse *pParse){  sqlite3 *db = pParse->db;  if( db->aDb[1].pBt!=0 ){    if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "        "from within a transaction");      return SQLITE_ERROR;    }    sqlite3BtreeClose(db->aDb[1].pBt);    db->aDb[1].pBt = 0;    sqlite3ResetInternalSchema(db, 0);  }  return SQLITE_OK;}#endif /* SQLITE_PAGER_PRAGMAS */#ifndef SQLITE_OMIT_PAGER_PRAGMAS/*** If the TEMP database is open, close it and mark the database schema** as needing reloading.  This must be done when using the SQLITE_TEMP_STORE** or DEFAULT_TEMP_STORE pragmas.*/static int changeTempStorage(Parse *pParse, const char *zStorageType){  int ts = getTempStore(zStorageType);  sqlite3 *db = pParse->db;  if( db->temp_store==ts ) return SQLITE_OK;  if( invalidateTempStorage( pParse ) != SQLITE_OK ){    return SQLITE_ERROR;  }  db->temp_store = ts;  return SQLITE_OK;}#endif /* SQLITE_PAGER_PRAGMAS *//*** Generate code to return a single integer value.*/static void returnSingleInt(Parse *pParse, const char *zLabel, int value){  Vdbe *v = sqlite3GetVdbe(pParse);  int mem = ++pParse->nMem;  sqlite3VdbeAddOp2(v, OP_Integer, value, mem);  if( pParse->explain==0 ){    sqlite3VdbeSetNumCols(v, 1);    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P4_STATIC);  }  sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);}#ifndef SQLITE_OMIT_FLAG_PRAGMAS/*** Check to see if zRight and zLeft refer to a pragma that queries** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.** Also, implement the pragma.*/static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){  static const struct sPragmaType {    const char *zName;  /* Name of the pragma */    int mask;           /* Mask for the db->flags value */  } aPragma[] = {    { "full_column_names",        SQLITE_FullColNames  },    { "short_column_names",       SQLITE_ShortColNames },    { "count_changes",            SQLITE_CountRows     },    { "empty_result_callbacks",   SQLITE_NullCallback  },    { "legacy_file_format",       SQLITE_LegacyFileFmt },    { "fullfsync",                SQLITE_FullFSync     },#ifdef SQLITE_DEBUG    { "sql_trace",                SQLITE_SqlTrace      },    { "vdbe_listing",             SQLITE_VdbeListing   },    { "vdbe_trace",               SQLITE_VdbeTrace     },#endif#ifndef SQLITE_OMIT_CHECK    { "ignore_check_constraints", SQLITE_IgnoreChecks  },#endif    /* The following is VERY experimental */    { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },    { "omit_readlock",            SQLITE_NoReadlock    },    /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted    ** flag if there are any active statements. */    { "read_uncommitted",         SQLITE_ReadUncommitted },  };  int i;  const struct sPragmaType *p;  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){    if( sqlite3StrICmp(zLeft, p->zName)==0 ){      sqlite3 *db = pParse->db;      Vdbe *v;      v = sqlite3GetVdbe(pParse);      if( v ){        if( zRight==0 ){          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );        }else{          if( getBoolean(zRight) ){            db->flags |= p->mask;          }else{            db->flags &= ~p->mask;          }          /* Many of the flag-pragmas modify the code generated by the SQL           ** compiler (eg. count_changes). So add an opcode to expire all          ** compiled SQL statements after modifying a pragma value.          */          sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);        }      }      return 1;    }  }  return 0;}#endif /* SQLITE_OMIT_FLAG_PRAGMAS *//*** Process a pragma statement.  **** Pragmas are of this form:****      PRAGMA [database.]id [= value]**** The identifier might also be a string.  The value is a string, and** identifier, or a number.  If minusFlag is true, then the value is** a number that was preceded by a minus sign.**** If the left side is "database.id" then pId1 is the database name** and pId2 is the id.  If the left side is just "id" then pId1 is the** id and pId2 is any empty string.*/void sqlite3Pragma(  Parse *pParse,   Token *pId1,        /* First part of [database.]id field */  Token *pId2,        /* Second part of [database.]id field, or NULL */  Token *pValue,      /* Token for <value>, or NULL */  int minusFlag       /* True if a '-' sign preceded <value> */){  char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */  char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */  const char *zDb = 0;   /* The database name */  Token *pId;            /* Pointer to <id> token */  int iDb;               /* Database index for <database> */  sqlite3 *db = pParse->db;  Db *pDb;  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);  if( v==0 ) return;  pParse->nMem = 2;  /* Interpret the [database.] part of the pragma statement. iDb is the  ** index of the database this pragma is being applied to in db.aDb[]. */  iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);  if( iDb<0 ) return;  pDb = &db->aDb[iDb];  /* If the temp database has been explicitly named as part of the   ** pragma, make sure it is open.   */  if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){    return;  }  zLeft = sqlite3NameFromToken(db, pId);  if( !zLeft ) return;  if( minusFlag ){    zRight = sqlite3MPrintf(db, "-%T", pValue);  }else{    zRight = sqlite3NameFromToken(db, pValue);  }  zDb = ((pId2 && pId2->n>0)?pDb->zName:0);  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){    goto pragma_out;  } #ifndef SQLITE_OMIT_PAGER_PRAGMAS  /*  **  PRAGMA [database.]default_cache_size  **  PRAGMA [database.]default_cache_size=N  **  ** The first form reports the current persistent setting for the  ** page cache size.  The value returned is the maximum number of  ** pages in the page cache.  The second form sets both the current  ** page cache size value and the persistent page cache size value  ** stored in the database file.  **  ** The default cache size is stored in meta-value 2 of page 1 of the  ** database file.  The cache size is actually the absolute value of  ** this memory location.  The sign of meta-value 2 determines the  ** synchronous setting.  A negative value means synchronous is off  ** and a positive value means synchronous is on.  */  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){    static const VdbeOpList getCacheSize[] = {      { OP_ReadCookie,  0, 1,        2},  /* 0 */      { OP_IfPos,       1, 6,        0},      { OP_Integer,     0, 2,        0},      { OP_Subtract,    1, 2,        1},      { OP_IfPos,       1, 6,        0},      { OP_Integer,     0, 1,        0},  /* 5 */      { OP_ResultRow,   1, 1,        0},    };    int addr;    if( sqlite3ReadSchema(pParse) ) goto pragma_out;    sqlite3VdbeUsesBtree(v, iDb);    if( !zRight ){      sqlite3VdbeSetNumCols(v, 1);      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);      pParse->nMem += 2;      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);      sqlite3VdbeChangeP1(v, addr, iDb);      sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);    }else{      int size = atoi(zRight);      if( size<0 ) size = -size;      sqlite3BeginWriteOperation(pParse, 0, iDb);      sqlite3VdbeAddOp2(v, OP_Integer, size, 1);      sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, 2);      addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);      sqlite3VdbeAddOp2(v, OP_Integer, -size, 1);      sqlite3VdbeJumpHere(v, addr);      sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 2, 1);      pDb->pSchema->cache_size = size;      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);    }  }else

⌨️ 快捷键说明

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