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

📄 dbcontrol.cpp

📁 数据库模拟程序 实现控制台命令词法分析
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}//置指针到正式的记录

		int tr;
		pt = 0;
		tr = 0;
		int amd;
		while(pt < recordCount)
		{
			amd=ff.tellg();
			for(tr = 0; tr < recordLen; tr++){
				f2.read(&ch,1);
				ff.write(&ch,1);
			}
			amd=ff.tellg();

			ch = 0;
			for(tr = 0; tr < ITEM_LEN; tr++){
				ff.write(&ch,1);
			}
			amd=ff.tellg();
			ff.write(";",1);
			ff<<endl;
			amd=ff.tellg();
			f2.read(&ch,1);//跳过回车
			pt++;
		}

		f2.close();
		ff.close();
		////////////////////////////////////////////////////////////
	}
	return false;
}

//DELETE FROM T WHERE PLOCTION='HAERBIN';
int CDBControl::Delete(CString str, Word word[], int len)
{
	int weizhi1 = -1;//如果成功找到该表中的属性,则weizhi为该属性的顺序索引号码。weizhi =[0..n-1]
	int ext1 = 0;//用于扩展''的形式,进行补位操作
	int ext2 = 0;

	IndexForCiDian index;
	Data data;
	memset(&data, 0, sizeof(Data));
	memset(&index, 0, sizeof(IndexForCiDian));
	index.indexType = TABLE;
	strcpy(index.name, word[2].name);

	if(strcmp(word[6].name, "'") == 0)
	{
		ext1 = 1;
		ext2 = 1;
	}//对SQL中是否含有'标志进行置位。分别代表4个可能出现'的位置。


	if((weizhi1 = getIndexFromCiDian(index, data, word[4].name)) != -1)
	{//如果本函数不返回-1,则index,data对象被已经初始化。

		char filename[20];
		char temp[ITEM_LEN];
		long saveOffset = -1;
		long fileLen = 0;
		long recordCount = 0;
		long recordLen = 0;
		char ch;

		memset(filename, 0, 20);
		memset(temp, 0, ITEM_LEN);

		strcpy(filename, word[2].name);
		strcat(filename, ".tab");//生成要查询的数据表的表名。word[2].name.tab

		fstream readDataFile, filetemp;
		readDataFile.open(filename, ios::in | ios::out | ios::nocreate);
		readDataFile.seekg(0, ios::end);
		fileLen = readDataFile.tellg();
		recordLen = NAME_LEN  + data.pDataArray_len * (ITEM_LEN + 1);//不包括回车
		recordCount = (fileLen - 10 - 2) / (recordLen + 2);//包括回车

		readDataFile.seekg(0, ios::beg);//将指针置于正文
		filetemp.open("temp", ios::out);
		while(readDataFile.read(&ch,1))
		{
			filetemp.write(&ch,1);
		}
		readDataFile.close();
		filetemp.close();//数据中转
		
		readDataFile.open(filename, ios::out);
		filetemp.open("temp", ios::in);
		int pt;
		pt = 0;
		while(pt < 10 + 1)
		{
			filetemp.read(&ch,1);
			readDataFile.write(&ch,1);
			pt++;
		}
		readDataFile.flush();


		int j = 0;//用于辅助指针点位记录项位置。j=[0,recordLen]

		Data dataTemp;
		memset(&dataTemp, 0, sizeof(dataTemp));
		dataTemp.pDataArray = new DataItem[data.pDataArray_len];
		memset(dataTemp.pDataArray, 0, data.pDataArray_len * sizeof(DataItem));

		while(1)
		{
			saveOffset = filetemp.tellg();//记录记录项的起始地址。
			filetemp.seekg(NAME_LEN, ios::cur);
			filetemp.seekg(weizhi1 * (ITEM_LEN + 1), ios::cur);//指针调到where后的属性
			filetemp.read(temp, ITEM_LEN);//读取当前记录的属性值
			
			if(strcmp(temp, word[6 + ext1].name) == 0)//判断如果是where后的属性指定的值,则改
			{
				filetemp.seekg(saveOffset + recordLen + 2, ios::beg);
			}
			else
			{
				filetemp.seekg(saveOffset, ios::beg);
				int k = 0;
				for(k = 0; k < recordLen + 1; k++)
				{
					filetemp.read(temp,1);
					readDataFile.write(temp,1);
				}
			}
	//		readDataFile.seekg(saveOffset + recordLen + 2, ios::beg);
			j++;
			if(j >= recordCount)
				break;
			readDataFile.flush();
		}
		readDataFile.close();
	}
	else
		AfxMessageBox("该表或属性不存在!");

	return false;
}

