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

📄 exec.c

📁 在VC6环境下开发
💻 C
📖 第 1 页 / 共 3 页
字号:
						** search the record with the idxKey
						*/
						rc = eDbBtreeMoveto(db->pCur[k],idxKey,m,&res);
						if(res == 0){
							eDbBtreeDelete(db->pCur[k]);
						}
					
					}
					rc = eDbBtreeDelete(db->pCur[base]);
					nRec ++;
				}
				rc = eDbBtreeNext(db->pCur[base],&res);
			}
		}		
	}	
	nRec = nRec;

err_handle:
	*nCur = iCur;
	return rc;
}

int dmleDbSelect(eDb *db,ParseResult *pRes, int *nCur){
	int rc,res;
	int iCur;
	int base;
	int aiCols[MAXLEN_COLUMN];		/* the field-th in table of result set*/
	int nColumn;
	int aiCur[MAXLEN_COLUMN];	
	int nTab;
	int nRec = 0;
	
	SrcList *pSrc;
	Expr *pWhere;
	ExprList *pColList;	

	pWhere = pRes->pSelect->pWhere;
	pSrc = pRes->pSelect->pSrc;
	pColList = pRes->pSelect->pEList;
	nTab = pSrc->nSrc;
	iCur = base = *nCur;
	if( pColList ){
		int i;
		Expr *pExpr;
		for( i=0; i<pColList->nExpr; i++){
			pExpr = pColList->a[i].pExpr;
			aiCols[i] = pExpr->iColumn;
			aiCur[i] = pExpr->iTable;
		}
		nColumn = i;
	}

	/* open the base table with iCur*/
	if(openTables(db,pSrc,&iCur) > 0)
		goto err_handle;

	if(!pWhere){
		/*
		** do natural join
		*/
		int p1Cur,p2Cur,p3Cur;

		Table *pTab1,*pTab2,*pTab3;

		pTab1 = pTab2 = pTab3 = 0;
		if(pSrc->nSrc > 0)	{
			pTab1 = pSrc->a[0].pTab;
			p1Cur = base + pSrc->a[0].iCursor;
		}
		if(pSrc->nSrc > 1)	{
			pTab2 = pSrc->a[1].pTab;
			p2Cur = base + pSrc->a[1].iCursor;		
		}
		if(pSrc->nSrc > 2)	{
			pTab3 = pSrc->a[2].pTab;
			p3Cur = base + pSrc->a[2].iCursor;
		}
		/*
		** select *|collist from tbl_name1,tbl_name2,tble_name3 
		** pColList is the column list
		*/
		if( pTab1 ){
			rc = eDbBtreeFirst(db->pCur[p1Cur],&res);
		}
		for(;pTab1;){		
			if( pTab2 ){
				rc = eDbBtreeFirst(db->pCur[p2Cur],&res);
			}
			for(;pTab2;){				
				if( pTab3 ){
					rc = eDbBtreeFirst(db->pCur[p3Cur],&res);
				}
				for(;pTab3;){	
					nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
					rc = eDbBtreeNext(db->pCur[p3Cur],&res);
					if(rc || res) break;					
				}/* for(;;) pTab3 */

				if(pTab3 == 0){
					nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
				}
				rc = eDbBtreeNext(db->pCur[p2Cur],&res);
				if(rc || res) break;
			}/*for(;;) pTab2*/
			if(pTab2 == 0){
				nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
			}
			rc = eDbBtreeNext(db->pCur[p1Cur],&res);
			if(rc || res) break;
		}/* for(;;) pTab3 */
	}else{
		int ok;
		if(aCExpr.useIndex){
			/*open the index */
			rc = openIndex(db, &iCur);
		}else{
			int p1Cur,p2Cur,p3Cur;
			Table *pTab1,*pTab2,*pTab3;

			pTab1 = pTab2 = pTab3 = 0;
			if(pSrc->nSrc > 0)	{
				pTab1 = pSrc->a[0].pTab;
				p1Cur = base + pSrc->a[0].iCursor;
			}
			if(pSrc->nSrc > 1)	{
				pTab2 = pSrc->a[1].pTab;
				p2Cur = base + pSrc->a[1].iCursor;		
			}
			if(pSrc->nSrc > 2)	{
				pTab3 = pSrc->a[2].pTab;
				p3Cur = base + pSrc->a[2].iCursor;
			}
			/*
			** select *|collist from tbl_name1,tbl_name2,tble_name3 
			** pColList is the column list
			*/
			if( pTab1 ){
				rc = eDbBtreeFirst(db->pCur[p1Cur],&res);
			}
			for(;pTab1;){
				if( pTab2 ){
					rc = eDbBtreeFirst(db->pCur[p2Cur],&res);
				}
				for(;pTab2;){
					if( pTab3 ){
						rc = eDbBtreeFirst(db->pCur[p3Cur],&res);
					}
					for(;pTab3;){
						ok = checkConditionOk(db,base,&aCExpr);
						if( ok ){
							nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
						}
						rc = eDbBtreeNext(db->pCur[p3Cur],&res);
						if(rc || res) break;					
					}/*for(;;)*/

					if(pTab3 == 0){
							ok = checkConditionOk(db,base,&aCExpr);
							if( ok ){
								nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
							}		
					}					
					rc = eDbBtreeNext(db->pCur[p2Cur],&res);
					if(rc || res) break;
				}/*for(;;)*/
				if(pTab2 == 0){
					ok = checkConditionOk(db,base,&aCExpr);
					if( ok ){
						nRec = dispRecord(db,aiCols,aiCur,nColumn,base,nRec);
					}
				}
				rc = eDbBtreeNext(db->pCur[p1Cur],&res);
				if(rc || res) break;
			}/*for(;;)*/
		}
		
	}	
	nRec = nRec;
err_handle:

	*nCur = iCur;
	return rc;
}
KeyData *fillKeyData(int zKey, char *apCols[], int nCol){
	char *pBuf;
	int nByte;
	int nPointer;
	int idxWidth;
	int iLen[MAX_COLUMNS];
	int i,j,offset;

	KeyData *pTuple = eDbMalloc(sizeof(KeyData));

	pTuple->nKey = sizeof(int);
	pTuple->pKey = eDbMalloc(sizeof(int));
	memcpy(pTuple->pKey,(const char *)&zKey,sizeof(int));
	
	nByte = 0;
	for(i=0; i<nCol; i++){
		if(apCols[i]){
			iLen[i] = strlen(apCols[i])+1;
		}
		else{
			iLen[i] = 0;
			}
		nByte += iLen[i];
	}	
	nPointer = nCol + 1;

	if( nByte + nPointer < 256 ){
		idxWidth = 1;
	}else if( nByte + 2*nPointer < 65536 ){
		idxWidth = 2;
	}else{
		idxWidth = 3;
	}
	offset = idxWidth*nPointer;
	nByte += offset;
	pBuf = pTuple->pData = eDbMalloc(nByte);
	pTuple->nData = nByte;
	
	/* ------------------------------------------------------------
	** p1 | p2 | p3 | pn | d1 | d2 | d3 |...| dn | d(n+1)
	** ------------------------------------------------------------
	**  |____|____|____|____|    |    |
	**       |____|____|_________|    |
	**            |____|______________|
	**                 |______________________|
	*/
	/* store the pointer p1, p2 ...*/
	j = 0;	
	for(i=0;i<nPointer;i++){
		pBuf[j++] = offset & 0xff;
		if(idxWidth > 1){
			pBuf[j++] = (offset >> 8) & 0xff;
		}
		if(idxWidth > 2){
			pBuf[j++] = (offset >> 16) & 0xff;
		}
		offset += iLen[i];
	}
	/* store the column value d1, d2 ...*/
	for(i=0; i<nCol; i++){
		if(apCols[i]){
			strcpy(&pBuf[j],apCols[i]);	
		}
		j += iLen[i];
	}	
	return pTuple;
}

