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

📄 pragma.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** 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.142 2007/06/26 10:38:55 danielk1977 Exp $*/#include "sqliteInt.h"#include "os.h"#include <ctype.h>/* Ignore this whole file if pragmas are disabled*/#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)# include "pager.h"# include "btree.h"#endif/*** 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 ){      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 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);  sqlite3VdbeAddOp(v, OP_Integer, value, 0);  if( pParse->explain==0 ){    sqlite3VdbeSetNumCols(v, 1);    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);  }  sqlite3VdbeAddOp(v, OP_Callback, 1, 0);}#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;          }        }      }      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 = sqlite3GetVdbe(pParse);  if( v==0 ) return;  /* 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(pId);  if( !zLeft ) return;  if( minusFlag ){    zRight = sqlite3MPrintf("-%T", pValue);  }else{    zRight = sqlite3NameFromToken(pValue);  }  zDb = ((iDb>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, 2,        0},  /* 0 */      { OP_AbsValue,    0, 0,        0},      { OP_Dup,         0, 0,        0},      { OP_Integer,     0, 0,        0},      { OP_Ne,          0, 6,        0},      { OP_Integer,     0, 0,        0},  /* 5 */      { OP_Callback,    1, 0,        0},    };    int addr;    if( sqlite3ReadSchema(pParse) ) goto pragma_out;    if( !zRight ){      sqlite3VdbeSetNumCols(v, 1);      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC);      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);      sqlite3VdbeAddOp(v, OP_Integer, size, 0);      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);      pDb->pSchema->cache_size = size;      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);    }  }else  /*  **  PRAGMA [database.]page_size  **  PRAGMA [database.]page_size=N  **  ** The first form reports the current setting for the  ** database page size in bytes.  The second form sets the  ** database page size value.  The value can only be set if  ** the database has not yet been created.  */  if( sqlite3StrICmp(zLeft,"page_size")==0 ){    Btree *pBt = pDb->pBt;    if( !zRight ){      int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;      returnSingleInt(pParse, "page_size", size);    }else{      sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);    }  }else  /*  **  PRAGMA [database.]max_page_count  **  PRAGMA [database.]max_page_count=N  **  ** The first form reports the current setting for the  ** maximum number of pages in the database file.  The   ** second form attempts to change this setting.  Both  ** forms return the current setting.  */  if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){    Btree *pBt = pDb->pBt;    int newMax = 0;    if( zRight ){      newMax = atoi(zRight);    }    if( pBt ){      newMax = sqlite3BtreeMaxPageCount(pBt, newMax);    }    returnSingleInt(pParse, "max_page_count", newMax);  }else  /*  **  PRAGMA [database.]locking_mode  **  PRAGMA [database.]locking_mode = (normal|exclusive)  */  if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){    const char *zRet = "normal";    int eMode = getLockingMode(zRight);    if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){      /* Simple "PRAGMA locking_mode;" statement. This is a query for      ** the current default locking mode (which may be different to      ** the locking-mode of the main database).      */      eMode = db->dfltLockMode;    }else{      Pager *pPager;      if( pId2->n==0 ){        /* This indicates that no database name was specified as part        ** of the PRAGMA command. In this case the locking-mode must be        ** set on all attached databases, as well as the main db file.        **        ** Also, the sqlite3.dfltLockMode variable is set so that        ** any subsequently attached databases also use the specified        ** locking mode.        */

⌨️ 快捷键说明

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