int CDBControl::show(CString str, Word word[], int len)
{
	char temp[20];
	strcpy(temp, "display.exe ");
	strcat(temp, word[3].name);
	WinExec(temp, SW_SHOW);
	return false;
}

/*
	filename等待查找的数据表名,如T
*/
int CDBControl::ReadTable(char filename[], long indexID, Data &data)
{	
	// TODO: Add your command handler code here
	strcat(filename, ".tab");

	ifstream file;
	
	file.open(filename, ios::nocreate);
	file.seekg(0, ios::end);
	long filelen = file.tellg();
	file.seekg(0, ios::beg);

	char countBuff[10];
	char buff[100];
	memset(buff, 0, 100);
	memset(countBuff, 0, 10);
	file.read(countBuff, 10);
	file.read(buff, 1);
//	file.read(data.name, NAME_LEN);
	char ch[2];
	memset(ch, 0, 2);
	int count = atoi(countBuff);

	data.pDataArray = new DataItem[count];
	data.pDataArray_len  = count;
	memset(data.pDataArray, 0, count * sizeof(DataItem));

	char a[10][ITEM_LEN + 1];//此语句限定程序只能处理最大10个属性
	memset(a, 0, 10 * ITEM_LEN + 1);
	//char (*a)[count] = new char[NAME_LEN][count];
	
	int i;
	CString str;
	int flag = 0;
	cout<<endl<<endl;
//	while(file.read(buff, 1))
	{
		str.Empty();

		int mn = file.tellg();
		mn = 10 + 2 + indexID * (NAME_LEN + count * (ITEM_LEN + 1)+ 2);
		file.seekg(10 + 2 + indexID * (NAME_LEN + count * (ITEM_LEN + 1)+ 2));
		mn = file.tellg();
		if(filelen <= 10 + 2 + indexID * (NAME_LEN + count * (ITEM_LEN + 1)+ 2)){
//			AfxMessageBox("索引溢出!");
			return false;
		}

//		file.seekg(-1, ios::cur);
		int offset = file.tellg();
		file.read(data.name, NAME_LEN);
		if(flag == 0 && data.name[0] != 0)
		{
			flag = 1;
			cout<<"读取表:"<<data.name<<endl<<endl;
		}
		offset = file.tellg();

		str.Format("表名:%s, 属性数据: ", data.name);
		i = 0;
		for(i = 0; i < count; i++)
		{
			file.getline(a[i], ITEM_LEN + 2, ';');//数据项最大ITEM_LEN但为了能读到‘;’所以加长一个单位,加长一个结束符。
			offset = file.tellg();
			str += a[i];
			strcpy(data.pDataArray[i].name, a[i]);
			str += "; ";
		}
		
		if(data.name[0] != 0)//如果是空数据则不显示。
		{
//			cout<<str.GetBuffer(str.GetLength())<<endl;
//			AfxMessageBox(str);
		}

//		file.read(buff, 1);//读取回车
	}
	file.close();
	return true;
}

int CDBControl::AddRecordIndex(char tableName[], long &startOffset, char dataName[])
{
	fstream f;
	static int count = 1;//每隔count个数据项,插入一个索引
	static long indexCount = 0;//索引号码
	char temp[20];
	long saveOffset = -1;
	memset(temp, 0, 20);
	strcat(tableName, ".ind");
	f.open(tableName, ios::in);
	f.close();
	f.open(tableName, ios::in | ios::out | ios::app);
	f.seekg(0, ios::end);
	saveOffset = f.tellg();
//	if(count % 10 != 0){
//		count++;
//		return false;
//	}
//	else
	{
		Index index;
		memset(&index, 0, sizeof(Index));
				
		char temp[10];
		memset(temp, 0, 10);
		ltoa(indexCount, temp, 10);
		strcpy(index.index, temp);//设定索引值

		memset(temp, 0, 10);
		ltoa(startOffset, temp, 10);
		strcpy(index.index_in_IndexForCiDian, temp);
		strcpy(index.value, dataName);

		f.write((char*)&index, sizeof(Index));
		f<<endl;
		indexCount++;
		count = 1;
	}
	f.close();
	return true;
}


