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

📄 build.c

📁 在VC6环境下开发
💻 C
📖 第 1 页 / 共 2 页
字号:
	pTab = eDbFindTable(pParse->db, zName, 0);	
	if( pTab==0 ){
		eDbErrorMsg(pParse, "no such table: %s", zName);
	}
	eDbFree(zName);
	return pTab;
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void eDbDropTable(Parser *pParse, Token *pName, int isView){
	Table *pTable;
	ParseResult *pRes;
	eDb *db = pParse->db;

	if( pParse->nErr || eDb_malloc_failed ) return;
	pTable = eDbTableFromToken(pParse, pName);
	if( pTable==0 ) return;  
	/* Delete the in-memory description of the table.
	**
	** Exception: if the SQL statement began with the EXPLAIN keyword,
	** then no changes should be made.
	*/
	if( !pParse->explain ){
		eDbUnlinkTable(db, pTable);
	}
	pRes = eDbMalloc(sizeof(ParseResult));
	pRes->pTable = pTable;
	pRes->op = Op_DropTable;
	pParse->pResult = pRes;
}

/*
** Create a new index for an SQL table.  pIndex is the name of the index 
** and pTable is the name of the table that is to be indexed.  Both will 
** be NULL for a primary key .  If pTable and pIndex are NULL, use pParse->pNewTable
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed.  pList will be NULL if this
** is a primary key on the most recent column added
** to the table currently under construction.  
*/
void eDbCreateIndex(
	Parser *pParse,		/* All information about this parse */
	Token *pName,		/* Name of the index.  May be NULL */
	SrcList *pTable,	/* Name of the table to index.  Use pParse->pNewTable if 0 */
	IdList *pList,		/* A list of columns to be indexed */
	int onError,		/* OP_Unique OP_None */
	Token *pStart,		/* The CREATE token that begins a CREATE TABLE statement */
	Token *pEnd			/* The ")" that closes the CREATE INDEX statement */
){	
	char *zName = 0;
	int i, j;
	Token nullId;    /* Fake token for an empty ID list */
	Table *pTab;     /* Table to be indexed */
	Index *pIndex;   /* The index to be created */
	ParseResult *pRes;
	eDb *db = pParse->db;

	if( pParse->nErr || eDb_malloc_failed ) goto exit_create_index;
	/*
	** Find the table that is to be indexed.  Return early if not found.
	*/
	if( pTable!=0 ){
		pTab =  eDbSrcListLookup(pParse, pTable);
	}else{
		pTab =  pParse->pNewTable;
	}
	if( pTab==0 || pParse->nErr ) goto exit_create_index;
  
	/*
	** Find the name of the index.  Make sure there is not already another
	** index or table with the same name.   
	*/
	if( pName){
		Index *pISameName;    /* Another index with the same name */
		Table *pTSameName;    /* A table with same name as the index */
		zName = eDbStrNDup(pName->z, pName->n);
		if( zName==0 ){
			goto exit_create_index;
		}
		if( (pISameName = eDbFindIndex(db, zName, 0))!=0 ){
			eDbErrorMsg(pParse, "index %s already exists", zName);
			goto exit_create_index;
		}
		if( (pTSameName = eDbFindTable(db, zName, 0))!=0 ){
			eDbErrorMsg(pParse, "there is already a table named %s", zName);
			goto exit_create_index;
		}
	}else if( pName==0 ){
		char zBuf[30];
		int n;
		Index *pLoop;
		for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
		sprintf(zBuf,"%d)",n);
		zName = 0;
		eDbSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
		if( zName==0 ) goto exit_create_index;
	}else{
		zName = eDbStrNDup(pName->z, pName->n);
	}

	if( pList==0 ){
		nullId.z = pTab->aCol[pTab->nCol-1].zName;
		nullId.n = strlen(nullId.z);
		pList = eDbIdListAppend(0, &nullId);
		if( pList==0 ) goto exit_create_index;
	}

	/* 
	** Allocate the index structure. 
	*/
	pIndex = eDbMalloc( sizeof(Index) + strlen(zName) + 1 +
						sizeof(int)*pList->nId );
	if( pIndex==0 ){
		goto exit_create_index;
	}
	pIndex->aiColumn = (int*)&pIndex[1];
	pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
	strcpy(pIndex->zName, zName);
	pIndex->pTable = pTab;
	pIndex->nColumn = pList->nId;
	pIndex->autoIndex = pName==0;
	pIndex->unique = onError;

	/* Scan the names of the columns of the table to be indexed and
	** load the column indices into the Index structure.  Report an error
	** if any column is not found.
	*/
	for(i=0; i<pList->nId; i++){
		for(j=0; j<pTab->nCol; j++){
			if( eDbStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
		}
		if( j>=pTab->nCol ){
			eDbErrorMsg(pParse, "table %s has no column named %s",
			pTab->zName, pList->a[i].zName);
			eDbFree(pIndex);
			goto exit_create_index;
		}
		pIndex->aiColumn[i] = j;
	}

	/* 
	** intert the index to hash table
	*/
	if( !pParse->explain ){
		Index *p;
		p = eDbHashInsert(&db->idxHash, 
							 pIndex->zName, strlen(pIndex->zName)+1, pIndex);
		if( p ){
			eDbFree(pIndex);
			goto exit_create_index;
		}
	}
	/*
	** add the index to list
	*/
	pIndex->pNext = pTab->pIndex;
	pTab->pIndex = pIndex;
	pRes = eDbMalloc(sizeof(ParseResult));
	pRes->pIndex = pIndex;
	pRes->op = Op_CreateIndex;
	pParse->pResult = pRes;

  /* Clean up before exiting */
exit_create_index:
	eDbIdListDelete(pList);
	eDbSrcListDelete(pTable);
	eDbFree(zName);
	return;
}

/*
** This routine will drop an existing named index.  This routine
** implements the DROP INDEX statement.
*/
void eDbDropIndex(Parser *pParse, SrcList *pName){
	Index *pIndex;
	ParseResult *pRes;
	eDb *db = pParse->db;

	if( pParse->nErr || eDb_malloc_failed ) return;
	pIndex = eDbFindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
	if( pIndex==0 ){
		eDbErrorMsg(pParse, "no such index: %s", pName->a[0].zName);
		goto exit_drop_index;
	}
	if( pIndex->autoIndex ){
		eDbErrorMsg(pParse, "index associated with UNIQUE "
		  "or PRIMARY KEY constraint cannot be dropped", 0);
		goto exit_drop_index;
	}
	/* Delete the in-memory description of this index.
	*/
	if( !pParse->explain ){
		eDbUnlinkIndex(db, pIndex);
	}
	pRes = eDbMalloc(sizeof(ParseResult));
	pRes->pIndex = pIndex;
	pRes->op = Op_DropIndex;
	pParse->pResult = pRes;

exit_drop_index:
	eDbSrcListDelete(pName);
}
/*
** Append a new element to the given IdList.  Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *eDbIdListAppend(IdList *pList, Token *pToken){
	if( pList==0 ){
		pList = eDbMalloc( sizeof(IdList) );
		if( pList==0 ) return 0;
		pList->nAlloc = 0;
	}
	if( pList->nId>=pList->nAlloc ){
		struct IdList_item *a;
		pList->nAlloc = pList->nAlloc*2 + 5;
		a = eDbRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
		if( a==0 ){
			eDbIdListDelete(pList);
			return 0;
		}
		pList->a = a;
	}
	memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
	if( pToken ){
		char **pz = &pList->a[pList->nId].zName;
		eDbSetNString(pz, pToken->z, pToken->n, 0);
		if( *pz==0 ){
			eDbIdListDelete(pList);
			return 0;
		}else{
			eDbDequote(*pz);
		}
	}
	pList->nId++;
	return pList;
}

/*
** Append a new table name to the given SrcList.  Create a new SrcList if
** need be.  A new entry is created in the SrcList even if pToken is NULL.
**
** A new SrcList is returned, or NULL if malloc() fails.
**
** If pDatabase is not null, it means that the table has an optional
** database name prefix.  Like this:  "database.table".  The pDatabase
** points to the table name and the pTable points to the database name.
** The SrcList.a[].zName field is filled with the table name which might
** come from pTable (if pDatabase is NULL) or from pDatabase.  
** SrcList.a[].zDatabase is filled with the database name from pTable,
** or with NULL if no database is specified.
**
** In other words, if call like this:
**
**         eDbSrcListAppend(A,B,0);
**
** Then B is a table name and the database name is unspecified.  If called
** like this:
**
**         eDbSrcListAppend(A,B,C);
**
** Then C is the table name and B is the database name.
*/
SrcList *eDbSrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
	if( pList==0 ){
		pList = eDbMalloc( sizeof(SrcList) );
		if( pList==0 ) return 0;
			pList->nAlloc = 1;
		}
		if( pList->nSrc>=pList->nAlloc ){
		SrcList *pNew;
		pList->nAlloc *= 2;
		pNew = eDbRealloc(pList,
				   sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
		if( pNew==0 ){
			eDbSrcListDelete(pList);
			return 0;
		}
		pList = pNew;
	}
	memset(&pList->a[pList->nSrc], 0, sizeof(pList->a[0]));
	if( pDatabase && pDatabase->z==0 ){
		pDatabase = 0;
	}
	if( pDatabase && pTable ){
		Token *pTemp = pDatabase;
		pDatabase = pTable;
		pTable = pTemp;
	}
	if( pTable ){
		char **pz = &pList->a[pList->nSrc].zName;
		eDbSetNString(pz, pTable->z, pTable->n, 0);
		if( *pz==0 ){
			eDbSrcListDelete(pList);
			return 0;
		}else{
			eDbDequote(*pz);
		}
	}
	if( pDatabase ){
		char **pz = &pList->a[pList->nSrc].zDatabase;
		eDbSetNString(pz, pDatabase->z, pDatabase->n, 0);
		if( *pz==0 ){
			eDbSrcListDelete(pList);
			return 0;
		}else{
			eDbDequote(*pz);
		}
	}
	pList->a[pList->nSrc].iCursor = -1;
	pList->nSrc++;
	return pList;
}

/*
** Assign cursors to all tables in a SrcList
*/
void eDbSrcListAssignCursors(Parser *pParse, SrcList *pList){
	int i;
	for(i=0; i<pList->nSrc; i++){
		if( pList->a[i].iCursor<0 ){
			pList->a[i].iCursor = pParse->nTab++;
		}
	}
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void eDbSrcListAddAlias(SrcList *pList, Token *pToken){
	if( pList && pList->nSrc>0 ){
		int i = pList->nSrc - 1;
		eDbSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
		eDbDequote(pList->a[i].zAlias);
	}
}

/*
** Delete an IdList.
*/
void eDbIdListDelete(IdList *pList){
	int i;
	if( pList==0 ) return;
	for(i=0; i<pList->nId; i++){
		eDbFree(pList->a[i].zName);
	}
	eDbFree(pList->a);
	eDbFree(pList);
}

/*
** Return the index in pList of the identifier named zId.  Return -1
** if not found.
*/
int eDbIdListIndex(IdList *pList, const char *zName){
	  int i;
	  if( pList==0 ) return -1;
	  for(i=0; i<pList->nId; i++){
			if( eDbStrICmp(pList->a[i].zName, zName)==0 ) return i;
	  }
	  return -1;
}

/*
** Delete an entire SrcList including all its substructure.
*/
void eDbSrcListDelete(SrcList *pList){
	int i;
	if( pList==0 ) return;
	for(i=0; i<pList->nSrc; i++){
		eDbFree(pList->a[i].zDatabase);
		eDbFree(pList->a[i].zName);
		eDbFree(pList->a[i].zAlias);
		eDbSelectDelete(pList->a[i].pSelect);
		eDbExprDelete(pList->a[i].pOn);
		eDbIdListDelete(pList->a[i].pUsing);
	}
	eDbFree(pList);
}

⌨️ 快捷键说明

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