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

📄 dbcontrol.cpp

📁 数据库模拟程序 实现控制台命令词法分析
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	file.open("CiDian.txt", ios::in | ios::out );

	memset(&data, 0, sizeof(Data));
	file.seekg(index.startOffset, ios::beg);
	file.read(data.name, 40);
	data.pDataArray_len = (index.item_len - 40) / sizeof(DataItem);
	data.pDataArray = new DataItem[data.pDataArray_len];
	int i = 0;
	for(i = 0; i < data.pDataArray_len; i++)
	{
		file.read((char*)&(data.pDataArray[i]), sizeof(DataItem));
	}

	return true;
}

int CDBControl::ReadFromCiDian(long indexID, Data &data)
{
	IndexForCiDian index;
	memset(&index, 0, sizeof(IndexForCiDian));
	if(ReadFromIndex(indexID, index))
	{
		ifstream file;
		file.open("CiDian.txt");
		file.seekg(index.startOffset);
		file.read(data.name, NAME_LEN);

		int count = (index.item_len - NAME_LEN) / sizeof(DataItem);
		DataItem *dataItem = new DataItem[count];
		memset(dataItem, 0, count * sizeof(DataItem));
		int i = 0;
		while(i <= count - 1)
		{
			file.read((char*)&(dataItem[i]), sizeof(DataItem));
			i++;
		}
		data.pDataArray = dataItem;
		data.pDataArray_len = count;
	/*
	if(file.good())
		AfxMessageBox(index.name);
	else
		AfxMessageBox("Error!");
	*/
		file.close();
		return true;
	}
	return false;
}

int CDBControl::RewriteIndexFile()
{
	fstream file;
	file.open("IndexForCiDian.txt", ios::in );

	//获得文件长度
	file.seekg(0 ,ios::end);
	long fileLen = file.tellg();
	long count = fileLen / sizeof(IndexForCiDian);

	//重置指针
	file.seekg(ios::beg);

	int i = 0;
	char buff[10];
	memset(buff, 0, 10);
	IndexForCiDian *index = new IndexForCiDian[count];
	while(file.read((char*)&(index[i]), sizeof(IndexForCiDian)))
	{
		file.read(buff, 1);//读取回车
		if(index[i].name[0] != 0)
			i++;
	}

	file.close();
	
	//从写文件
	file.open("IndexForCiDian.txt", ios::out);
	int com = i - 1;
	i = 0;
	while(i <= com)
	{
		file.write((char*)&(index[i]), sizeof(IndexForCiDian));
		file.write("\n", 1);
		i++;
	}
	file.close();
	return true;
}

int CDBControl::RewriteCiDian()
{
	fstream file;
	char buff[400];
	memset(buff, 0, 400);
	file.open("CiDian.txt", ios::in);
	file.seekg(0 ,ios::end);
	long count = 0;
/*	while(file.getline(buff, 400))
	{
		memset(buff, 0, 400);
		count++;
	}
	*/
	file.seekg(0, ios::beg);
	while(file.read(buff, 1))
	{
		if(buff[0] == '\n')
			count++;
	}
	char (*p)[400] = new char[count][400];
	int *len = new int[count];

	file.clear();
	file.seekg(ios::beg);
	int i = 0, j = 0;
	char ch[2];
	memset(ch, 0, 2);
	while(file.read(ch, 1))
	{
		if(ch[0] != '\n')
			file.seekg(-1, ios::cur);
		else
			continue;
		
		i = 0;
		memset(buff, 0, 400);
		while(file.read(ch, 1))
		{
			if(ch[0] == '\n')
				break;
			else
			{
				buff[i] = ch[0];
				i++;
			}
		}
		
		if(buff[0] != 0)
		{
			int m = 0;
			for(m = 0; m <= i - 1; m++)
				p[j][m] = buff[m];
			len[j] = i - 1;
			j++;//记录个数计数
		}
	}
	file.close();

	//从写文件
	file.open("CiDian.txt", ios::out);
	file.close();
	file.open("CiDian.txt", ios::out | ios::app);

	int com = j - 1;
	i = 0;
	int m = 0, n = 0;
	while(i <= com)
	{
		while(m <= len[n])
		{
			file.write(&p[i][m], 1);
			m++;
		}
		n++;
		m = 0;
		file.write("\n", 1);
		i++;
	}
	file.close();
	delete [] p;
	delete [] len;
	return true;
}

