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

📄 build.c

📁 一个小型的嵌入式数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
void sqlite3AddColumn(Parse *pParse, Token *pName){  Table *p;  int i;  char *z;  Column *pCol;  if( (p = pParse->pNewTable)==0 ) return;  z = sqlite3NameFromToken(pName);  if( z==0 ) return;  for(i=0; i<p->nCol; i++){    if( STRICMP(z, p->aCol[i].zName) ){      sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);      sqliteFree(z);      return;    }  }  if( (p->nCol & 0x7)==0 ){    Column *aNew;    aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));    if( aNew==0 ) return;    p->aCol = aNew;  }  pCol = &p->aCol[p->nCol];  memset(pCol, 0, sizeof(p->aCol[0]));  pCol->zName = z;   /* If there is no type specified, columns have the default affinity  ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will  ** be called next to set pCol->affinity correctly.  */  pCol->affinity = SQLITE_AFF_NONE;  pCol->pColl = pParse->db->pDfltColl;  p->nCol++;}/*** This routine is called by the parser while in the middle of** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has** been seen on a column.  This routine sets the notNull flag on** the column currently under construction.*/void sqlite3AddNotNull(Parse *pParse, int onError){  Table *p;  int i;  if( (p = pParse->pNewTable)==0 ) return;  i = p->nCol-1;  if( i>=0 ) p->aCol[i].notNull = onError;}/*** Scan the column type name zType (length nType) and return the** associated affinity type.**** This routine does a case-independent search of zType for the ** substrings in the following table. If one of the substrings is** found, the corresponding affinity is returned. If zType contains** more than one of the substrings, entries toward the top of ** the table take priority. For example, if zType is 'BLOBINT', ** SQLITE_AFF_INTEGER is returned.**** Substring     | Affinity** --------------------------------** 'INT'         | SQLITE_AFF_INTEGER** 'CHAR'        | SQLITE_AFF_TEXT** 'CLOB'        | SQLITE_AFF_TEXT** 'TEXT'        | SQLITE_AFF_TEXT** 'BLOB'        | SQLITE_AFF_NONE**** If none of the substrings in the above table are found,** SQLITE_AFF_NUMERIC is returned.*/static char sqlite3AffinityType(const char *zType, int nType){  u32 h = 0;  char aff = SQLITE_AFF_NUMERIC;  const unsigned char *zIn = zType;  const unsigned char *zEnd = (zIn+nType);  while( zIn!=zEnd ){    h = (h<<8) + sqlite3UpperToLower[*zIn];    zIn++;    if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */      aff = SQLITE_AFF_TEXT;     }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */      aff = SQLITE_AFF_TEXT;    }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */      aff = SQLITE_AFF_TEXT;    }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */        && aff==SQLITE_AFF_NUMERIC ){      aff = SQLITE_AFF_NONE;    }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */      aff = SQLITE_AFF_INTEGER;       break;    }  }  return aff;}/*** This routine is called by the parser while in the middle of** parsing a CREATE TABLE statement.  The pFirst token is the first** token in the sequence of tokens that describe the type of the** column currently under construction.   pLast is the last token** in the sequence.  Use this information to construct a string** that contains the typename of the column and store that string** in zType.*/ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){  Table *p;  int i, j;  int n;  char *z;  const unsigned char *zIn;  Column *pCol;  if( (p = pParse->pNewTable)==0 ) return;  i = p->nCol-1;  if( i<0 ) return;  pCol = &p->aCol[i];  zIn = pFirst->z;  n = pLast->n + (pLast->z - zIn);  assert( pCol->zType==0 );  z = pCol->zType = sqliteMallocRaw(n+1);  if( z==0 ) return;  for(i=j=0; i<n; i++){    int c = zIn[i];    if( isspace(c) ) continue;    z[j++] = c;  }  z[j] = 0;  pCol->affinity = sqlite3AffinityType(z, n);}/*** The expression is the default value for the most recently added column** of the table currently under construction.**** Default value expressions must be constant.  Raise an exception if this** is not the case.**** This routine is called by the parser while in the middle of** parsing a CREATE TABLE statement.*/void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){  Table *p;  Column *pCol;  if( (p = pParse->pNewTable)==0 ) return;  pCol = &(p->aCol[p->nCol-1]);  if( !sqlite3ExprIsConstant(pExpr) ){    sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",        pCol->zName);  }else{    sqlite3ExprDelete(pCol->pDflt);    pCol->pDflt = sqlite3ExprDup(pExpr);  }  sqlite3ExprDelete(pExpr);}/*** Designate the PRIMARY KEY for the table.  pList is a list of names ** of columns that form the primary key.  If pList is NULL, then the** most recently added column of the table is the primary key.**** A table can have at most one primary key.  If the table already has** a primary key (and this is the second primary key) then create an** error.**** If the PRIMARY KEY is on a single column whose datatype is INTEGER,** then we will try to use that column as the rowid.  Set the Table.iPKey** field of the table under construction to be the index of the** INTEGER PRIMARY KEY column.  Table.iPKey is set to -1 if there is** no INTEGER PRIMARY KEY.**** If the key is not an INTEGER PRIMARY KEY, then create a unique** index for the key.  No index is created for INTEGER PRIMARY KEYs.*/void sqlite3AddPrimaryKey(  Parse *pParse,    /* Parsing context */  ExprList *pList,  /* List of field names to be indexed */  int onError,      /* What to do with a uniqueness conflict */  int autoInc       /* True if the AUTOINCREMENT keyword is present */){  Table *pTab = pParse->pNewTable;  char *zType = 0;  int iCol = -1, i;  if( pTab==0 ) goto primary_key_exit;  if( pTab->hasPrimKey ){    sqlite3ErrorMsg(pParse,       "table \"%s\" has more than one primary key", pTab->zName);    goto primary_key_exit;  }  pTab->hasPrimKey = 1;  if( pList==0 ){    iCol = pTab->nCol - 1;    pTab->aCol[iCol].isPrimKey = 1;  }else{    for(i=0; i<pList->nExpr; i++){      for(iCol=0; iCol<pTab->nCol; iCol++){        if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){          break;        }      }      if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;    }    if( pList->nExpr>1 ) iCol = -1;  }  if( iCol>=0 && iCol<pTab->nCol ){    zType = pTab->aCol[iCol].zType;  }  if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){    pTab->iPKey = iCol;    pTab->keyConf = onError;    pTab->autoInc = autoInc;  }else if( autoInc ){#ifndef SQLITE_OMIT_AUTOINCREMENT    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "       "INTEGER PRIMARY KEY");#endif  }else{    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);    pList = 0;  }primary_key_exit:  sqlite3ExprListDelete(pList);  return;}/*** Set the collation function of the most recently parsed table column** to the CollSeq given.*/void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){  Table *p;  Index *pIdx;  CollSeq *pColl;  int i;  if( (p = pParse->pNewTable)==0 ) return;  i = p->nCol-1;  pColl = sqlite3LocateCollSeq(pParse, zType, nType);  p->aCol[i].pColl = pColl;  /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",  ** then an index may have been created on this column before the  ** collation type was added. Correct this if it is the case.  */  for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){    assert( pIdx->nColumn==1 );    if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;  }}/*** Locate and return an entry from the db.aCollSeq hash table. If the entry** specified by zName and nName is not found and parameter 'create' is** true, then create a new entry. Otherwise return NULL.**** Each pointer stored in the sqlite3.aCollSeq hash table contains an** array of three CollSeq structures. The first is the collation sequence** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.**** Stored immediately after the three collation sequences is a copy of** the collation sequence name. A pointer to this string is stored in** each collation sequence structure.*/static CollSeq * findCollSeqEntry(  sqlite3 *db,  const char *zName,  int nName,  int create){  CollSeq *pColl;  if( nName<0 ) nName = strlen(zName);  pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);  if( 0==pColl && create ){    pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );    if( pColl ){      pColl[0].zName = (char*)&pColl[3];      pColl[0].enc = SQLITE_UTF8;      pColl[1].zName = (char*)&pColl[3];      pColl[1].enc = SQLITE_UTF16LE;      pColl[2].zName = (char*)&pColl[3];      pColl[2].enc = SQLITE_UTF16BE;      memcpy(pColl[0].zName, zName, nName);      pColl[0].zName[nName] = 0;      sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);    }  }  return pColl;}/*** Parameter zName points to a UTF-8 encoded string nName bytes long.** Return the CollSeq* pointer for the collation sequence named zName** for the encoding 'enc' from the database 'db'.**** If the entry specified is not found and 'create' is true, then create a** new entry.  Otherwise return NULL.*/CollSeq *sqlite3FindCollSeq(  sqlite3 *db,  u8 enc,  const char *zName,  int nName,  int create){  CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );  if( pColl ) pColl += enc-1;  return pColl;}/*** Invoke the 'collation needed' callback to request a collation sequence** in the database text encoding of name zName, length nName.** If the collation sequence*/static void callCollNeeded(sqlite3 *db, const char *zName, int nName){  assert( !db->xCollNeeded || !db->xCollNeeded16 );  if( nName<0 ) nName = strlen(zName);  if( db->xCollNeeded ){    char *zExternal = sqliteStrNDup(zName, nName);    if( !zExternal ) return;    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);    sqliteFree(zExternal);  }#ifndef SQLITE_OMIT_UTF16  if( db->xCollNeeded16 ){    char const *zExternal;    sqlite3_value *pTmp = sqlite3GetTransientValue(db);    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);    if( !zExternal ) return;    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);  }#endif}/*** This routine is called if the collation factory fails to deliver a** collation function in the best encoding but there may be other versions** of this collation function (for other text encodings) available. Use one** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if** possible.*/static int synthCollSeq(Parse *pParse, CollSeq *pColl){  CollSeq *pColl2;  char *z = pColl->zName;  int n = strlen(z);  sqlite3 *db = pParse->db;  int i;  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };  for(i=0; i<3; i++){    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);    if( pColl2->xCmp!=0 ){      memcpy(pColl, pColl2, sizeof(CollSeq));      return SQLITE_OK;    }  }  if( pParse->nErr==0 ){    sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z);  }  pParse->nErr++;  return SQLITE_ERROR;}/*** This routine is called on a collation sequence before it is used to** check that it is defined. An undefined collation sequence exists when** a database is loaded that contains references to collation sequences** that have not been defined by sqlite3_create_collation() etc.**** If required, this routine calls the 'collation needed' callback to** request a definition of the collating sequence. If this doesn't work, ** an equivalent collating sequence that uses a text encoding different** from the main database is substituted, if one is available.*/int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){  if( pColl && !pColl->xCmp ){    /* No collation sequence of this type for this encoding is registered.    ** Call the collation factory to see if it can supply us with one.    */    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){      return SQLITE_ERROR;    }  }  return SQLITE_OK;}/*** Call sqlite3CheckCollSeq() for all collating sequences in an index,** in order to verify that all the necessary collating sequences are** loaded.*/int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){  if( pIdx ){    int i;    for(i=0; i<pIdx->nColumn; i++){      if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){        return SQLITE_ERROR;      }    }  }  return SQLITE_OK;}

⌨️ 快捷键说明

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