/*
** update index record
** pIdx point to a index
** iCur is the opened index cursor
** tCur is the opened base table cursor
** return 0 if success, return 1 if any error
*/
int updateIndexRec(eDb *db,Index *pIdx,ParseResult *pRes, 
				   int zKey, int iCur,int tCur){
	int i,k;
	int rc,res;
	char zCols[MAXLEN_IDXCOLUMN];
	char zIdxKey[MAXLEN_IDXKEY];
	KeyData *p;
	zIdxKey[0] = 0;
	
	p = makeIdxKey(db->pCur[tCur],pIdx,zKey,TK_UPDATE,pRes);
	
	if( p == 0) return 0;
	/*
	** make a old index key 
	*/
	for(i=0;i<pIdx->nColumn;i++){	
		k = pIdx->aiColumn[i];
		eDbBtreeGetColumnData(db->pCur[tCur],k,zCols);
		strcat(zIdxKey,zCols);
	}
	k = strlen(zIdxKey);
	zIdxKey[k++] = 0;
	memcpy(&zIdxKey[k],&zKey,SIZEOFINT);
	k += SIZEOFINT;

	/*
	** find the old index record
	*/
	rc = eDbBtreeMoveto(db->pCur[iCur],zIdxKey,k,&res);	
	assert(res == 0);
	if(res == 0) {
		/*
		** delete the old key
		*/
		res = 1;
		rc = eDbBtreeDelete(db->pCur[iCur]);
		if( pIdx->unique ){
			rc = eDbBtreeMoveto(db->pCur[iCur],
				p->pKey,p->nKey-SIZEOFINT,&res);
			if(res >= 0){
				rc = eDbBtreeKeyCompare(db->pCur[iCur],
					p->pKey,p->nKey-SIZEOFINT,SIZEOFINT,&res);
			}
		}
		if(res){
			rc = eDbBtreeInsert(db->pCur[iCur],
				p->pKey,p->nKey,0,0);
			eDbFreeKayData(p);
		}
	}
	return res == 0;
}


