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

📄 exec.c

📁 在VC6环境下开发
💻 C
📖 第 1 页 / 共 3 页
字号:
			case TK_GE:
			case TK_GT:
			case TK_NE:
			case TK_EQ:{
				pE = pE->pLeft;
				idxPage = pE->iIndex;
				if(pE->iIndex > 0){
					int j;
					/*
					** if the index has opened
					** then do not open again
					*/
					for(j=base;j<nCur;j++){
						if(aiCur[j] == pE->iIndex){
							pE->iIndex = j;
							break;					
						}
					}
					if(j < nCur) continue;
					rc = eDbBtreeCursor(db->pBt,idxPage,1,&db->pCur[nCur]);
					if(rc) nErr++;
					aiCur[nCur] = pE->iIndex;
					pE->iIndex = nCur++;					
				}
				break;
			}
			default:{
				nErr ++;
			}
		} 
		if(nErr) break;
	} /* end for(i=0;i<aCExpr.nExpr;i++)*/
	*iCur = nCur;
	return nErr;
}

/*
** open all tables with db->pCur[i],
** return 0 if success and set SrcList.a[].iCursor to i,
** return >0 if any error occured
*/
int openTables(eDb *db, SrcList *pSrc, int *iCur){
	int i,rc,nErr;	
	int nCur;
	Table *pTable;
	nErr = 0;
	nCur = *iCur;
	for(i=0;i<pSrc->nSrc;i++){
		pTable = pSrc->a[i].pTab;
		rc = eDbBtreeCursor(db->pBt,pTable->tnum,0,&db->pCur[nCur++]);
		if( rc ){
			nErr ++;
			break;
		}
		pSrc->a[i].iCursor = i;		
	}
	*iCur = nCur;
	return nErr;
}

/*
** get a key id
*/ 
int getKeyID(eDb *db,BtCursor *pCur){
	int zKey;
	int rc,res;
	if(!db->nextRowidValid){
		rc = eDbBtreeLast(pCur,&res);
		if(res){
			zKey = 1;
		}
		else{
			eDbBtreeKey(pCur,0,sizeof(int),(char *)&zKey);
			zKey = keyToInt(zKey)+1;
		}	
		assert(zKey < 0x7fffffff);
		db->nextRowid = zKey+1;
		db->nextRowidValid = 1;
	}
	else{
		zKey = db->nextRowid++;
	}
	zKey = intToKey(zKey);
	return zKey;
}

/*
** make a KeyData structure
*/
KeyData *makeOneTupleRec(BtCursor *pCur, int zKey, int flag,ParseResult *pRes){
	char **aCol;
	int i,j;
	
	Table *pTab;
	IdList *pIdList;
	ExprList *pEList;
	KeyData *pTuple;
	
	pTab = pRes->pTable;
	pIdList = pRes->pIdList;
	pEList = pRes->pEList;
	aCol = eDbMalloc(sizeof(char *) * pTab->nCol);
	if( aCol == 0){
		return 0;
	}
	for(i=0;i<pTab->nCol;i++){
		if(pIdList){
			/*
			** get the column values from ExprList
			** 
			*/
			for(j=0;j<pIdList->nId;j++){
				if(pIdList->a[j].idx == i){				
					eDbSetNString(&aCol[i],
						pEList->a[j].pExpr->token.z,
						pEList->a[j].pExpr->token.n,0
						);
					eDbDequote(aCol[i]);
					break;
				}
			}
			if(j >= pIdList->nId){
				/*
				** if the column id not exists 
				** then get it from old value [in UPDATE] or
				** set it NULL [in INSERT]
				*/
				if(flag == TK_UPDATE)
					aCol[i] = eDbBtreeGetColumnData(pCur,i,0);
				else
					aCol[i] = 0;
			}
		}else{
			eDbSetNString(&aCol[i],
				pEList->a[i].pExpr->token.z,
				pEList->a[i].pExpr->token.n,0
				);
			eDbDequote(aCol[i]);
		}
		if(eDb_malloc_failed) break;
	}
	if( eDb_malloc_failed ){
		pTuple = 0;			
	}else{
		if(pTab->hasPrimKey && pTab->iPKey >= 0){
			zKey = atoi(aCol[pTab->iPKey]);
			zKey = intToKey(zKey);
		}
		pTuple = fillKeyData(zKey,aCol,pTab->nCol);
	}
	for(j=0; j < i; j++){
		eDbFree(aCol[j]);
	}
	eDbFree(aCol);
	return pTuple;
}

