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

📄 pragma.c

📁 sqlite数据库管理系统开放源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 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.19 2004/04/23 17:04:45 drh Exp $*/#include "sqliteInt.h"#include <ctype.h>/*** Interpret the given string as a boolean value.*/static int getBoolean(const char *z){  static char *azTrue[] = { "yes", "on", "true" };  int i;  if( z[0]==0 ) return 0;  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){    return atoi(z);  }  for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){    if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;  }  return 0;}/*** 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 sqliteBtreeSetSafetyLevel().  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(char *z){  static const struct {    const char *zWord;    int val;  } aKey[] = {    { "no",    0 },    { "off",   0 },    { "false", 0 },    { "yes",   1 },    { "on",    1 },    { "true",  1 },    { "full",  2 },  };  int i;  if( z[0]==0 ) return 1;  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){    return atoi(z);  }  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){    if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;  }  return 1;}/*** 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( sqliteStrICmp(z, "file")==0 ){    return 1;  }else if( sqliteStrICmp(z, "memory")==0 ){    return 2;  }else{    return 0;  }}/*** 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);  sqlite *db = pParse->db;  if( db->temp_store==ts ) return SQLITE_OK;  if( db->aDb[1].pBt!=0 ){    if( db->flags & SQLITE_InTrans ){      sqliteErrorMsg(pParse, "temporary storage cannot be changed "        "from within a transaction");      return SQLITE_ERROR;    }    sqliteBtreeClose(db->aDb[1].pBt);    db->aDb[1].pBt = 0;    sqliteResetInternalSchema(db, 0);  }  db->temp_store = ts;  return SQLITE_OK;}/*** 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 {    const char *zName;  /* Name of the pragma */    int mask;           /* Mask for the db->flags value */  } aPragma[] = {    { "vdbe_trace",               SQLITE_VdbeTrace     },    { "full_column_names",        SQLITE_FullColNames  },    { "short_column_names",       SQLITE_ShortColNames },    { "show_datatypes",           SQLITE_ReportTypes   },    { "count_changes",            SQLITE_CountRows     },    { "empty_result_callbacks",   SQLITE_NullCallback  },  };  int i;  for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){    if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){      sqlite *db = pParse->db;      Vdbe *v;      if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){        sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);        sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);        sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,                          OP_Callback, 1, 0,                          0);      }else if( getBoolean(zRight) ){        db->flags |= aPragma[i].mask;      }else{        db->flags &= ~aPragma[i].mask;      }      return 1;    }  }  return 0;}/*** Process a pragma statement.  **** Pragmas are of this form:****      PRAGMA 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.*/void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){  char *zLeft = 0;  char *zRight = 0;  sqlite *db = pParse->db;  Vdbe *v = sqliteGetVdbe(pParse);  if( v==0 ) return;  zLeft = sqliteStrNDup(pLeft->z, pLeft->n);  sqliteDequote(zLeft);  if( minusFlag ){    zRight = 0;    sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);  }else{    zRight = sqliteStrNDup(pRight->z, pRight->n);    sqliteDequote(zRight);  }  if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){    sqliteFree(zLeft);    sqliteFree(zRight);    return;  }   /*  **  PRAGMA default_cache_size  **  PRAGMA 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( sqliteStrICmp(zLeft,"default_cache_size")==0 ){    static VdbeOpList getCacheSize[] = {      { OP_ReadCookie,  0, 2,        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_ColumnName,  0, 1,        "cache_size"},      { OP_Callback,    1, 0,        0},    };    int addr;    if( pRight->z==pLeft->z ){      addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);      sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);    }else{      int size = atoi(zRight);      if( size<0 ) size = -size;      sqliteBeginWriteOperation(pParse, 0, 0);      sqliteVdbeAddOp(v, OP_Integer, size, 0);      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);      sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);      sqliteVdbeAddOp(v, OP_Negative, 0, 0);      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);      sqliteEndWriteOperation(pParse);      db->cache_size = db->cache_size<0 ? -size : size;      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);    }  }else  /*  **  PRAGMA cache_size  **  PRAGMA cache_size=N  **  ** The first form reports the current local setting for the  ** page cache size.  The local setting can be different from  ** the persistent cache size value that is stored in the database  ** file itself.  The value returned is the maximum number of  ** pages in the page cache.  The second form sets the local  ** page cache size value.  It does not change the persistent  ** cache size stored on the disk so the cache size will revert  ** to its default value when the database is closed and reopened.  ** N should be a positive integer.  */  if( sqliteStrICmp(zLeft,"cache_size")==0 ){    static VdbeOpList getCacheSize[] = {      { OP_ColumnName,  0, 1,        "cache_size"},      { OP_Callback,    1, 0,        0},    };    if( pRight->z==pLeft->z ){      int size = db->cache_size;;      if( size<0 ) size = -size;      sqliteVdbeAddOp(v, OP_Integer, size, 0);      sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);    }else{      int size = atoi(zRight);      if( size<0 ) size = -size;      if( db->cache_size<0 ) size = -size;      db->cache_size = size;      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);    }  }else  /*  **  PRAGMA default_synchronous  **  PRAGMA default_synchronous=ON|OFF|NORMAL|FULL  **  ** The first form returns the persistent value of the "synchronous" setting  ** that is stored in the database.  This is the synchronous setting that  ** is used whenever the database is opened unless overridden by a separate  ** "synchronous" pragma.  The second form changes the persistent and the  ** local synchronous setting to the value given.  **  ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls  ** to make sure data is committed to disk.  Write operations are very fast,  ** but a power failure can leave the database in an inconsistent state.  ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to  ** make sure data is being written to disk.  The risk of corruption due to  ** a power loss in this mode is negligible but non-zero.  If synchronous  ** is FULL, extra fsync()s occur to reduce the risk of corruption to near  ** zero, but with a write performance penalty.  The default mode is NORMAL.  */  if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){    static VdbeOpList getSync[] = {      { OP_ColumnName,  0, 1,        "synchronous"},      { OP_ReadCookie,  0, 3,        0},      { OP_Dup,         0, 0,        0},      { OP_If,          0, 0,        0},  /* 3 */      { OP_ReadCookie,  0, 2,        0},      { OP_Integer,     0, 0,        0},      { OP_Lt,          0, 5,        0},      { OP_AddImm,      1, 0,        0},      { OP_Callback,    1, 0,        0},      { OP_Halt,        0, 0,        0},      { OP_AddImm,     -1, 0,        0},  /* 10 */      { OP_Callback,    1, 0,        0}    };    if( pRight->z==pLeft->z ){      int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);      sqliteVdbeChangeP2(v, addr+3, addr+10);    }else{      int addr;      int size = db->cache_size;      if( size<0 ) size = -size;      sqliteBeginWriteOperation(pParse, 0, 0);      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);      sqliteVdbeAddOp(v, OP_Dup, 0, 0);      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);      sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);      sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);      sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);      db->safety_level = getSafetyLevel(zRight)+1;      if( db->safety_level==1 ){        sqliteVdbeAddOp(v, OP_Negative, 0, 0);        size = -size;      }      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);      sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);      sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);      sqliteEndWriteOperation(pParse);      db->cache_size = size;      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);    }  }else  /*  **   PRAGMA synchronous  **   PRAGMA synchronous=OFF|ON|NORMAL|FULL  **  ** Return or set the local value of the synchronous flag.  Changing  ** the local value does not make changes to the disk file and the  ** default value will be restored the next time the database is  ** opened.  */  if( sqliteStrICmp(zLeft,"synchronous")==0 ){    static VdbeOpList getSync[] = {      { OP_ColumnName,  0, 1,        "synchronous"},      { OP_Callback,    1, 0,        0},    };    if( pRight->z==pLeft->z ){      sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);      sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);    }else{      int size = db->cache_size;      if( size<0 ) size = -size;      db->safety_level = getSafetyLevel(zRight)+1;      if( db->safety_level==1 ) size = -size;      db->cache_size = size;      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);    }  }else#ifndef NDEBUG  if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){    if( getBoolean(zRight) ){      always_code_trigger_setup = 1;    }else{      always_code_trigger_setup = 0;

⌨️ 快捷键说明

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