//select * from t where a=2 and b=4;
int CDBControl::Select_Index(CString str, Word word[], int len)
{


	int ptFrom = -1, ptWhere = -1;//存储From 和 Where 的索引位置[0..N-1]
	int isLink = -1;
	int off1 = -1, off2 = -1, off3 = -1;
	
	int i = 0;
	while(i < len)
	{
		if(strcmp(word[i].mark, "f") == 0){
			ptFrom = i;
		}
		else if(strcmp(word[i].mark, "w") == 0){
			ptWhere = i;
		}
		if(ptWhere != -1 && strcmp(word[i].name, ".") == 0)
			isLink = i;
		i++;
	}
	off1 = ptFrom - 1;		  //获得属性组长度
	off2 = ptWhere - ptFrom - 1;//获得表组长度
	off3 = len - 1 - ptWhere ;//获得条件组的长度
	//#############################################################

	if(!isExistTheKey(word[3].name)){
		CString msg;
		msg = word[3].name;
		msg += "不存在!";
		AfxMessageBox(msg);
		return false;
	}//判断表名是否存在。不存在则不合法。
	//##############################################################

	if(ptWhere != -1)
	{	
		//##################################################
		//启动计时器
		CRunTimer a;
		START_TIMER(a)
		//##################################################
			
		char tableName[20];
		char indexName[20];
		char chReturn;//用来过滤回车字符
		Data data;
		IndexForCiDian index;
		memset(tableName, 0, 20);
		memset(indexName, 0, 20);
		memset(&data, 0, sizeof(Data));
		memset(&index, 0, sizeof(IndexForCiDian));
		
		fstream fInd,//访问索引文件(.ind)
			fTab, //访问表数据文件(.tab)
			fresult;   //访问结果文件(SearchResult.txt)
		strcpy(tableName, word[3].name);
		strcat(tableName, ".tab");
		strcpy(indexName, word[3].name);
		strcat(indexName, ".ind");

		fInd.open(indexName, ios::in );
		fTab.open(tableName, ios::in);
		fresult.open("SearchResult.txt",ios::out);

		char chDataItemCounter[10];
		int iDataItemCounter = 0;
		fTab.read(chDataItemCounter, TABLE_HEAD);
		fTab.read(&chReturn, RETURN_LEN-1);//滤去回车符,因为是文本方式读写,所以要减去一个字符
		iDataItemCounter = atoi(chDataItemCounter);
		long itemLen = NAME_LEN + iDataItemCounter * (ITEM_LEN + FENHAO_LEN);
		

		Index recordIndex;
		memset(&recordIndex, 0, sizeof(Index));

		char ch;
		char buff[256];
		int k = 0;

		memset(buff, 0, 256);

		while(fInd.read((char*)&recordIndex, sizeof(Index)))
		{
			if(strcmp(recordIndex.value, word[7].name) == 0)
			{				
				int tell = fTab.tellg();
				fTab.seekg(TABLE_HEAD + RETURN_LEN + atol(recordIndex.index) * (itemLen + RETURN_LEN), ios::beg);
				tell = fTab.tellg();

				k = 0;
				
				memset(buff, 0, 256);
				while(fTab.read(&ch, 1) && ch != '\n')
				{
					buff[k] = ch;
					k++;
				}//初始buff,获得一个数据项。由于数据项中含有的不可见字符0x0,他会终止string,所以只能采用这种逐个赋值的方式
				
				int indicator = 0;
				indicator = 0;
				while( k > 0 )
				{
					fresult.write(&(buff[indicator]), 1);
					indicator++;
					k--;
				}
				
				fresult<<endl;
			}
			fInd.read(&chReturn, RETURN_LEN-1);//滤去回车符,因为是文本方式读写,所以要减去一个字符
			memset(&recordIndex, 0, sizeof(Index));
		}
		fInd.close();
		
		//###################################
		//停止计时器
		END_TIMER(a)
		a.GetTime();
		//#####################################
		
		AfxMessageBox("索引查询模式");
		system("type.bat SearchResult");//显示

		return true;
	}
	//#######################################################################
	return false;
}