KeyData *makeIdxKey(BtCursor *pCur, Index *pIdx,
					int zKey,int flag,ParseResult *pRes){	
	int i,j,k;
	int nByte;
	int newidx;
	char **aCol;
	IdList *pIdList;
	ExprList *pExpr;
	Table *pTab;
	KeyData *pTuple;

	pTab = pIdx->pTable;	
	pIdList = pRes->pIdList;
	pExpr = pRes->pEList;

	nByte = 0;
	newidx = 0;
	aCol = eDbMalloc(sizeof(char *) * pIdx->nColumn);
	for(i=0; i<pIdx->nColumn; i++){
		if(eDb_malloc_failed) break;
		if(pIdList){
			/*
			** find the idx column in table
			*/
			for(j=0;j<pIdList->nId;j++){
				if(pIdList->a[j].idx == pIdx->aiColumn[i]){	
					newidx = 1;
					eDbSetNString(&aCol[i],
						pExpr->a[j].pExpr->token.z,
						pExpr->a[j].pExpr->token.n,0
						);
					eDbDequote(aCol[i]);
					nByte += strlen(aCol[i]);
					break;
				}else{
					aCol[i] = 0;
				}

			}
		}else{
			/*
			** no column name 
			** if the op is insert, then get the value from Expr
			** else if op is update, then get the value from old value
 			*/
			if( flag == TK_INSERT ){
				newidx = 1;
				j = pIdx->aiColumn[i];
				eDbSetNString(&aCol[i],
					pExpr->a[j].pExpr->token.z,
					pExpr->a[j].pExpr->token.n,0
					);
				eDbDequote(aCol[i]);
			}else{
				aCol[i] = eDbBtreeGetColumnData(pCur,i,0);
			}
			nByte += strlen(aCol[i]);
		}		
	}

	if(eDb_malloc_failed || !newidx) {
		/*
		** the memory fail to malloc 
		** or the index not changed
		*/
		for(j=0;j<i;j++){
			eDbFree(aCol[j]);		
		}
		eDbFree(aCol);
		pTuple = 0;
	}else{
		pTuple = eDbMalloc(sizeof(KeyData));
		pTuple->nKey = nByte + 1 + sizeof(int);
		pTuple->pKey = eDbMalloc(pTuple->nKey);
		j = 0;
		for(i=0;i<pIdx->nColumn;i++){
			/*
			int t = pTab->aCol[pIdx->aiColumn[i]].type;
			if(t != eDb_SO_TEXT){
				double r;
				char z[32];
				r = eDbAtoF(aCol[i],0);
				eDbRealToSortable(r,z);
				k = strlen(z)+1;
				pData->pKey[j++] = 'b';
				memcpy(&pData->pKey[j],z,k);
			}
			else{
				k = strlen(aCol[i])+1;
				pData->pKey[j++] = 'c';
				memcpy(&pData->pKey[j],aCol[i],k);
			}
			*/
			k = strlen(aCol[i]);
			memcpy(&pTuple->pKey[j],aCol[i],k);
			j += k;
			eDbFree(aCol[i]);		
		}
		memcpy(&pTuple->pKey[j+1],&zKey,sizeof(int));
		eDbFree(aCol);
	}
	return pTuple;
}

