📄 exec.c
字号:
#include "eDbInit.h"
extern int eDbRunParser(Parser*, const char*, char **);
int getKeyID(eDb *db,BtCursor *pCur);
int checkConditionOk(eDb *db, int base, WhereExpr *pW);
KeyData *fillKeyData(int zKey, char *apCols[], int nCol);
int updateIndexRec(eDb *db,Index *pIdx,ParseResult *pRes,
int zKey, int iCur,int tCur);
int dispRecord(eDb *db, int aiCols[],int aiCur[], int n, int base, int nRec);
#ifndef WIN32
void eDbStart(void){
extern void ARMTargetInit(void);
ARMTargetInit();
mem_init();
/* needed by uC/OS */
OSInit();
initFileSys();
Uart_Printf("Start Runing EDB ...\n");
}
void eDbStop(void){
Uart_Printf("Stop Runing EDB ...\n");
}
#endif
void eDbDeleteAllTable(eDb *db){
HashElem *pElem;
for(pElem=eDbHashFirst(&db->tblHash); pElem; pElem=eDbHashNext(pElem)){
Table *pTab = eDbHashData(pElem);
eDbDeleteTable(db, pTab);
}
eDbHashClear(&db->tblHash);
}
/*
** if the zDbname does not existed
** then Create a empty database file in disk
*/
int eDbCreateDB(const char *zDbname){
Btree *pBt;
int rc;
if( eDbOsFileExists(zDbname) ) return eDb_OK;
rc = eDbBtreeOpen(zDbname,1,MAX_PAGES,&pBt);
if( rc ){
return eDb_ERROR;
}
rc = eDbBtreeBeginTrans(pBt);
if( rc ){
return eDb_ERROR;
}
rc = eDbBtreeCommit(pBt);
if( rc ){
eDbBtreeRollback(pBt);
}
eDbBtreeClose(pBt);
return rc;
}
/*
** close the database in memory
** release all memory
*/
int eDbCloseDB(eDb *db){
if( db ){
if(db->pBt){
eDbBtreeClose(db->pBt);
db->pBt = 0;
}
eDbDeleteAllTable(db);
eDbHashClear(&db->idxHash);
eDbFree(db);
}
return eDb_OK;
}
/*
** open the database with zDbname
** return eDb_OK and db is a handle point to the opened database
** or else return eDb_ERROR and db is 0
*/
int eDbOpenDB(eDb **db,const char *zDbname){
int rc,res;
eDb *tDb = eDbMalloc(sizeof(eDb));
*db = tDb;
tDb->zName = (char *)zDbname;
/*
** init the hash structure
*/
eDbHashInit(&tDb->tblHash, eDb_HASH_STRING, 0);
eDbHashInit(&tDb->idxHash, eDb_HASH_STRING, 0);
/*
** Create a Btree
*/
rc = eDbBtreeOpen(zDbname,1,MAX_PAGES,&tDb->pBt);
if( rc ) {
goto open_err;
}
/*
** Create a BtCursor
*/
rc = eDbBtreeCursor(tDb->pBt,2,0,&tDb->pCur[0]);
if( rc ){
goto open_err;
}
/*
** rewind the cursor to begin
*/
rc = eDbBtreeFirst(tDb->pCur[0],&res);
/*
** loop
** deal with all tables and indexs
*/
while( !rc && !res ){
char *z;
int isTable;
/*
** 0 table or index
** 1 index name or table name
** 2 table name
** 3 rootpage
** 4 sql text
*/
z = eDbBtreeGetColumnData(tDb->pCur[0],0,0);
if(strcmp(z,"table") == 0){
isTable = 1;
}
else
isTable = 0;
eDbFree(z);
z = eDbBtreeGetColumnData(tDb->pCur[0],4,0);
if( z && z[0] ){
Parser sParse;
memset(&sParse,0,sizeof(sParse));
sParse.db = tDb;
rc = eDbRunParser(&sParse,z,0);
eDbFreeParseResult(sParse.pResult);
eDbFree(z);
if( rc ) goto open_err;
/*
** get root page number of the table
*/
z = eDbBtreeGetColumnData(tDb->pCur[0],3,0);
if(isTable){
ParseResult *pRes = sParse.pResult;
Table *p = pRes->pTable;
p->tnum = atoi(z);
}
else{
ParseResult *pRes = sParse.pResult;
Index *p = pRes->pIndex;
p->tnum = atoi(z);
}
eDbFree(z);
}
else{
if(!isTable){
Index *pIndex;
z = eDbBtreeGetColumnData(tDb->pCur[0],1,0);
pIndex = eDbFindIndex(tDb,z,0);
eDbFree(z);
if(pIndex){
z = eDbBtreeGetColumnData(tDb->pCur[0],3,0);
if(pIndex) pIndex->tnum = atoi(z);
eDbFree(z);
}
}
}
rc = eDbBtreeNext(tDb->pCur[0],&res);
}/* end while(!rc && !res )*/
eDbBtreeCloseCursor(tDb->pCur[0]);
return eDb_OK;
open_err:
if ( tDb->pCur[0] ) {
eDbBtreeCloseCursor(tDb->pCur[0]);
}
tDb->pCur[0] = 0;
eDbFree(tDb);
return eDb_ERROR;
}
/*
** create a table
*/
int ddlCreateTable(eDb *db,ParseResult *pRes, int *nCur){
int rc;
int rootPage;
int zKey;
int iCur;
int base;
char tnum[11];
char *aCols[5];
char *zType = "table";
Table *pTable;
Index *pIndex;
KeyData *pTuple;
pTable = pRes->pTable;
pIndex = pTable->pIndex;
base = iCur = *nCur;
rc = eDbBtreeCursor(db->pBt,2,1,&db->pCur[iCur++]);
if( rc ){
goto err_handle;
}
rc = eDbBtreeCreateTable(db->pBt,&rootPage);
if( rc ){
goto err_handle;
}
itoa(rootPage,tnum,10);
pTable->tnum = rootPage;
aCols[0] = zType;
aCols[1] = aCols[2] = pTable->zName;
aCols[3] = tnum;
aCols[4] = pRes->zSql;
zKey = getKeyID(db,db->pCur[base]);
pTuple = fillKeyData(zKey,aCols,5);
rc = eDbBtreeInsert(db->pCur[base],
pTuple->pKey, pTuple->nKey,
pTuple->pData, pTuple->nData);
eDbFreeKayData(pTuple);
if( rc ){
goto err_handle;
}
if( pIndex ) {
pRes->zSql = 0;
pRes->pIndex = pIndex;
rc = ddlCreateIndex(db,pRes,&iCur);
}
err_handle:
*nCur = iCur;
return rc;
}
/*
** drop a table
*/
int ddlDropTable(eDb *db,ParseResult *pRes, int *nCur){
int rc,res;
int iCur;
int base;
int rootPage = 0;
char *zTablename;
char *zBuf;
Table *pTable;
pTable = pRes->pTable;
rootPage = pTable->tnum;
zTablename = eDbStrDup(pTable->zName);
eDbDeleteTable(db,pTable);
iCur = base = *nCur;
rc = eDbBtreeCursor(db->pBt,2,1,&db->pCur[iCur++]);
if( rc ) {
goto err_handle;
}
rc = eDbBtreeFirst(db->pCur[base],&res);
/*
** search the record contained the table name
*/
while(!rc && !res){
zBuf = eDbBtreeGetColumnData(db->pCur[base],1,0);
if(eDbStrICmp(zTablename, zBuf) == 0){
eDbFree(zBuf);
break;
}
eDbFree(zBuf);
rc = eDbBtreeNext(db->pCur[base],&res);
}
eDbFree(zTablename);
if( rc || res ){
goto err_handle;
}
rc = eDbBtreeDelete(db->pCur[base]);
if( rc ) {
goto err_handle;
}
/*
** clear all records in table
*/
rc = eDbBtreeDropTable(db->pBt,rootPage);
if( rc ) {
goto err_handle;
}
err_handle:
*nCur = iCur;
return rc;
}
/*
** create a index table by zSql statement
** return eDb_OK if success
** or else return eDb_ERROR
*/
int ddlCreateIndex(eDb *db,ParseResult *pRes, int *nCur){
int iTable;
int iIndex;
int i,nCol;
int rc,res;
int zKey;
int iCur;
int base;
char *aCols[5];
char tnum[12];
char *zType = "index";
KeyData *pTuple;
Index *pIndex;
Table *pTab;
pIndex = pRes->pIndex;
pTab = pIndex->pTable;
iTable = pTab->tnum;
/*
** database rootpage: pCur[0] opened for write
** table rootpage: pCur[1] opened for read
** index rootpage: pCur[2] opened for write
*/
iCur = base = *nCur;
rc = eDbBtreeCursor(db->pBt, 2, eDb_WRITEN, &db->pCur[iCur++]);
if( rc ){
goto err_handle;
}
rc = eDbBtreeCursor(db->pBt, iTable,eDb_READ, &db->pCur[iCur++]);
if( rc ){
goto err_handle;
}
rc = eDbBtreeCreateIndex(db->pBt,&iIndex);
if( rc ){
goto err_handle;
}
rc = eDbBtreeCursor(db->pBt, iIndex,eDb_WRITEN, &db->pCur[iCur++]);
if( rc ){
goto err_handle;
}
/*
** create the index schema
*/
itoa(iIndex,tnum,10);
pIndex->tnum = iIndex;
aCols[0] = zType;
aCols[1] = pIndex->zName;
aCols[2] = pTab->zName;
aCols[3] = tnum;
aCols[4] = pRes->zSql;
nCol = pIndex->nColumn;
rc = eDbBtreeFirst(db->pCur[base+1],&res);
/*
** do a index key for each tuple in base table
** insert the index key to index table
*/
while(!rc && !res){
int nKey;
char idxKey[MAXLEN_IDXKEY];
char *zBuf;
/*
** make a index key
*/
eDbBtreeKey(db->pCur[base+1],0,sizeof(int),(char *)&zKey);
assert(nCol <= 3);
idxKey[0] = 0;
for(i=0;i<nCol;i++){
int k = pIndex->aiColumn[i];
zBuf = eDbBtreeGetColumnData(db->pCur[base+1],k,0);
strcat(idxKey,zBuf);
eDbFree(zBuf);
}
nKey = strlen(idxKey);
idxKey[nKey++] = 0;
memcpy(&idxKey[nKey],&zKey,sizeof(int));
nKey += sizeof(int);
if(pIndex->unique == OP_Unique){
/*
** check the exists of the key
*/
rc = eDbBtreeMoveto(db->pCur[base+2],idxKey,nKey-sizeof(int),&res);
if(res >= 4 ){
rc = eDbBtreeKeyCompare(db->pCur[base+2],idxKey,nKey-4,4,&res);
if(res == 0){
rc = 1;
goto err_handle;
}
}
}
rc = eDbBtreeInsert(db->pCur[base+2],idxKey,nKey,0,0);
if( rc ) {
goto err_handle;
}
rc = eDbBtreeNext(db->pCur[base+1],&res);
} /* end while */
/*
** make index schema
*/
zKey = getKeyID(db,db->pCur[base]);
pTuple = fillKeyData(zKey,aCols,5);
rc = eDbBtreeInsert(db->pCur[base],
pTuple->pKey, pTuple->nKey,
pTuple->pData, pTuple->nData);
eDbFreeKayData(pTuple);
if( rc ){
goto err_handle;
}
err_handle:
*nCur = iCur;
return rc;
}
/*
** drop a index table by zSql statement
** return eDb_OK if success
** or else return eDb_ERROR
*/
int ddlDropIndex(eDb *db,ParseResult *pRes, int *nCur){
int rc,res;
int nRootPage;
int iCur;
int base;
char *zName;
char *zBuf;
Index *pIndex;
pIndex = pRes->pIndex;
zName = eDbStrDup(pIndex->zName);
nRootPage = pIndex->tnum;
eDbDeleteIndex(db,pIndex);
iCur = base = *nCur;
rc = eDbBtreeCursor(db->pBt,2,1,&db->pCur[iCur++]);
if ( rc ) {
goto err_handle;
}
rc = eDbBtreeFirst(db->pCur[base],&res);
if ( rc ) {
goto err_handle;
}
while(!rc && !res){ /*find the tuple*/
zBuf = eDbBtreeGetColumnData(db->pCur[base],1,0);
if(eDbStrICmp(zName,zBuf) == 0){
eDbFree(zBuf);
break;
}
eDbFree(zBuf);
rc = eDbBtreeNext(db->pCur[base],&res);
}
eDbFree(zName);
if( rc || res ){
goto err_handle;
}
rc = eDbBtreeDelete(db->pCur[base]);
if( rc ){
goto err_handle;
}
rc = eDbBtreeDropTable(db->pBt,nRootPage);
if( rc ){
goto err_handle;
}
err_handle:
*nCur = iCur;
return rc;
}
/*
** open all indecis with db->pCur[i],
** return 0 if success and set Expr.iIndex i,
** return >0 if any error occured
*/
int openIndex(eDb *db, int *iCur){
int i,rc,nErr;
int idxPage,nCur;
int aiCur[MAX_CURSORS];
int base = nCur = *iCur;
Expr *pE;
nErr = 0;
memset(aiCur,0,sizeof(aiCur));
for(i=0;i<aCExpr.nExpr;i++){
pE = aCExpr.a[i].pExpr;
switch(pE->op){
case TK_LE:
case TK_LT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -