📄 common.cpp
字号:
#include "stdafx.h"
#include "common.h"
//进行词法分析,将命令符分解成一个个字串
bool SplitCommand(char *pStrCommand,vector<string> &pCommandField)
{
if(pStrCommand == NULL)
{
printf("当前没有分析的字符串\n");
return false;
}
int iIndex = 0;//标识当前读到那个字符,是总缓冲区的游标
char nextChar = pStrCommand[iIndex++];
string strValue;
while(nextChar != '\0')
{
switch(nextChar)
{
case '\t':
case ' ':
if(strValue.size() != 0)
{
pCommandField.push_back(strValue);
strValue = "";
}
break;
case '(':
case ')':
case ',':
if(strValue.size() != 0)
{
pCommandField.push_back(strValue);
}
strValue = nextChar;
pCommandField.push_back(strValue);
strValue = "";
break;
default:
strValue += nextChar;
break;
}
nextChar = pStrCommand[iIndex++];
}
if(strValue.size() >= 1)
{
pCommandField.push_back(strValue);
}
return true;
}
//用于查询关键符号的类型
int QueryKeyType(const char *pSQL)
{
if(pSQL == NULL)
return -1;
for(int i = 0; i < KEY_ROW; i++)
{
if(strcmp(pSQL,KeyList[i]) == 0)
return i;
}
return -2;
}
//返回当前的命令格式,具体见其返回值
int QuerySQLType(vector<string> &pCommandField)
{
if(pCommandField.size() == 0)
return -1;
//处理双前缀命令格式
for(int i = 0; i < ACTION_ROW-7; i++)
{
if(strcmp(pCommandField[0].c_str(),ActionList[i][0]) == 0
&& strcmp(pCommandField[1].c_str(),ActionList[i][1]) == 0)
{
return i;
}
}
//处理单前缀命令格式
for(i = ACTION_ROW-7; i < ACTION_ROW; i++)
{
if(strcmp(pCommandField[0].c_str(),ActionList[i][0]) == 0 )
{
return i;
}
}
return -2;
}
bool CharIsNum(char ch)
{
if(ch >= '0' && ch <= '9')
{
return true;
}
return false;
}
bool CharIsAlphabet(char ch)
{
if((ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z'))
{
return true;
}
return false;
}
//用于检查字符串是否为数字
bool CheckRuleForNum(const char *pStr)
{
if(pStr == NULL)
{
printf("无要检查的数据\n");
return false;
}
if(pStr[0] >= '1' && pStr[0] <= '9')
{
int iIndex = 1;
while(pStr[iIndex] != '\0')
{
if(!CharIsNum(pStr[iIndex++]))
{
return false;
}
}
return true;
}
return false;
}
//用于检查字符串是否合法,主要用于检查是否符合关键字命名规则
bool CheckRuleForString(const char *pStr)
{
if(pStr == NULL)
{
printf("无要检查的数据\n");
return false;
}
int iIndex = 0;
char nextChar = pStr[iIndex];
if(!CharIsAlphabet(nextChar))
{
printf("首字符不满足\n");
return false;
}
if(iIndex+1 >= strlen(pStr))
{
return true;
}
nextChar = pStr[++iIndex];
while(nextChar != '\0')
{
if(!CharIsNum(nextChar)
&& !CharIsAlphabet(nextChar)
&& nextChar != '_' )
{
printf("当前字符 [%c] \n",nextChar);
return false;
}
nextChar = pStr[iIndex++];
}
return true;
}
//设置时间,将操作时间改为当前的时间
void SetTime(long &lTime,char *pStrTime)
{
struct tm *p;
time(&lTime);
p=localtime(&lTime);
strftime(pStrTime,29,"%a %d %b %Y %H:%M:%S GMT",p);
}
//----------------------Database API-------------------------------------------
//注意:本版本中对于出错没有做事务回滚,这在出现异常时会造成一些潜在的问题
//检查当前要操作的数据库是否存在
bool IsDBExist(const char *pStrDBName)
{
vector<DataBase> vHeader;
ReadDBInfor(vHeader);
int iCount = vHeader.size();
if(iCount <= 0)
{
return false;
}
for(int i = 0; i < iCount; i++)
{
if(strcmp(vHeader[i].strDBName,pStrDBName) == 0)
{
return true;
}
}
return false;
}
//进一步检查数据库的SQL语法有无问题
bool CheckDBSQLRule(vector<string> &pCommandField)
{
if(pCommandField.size() != 3)
{
printf("当前的参数个数不合法,默认为三个参数\n");
return false;
}
if(pCommandField[2].length() <= 0)
{
printf("数据库名不能为空\n");
return false;
}
return true;
}
//从数据库配置表中写入当前的记录信息
bool WriteDBInfor(struct DataBase pDB)
{
if(&pDB == NULL)
{
return false;
}
FILE *fp;
if((fp=fopen("data\\configsys.dcy","ab+"))==NULL)
{
return false;
}
fwrite(&pDB,sizeof(DataBase),1,fp);
fclose(fp);
return true ;
}
//从配置表中读取当前所有信息,到数据库向量
void ReadDBInfor( vector<DataBase> &pDB)
{
FILE *fp;
if((fp=fopen("data\\configsys.dcy","rb"))==NULL)
{
return ;
}
int iCount = 1;
DataBase dbNode;
while(!feof(fp))
{
if(fread(&dbNode,sizeof(DataBase),1,fp))
{
pDB.push_back(dbNode);
}
iCount++;
}
fclose(fp);
}
//删除当前记录
bool DeleteDBinfor(const char *pStrDBName)
{
vector<DataBase> vHeader;
ReadDBInfor(vHeader);
int iCount = vHeader.size();
if(iCount <= 0)
{
return false;
}
if( remove("data\\configsys.dcy") == -1)
{
printf("删除失败[data\\configsys.dcy]\n");
return false;
}
FILE *fp;
if((fp=fopen("data\\configsys.dcy","ab+"))==NULL)
{
return false;
}
for(int i = 0; i < iCount; i++)
{
if(strcmp(vHeader[i].strDBName,pStrDBName) != 0)
{
fwrite(&vHeader[i],sizeof(DataBase),1,fp);
}
}
fclose(fp);
return true;
}
//具体执行创建命令
bool CreateDataBase(const char *pStrDBName)
{
if(pStrDBName == NULL)
{
return false;
}
char currentDir[2048];
getcwd(currentDir,2048);
strcat(currentDir,"\\data\\");
strcat(currentDir,pStrDBName);
struct DataBase db;
strcpy(db.strDBName,pStrDBName);
strcpy(db.strAuthor,g_strUserName);
SetTime(db.lCreatTime,db.strCreateTime);
if(mkdir(currentDir) == 0)
{
string str;
str = "data\\";
str += pStrDBName;
str += "\\table.list";
FILE *fp;
if( (fp = fopen(str.c_str(),"ab+") ) == NULL)
{
return true;
}
fclose(fp);
if(WriteDBInfor(db))
return true;
}
return false;
}
//具体执行删除命令
bool DropDatabase(const char *pStrDBName)
{
if(pStrDBName == NULL)
{
return false;
}
char currentDir[2048];
getcwd(currentDir,2048);
strcat(currentDir,"\\data\\");
strcat(currentDir,pStrDBName);
string confFile;
confFile = currentDir;
confFile += "\\table.list";
vector<TableNode> vHeader;
FILE *fp;
if((fp=fopen(confFile.c_str(),"rb"))==NULL)
{
return false;
}
int iCount = 1;
TableNode tableNode;
while(!feof(fp))
{
if(fread(&tableNode,sizeof(TableNode),1,fp))
{
vHeader.push_back(tableNode);
}
iCount++;
}
fclose(fp);
remove(confFile.c_str());
vector<TableNode>::iterator pData;
for(pData = vHeader.begin();pData!=vHeader.end();pData++)
{
string strPath;
strPath = currentDir;
strPath += "\\";
strPath += pData->strTableName;
string strFile;
strFile = strPath + ".lst";
remove(strFile.c_str());
strFile = strPath + ".lid";
remove(strFile.c_str());
strFile = strPath + ".ltd";
remove(strFile.c_str());
}
//此处加一个For循环,用于删除当前所有表信息和结构
if(rmdir(currentDir) == 0 && DeleteDBinfor(pStrDBName))
{
//若当前使用的数据库是被删除的,则将全局变量置为空
if(strcmp(g_strCurrentDBName,pStrDBName) == 0)
{
strcpy(g_strCurrentDBName,"");
}
return true;
}
return false;
}
//----------------------有关表操作API开发库---------------------------
//检查当前的表是否存在 tables.list
bool IsTableExist(const char *pStrTableName)
{
vector<TableNode> vHeader;
ReadTableInfor(vHeader);
int iCount = vHeader.size();
if(iCount <= 0)
{
return false;
}
for(int i = 0; i < iCount; i++)
{
if(strcmp(vHeader[i].strTableName,pStrTableName) == 0)
{
return true;
}
}
return false;
}
//将表信息写入配置文件
bool WriteTableInfor(struct TableNode pTable)
{
FILE *fp;
char strFileName[2048] = "data\\";
strcat(strFileName,g_strCurrentDBName);
strcat(strFileName,"\\table.list");
if((fp=fopen(strFileName,"ab+"))==NULL)
{
return false;
}
fwrite(&pTable,sizeof(TableNode),1,fp);
fclose(fp);
return true ;
}
//从配置表中读取当前所有信息,里面得到提当前表信息
void ReadTableInfor( vector<TableNode> &pTable)
{
FILE *fp;
char strFileName[2048] = "data\\";
strcat(strFileName,g_strCurrentDBName);
strcat(strFileName,"\\table.list");
if((fp=fopen(strFileName,"rb"))==NULL)
{
return ;
}
int iCount = 1;
TableNode tableNode;
while(!feof(fp))
{
if(fread(&tableNode,sizeof(TableNode),1,fp))
{
pTable.push_back(tableNode);
}
iCount++;
}
fclose(fp);
}
//删除当前记录
bool DeleteTableinfor(const char *pStrTableName)
{
vector<TableNode> vHeader;
ReadTableInfor(vHeader);
int iCount = vHeader.size();
if(iCount <= 0)
{
return false;
}
char strFileName[2048] = "data\\";
strcat(strFileName,g_strCurrentDBName);
strcat(strFileName,"\\table.list");
if( remove(strFileName) == -1)
{
printf("删除tablelist失败[%s]\n",strFileName);
return false;
}
FILE *fp;
if((fp=fopen(strFileName,"ab+"))==NULL)
{
return false;
}
for(int i = 0; i < iCount; i++)
{
if(strcmp(vHeader[i].strTableName,pStrTableName) != 0)
{
fwrite(&vHeader[i],sizeof(TableNode),1,fp);
}
}
fclose(fp);
return true;
}
//删除三张表
bool DropTable(const char *pStrTableName)
{
if(!DeleteTableinfor(pStrTableName))
{
printf("当前无法清除结点记录\n");
return false;
}
char strFileName[2048] = "data\\";
strcat(strFileName,g_strCurrentDBName);
strcat(strFileName,"\\");
strcat(strFileName,pStrTableName);
char *filename1 = (char *)malloc(strlen(strFileName)+4);
char *filename2 = (char *)malloc(strlen(strFileName)+4);
char *filename3 = (char *)malloc(strlen(strFileName)+4);
strcpy(filename1,strFileName);
strcat(filename1,".lst");
strcpy(filename2,strFileName);
strcat(filename2,".lid");
strcpy(filename3,strFileName);
strcat(filename3,".ltd");
remove(filename1);
remove(filename2);
remove(filename3);
return true;
}
//检查是否存在primary键
bool IsPrimaryExist(vector<FieldNode> &pFiledList)
{
vector<FieldNode>::iterator pData;
for(pData = pFiledList.begin(); pData != pFiledList.end(); pData++)
{
if(pData->bIsPrimaryKey)
return true;
}
return false;
}
//检查当前字段名是否存在
bool IsFieldExist(const char *pstrFieldName,const char *pTableName)
{
vector<FieldNode> pFiledList;
ReadFiledListStruct(pFiledList,pTableName);
vector<FieldNode>::iterator pData;
for(pData = pFiledList.begin(); pData != pFiledList.end(); pData++)
{
if(strcmp(pData->strFieldName,pstrFieldName) == 0)
return true;
}
return false;
}
//用于分析表创建时的Check规则检查
int AnalysisCheck(vector<string> &pCommandField,int iIndex,vector<FieldNode> &pFieldList)
{
//check fieldname between xx and xx
if(iIndex+1 >= pCommandField.size())
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -