Intepretor.cpp
资源名称:minisqlc.rar [点击查看]
上传用户:lkd6667
上传日期:2015-05-13
资源大小:1448k
文件大小:36k
源码类别:
其他数据库
开发平台:
C/C++
- #include "Intepretor.h"
- #include "Glob_Var.h"
- extern char CurLocation[256];
- //<---存有当前正在使用的表的相对路径
- extern char CurRelationName[33];
- //<---存当前表的表名
- char CurDB[33] = "";
- //---用于抛出字串输入错误时输出错误提示使用
- char* ppErr[] = {"Not an available command!",
- "Common typing error!",
- "Wrong type of the data ,you can only use 'char','float','int' ",
- "Please type the correct keyword!--like 'NotNull','imary'",
- "Your Column name doesn't exist!",
- "We does't support your operator typed",
- "You must specify at least one Column for us to select it!"};
- //<---用于抛出一般性错误时输出错误提示使用
- char* ppGnlErr[] = {"The DB doesn't exist!",
- "The Table doesn't exist!",
- "You haven't choose a database!",
- "This DB has already existed!",
- "This Table has already existed!",
- "You must have 2 ' to match each other!",
- "No primary key exists!"};
- ECMD_TYPE GetCommand(TB_Create_Info** ptrCreateInfo,TB_Select_Info** ptrSelectInfo,TB_Insert_Info** ptrInsertInfo,TB_Update_Info** ptrUpdateInfo,TB_Delete_Info** ptrDeleteInfo)
- {
- ECMD_TYPE CmdType = UNORMAL;//<---假设给出的命令是非正常的
- try{
- //--->打出提示信息
- std::cout<<'n';
- std::cout<<"MiniSQL->";
- Ch_csVstrBlk CommandInput;
- //<---开始作解析命令的尝试
- CmdType = CommandInput.ResolveCmd();
- //<---开始对输入的是何命令作解析,由ResolveCmd()对第一个有意字串作判断
- if(CmdType != USE && CmdType != HELP && CmdType != QUIT
- && CmdType != SHOWDB && CmdType != DROP&&CmdType != NEW)
- //<---以下命令必须在选择数据库后才能执行
- {if(CompStrEver(CurDB,""))
- { CmdType = UNORMAL;
- GnlTrwErr(NODBUSED);}
- }
- switch(CmdType) //<---选择命令
- {
- case CREATE:
- *ptrCreateInfo = CommandInput.CH_Create();
- //<---对非该命令的指针赋0
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- return CREATE;
- break;
- case SELECT:
- *ptrSelectInfo = CommandInput.CH_Select();
- *ptrCreateInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- return SELECT;
- break;
- case INSERT:
- *ptrInsertInfo = CommandInput.CH_Insert();
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- return INSERT;
- break;
- case DELETE:
- *ptrDeleteInfo = CommandInput.CH_Delete();
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- return DELETE;
- break;
- case USE: //<---选择数据库
- *ptrDeleteInfo = 0;
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- CommandInput.ChoseDatabase();
- return USE;
- break;
- case DROP:
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- CommandInput.DropTB();
- return DROP;
- break;
- case DROPDB:
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- CommandInput.DropDB();
- return DROPDB;
- break;
- case NEW:
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- CommandInput.NewDB();
- return NEW;
- break;
- case QUIT:
- CommandInput.PassCommon(";");
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- QuitSQL();
- return QUIT;
- break;
- case SHOWDB:
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- ShowDB();
- break;
- case SHOWTABLE:
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- if(CompStrEver(CurDB,""))
- GnlTrwErr(NODBUSED);
- ShowTable();
- break;
- case HELP:
- CommandInput.PassCommon(";");
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- ShowHelp();
- break;
- default :
- *ptrCreateInfo=0;
- *ptrSelectInfo=0;
- *ptrInsertInfo=0;
- *ptrUpdateInfo=0;
- *ptrDeleteInfo = 0;
- break;
- }
- }
- catch(ErrInfo a)
- //字串输入错误,给出提示--->
- {
- std::cout<<"The Error near '"<<a.pErrStr<<"'"<<"in Line "<<a.iLineNo<<" may be: n";
- std::cout<< ppErr[a.iErrType]<<'n';
- CmdType = UNORMAL;
- }
- catch(GnlErrInfo a)
- //一般性错误--->
- {
- std::cout<< ppGnlErr[a.iErrType]<<'n';
- std::cout<< "Please type 'help' to get help!n";
- CmdType = UNORMAL;
- }
- return CmdType;
- }
- //构造函数,对输入进行处理,产生一个有以字串的集合--->
- Ch_csVstrBlk::Ch_csVstrBlk()
- {
- InitialVar(); //<---初始化输入字串
- MakeVstrBlkList(); //<---生成有意字串块的链表
- }
- void Ch_csVstrBlk::InitialVar()
- {
- //初始化某些参数--->
- StrHead = 0;
- StrNow = 0;
- StrTail = 0;
- iNumNowInVstr = 0;
- iLineNum[0][0] = 0;
- sta_i = 0;
- strInputCharList = InitialInput();
- }
- //对输入进行处理,产生一个有意字串的集合--->
- void Ch_csVstrBlk::MakeVstrBlkList()
- {
- int flag;
- int iForLineNum = 0;
- char* tempStr;
- VSTR_BLK_PTR vbNewBlk;
- do
- {
- flag = InString(&tempStr);
- //<---可能在字符串拷贝时会出错,小心
- if(flag == 0)
- {
- //<---返回有意字串
- iNumNowInVstr++;
- //<---有意字串个数加1
- {vbNewBlk = new VSTR_BLK;
- vbNewBlk->str = tempStr;
- vbNewBlk->next = 0;
- if(StrHead == 0)
- StrHead = vbNewBlk;
- else
- StrTail->next = vbNewBlk;
- StrTail = vbNewBlk;
- }
- //<---生成一个有意字串的结构体,并将它链成链表
- }
- else
- { //<--- 回车,说明行数加一
- iLineNum[iForLineNum++][1] = iNumNowInVstr;
- //<--- 原来末行的末地址
- iLineNum[iForLineNum][0] = iNumNowInVstr + 1;
- //<--- 新行的首地址
- }
- }
- while(CompStrEver(tempStr,"xff") != 1);
- //<--- 得到的是"xff"时,表示用户输入已经结束
- iNumNowInVstr = 0;
- //<--- 再次初始化iNumNowInVstr,用于正式输入处理时的位置计算
- StrNow = StrHead;
- //<--- 将StrNow指到StrHead上
- }
- bool Ch_csVstrBlk::InString(char** ObjectStr)
- {
- int i = 0;
- char chTemp;
- *ObjectStr = new char[NAMEMAXLEN];
- if((chTemp = strInputCharList[sta_i++]) != ' ')
- (*ObjectStr)[i++] = chTemp;
- //<--- 第一个字符如果为空,则必须略过
- do{
- chTemp = strInputCharList[sta_i++];
- (*ObjectStr)[i++] = chTemp;
- }
- while(chTemp != ' ');
- if(CompStrEver(*ObjectStr, "n"))
- return 1;//<--- 回车
- else
- return 0;//<--- 有意字串
- }
- char* Ch_csVstrBlk::InitialInput()
- {
- //保留有效信息,只留下回车和其他字符,用'xff'来表示字串的结束
- char* strResult;
- strResult = new char[INPUTMAX];
- char tempIn;
- int i = 0;
- int DoGetcharFlag = 1;
- int MaybeEnd = 0;
- int EndFlag = 0;
- do{
- if(DoGetcharFlag)
- {
- tempIn = getchar();
- }
- else
- DoGetcharFlag = 1;
- switch(tempIn)
- {
- case ' ' : //<--- 过滤空格
- {
- if(strResult[i - 1] != 0)
- strResult[i++] = 0;
- do{
- tempIn = getchar();
- }while(tempIn == ' '); //<--- 过滤空格
- DoGetcharFlag = 0; //<--- 则新的循环中无需再读入一个字符
- }
- break;
- case ';' : //<--- 输入结束标志
- SaveKeyChar(strResult,&i,tempIn);
- MaybeEnd = 1; //<--- 表示可能是输入结束,MaybeEnd在下一次输入回车时会用到
- break;
- case ',' :
- case '(' :
- case ')' :
- case '>' :
- case '<' :
- case '=' :
- SaveKeyChar(strResult,&i,tempIn);
- break;
- case ''' : //<--- 在回车之前必须得到另外一个 ' 以作匹配
- strResult[i++] = tempIn;
- while( (tempIn = getchar())!='n' &&tempIn != ','&&tempIn!= '''&&tempIn!= ';')
- strResult[i++] = tempIn;
- if(tempIn == ''')
- {strResult[i++] = tempIn;
- strResult[i++] = ' ';}
- else{
- do{tempIn=getchar();}while(tempIn !='n');
- GnlTrwErr(WITHOUTMATCH);//<--- 单引号不匹配
- }
- break;
- case 'n' :
- if(MaybeEnd == 0)
- {
- // 回车后将呈现的提示符 --->
- std::cout<<" ->";
- SaveKeyChar(strResult,&i,tempIn);
- }
- else //<--- 这一次是整个命令的正式结束
- {SaveKeyChar(strResult,&i,tempIn);
- EndFlag = 1;}
- break;
- default : //<--- 一般的字符输入
- strResult[i++] = tempIn;
- break;
- }
- }
- while(EndFlag == 0 && i < INPUTMAX);//<--- 检查何种原因退出循环
- SaveKeyChar(strResult,&i,'xff');
- strResult[i] = ' ';
- return strResult;
- }
- TB_Create_Info* Ch_csVstrBlk::CH_Create()
- //表示一个完整的有关Create操作的参数类,负责Create命令的所有操作
- {
- // 命令输入应该如:create table tablename(columnname,type);
- char* strTableName = 0;
- TB_Create_Info* tbReturn;
- pCreate_Column pTemp = 0,pHead = 0,pTail = 0;
- int iColNum = 0;
- bool NotEnd = 1;
- bool bPriKeyExist = 0; //<--- 用于判断Primary key是否存在的标志
- PassCommon("table");
- strTableName = GetTBName(); //<--- 取得表名
- if(CheckTB(strTableName))
- GnlTrwErr(SUCHTBEXIST); //<--- 检验输入的该table是否存在,存在则给出错误
- SetCurRelation(strTableName);
- PassCommon("(");
- do //<--- 取得各个列定义的名称和类型
- {
- if(CompStrEver(StrNow->str,"check"))
- GetCheckInfo(&NotEnd,pHead); //<--- 该行是有关列的约束信息
- else
- {pTemp = GetColumnInfo(&NotEnd,bPriKeyExist);
- iColNum++; //<--- 列的数量+1
- if(pHead == 0)
- {pHead = pTemp;
- pTail = pTemp;
- }
- else{
- pTail->next = pTemp;
- pTail = pTemp;}
- }
- }while(NotEnd);
- PassCommon(")");
- PassCommon(";");
- if(bPriKeyExist == 0) //<--- primary key不存在
- GnlTrwErr(NOPRIMARYKEY);
- tbReturn = new TB_Create_Info(iColNum,pHead,strTableName);
- //<--- 生成该表
- return tbReturn;
- }
- void Ch_csVstrBlk::GetCheckInfo(bool *NotEnd,pCreate_Column pHead)
- {
- //功能描述:得到有关一个列的约束信息
- char* strColName = new char[NAMEMAXLEN];
- EOPE_TYPE optype;
- ECOL_TYPE coltype;
- COLVAL tmin;
- COLVAL tmax;
- pCreate_Column pColtemp = 0;
- PassCommon("check");
- PassCommon("(");
- pColtemp = GetColForCheck(StrNow->str,pHead); //<--- 得到check中列的各个信息
- optype = GetOptype(); //<--- 得到所要check的列的操作类型
- coltype = pColtemp->ColType; //<--- 赋所要check的列的数据类型(char,int,float)中的一种
- if(optype == BETWEEN) //<--- BETWEEN AND 比较特殊,单独处理
- {PassCommon("between");
- switch(coltype) //<--- 根据数据类型给约束条件赋值
- {
- case I:
- tmin.IntValue = atoi(StrNow->str);
- NextStr();
- PassCommon("and");
- tmax.IntValue = atoi(StrNow->str);
- NextStr();
- pColtemp->SetColValint(optype,tmin.IntValue,tmax.IntValue);
- break;
- case F:
- tmin.FloatValue = atof(StrNow->str);
- NextStr();
- PassCommon("and");
- tmax.FloatValue = atof(StrNow->str);
- NextStr();
- pColtemp->SetColValfloat(optype,tmin.FloatValue,tmax.FloatValue);
- break;
- case C:
- tmin.pCharValue = FilterQuota(StrNow->str);
- NextStr();
- PassCommon("and");
- tmax.pCharValue = FilterQuota(StrNow->str);
- pColtemp->SetColValstr(optype,tmin.pCharValue,tmax.pCharValue);
- break;
- }
- }
- else //<--- 非Between的操作类型,就可以直接设置
- {SetMin_Max(tmin,tmax,optype,coltype);
- pColtemp->SetColVal(optype,tmin,tmax);
- } //<--- 善后工作
- PassCommon(")");
- if(CompStrEver(StrNow->str,","))
- NextStr();
- else
- if(CompStrEver(StrNow->str,")"))
- *NotEnd = 0;
- }
- EOPE_TYPE Ch_csVstrBlk::GetOptype()
- {
- //功能描述:得到一个列的操作类型
- VSTR_BLK_PTR StrTemp = StrNow;
- EOPE_TYPE ret;
- if(CompStrEver(StrNow->str,"between"))
- ret = BETWEEN;
- else
- if(CompStrEver(StrNow->str,"="))
- {
- NextStr();
- ret = E;}
- else
- if(CompStrEver(StrNow->str,"!"))
- {NextStr();
- PassCommon("=");
- ret = NE;
- }
- else
- if(CompStrEver(StrNow->str,">"))
- {NextStr();
- if(CompStrEver(StrNow->str,"="))
- {NextStr();
- ret = BE;}
- else
- ret = B;
- }
- else
- if(CompStrEver(StrNow->str,"<"))
- {NextStr();
- if(CompStrEver(StrNow->str,"=")) //<--- 但是<时还要判断后面有没有=
- {
- NextStr();
- ret = LE;}
- else
- ret = L;
- }
- else
- ThrowStrErr(GET_OP_ERR,iNumNowInVstr);
- return ret;
- }
- pCreate_Column Ch_csVstrBlk::GetColForCheck(char* str,pCreate_Column pHead)
- {
- // 已知check中的列名,在前面已经只好的pHead列表中寻找该列的各个相关信息
- pCreate_Column pCol = pHead,pTemp;
- bool bNotFind = 1;
- for(;pCol != 0 && bNotFind; pCol = pCol->next)
- {bNotFind = !(CompStrEver(pCol->ColumnName,str));
- pTemp = pCol;
- } //<--- 在列链表中搜索所要找的列名
- NextStr();
- if(bNotFind)
- ThrowStrErr(COLNAMEERR_IN_CHECK,iNumNowInVstr);//<--- check的列名实际上并不存在
- return pTemp;
- }
- pCreate_Column Ch_csVstrBlk::GetColumnInfo(bool* NotEnd,bool& bPriKeyExist)
- {
- char strColName[NAMEMAXLEN];
- bool bError = 0,isnulltemp = 0,ispritemp = 0,ColNotEnd = 1;
- VSTR_BLK_PTR StrTemp = 0;
- pCreate_Column csOneCol = 0;
- ECOL_TYPE coltypetemp;
- int iStrlen = 0;
- strcpy(strColName,StrNow->str); //<--- 得到一列的列名信息
- NextStr();
- if(CompStrEver(StrNow->str,"char"))
- { //<--- 针对字段类型是char
- coltypetemp = C;
- NextStr();
- PassCommon("(");
- if(CompStrEver(StrNow->str,")"))
- iStrlen = 0;
- else
- {iStrlen = atoi(StrNow->str);
- NextStr();} //<--- 如将har(8)中的8取得
- PassCommon(")");
- }
- else
- if(CompStrEver(StrNow->str,"int"))
- { //<--- 针对字段类型是int
- coltypetemp = I;
- NextStr();
- }
- else
- if(CompStrEver(StrNow->str,"float"))
- { //<--- 针对字段类型是float
- coltypetemp = F;
- NextStr();
- }
- else
- bError = 1;
- if(bError == 1)
- ThrowStrErr(COLUMNTYPE,iNumNowInVstr);
- do
- {
- if(CompStrEver(StrNow->str,"notnull")) //<--- 有关一个列的定义之后如带有notnull或primary则记录下信息
- {isnulltemp = 0;
- NextStr();}
- else
- if(CompStrEver(StrNow->str,"primary"))
- {ispritemp = 1;
- bPriKeyExist = 1; //<--- primary key exists
- NextStr();}
- else
- if(CompStrEver(StrNow->str,","))
- {
- ColNotEnd = 0;
- NextStr();
- }
- else
- if(CompStrEver(StrNow->str,")"))
- {ColNotEnd = 0;
- *NotEnd = 0;}
- else
- ThrowStrErr(KEYWORD,iNumNowInVstr);
- }while(ColNotEnd);
- csOneCol = new Create_Column(strColName,coltypetemp,iStrlen,isnulltemp,ispritemp);
- return csOneCol;
- }
- void Ch_csVstrBlk::NextStr()
- {
- //功能描述: 转到下一个StrNow(即StrNow = StrNow->Next)
- iNumNowInVstr++;
- StrNow = StrNow->next;
- }
- char* Ch_csVstrBlk::GetTBName()
- { //<--- 取得表名
- char* strTBName = new char[NAMEMAXLEN];
- strcpy(strTBName,StrNow->str);
- NextStr();
- return strTBName;
- }
- void Ch_csVstrBlk::PassCommon(char* pStrIn)
- /*对StrNow当前所指的字串是否和输入的字串一致,一致则iNumNowInVstr++,StrNow = StrNow->next;
- 不一致ThrowStrErr(COMMON,iNumNowInVstr);
- */
- {
- if(CompStrEver(pStrIn,StrNow->str))
- NextStr();
- else
- ThrowStrErr(COMMON,iNumNowInVstr);
- }
- ECMD_TYPE Ch_csVstrBlk::ResolveCmd()
- //功能描述:解析取得命令
- {
- ECMD_TYPE ReturnValue = HELP;
- bool bError = 0;
- if(CompStrEver(StrNow->str,"HELP"))
- {
- ReturnValue = HELP;
- }
- else
- if(CompStrEver(StrNow->str,"?"))
- {
- ReturnValue = HELP;
- }
- else
- if(CompStrEver(StrNow->str,"QUIT"))
- {ReturnValue = QUIT;}
- else
- if(CompStrEver(StrNow->str,"EXIT"))
- {ReturnValue = QUIT;}
- else
- if(CompStrEver(StrNow->str,"DROPDB"))
- ReturnValue = DROPDB;
- else
- if(CompStrEver(StrNow->str,"SHOWDB"))
- ReturnValue = SHOWDB;
- else
- if(CompStrEver(StrNow->str,"USE"))
- ReturnValue = USE;
- else
- if(CompStrEver(StrNow->str,"NEW"))
- ReturnValue = NEW;
- else
- if(CompStrEver(StrNow->str,"DROP"))
- ReturnValue = DROP;
- else
- {
- if(CompStrEver(StrNow->str,"CREATE"))
- ReturnValue = CREATE;
- else
- if(CompStrEver(StrNow->str,"SELECT"))
- ReturnValue = SELECT;
- else
- if(CompStrEver(StrNow->str,"INSERT"))
- ReturnValue = INSERT;
- else
- if(CompStrEver(StrNow->str,"UPDATE"))
- ReturnValue = UPDATE;
- else
- if(CompStrEver(StrNow->str,"DELETE"))
- ReturnValue = DELETE;
- else
- if(CompStrEver(StrNow->str,"SHOWTABLE"))
- ReturnValue = SHOWTABLE;
- else
- bError = 1;}
- if(bError == 1)
- ThrowStrErr(RESOLVE,iNumNowInVstr);
- else
- NextStr(); //<--- 第一个有意字串不出错,则iNumNowInVstr+1
- return ReturnValue;
- }
- void Ch_csVstrBlk::ThrowStrErr(int type,int iNum)
- { //<--- 负责构造一个错误类并将它抛出来,由主函数来处理
- ErrInfo eiTemp;
- int iLine = 0;
- int i = 0;
- char* str = new char[NAMEMAXLEN];
- VSTR_BLK_PTR StrTemp = StrHead;
- for(;iNum > iLineNum[iLine][1];iLine++)
- ;
- i = iNum; //<--- 查找出错在那一行
- for(; i != 0;i--)
- StrTemp = StrTemp->next; //<--- 查找出错在哪个有意字串
- eiTemp.iErrType = type;
- eiTemp.iLineNo = iLine;
- strcpy(str,StrTemp->str);
- eiTemp.pErrStr = str;
- throw(eiTemp);
- }
- //<--- 设置好列中的Min&Max约束
- void Ch_csVstrBlk::SetMin_Max(COLVAL temp,COLVAL& min,COLVAL& max,EOPE_TYPE optype,ECOL_TYPE coltype)
- {
- switch(optype)
- {
- case E:
- case NE:
- switch(coltype)
- {case I:
- min = temp;
- max = min;
- break;
- case F:
- min = temp;
- max = min;
- break;
- case C:
- min = temp;
- max = min;
- break;
- }
- case LE:
- case L:
- switch(coltype)
- {case I:
- max = temp;
- break;
- case F:
- max = temp;
- break;
- case C:
- max.pCharValue = FilterQuota(temp.pCharValue);
- break;
- }
- case B:
- case BE:
- switch(coltype)
- {case I:
- min = temp;
- break;
- case F:
- min = temp;
- break;
- case C:
- min.pCharValue = FilterQuota(temp.pCharValue);
- break;
- }
- }
- }
- void Ch_csVstrBlk::SetMin_Max(COLVAL& min,COLVAL& max,EOPE_TYPE optype,ECOL_TYPE coltype,bool next)
- {
- //根据optype给min和max赋值,当前StrNow必须处在处理的有意字串上
- switch(optype)
- {
- case E:
- case NE:
- switch(coltype)
- {case I:
- min.IntValue = atoi(StrNow->str);
- max.IntValue = min.IntValue;
- break;
- case F:
- min.FloatValue = atof(StrNow->str);
- max.FloatValue = min.FloatValue;
- break;
- case C:
- min.pCharValue = FilterQuota(StrNow->str);
- max.pCharValue = min.pCharValue;
- break;
- }
- case LE:
- case L:
- switch(coltype)
- {case I:
- max.IntValue = atoi(StrNow->str);
- break;
- case F:
- max.FloatValue = atof(StrNow->str);
- break;
- case C:
- max.pCharValue = FilterQuota(StrNow->str);
- break;
- }
- case B:
- case BE:
- switch(coltype)
- {case I:
- min.IntValue = atoi(StrNow->str);
- break;
- case F:
- min.FloatValue = atof(StrNow->str);
- break;
- case C:
- min.pCharValue = FilterQuota(StrNow->str);
- break;
- }
- }
- if(next)
- NextStr();
- }
- //结构体TB_Create_Info
- TB_Create_Info::TB_Create_Info(int i,pCreate_Column p,char* str):TotalColumn(i),head(p)
- {
- strcpy(TableName,str);
- }
- //结构体Create_Column
- Create_Column::Create_Column(char* str,ECOL_TYPE coltype,int strlen,bool is_null,bool ispri):
- ColType(coltype),length(strlen),IsNull(is_null),isprimary(ispri),next(0)
- {
- strcpy(ColumnName,str);
- switch(coltype)
- {case C ://<--- 即该列为字符
- min.pCharValue = new char[2];
- strcpy(min.pCharValue,"z");
- max.pCharValue = new char[2];
- strcpy(max.pCharValue,"a");
- break;
- case F ://<--- 即该列为浮点数
- min.FloatValue = 1.0;
- max.FloatValue = 0;
- break;
- case I ://<--- 即该列为整数
- min.IntValue = 1;
- max.IntValue = -1;
- break;
- default :
- break;
- }
- }
- void Create_Column::SetColVal(EOPE_TYPE optype,COLVAL &tMin ,COLVAL &tMax)
- {
- OperType = optype;
- min = tMin;
- max = tMax;
- }
- void Create_Column::SetColValstr(EOPE_TYPE optype,char* chMin = 0,char* chMax = 0)
- {
- //初始化min.pCharValue,max.pCharValue
- int iStrLen = length;
- OperType = optype;
- if(chMin != 0) //<--- 如果min.pCharValue和max.pCharValue有范围限制
- {delete min.pCharValue;
- delete max.pCharValue;
- if(length == 0)
- iStrLen = NAMEMAXLEN;
- min.pCharValue = new char[iStrLen];
- max.pCharValue = new char[iStrLen];
- strcpy(min.pCharValue,chMin);
- strcpy(max.pCharValue,chMax);
- }
- }
- void Create_Column::SetColValint(EOPE_TYPE optype,int iMin,int iMax)
- {
- //初始化min.IntValue,max.IntValue
- min.IntValue = iMin;
- max.IntValue = iMax;
- OperType = optype;
- }
- void Create_Column::SetColValfloat(EOPE_TYPE optype,float fMin,float fMax)
- {
- // 初始化min.FloatValue,max.FloatValue初始一下
- OperType = optype;
- min.FloatValue = fMin;
- max.FloatValue = fMax;
- }
- //表示一个完整的有关Insert操作的参数类,负责Insert命令的所有操作
- TB_Insert_Info* Ch_csVstrBlk::CH_Insert()
- {
- char* strTableName = 0; //<--- 所要插入的表名
- TB_Insert_Info* tbReturn = 0;
- pIns_Col pHead = 0;
- int iValNum = 0; //<--- 链表长度
- //<--- 取得insert插入值列表
- PassCommon("into");
- strTableName = GetTBName(); //<--- 取得表名
- if(!CheckTB(strTableName))
- GnlTrwErr(NOSUCHTB); //<--- 检验输入的该table是否存在
- SetCurRelation(strTableName); //<--- 保存表名
- PassCommon("values");
- PassCommon("(");
- pHead = GetInsValList(iValNum); //<--- 取得插入值序列
- PassCommon(")");
- PassCommon(";");
- tbReturn = new TB_Insert_Info(strTableName,pHead,iValNum);
- return tbReturn;
- }
- pIns_Col Ch_csVstrBlk::GetInsValList(int& iValNum)
- {
- pIns_Col pHead = 0,pTail,pTemp = 0;
- Column_Type ColType; //<--- 此字段的类型
- COLVAL value;
- int FirstTime = 1;
- do{
- iValNum++;
- if(!FirstTime) //<--- 不是第一个值
- PassCommon(","); //<--- 各值以" , "相隔
- else
- FirstTime = 0;
- SetColValFStr(ColType,value);
- pTemp = new Ins_Col("*",ColType,value); //<--- 设置好各个列值
- if(pHead == 0)
- {pHead = pTemp;
- pTail = pTemp;
- }
- else{
- pTail->next = pTemp;
- pTail = pTemp;}
- }
- while(CompStrEver(StrNow->str,","));
- return pHead;
- }
- //表示一个完整的有关Select操作的参数类,负责Select命令的所有操作
- TB_Select_Info* Ch_csVstrBlk::CH_Select()
- {
- char* strTableName = 0;
- TB_Select_Info* tbReturn = 0;
- pSel_Col pSel_ColHead = 0;
- pSel_Cond pCond_Head = 0;
- int iColNum = 0;
- int iCondNum = 0;
- bool NotEnd = 1;
- if(CompStrEver(StrNow->str,"from"))
- ThrowStrErr(NOCOL,iNumNowInVstr);
- else
- pSel_ColHead = GetSelColList(iColNum);
- //<--- 取得select 列名列表
- PassCommon("from");
- strTableName = GetTBName();
- //<--- 得到表名
- if(!CheckTB(strTableName))
- GnlTrwErr(NOSUCHTB); //<--- 检验输入的该table是否存在
- SetCurRelation(strTableName); //<--- 保存表名
- if(CompStrEver(StrNow->str,";"))
- {iCondNum = 0;pCond_Head = 0;}
- else
- {PassCommon("where");
- pCond_Head = GetCondList(iCondNum);} //<--- 得到条件链表
- tbReturn = new TB_Select_Info(strTableName,iColNum,pSel_ColHead,iCondNum,pCond_Head);
- return tbReturn;
- }
- //功能描述:得到select,update,delete,insert中有关条件的描述信息的列表--->
- pSel_Cond Ch_csVstrBlk::GetCondList(int& iCondNum)
- {
- pSel_Cond pHead = 0,pTail,pTemp = 0;
- int FirstTime = 1;
- char PriKey[NAMEMAXLEN]; //<--- 主键名
- COLVAL tmax; //<--- 上限
- COLVAL tmin; //<--- 下限
- COLVAL tColVal;
- Column_Type tColType;
- Operator_Type tOperType; //<--- 关系运算符
- do{
- iCondNum++;
- if(!FirstTime)
- PassCommon("and");
- else
- FirstTime = 0;
- strcpy(PriKey,StrNow->str);
- NextStr(); //<--- 获得第一个条件的列名
- tOperType = GetOptype(); //<--- 得到操作类型
- if(tOperType == BETWEEN)
- {
- PassCommon("between");
- SetColValFStr(tColType,tmin);
- PassCommon("and");
- SetColValFStr(tColType,tmax);
- }
- else
- {SetColValFStr(tColType,tColVal);
- SetMin_Max(tColVal,tmin,tmax,tOperType,tColType);}
- pTemp = new TSelect_Condition(PriKey,tmin,tmax,tColType,tOperType);
- if(pHead == 0)
- {pHead = pTemp;
- pTail = pTemp;
- }
- else{
- pTail->next = pTemp;
- pTail = pTemp;}
- }while(CompStrEver(StrNow->str,"and"));
- return pHead;
- }
- //<--- 功能描述:得到有关一个输入的字串为和类型(I,C,F)及对相应的tColVal赋值
- void Ch_csVstrBlk::SetColValFStr(ECOL_TYPE& coltype,COLVAL& tColVal,bool next)
- {
- int i = 0;
- bool NotFind = 1;
- char* strTemp = StrNow->str;
- if(strTemp[0] == ''')
- {strTemp = FilterQuota(StrNow->str);
- coltype = C;
- tColVal.pCharValue = strTemp;
- }
- else
- {
- for(i = 0;strTemp[i] !=' ' && NotFind;i++)
- if(strTemp[i] == '.') //<--- 存在点号,则说明是float
- NotFind = 0;
- if(NotFind == 0)
- {
- tColVal.FloatValue = atof(StrNow->str);
- coltype = F;
- }
- else
- {
- tColVal.IntValue = atoi(StrNow->str);
- coltype = I;
- }
- }
- if(next)
- NextStr(); //<--- 转到下一个条件上
- }
- //<--- 功能描述:得到select中关于字段(列名)的列表
- pSel_Col Ch_csVstrBlk::GetSelColList(int& i)
- {
- pSel_Col pHead = 0,pTail,pTemp = 0;
- pHead = new Sel_Col(StrNow->str);
- pTail = pHead; //<--- 得到第一个列名
- i++;
- NextStr();
- while(!CompStrEver(StrNow->str,"from")) //<--- 当不是from(应该是" , ")时,说明还有列名
- {
- PassCommon(",");
- pTemp = new Sel_Col(StrNow->str);
- NextStr();
- pTail->next = pTemp;
- pTail = pTemp;
- i++; //<--- 计算列名的数量
- }
- return pHead;
- }
- //表示一个完整的有关Update操作的参数类,负责Update命令的所有操作
- TB_Update_Info* Ch_csVstrBlk::CH_Update()
- {
- char* strTableName = 0; //<--- 要执行修改的表名
- Update_Column* pUpd_ColHead = 0; //<--- 所要修改的字段及其值的链表
- pConds pCond_Head = 0; //<--- 修改的范围的查询条件链表
- int iColNum = 0; //<--- 字段数
- int iCondNum = 0; //<--- 条件数
- TB_Update_Info* tbReturn = 0;
- strTableName = GetTBName(); //<--- 得到表名
- if(!CheckTB(strTableName))
- GnlTrwErr(NOSUCHTB); //<--- 检验输入的该table是否存在
- SetCurRelation(strTableName); //<--- 保存表名
- PassCommon("set"); //<--- 过滤set,进入取得列名链表阶段
- pUpd_ColHead = GetUpdColList(iColNum);
- PassCommon("where");
- pCond_Head = GetCondList(iCondNum); //<--- 得到条件链表
- tbReturn = new TB_Update_Info(strTableName,pUpd_ColHead,iColNum,pCond_Head,iCondNum);
- return tbReturn;
- }
- pUpd_Col Ch_csVstrBlk::GetUpdColList(int &iColNum)
- //<--- 得到update中要重新设值的列名
- { pUpd_Col pHead = 0,pTail = 0,pTemp = 0;
- char ColName[NAMEMAXLEN]; //<--- 字段名
- Column_Type ColType; //<--- 此字段的类型
- COLVAL value;
- int FirstTime = 1;
- do{
- iColNum++;
- if(!FirstTime)
- PassCommon(",");
- else
- FirstTime = 0;
- strcpy(ColName,StrNow->str);
- NextStr();
- PassCommon("=");
- SetColValFStr(ColType,value); //<--- 对该字段的新值和列的值类型赋值
- pTemp = new TUpdate_Column(ColName,ColType,value);//<--- 生成该字段
- if(pHead == 0)
- {pHead = pTemp;
- pTail = pTemp;
- }
- else{
- pTail->next = pTemp;
- pTail = pTemp;} //<--- 链到链表中
- }while(CompStrEver(StrNow->str,",")); //<--- 如果以','结尾,说明可能是多个列同时更新值
- return pHead;
- }
- TB_Delete_Info* Ch_csVstrBlk::CH_Delete()
- { char* strTableName = 0; //<--- 要执行修改的表名
- pConds pCond_Head = 0; //<--- 所要修改的字段及其值的链表
- int iCondNum = 0; //<--- 条件数
- TB_Delete_Info* tbReturn = 0;
- PassCommon("from");
- strTableName = GetTBName(); //<--- 取得表名
- if(!CheckTB(strTableName))
- GnlTrwErr(NOSUCHTB); //<--- 检验输入的该table是否存在
- SetCurRelation(strTableName); //<--- 保存表名
- PassCommon("where");
- pCond_Head = GetCondList(iCondNum);//<--- 得到条件列表
- tbReturn = new TB_Delete_Info(strTableName,pCond_Head,iCondNum);
- return tbReturn;
- }
- void Ch_csVstrBlk::ChoseDatabase()
- {
- if(CompStrEver(StrNow->str,";"))
- ThrowStrErr(COMMON,iNumNowInVstr);//<--- 可能漏输database name
- char* dbname = StrNow->str;
- NextStr();
- PassCommon(";"); //<--- 在database name后不能有其他的输入
- if(!CheckDB(dbname))
- GnlTrwErr(NOSUCHDB); //<--- 检验输入的该database是否存在
- SetCurLocation(dbname); //<--- 根据该输入设置好当前路径
- strcpy(CurDB,dbname); //<--- 设置好当前的数据库
- ShowTable();
- }
- void Ch_csVstrBlk::DropTB()
- {
- if(CompStrEver(StrNow->str,";"))
- ThrowStrErr(COMMON,iNumNowInVstr);//<--- 可能漏输database name
- if(CompStrEver(CurDB,""))
- GnlTrwErr(NODBUSED); //<--- 如果该数据库不存在,则出错
- char* tbname = StrNow->str;
- NextStr();
- PassCommon(";"); //<--- 在table name后不能有其他的输入
- if(!CheckTB(tbname))
- GnlTrwErr(NOSUCHTB); //<--- 检验输入的该table是否存在
- SetCurRelation(tbname); //<--- 保存表名
- }
- void Ch_csVstrBlk::DropDB()
- {
- if(CompStrEver(StrNow->str,";"))
- ThrowStrErr(COMMON,iNumNowInVstr);//<--- 可能漏输database name
- char* dbname = StrNow->str;
- NextStr();
- PassCommon(";"); //<--- 在database name后不能有其他的输入
- if(!CheckDB(dbname))
- GnlTrwErr(NOSUCHDB); //<--- 检验输入的该database是否存在
- SetCurLocation(dbname); //<--- 根据该输入设置好当前路径
- strcpy(CurDB,dbname); //<--- 设置好当前的数据库
- }
- // 创建一个数据库--->
- void Ch_csVstrBlk::NewDB()
- {
- if(CompStrEver(StrNow->str,";"))
- ThrowStrErr(COMMON,iNumNowInVstr); //<--- 可能漏输database name
- char* dbname = StrNow->str;
- NextStr();
- PassCommon(";"); //<--- 在database name后不能有其他的输入
- if(CheckDB(dbname))
- GnlTrwErr(SUCHDBEXIST); //<--- 检验输入的该database是否存在
- CreateDB(dbname);
- }
- char* FilterQuota(char* strin)
- {
- // 去除字符串中的' '
- char* strTemp = new char[NAMEMAXLEN];
- int i = 0;
- if(strin[0] != ''')
- strcpy(strTemp,strin);
- else
- { for(;strin[i+1]!=''';i++)
- strTemp[i] = strin[i+1];
- strTemp[i] = ' ';}
- return strTemp;
- }
- bool CompStrEver(char* str1,char* str2)
- //比较两个字符串是否相等
- { char a,b;
- bool IsSame,NotEnd;
- int i = 0;
- do{
- a = ChUpToLowCase(str1[i]);
- b = ChUpToLowCase(str2[i++]);
- IsSame = (a==b);
- NotEnd = (a!=' ');
- }while(IsSame&&NotEnd);
- if (IsSame == 1)
- return 1;
- //<--- IsSame == 1,则说明NotEnd == 0,即比较的结果是str1与str2相等
- else
- return 0;
- }
- void SaveKeyChar(char* str,int* index,char in)
- /*str 目标字符串数组
- index 字符所要保存的位置
- in 所要保存的字符
- */
- {
- if(str[*index-1] != 0)
- str[(*index)++] = 0;
- str[(*index)++] = in;
- str[(*index)++] = 0;
- }
- // 将一个大写字母换成小写,否则原样返回 --->
- char ChUpToLowCase(char chIn)
- {
- if(chIn >= 'A' && chIn <= 'Z')
- chIn += 32;
- return chIn;
- }
- // 将当前的路径设置好 --->
- void SetCurLocation(char* str)
- {
- strcpy(CurLocation,"..\data\");
- strcat(CurLocation,str);
- strcat(CurLocation,"\");
- }
- // 将当前的表名设置好 --->
- void SetCurRelation(char* str)
- {
- strcpy(CurRelationName,str);
- }
- void ShowHelp()
- {//<--- 帮助提示信息
- std::cout<<"n
- Every Command must be ended with ';'n
- help Display the help informationn
- -----------------------------------------------------------------------------n
- ? Display the help informationn
- -----------------------------------------------------------------------------n
- create creat a table in the dbn
- create table tablename(valuename type notnull);n
- -----------------------------------------------------------------------------n
- select select a specify column from the tablen
- select columnname from tablename where check straint;n
- -----------------------------------------------------------------------------n
- delete delete a specify column from the table n
- delete columnname from tablename where check straint;n
- -----------------------------------------------------------------------------n
- update update a table n
- update tablename set columnname = columnvalue where check straint;n
- -----------------------------------------------------------------------------n
- insert insert data into the table n
- insert into tablename(values);n
- -----------------------------------------------------------------------------n
- use Use a databasen
- use dbname;n
- -----------------------------------------------------------------------------n
- showdb Show all the databases n
- -----------------------------------------------------------------------------n
- showtable Show all the tables in the current db,n
- so there must have at least one db existn
- -----------------------------------------------------------------------------n
- drop drop a table n
- drop tablename;n
- -----------------------------------------------------------------------------n
- dropdb drop a database n
- dropdb dbname;n
- -----------------------------------------------------------------------------n
- exit Quit mysqln
- -----------------------------------------------------------------------------n
- quit Quit mysqln"<<'n';
- }
- void QuitSQL()
- {
- std::cout<<"BYE BYE!:-)";
- }
- void ShowMsg(char* str)
- {
- std::cout<<str<<'n';
- }
- //<--- Throw the General Errors,一般性错误,如db不存在
- void GnlTrwErr(int ErrType)
- {
- GnlErrInfo eErrTemp;
- eErrTemp.iErrType = ErrType;
- throw(eErrTemp);
- }