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

📄 build.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
  db->flags &= ~SQLITE_InternChanges;  /* If one or more of the auxiliary database files has been closed,  ** then remove them from the auxiliary database list.  We take the  ** opportunity to do this here since we have just deleted all of the  ** schema hash tables and therefore do not have to make any changes  ** to any of those tables.  */  for(i=0; i<db->nDb; i++){    struct Db *pDb = &db->aDb[i];    if( pDb->pBt==0 ){      if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);      pDb->pAux = 0;    }  }  for(i=j=2; i<db->nDb; i++){    struct Db *pDb = &db->aDb[i];    if( pDb->pBt==0 ){      sqliteFree(pDb->zName);      pDb->zName = 0;      continue;    }    if( j<i ){      db->aDb[j] = db->aDb[i];    }    j++;  }  memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));  db->nDb = j;  if( db->nDb<=2 && db->aDb!=db->aDbStatic ){    memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));    sqliteFree(db->aDb);    db->aDb = db->aDbStatic;  }}/*** This routine is called when a commit occurs.*/void sqlite3CommitInternalChanges(sqlite3 *db){  db->flags &= ~SQLITE_InternChanges;}/*** Clear the column names from a table or view.*/static void sqliteResetColumnNames(Table *pTable){  int i;  Column *pCol;  assert( pTable!=0 );  if( (pCol = pTable->aCol)!=0 ){    for(i=0; i<pTable->nCol; i++, pCol++){      sqliteFree(pCol->zName);      sqlite3ExprDelete(pCol->pDflt);      sqliteFree(pCol->zType);      sqliteFree(pCol->zColl);    }    sqliteFree(pTable->aCol);  }  pTable->aCol = 0;  pTable->nCol = 0;}/*** Remove the memory data structures associated with the given** Table.  No changes are made to disk by this routine.**** This routine just deletes the data structure.  It does not unlink** the table data structure from the hash table.  Nor does it remove** foreign keys from the sqlite.aFKey hash table.  But it does destroy** memory structures of the indices and foreign keys associated with ** the table.*/void sqlite3DeleteTable(Table *pTable){  Index *pIndex, *pNext;  FKey *pFKey, *pNextFKey;  if( pTable==0 ) return;  /* Do not delete the table until the reference count reaches zero. */  pTable->nRef--;  if( pTable->nRef>0 ){    return;  }  assert( pTable->nRef==0 );  /* Delete all indices associated with this table  */  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){    pNext = pIndex->pNext;    assert( pIndex->pSchema==pTable->pSchema );    sqliteDeleteIndex(pIndex);  }#ifndef SQLITE_OMIT_FOREIGN_KEY  /* Delete all foreign keys associated with this table.  The keys  ** should have already been unlinked from the pSchema->aFKey hash table   */  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){    pNextFKey = pFKey->pNextFrom;    assert( sqlite3HashFind(&pTable->pSchema->aFKey,                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );    sqliteFree(pFKey);  }#endif  /* Delete the Table structure itself.  */  sqliteResetColumnNames(pTable);  sqliteFree(pTable->zName);  sqliteFree(pTable->zColAff);  sqlite3SelectDelete(pTable->pSelect);#ifndef SQLITE_OMIT_CHECK  sqlite3ExprDelete(pTable->pCheck);#endif  sqlite3VtabClear(pTable);  sqliteFree(pTable);}/*** Unlink the given table from the hash tables and the delete the** table structure with all its indices and foreign keys.*/void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){  Table *p;  FKey *pF1, *pF2;  Db *pDb;  assert( db!=0 );  assert( iDb>=0 && iDb<db->nDb );  assert( zTabName && zTabName[0] );  pDb = &db->aDb[iDb];  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, strlen(zTabName)+1,0);  if( p ){#ifndef SQLITE_OMIT_FOREIGN_KEY    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){      int nTo = strlen(pF1->zTo) + 1;      pF2 = sqlite3HashFind(&pDb->pSchema->aFKey, pF1->zTo, nTo);      if( pF2==pF1 ){        sqlite3HashInsert(&pDb->pSchema->aFKey, pF1->zTo, nTo, pF1->pNextTo);      }else{        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }        if( pF2 ){          pF2->pNextTo = pF1->pNextTo;        }      }    }#endif    sqlite3DeleteTable(p);  }  db->flags |= SQLITE_InternChanges;}/*** Given a token, return a string that consists of the text of that** token with any quotations removed.  Space to hold the returned string** is obtained from sqliteMalloc() and must be freed by the calling** function.**** Tokens are often just pointers into the original SQL text and so** are not \000 terminated and are not persistent.  The returned string** is \000 terminated and is persistent.*/char *sqlite3NameFromToken(Token *pName){  char *zName;  if( pName ){    zName = sqliteStrNDup((char*)pName->z, pName->n);    sqlite3Dequote(zName);  }else{    zName = 0;  }  return zName;}/*** Open the sqlite_master table stored in database number iDb for** writing. The table is opened using cursor 0.*/void sqlite3OpenMasterTable(Parse *p, int iDb){  Vdbe *v = sqlite3GetVdbe(p);  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);  sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */}/*** The token *pName contains the name of a database (either "main" or** "temp" or the name of an attached db). This routine returns the** index of the named database in db->aDb[], or -1 if the named db ** does not exist.*/int sqlite3FindDb(sqlite3 *db, Token *pName){  int i = -1;    /* Database number */  int n;         /* Number of characters in the name */  Db *pDb;       /* A database whose name space is being searched */  char *zName;   /* Name we are searching for */  zName = sqlite3NameFromToken(pName);  if( zName ){    n = strlen(zName);    for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){      if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) &&           0==sqlite3StrICmp(pDb->zName, zName) ){        break;      }    }    sqliteFree(zName);  }  return i;}/* The table or view or trigger name is passed to this routine via tokens** pName1 and pName2. If the table name was fully qualified, for example:**** CREATE TABLE xxx.yyy (...);** ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if** the table name is not fully qualified, i.e.:**** CREATE TABLE yyy(...);**** Then pName1 is set to "yyy" and pName2 is "".**** This routine sets the *ppUnqual pointer to point at the token (pName1 or** pName2) that stores the unqualified table name.  The index of the** database "xxx" is returned.*/int sqlite3TwoPartName(  Parse *pParse,      /* Parsing and code generating context */  Token *pName1,      /* The "xxx" in the name "xxx.yyy" or "xxx" */  Token *pName2,      /* The "yyy" in the name "xxx.yyy" */  Token **pUnqual     /* Write the unqualified object name here */){  int iDb;                    /* Database holding the object */  sqlite3 *db = pParse->db;  if( pName2 && pName2->n>0 ){    assert( !db->init.busy );    *pUnqual = pName2;    iDb = sqlite3FindDb(db, pName1);    if( iDb<0 ){      sqlite3ErrorMsg(pParse, "unknown database %T", pName1);      pParse->nErr++;      return -1;    }  }else{    assert( db->init.iDb==0 || db->init.busy );    iDb = db->init.iDb;    *pUnqual = pName1;  }  return iDb;}/*** This routine is used to check if the UTF-8 string zName is a legal** unqualified name for a new schema object (table, index, view or** trigger). All names are legal except those that begin with the string** "sqlite_" (in upper, lower or mixed case). This portion of the namespace** is reserved for internal use.*/int sqlite3CheckObjectName(Parse *pParse, const char *zName){  if( !pParse->db->init.busy && pParse->nested==0           && (pParse->db->flags & SQLITE_WriteSchema)==0          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);    return SQLITE_ERROR;  }  return SQLITE_OK;}/*** Begin constructing a new table representation in memory.  This is** the first of several action routines that get called in response** to a CREATE TABLE statement.  In particular, this routine is called** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp** flag is true if the table should be stored in the auxiliary database** file instead of in the main database file.  This is normally the case** when the "TEMP" or "TEMPORARY" keyword occurs in between** CREATE and TABLE.**** The new table record is initialized and put in pParse->pNewTable.** As more of the CREATE TABLE statement is parsed, additional action** routines will be called to add more information to this record.** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine** is called to complete the construction of the new table record.*/void sqlite3StartTable(  Parse *pParse,   /* Parser context */  Token *pName1,   /* First part of the name of the table or view */  Token *pName2,   /* Second part of the name of the table or view */  int isTemp,      /* True if this is a TEMP table */  int isView,      /* True if this is a VIEW */  int isVirtual,   /* True if this is a VIRTUAL table */  int noErr        /* Do nothing if table already exists */){  Table *pTable;  char *zName = 0; /* The name of the new table */  sqlite3 *db = pParse->db;  Vdbe *v;  int iDb;         /* Database number to create the table in */  Token *pName;    /* Unqualified name of the table to create */  /* The table or view name to create is passed to this routine via tokens  ** pName1 and pName2. If the table name was fully qualified, for example:  **  ** CREATE TABLE xxx.yyy (...);  **   ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if  ** the table name is not fully qualified, i.e.:  **  ** CREATE TABLE yyy(...);  **  ** Then pName1 is set to "yyy" and pName2 is "".  **  ** The call below sets the pName pointer to point at the token (pName1 or  ** pName2) that stores the unqualified table name. The variable iDb is  ** set to the index of the database that the table or view is to be  ** created in.  */  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);  if( iDb<0 ) return;  if( !OMIT_TEMPDB && isTemp && iDb>1 ){    /* If creating a temp table, the name may not be qualified */    sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");    return;  }  if( !OMIT_TEMPDB && isTemp ) iDb = 1;  pParse->sNameToken = *pName;  zName = sqlite3NameFromToken(pName);  if( zName==0 ) return;  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){    goto begin_table_error;  }  if( db->init.iDb==1 ) isTemp = 1;#ifndef SQLITE_OMIT_AUTHORIZATION  assert( (isTemp & 1)==isTemp );  {    int code;    char *zDb = db->aDb[iDb].zName;    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){      goto begin_table_error;    }    if( isView ){      if( !OMIT_TEMPDB && isTemp ){        code = SQLITE_CREATE_TEMP_VIEW;      }else{        code = SQLITE_CREATE_VIEW;      }    }else{      if( !OMIT_TEMPDB && isTemp ){        code = SQLITE_CREATE_TEMP_TABLE;      }else{        code = SQLITE_CREATE_TABLE;      }    }    if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){      goto begin_table_error;    }  }#endif  /* Make sure the new table name does not collide with an existing  ** index or table name in the same database.  Issue an error message if  ** it does. The exception is if the statement being parsed was passed  ** to an sqlite3_declare_vtab() call. In that case only the column names  ** and types will be used, so there is no need to test for namespace  ** collisions.  */  if( !IN_DECLARE_VTAB ){    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){      goto begin_table_error;    }    pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);    if( pTable ){      if( !noErr ){        sqlite3ErrorMsg(pParse, "table %T already exists", pName);      }      goto begin_table_error;    }    if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){      sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);      goto begin_table_error;    }  }  pTable = sqliteMalloc( sizeof(Table) );  if( pTable==0 ){    pParse->rc = SQLITE_NOMEM;    pParse->nErr++;    goto begin_table_error;  }  pTable->zName = zName;  pTable->iPKey = -1;  pTable->pSchema = db->aDb[iDb].pSchema;  pTable->nRef = 1;  if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);  pParse->pNewTable = pTable;  /* If this is the magic sqlite_sequence table used by autoincrement,  ** then record a pointer to this table in the main database structure  ** so that INSERT can find the table easily.  */#ifndef SQLITE_OMIT_AUTOINCREMENT  if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){    pTable->pSchema->pSeqTab = pTable;  }#endif

⌨️ 快捷键说明

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