//UPDATE T SET A='BeiJing' WHERE B=4036;
//字符窜不能有分隔符',只能直接写,如'BeiJing'应写成BeiJing
int CDBControl::UpdateTable(CString strCmd, Word word[], int len)
{

	int weizhi1 = -1;//如果成功找到该表中的属性,则weizhi为该属性的顺序索引号码。weizhi =[0..n-1]
	int weizhi2 = -1;
	int ext1 = 0;//用于扩展''的形式,进行补位操作
	int ext2 = 0;
	int ext3 = 0;
	int ext4 = 0;

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

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


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

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

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

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

		fstream readDataFile;
		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(10 + 2, ios::beg);//将指针置于正文,跳过表头信息。

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

		while(1)
		{
			saveOffset = readDataFile.tellg();//记录记录项的起始地址。
			readDataFile.seekg(NAME_LEN, ios::cur);
			readDataFile.seekg(weizhi1 * (ITEM_LEN + 1), ios::cur);//指针调到where后的属性
			readDataFile.read(temp, ITEM_LEN);//读取当前记录的属性值
			
			if(strcmp(temp, word[9 + ext1 + ext2 + ext3].name) == 0)//判断如果是where后的属性指定的值,则改为属性名为word[3].name的值为word[5].name。
			{
				IndexForCiDian indexTemp;
				Data dataTemp;
				memset(&indexTemp, 0, sizeof(IndexForCiDian));
				memset(&dataTemp, 0, sizeof(Data));
				
				indexTemp.indexType = TABLE;
				strcpy(indexTemp.name, index.name);
				
				if((weizhi2 = getIndexFromCiDian(indexTemp, dataTemp, word[3].name)) != -1)
				{
					readDataFile.seekg(saveOffset + NAME_LEN + weizhi2 * (ITEM_LEN + 1), ios::beg);//置指针到属性位置
					char ok[ITEM_LEN];
					memset(ok, 0, ITEM_LEN);
					strcpy(ok, word[5 + ext1].name);
					readDataFile.write(ok, ITEM_LEN);
				}
			}
			readDataFile.seekg(saveOffset + recordLen + 2, ios::beg);
			j++;
			if(j >= recordCount)
				break;
		}
		readDataFile.close();
	}
	else
		AfxMessageBox("该表或属性不存在!");

	return false;
}

/**

  [in][out]	@param index为已经初始化index.name,index.indexType的数据词典索引
  [in]		@param name为代查的属性名
  [out]		@param data为数据词典中读到的数据
			@return 属性在表模式结构中的位置索引[0...N-1]
*/

int CDBControl::getIndexFromCiDian(IndexForCiDian &index, Data &data, char name[])
{
	long offset = -1;
	if((offset = findInIndexFile(index)) == -1)//从索引文件中读取名为name的项在数据字典文件中的位置。
		return -1;

	int i = 0, flag = 0;

	if(!ReadFromCiDian(index, data))//从数据词典中读取数据到data中
		return -1;

	int count = data.pDataArray_len;
	int weizhi = -1;//如果成功找到该表中的属性,则weizhi为该属性的顺序索引号码。weizhi =[0...n-1]
	i = 0;
	while(i < count)
	{
		if(strcmp(data.pDataArray[i].name, name) == 0){//该语句用于找到name位置,存到weizhi.
			flag = 1;
			weizhi = i;
			break;
		}
		i++;
	}
	return weizhi;
}