bool CDBControl::CheckRight(int cmdId)
{
/*
#define CREATE_RIGHT 1
#define ALTER_RIGHT  1<<1
#define DROP_RIGHT 1<<2
#define INSERT_RIGHT 1<<3
#define SELECT_RIGHT 1<<4
#define UPDATE_RIGHT 1<<5
#define DELETE_RIGHT 1<<6
#define GRANT_RIGHT 1<<7
#define REVOKE_RIGHT 1<<8

#define COMMON_RIGHT SELECT_RIGHT
#define ADMIN_RIGHT 0xffff
	*/
	currentUser = GlobalUser;
	switch(cmdId)
	{
	case CREATE_RIGHT:
		{
			return ((CREATE_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case ALTER_RIGHT:
		{
			return ((ALTER_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case DROP_RIGHT:
		{
			return ((DROP_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case INSERT_RIGHT:
		{
			return ((INSERT_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case SELECT_RIGHT:
		{
			return ((SELECT_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case UPDATE_RIGHT:
		{
			return ((UPDATE_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case DELETE_RIGHT:
		{
			return ((DELETE_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case GRANT_RIGHT:
		{
			return ((GRANT_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	case REVOKE_RIGHT:
		{
			return ((REVOKE_RIGHT & currentUser.right) ? TRUE:FALSE);
		}
	default:
		{
			AfxMessageBox("异常权限");
			return FALSE;
		}
	}
}

/*
	GRANT select,drop,insert ON PROJECT TO USER1,USER2,USER3,USER4;
*/
int CDBControl::Grant(CString str, Word word[], int len)
{
	int off1 = -1, //ON位置 基于0索引
		off2 = -1; //TO位置 基于0索引
	int i = 0;
	while(i < len)
	{
		if(strcmp(word[i].name, "ON") == 0)
			off1 = i;
		else if(strcmp(word[i].name, "TO") == 0)
			off2 = i;
		i++;
	}//获得ON TO的位置

	i = 1;
	int right = 0;
	int rightId = 0;
	while(i < off1)
	{
		if((rightId = ConvertWordToRightId(word[i])) != -1){
			right |= rightId;
		}
		i++;
	}//获得新加的权限


	//写入用户信息文件
	fstream fuser1;
	fuser1.open("user.dat", ios::in | ios::out);
	struct USER us;
	memset(&us, 0, sizeof(struct USER));
	i = 1;
	while(i + off2 < len)
	{
		fuser1.seekg(0, ios::beg);
		while(fuser1.read((char*)&us, sizeof(USER)))
		{
			if(strcmp(us.name, word[off2 + i].name) == 0)
			{
				us.right |= right;
				fuser1.seekp(-signed(sizeof(struct USER)), ios::cur);
				fuser1.write((char*)&us, sizeof(USER));
				break;
			}
				fuser1.read((char*)&us, 1);
		}
		i++;
		if(strcmp(word[i].name, ",") == 0)
			i++;
	}
	fuser1.close();
	
	GlobalUser.GetCurrentUser();

	return true;
}

/*
	REVOKE delete,update,drop ON PROJECT FROM USER1,USER2,USER3,USER4;
*/
int CDBControl::Revoke(CString str, Word word[], int len)
{
	int off1 = -1, //ON位置 基于0索引
		off2 = -1; //FROM位置 基于0索引
	int i = 0;
	while(i < len)
	{
		if(strcmp(word[i].name, "ON") == 0)
			off1 = i;
		else if(strcmp(word[i].name, "FROM") == 0)
			off2 = i;
		i++;
	}//获得ON TO的位置

	i = 1;
	int right = 0;
	int rightId = 0;
	while(i < off1)
	{
		if((rightId = ConvertWordToRightId(word[i])) != -1){
			right |= rightId;
		}
		i++;
	}
	right = ~right;
	//获得想要去除的权限


	//写入用户信息文件
	fstream fuser1;
	fuser1.open("user.dat", ios::in | ios::out);
	struct USER us;
	i = 1;
	while(i + off2 < len)
	{
		fuser1.seekg(0, ios::beg);
		while(fuser1.read((char*)&us, sizeof(USER)))
		{
			if(strcmp(us.name, word[off2 + i].name) == 0)
			{
				us.right &= right;
				fuser1.seekp(-signed(sizeof(struct USER)), ios::cur);
				fuser1.write((char*)&us, sizeof(USER));
				break;
			}
				fuser1.read((char*)&us, 1);
		}
		i++;
		if(strcmp(word[i].name, ",") == 0)
			i++;
	}
	fuser1.close();

	GlobalUser.GetCurrentUser();

	return true;
}

int CDBControl::ConvertWordToRightId(Word wordItem)
{
	int Id = -1;

	if(strcmp(wordItem.name, "create") == 0)
		Id = CREATE_RIGHT;
	else if(strcmp(wordItem.name, "drop") == 0)
		Id = DROP_RIGHT;
	else if(strcmp(wordItem.name, "alter") == 0)
		Id = ALTER_RIGHT;
	else if(strcmp(wordItem.name, "insert") == 0)
		Id = INSERT_RIGHT;
	else if(strcmp(wordItem.name, "select") == 0)
		Id = SELECT_RIGHT;
	else if(strcmp(wordItem.name, "update") == 0)
		Id = UPDATE_RIGHT;
	else if(strcmp(wordItem.name, "grant") == 0)
		Id = GRANT_RIGHT;
	else if(strcmp(wordItem.name, "revoke") == 0)
		Id = REVOKE_RIGHT;
	else if(strcmp(wordItem.name, "delete") == 0)
		Id = DELETE_RIGHT;

	return Id;
}

⌨️ 快捷键说明

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