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

📄 intepretor.cpp

📁 设计并实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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\',\'primary\'",
				  "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++]) != '\0')
    (*ObjectStr)[i++] = chTemp;
  //<--- 第一个字符如果为空,则必须略过
  do{
	  chTemp = strInputCharList[sta_i++];
	  (*ObjectStr)[i++] = chTemp;
  }
  while(chTemp != '\0');
  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++] = '\0';}
         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] = '\0';
  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;

⌨️ 快捷键说明

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