int dmleDbInsert(eDb *db,ParseResult *pRes, int *nCur){
	int rc;
	int iTable;	
	int zKey;
	int iCur;
	int base;

	Table *pTab;
	Index *pIdx;
	IdList *pId;
	ExprList *pExpr;
	KeyData *pTuple, *pIdxTuple;

	pTab = pRes->pTable;
	pId = pRes->pIdList;
	pExpr = pRes->pEList;
	pIdx = pTab->pIndex;	
	iTable = pTab->tnum;

	iCur = base = *nCur;
	rc = eDbBtreeCursor(db->pBt,iTable,1,&db->pCur[iCur++]);
	if( rc ) {
		goto err_handle;
	} 
	/*
	** make tuple and insert into table
	*/	
	zKey = getKeyID(db,db->pCur[base]);
	pTuple = makeOneTupleRec(db->pCur[base],zKey,TK_INSERT,pRes);
	if(pTuple == 0){
		goto err_handle;
	}
	memcpy(&zKey,pTuple->pKey,SIZEOFINT);
	/*
	** insert the idx key to index table
	*/
	for(;pIdx;pIdx=pIdx->pNext,iCur++){
		rc = eDbBtreeCursor(db->pBt,pIdx->tnum,1,&db->pCur[iCur]);
		if( rc ){
			goto err_handle;
		}
		pIdxTuple = makeIdxKey(db->pCur[iCur],pIdx,zKey,TK_INSERT,pRes);
		if(pIdxTuple == 0) continue;
		if(pIdx->unique == OP_Unique){
			rc = eDbLookupTupleByIdxKey(db->pCur[iCur],
					pIdxTuple->pKey,pIdxTuple->nKey,
					SIZEOFINT,TK_EQ);
			/* go error if no unique*/
			if( rc ){
				eDbFreeKayData(pIdxTuple);
				goto err_handle;
			}
		}
		rc = eDbBtreeInsert(db->pCur[iCur],
			pIdxTuple->pKey,pIdxTuple->nKey,0,0);
		eDbFreeKayData(pIdxTuple);
		if( rc ) {
			goto err_handle;
		}		
	}

	if(pTab->hasPrimKey && pTab->iPKey >= 0){
		int res;
		rc = eDbBtreeMoveto(db->pCur[base],pTuple->pKey,pTuple->nKey,&res);
		if( res==0 || rc ){ 
			rc = 1;
			goto err_handle;
		}
	}
	rc = eDbBtreeInsert(db->pCur[base],
		pTuple->pKey, pTuple->nKey,
		pTuple->pData, pTuple->nData);
	if( rc ) {
		goto err_handle;
	} 	
	eDbFreeKayData(pTuple);

err_handle:
	
	*nCur = iCur;
	return rc;
}

