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

📄 common.cpp

📁 DBMS(Database Management System)在当前的信息系统开发中处于主导位置
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#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 + -