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

📄 pragma.c

📁 sqlite 嵌入式数据库的源码
💻 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.95 2005/06/12 21:35:52 drh 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 u8 *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 u8 *z){  return getSafetyLevel(z)&1;}#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->flags & SQLITE_InTrans ){      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, 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[] = {    { "vdbe_trace",               SQLITE_VdbeTrace     },    { "sql_trace",                SQLITE_SqlTrace      },    { "vdbe_listing",             SQLITE_VdbeListing   },    { "full_column_names",        SQLITE_FullColNames  },    { "short_column_names",       SQLITE_ShortColNames },    { "count_changes",            SQLITE_CountRows     },    { "empty_result_callbacks",   SQLITE_NullCallback  },    /* The following is VERY experimental */    { "writable_schema",          SQLITE_WriteSchema   },    { "omit_readlock",            SQLITE_NoReadlock    },  };  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;          }        }        /* If one of these pragmas is executed, any prepared statements        ** need to be recompiled.        */        sqlite3VdbeAddOp(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 = 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];  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, "cache_size", P3_STATIC);      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);      sqlite3VdbeChangeP1(v, addr, iDb);      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);    }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->cache_size = size;      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->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#endif /* SQLITE_OMIT_PAGER_PRAGMAS */  /*  **  PRAGMA [database.]auto_vacuum  **  PRAGMA [database.]auto_vacuum=N  **  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.

⌨️ 快捷键说明

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