int dmleDbUpdate(eDb *db,ParseResult *pRes, int *nCur){
	int rc,res;
	int iTable;
	int iCur;
	int base;	
	int nRec = 0;

	Table *pTab;
	Index *pIdx;
	Expr *pWhere;
	IdList *pIdList;
	KeyData *pTuple;

	pTab = pRes->pTable;
	iTable = pTab->tnum;
	pWhere = pRes->pWhere;
	pIdList = pRes->pIdList;

	/* 
	** open the base table with iCur=0
	*/
	iCur = base = *nCur;
	rc = eDbBtreeCursor(db->pBt,iTable,1,&db->pCur[iCur++]);
	if( rc ) {
		goto err_handle;
	}
	/*
	** open the index 
	*/
	pIdx = pTab->pIndex;
	for(; pIdx; pIdx=pIdx->pNext){
		rc = eDbBtreeCursor(db->pBt,pIdx->tnum,1,&db->pCur[iCur++]);
		if( rc ) goto err_handle;
	}
	if(!pWhere){
		/*
		** update all record
		*/
	
	}else{
		int ok;
		int zOldKey,zNewKey;
		if(aCExpr.useIndex){
			
		}else{
			rc = eDbBtreeFirst(db->pCur[base],&res);
			while(!rc && !res){
				/*exec each expression*/
				ok = checkConditionOk(db,base,&aCExpr);
				if( ok ){
					int i;
					pIdx = pTab->pIndex;
					/*
					** update the record in table
 					*/
					eDbBtreeKey(db->pCur[base],0,SIZEOFINT,(char *)&zOldKey);
					pTuple = makeOneTupleRec(db->pCur[base],zOldKey,TK_UPDATE,pRes);
					if(pTab->hasPrimKey && pTab->iPKey >= 0){
						/*
						** integer primary key must be unique
						*/
						memcpy(&zNewKey,pTuple->pKey,SIZEOFINT);
						if(zNewKey != zOldKey){
							rc = eDbBtreeDelete(db->pCur[base]);
							rc = eDbBtreeMoveto(db->pCur[base],pTuple->pKey,pTuple->nKey,&res);
							if( res == 0) goto err_handle;		
						}
					}
					/*
					** update index
					*/
					for(i=1; pIdx; pIdx=pIdx->pNext, i++){
						rc = updateIndexRec(db,pIdx,pRes,zOldKey,i,base);
						if( rc ) goto err_handle;
					}
					
					rc = eDbBtreeInsert(db->pCur[base],pTuple->pKey,pTuple->nKey,pTuple->pData,pTuple->nData);
					eDbFreeKayData(pTuple);
					nRec ++;
				}
				rc = eDbBtreeNext(db->pCur[base],&res);
			}	/* end while */
		}
	}	

	nRec = nRec;

err_handle:
	*nCur = iCur;
	return rc;
}

int dmleDbDelete(eDb *db,ParseResult *pRes, int *nCur){
	int rc,res;
	int iTable;
	int iCur;
	int base;
	int aiCur[MAX_CURSORS];
	int nRec = 0;
	
	Table *pTab;
	Index *pIdx;
	Expr *pExpr;

	pTab = pRes->pTable;
	iTable = pTab->tnum;
	pExpr = pRes->pWhere;
	memset(aiCur,-1,sizeof(aiCur));

	iCur = base = *nCur;
	/* open the base table with iCur=0*/
	rc = eDbBtreeCursor(db->pBt,iTable,1,&db->pCur[iCur++]);
	if( rc ){
		goto err_handle;
	}
	pIdx = pTab->pIndex;
	/*
	** open all index
 	*/
	for(;pIdx;pIdx=pIdx->pNext){
		rc = eDbBtreeCursor(db->pBt,pIdx->tnum,1,&db->pCur[iCur++]);
		if( rc ) goto err_handle;
	}
	if(!pExpr){/*delete all record*/
	
	}else{
		int ok;
		if(aCExpr.useIndex){

		}else{			
			rc = eDbBtreeFirst(db->pCur[base],&res);
			while(!rc && !res){
				ok = checkConditionOk(db,base,&aCExpr);
				if( ok ){
					int n,m,k,zKey;
					char zCols[MAXLEN_IDXCOLUMN];
					char idxKey[MAXLEN_IDXKEY];										
					eDbBtreeKey(db->pCur[base],0,SIZEOFINT,(char*)&zKey);
					
					pIdx = pTab->pIndex;
					for(k=base+1;pIdx;pIdx=pIdx->pNext,k++){
						rc = eDbBtreeCursor(db->pBt,pIdx->tnum,1,&db->pCur[k]);
						if( rc ){
							goto err_handle;
						}
						/*
						** make idx key
						*/
						idxKey[0] = 0;
						for(n=0;n<pIdx->nColumn;n++){
							m = pIdx->aiColumn[n];
							eDbBtreeGetColumnData(db->pCur[base],m,zCols);
							strcat(idxKey,zCols);
						}
						m = strlen(idxKey);
						idxKey[m++] = 0;
						memcpy(&idxKey[m],&zKey,SIZEOFINT);
						m += SIZEOFINT;
						/*

⌨️ 快捷键说明

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