//ALTER TABLE EMPLOYEE DROP JOB VARCHAR(10);
int CDBControl::Alter(CString str, Word word[], int len)
{
	IndexForCiDian index;
	Data data;
	memset(&index, 0, sizeof(IndexForCiDian ));
	memset(&data, 0, sizeof(Data));

	long offset = -1;
	strcpy(index.name, word[2].name);
	index.indexType = TABLE;
	if((offset = findInIndexFile(index)) == -1)
	{
		AfxMessageBox("该表不存在!");
		return false;
	}

	if(strcmp(word[3].name, "DROP") == 0)
	{
		fstream ff;
		fstream f2;

		long recordCount = 0;
		long recordLen = 0;
		long count =(index.item_len - NAME_LEN) / (sizeof(DataItem));//属性个数计数

		////////////////////////////////////////////////////////////
		//////////原数据词典文件转存到临时文件temp中
		////////////////////////////////////////////////////////////
		ff.open("CiDian.txt", ios::in | ios::out | ios::nocreate);
		f2.open("temp",ios::out);
		char ch;
		while(ff.read(&ch,1))
		{
			f2.write(&ch,1);
		}
		f2.close();
		ff.close();
		////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////
		/////////////获取需修改的属性的索引号
		////////////////////////////////////////////////////////////
		long weizhi;
		weizhi = -1;
		IndexForCiDian index2;
		Data data2;
		char name[20];
		
		memset(&data2, 0, sizeof(Data));
			
		memset(&index2, 0, sizeof(IndexForCiDian));
		strcpy(index2.name, word[2].name);
		index2.indexType = TABLE;//初始Index
		
		memset(name, 0, 20);
		strcpy(name, word[4].name);//初始属性名

		if((weizhi = getIndexFromCiDian(index2, data2, name)) == -1){
			CString out;
			out.Format("%s不是%s的属性!", name, index2.name);
			AfxMessageBox(out);
			return false;
		}
		////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////
		///////处理数据词典文件
		////////////////////////////////////////////////////////////
		ff.open("CiDian.txt",ios::out);
		f2.open("temp",ios::in);
		long off;
		off = 0;

		//##################################
		//修改数据字典中的表模式
		while(f2.read(&ch,1))
		{
			if(!(( unsigned(off) >= index.startOffset + NAME_LEN + weizhi * (sizeof(DataItem)))
				&& (unsigned(off) < index.startOffset + NAME_LEN + (weizhi + 1) * (sizeof(DataItem))))){
				ff.write(&ch,1);
				ff.flush();
			}
			else
			{
				;
			}
			off++;
		}
		ff.close();
		f2.close();
		//##################################
		//处理数据词典文件
		////////////////////////////////////////////////////////////

		count = count - 1;//属性加一		

		////////////////////////////////////////////////////////////
		///处理索引文件,调整索引范围
		////////////////////////////////////////////////////////////
		IndexForCiDian tempIndex;
		memset(&tempIndex, 0, sizeof(IndexForCiDian));
		tempIndex = index;
		tempIndex.item_len -= sizeof(DataItem);

		ff.open("IndexForCiDian.txt", ios::in | ios::out | ios::nocreate);
		ff.seekg(offset, ios::beg);//移动指针到该记录的索引位置。
		ff.write((char*)&tempIndex, sizeof(tempIndex));
		ff.read(&ch,1);//跳过回车

		memset(&tempIndex, 0, sizeof(IndexForCiDian));
		while(ff.read((char*)&tempIndex, sizeof(tempIndex)))
		{
			tempIndex.startOffset -= sizeof(DataItem);
			ff.seekg(-signed(sizeof(IndexForCiDian)),ios::cur);
			ff.write((char*)&tempIndex, sizeof(tempIndex));
			ff.read(&ch,1);
		}//////处理后续的所有的索引
		ff.close();
		////////////////////////////////////////////////////////////
		
		////////////////////////////////////////////////////////////
		////修改数据表表头信息
		////////////////////////////////////////////////////////////
		char filename[20];
		memset(filename, 0, 20);
		strcpy(filename, word[2].name);
		strcat(filename, ".tab");
		ff.open(filename, ios::in | ios::out | ios::nocreate);
		char buff[100];
		memset(buff, 0, 100);
		itoa(count, buff, 10);
		ff.write(buff, 10);
		ff<<endl;//修改表头信息
		ff.close();
		////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////
		////修改表模式信息=〉删除属性信息
		////////////////////////////////////////////////////////////
		
		ff.open(filename, ios::in);
		f2.open("temp",ios::out);
		while(ff.read(&ch,1))
		{
			f2.write(&ch,1);
		}
		f2.close();
		ff.close();//文件中转

		ff.open(filename, ios::in);
		ff.seekg(0, ios::end);
		long fileLen = ff.tellg();
		recordCount = (fileLen - 10 - 2) / (NAME_LEN + (count + 1) * (ITEM_LEN + 1) + 2);
		recordLen = NAME_LEN + (count + 1) * (ITEM_LEN + 1);
		ff.close();
		
		ff.open(filename, ios::out);
		f2.open("temp",ios::in);
		long pt ;

		pt = 0;
		while(pt < 10 + 1)
		{
			f2.read(&ch,1);
			ff.write(&ch,1);
			pt++;
		}//置指针到正式的记录

		int tr;
		pt = 0;
		tr = 0;
		int amd;
		while(pt < recordCount)
		{
			amd=ff.tellg();
			for(tr = 0; tr < recordLen + 1; tr++){
				f2.read(&ch,1);
				if(!((tr >= NAME_LEN + weizhi * (ITEM_LEN + 1)) 
					&& (tr < NAME_LEN + (weizhi + 1) * (ITEM_LEN + 1))))
					ff.write(&ch,1);
			}
			amd=ff.tellg();
			pt++;
		}

		f2.close();
		ff.close();
		////////////////////////////////////////////////////////////
	}
	else if(strcmp(word[3].name, "ADD") == 0)
	{
		fstream ff;
		fstream f2;
		DataItem dataItem;
		long recordCount = 0;
		long recordLen = 0;
		long count =(index.item_len - NAME_LEN) / (sizeof(DataItem));//属性个数计数

		////////////////////////////////////////////////////////////
		//////////原表转存到临时表temp中
		////////////////////////////////////////////////////////////
		ff.open("CiDian.txt", ios::in | ios::out | ios::nocreate);
		f2.open("temp",ios::out);
		char ch;
		while(ff.read(&ch,1))
		{
			f2.write(&ch,1);
		}
		f2.close();
		ff.close();
		////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////
		///////原数据词典文件转存到临时文件temp中
		////////////////////////////////////////////////////////////
		ff.open("CiDian.txt",ios::out);
		f2.open("temp",ios::in);
		long off;
		off = 0;
		while(unsigned(off) < index.startOffset + NAME_LEN + count * (sizeof(DataItem)))
		{
			f2.read(&ch,1);
			ff.write(&ch,1);
			off++;
		}
		f2.read(&ch, 1);//跳过回车

		memset(&dataItem, 0, sizeof(DataItem));
		strcpy(dataItem.name, word[4].name);
		if(strcmp(word[5].mark ,"a") == 0){
			dataItem.type = 2;
			dataItem.len = atoi(word[7].name);
		}
		ff.write((char*)&dataItem ,sizeof(DataItem));
		ff<<endl;

		while(f2.read(&ch,1))
		{
			ff.write(&ch,1);
		}
		f2.close();
		ff.close();//处理数据词典文件
		////////////////////////////////////////////////////////////

		count = count + 1;//属性加一		

		////////////////////////////////////////////////////////////
		///处理索引文件,调整索引范围
		////////////////////////////////////////////////////////////
		IndexForCiDian tempIndex;
		memset(&tempIndex, 0, sizeof(IndexForCiDian));
		tempIndex = index;
		tempIndex.item_len += sizeof(DataItem);

		ff.open("IndexForCiDian.txt", ios::in | ios::out | ios::nocreate);
		ff.seekg(offset, ios::beg);//移动指针到该记录的索引位置。
		
		ff.write((char*)&tempIndex, sizeof(tempIndex));
		ff.read(&ch,1);//跳过回车

		memset(&tempIndex, 0, sizeof(IndexForCiDian));
		while(ff.read((char*)&tempIndex, sizeof(tempIndex)))
		{
			tempIndex.startOffset += sizeof(DataItem);
			ff.seekg(-signed(sizeof(IndexForCiDian)),ios::cur);
			ff.write((char*)&tempIndex, sizeof(tempIndex));
			ff.read(&ch,1);
		}//////处理后续的所有的索引
		ff.close();
		////////////////////////////////////////////////////////////
		
		////////////////////////////////////////////////////////////
		////修改数据表表头信息
		////////////////////////////////////////////////////////////
		char filename[20];
		memset(filename, 0, 20);
		strcpy(filename, word[2].name);
		strcat(filename, ".tab");
		ff.open(filename, ios::in | ios::out | ios::nocreate);
		char buff[100];
		memset(buff, 0, 100);
		itoa(count, buff, 10);
		ff.write(buff, 10);
		ff<<endl;//修改表头信息
		////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////
		////修改表模式信息=〉添加属性信息
		////////////////////////////////////////////////////////////
		ff.close();
		ff.open(filename, ios::in);
		f2.open("temp",ios::out);
		while(ff.read(&ch,1))
		{
			f2.write(&ch,1);
		}
		f2.close();
		ff.close();//文件中转

		ff.open(filename, ios::in);
		ff.seekg(0, ios::end);
		long fileLen = ff.tellg();
		recordCount = (fileLen - 10 - 2) / (NAME_LEN + (count - 1) * (ITEM_LEN + 1) + 2);
		recordLen = NAME_LEN + (count - 1) * (ITEM_LEN + 1);
		ff.close();
		
		ff.open(filename, ios::out);
		f2.open("temp",ios::in);
		long pt ;

		pt = 0;
		while(pt < 10 + 1)
		{
			f2.read(&ch,1);
			ff.write(&ch,1);
			pt++;

⌨️ 快捷键说明

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