int eDb_exec(eDb *db,const char *zSql){	
	int rc;
	int nCur;
	int i;
	char *errMsg;
	Parser sParse;
	ParseResult *pRes;

	eDbBtreeBeginTrans(db->pBt);

	nCur = 0;
	memset(&sParse,0,sizeof(sParse));		
	sParse.db = db;
	rc = eDbRunParser(&sParse,zSql,&errMsg);
	pRes = sParse.pResult;
	if( rc || sParse.rc ){
		goto rollback;
	}		
	if(pRes == 0) goto rollback;
	pRes->zSql=eDbStrDup(zSql);
	switch(pRes->op){
		case Op_CreateTable:{
			rc = ddlCreateTable(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_DropTable:{
			rc = ddlDropTable(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_CreateIndex:{
			rc = ddlCreateIndex(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_DropIndex:{
			rc = ddlDropIndex(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_Insert:{
			rc = dmleDbInsert(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_Update:{
			rc = dmleDbUpdate(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_Delete:{
			rc = dmleDbDelete(db,pRes,&nCur);
			if( rc ) goto rollback;
			break;
		}
		case Op_Select:{
			rc = dmleDbSelect(db,pRes,&nCur);
			break;
		}
		default:{
		}
	}
	if(nCur > 4){
		for(i=0; i< nCur; i++){
			eDbBtreeCloseCursor(db->pCur[i]);
		}
		nCur = 0;
	}
	eDbFreeParseResult(pRes);

	rc = eDbBtreeCommit(db->pBt);
	if( rc ){
		goto rollback;
	}
	for(i=0; i< nCur; i++){
		eDbBtreeCloseCursor(db->pCur[i]);
	}		
	return eDb_OK;

rollback:

	eDbBtreeRollback(db->pBt);
	for(i=0; i< nCur; i++){
		eDbBtreeCloseCursor(db->pCur[i]);
	}
	eDbFreeParseResult(pRes);
	return eDb_ERROR;
}

int checkConditionOk(eDb *db, int base, WhereExpr *pW){
	int i;
	int rc,res;
	int allExprIsEnd;
	int oldOp,iCol;
	int iCur;
	int type;
	int allExprOk,singleExprOk;
	CExpr *pCE;
	Expr *pE,*pLeft,*pRight;
	char *zDes,*zSrc;
	for(i=0;i<pW->nExpr;){
		allExprIsEnd = 0;
		pE = pW->a[i].pExpr;
		pCE = &pW->a[i];
		pLeft = pE->pLeft;
		pRight = pE->pRight;
		assert(pLeft !=0 && pRight != 0);
		type = pLeft->dataType;
		if(pRight->op != TK_COLUMN){
			zDes = eDbStrNDup(pRight->token.z,pRight->token.n);
		}else{
			iCol = pRight->iColumn;
			iCur = base + pRight->iTable;
			zDes = eDbBtreeGetColumnData(db->pCur[iCur],iCol,0);
		}
		eDbDequote(zDes);

		iCol = pLeft->iColumn;
		iCur = base + pLeft->iTable;
		if(i == 0) oldOp = 0;
		else
			oldOp = pW->a[i-1].op;

		/*loop search from table*/
		rc = res = 0;		
		singleExprOk = 0;
		zSrc = eDbBtreeGetColumnData(db->pCur[iCur],iCol,0);
		if(eDbStrCompareOK(pE->op,type,zSrc,zDes)){
			singleExprOk = 1;
		}
		eDbFree(zSrc);								
		eDbFree(zDes);
		switch(oldOp){
			case TK_AND:{						
				allExprOk &= singleExprOk;
				break;
			}
			case TK_OR:{
				allExprOk |= singleExprOk;
				break;  
			}
			default:{
				allExprOk = singleExprOk;
			}
		}
		switch(pCE->op){
			case TK_AND:{						
				if(singleExprOk) i = pCE->next;
				else{
					i = pCE->go;
					while(i > 0 && pW->a[i-1].op == TK_AND){
						i = pW->a[i].go;
					}
				}
				break;
			}
			case TK_OR:{
				if(!singleExprOk) i = pCE->next;
				else{
					i = pCE->go;
					while(i > 0 && pW->a[i-1].op == TK_OR){
						i = pW->a[i].go;
					}
				}
				break;  
			}
			default:{
				allExprIsEnd = 1;
			}
		}
		if(i >= pW->nExpr || allExprIsEnd || i==0 ){
			break;
		}
	}/* end for(i=0;i<aCExpr.nExpr;i++)*/
	return allExprOk;
}

int dispRecord(eDb *db, int aiCols[],int aiCur[], int n, int base, int nRec){
	int i,j;
	char *zBuf;
	fprintf(fout,"\nRecord%d:\t",nRec+1);
	for(i=0;i<n;i++){
		j = aiCur[i];
		zBuf = eDbBtreeGetColumnData(db->pCur[base+j],aiCols[i],0);
		fprintf(fout,"%s | ",zBuf);
		eDbFree(zBuf);
	}
	nRec ++;
	return nRec;
}

⌨️ 快捷键说明

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