📄 dbcontrol.cpp
字号:
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 + -