📄 dbcontrol.cpp
字号:
// DBControl.cpp: implementation of the CDBControl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "database.h"
#include "DBControl.h"
#include "Index.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CUser GlobalUser;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDBControl::CDBControl()
{
m_strCmd = "";
word = 0;
len = 0;
memset(data.name, 0, 40);
data.pDataArray = NULL;
data.pDataArray_len = 0;
indexArray = NULL;
dataArray_len = 0;
indexArray_len = 0;
noIndex = 1;
}
CDBControl::~CDBControl()
{
}
int CDBControl::CreateTable(CString CmdLine, Word word[], int LenOfWord)
{
//对word 中 char float integer 的个数分别计数 为n_char,n_float,n_integer
//!!!n_float 暂时未实现,不支持float结构
int n_char = 0, n_integer = 0;
int i = 0;
if(isExistTheKey(word[2].name))
{
CString temp, out;
if(strcmp(word[1].mark, "t") == 0)
temp.Format("表 %s", word[2].name);
else if(strcmp(word[1].mark, "v") == 0)
temp.Format("视图 %s", word[2].name);
else if(strcmp(word[1].mark, "x") == 0)
temp.Format("索引 %s", word[2].name);
else
temp = "错误!";
out.Format("该%s已经存在!", temp);
AfxMessageBox(out);
return false;
}
while(i < LenOfWord)
{
if(strcmp(word[i].mark, "a") == 0)
n_char++;
else if(strcmp(word[i].mark, "i") == 0)
n_integer++;
i++;
}
//m_strCmd = CmdLine;
//数据项清空
memset(data.name, 0, 40);
if(data.pDataArray != NULL){
delete [] data.pDataArray;
data.pDataArray = NULL;
}
data.pDataArray_len = 0;
//数据项赋值
if(strlen(word[2].name) < 40)
strcpy(data.name, word[2].name);
else
{
AfxMessageBox("表名超过40个字符!请输入小于40个字符的名字!");
return false;
}
data.pDataArray_len = n_char + n_integer;
data.pDataArray = new DataItem[data.pDataArray_len];
ZeroMemory(data.pDataArray, sizeof(DataItem) * data.pDataArray_len);
i = 0;
int m =0;
while(i < data.pDataArray_len)
{
strcpy(data.pDataArray[i].name, word[4+m].name);
if(strcmp(word[4+m+1].mark, "a") ==0)
{
data.pDataArray[i].type = 2;
m += 3;
data.pDataArray[i].len = atoi(word[4+m].name);
m++;
}
else if(strcmp(word[4+m+1].mark, "i") ==0)
m++;
// AfxMessageBox(word[4+i].name);
m++;
i++;
if(m + 4 < LenOfWord)
m++;
}
long start,len;
len = AddToDataCiDian(data, start);
//赋值索引变量++++
IndexForCiDian index;
strcpy(index.name, word[2].name);
if(strcmp(word[1].mark, "t") == 0)
index.indexType = TABLE;
else if(strcmp(word[1].mark, "v") == 0)
index.indexType = VIEW;
else if(strcmp(word[1].mark, "x") == 0)
index.indexType = INDEX;
index.item_len = len;
index.startOffset = start;
AddToIndex_ForCiDian(index);
//////////////////////////////////////////////////////////////////////////
ofstream fout;
char filename[20];
char buff[10];
memset(filename, 0, 20);
memset(buff, 0, 10);
strcpy(filename, word[2].name);
strcat(filename, ".tab");
itoa(data.pDataArray_len, buff, 9);
fout.open(filename, ios::out);
fout.write(buff, 10);
fout<<endl;
fout.close();
return false;
}
//传递表,索引,视图的名字进来
//判断表,索引,视图是否存在
int CDBControl::isExistTheKey(CString str)
{
if(indexArray == NULL)
ASSERT(initTable());
int i = 0;
while(i < indexArray_len)
{
if(str == indexArray[i].name)
break;
i++;
}
return ((i == indexArray_len) ? false : true);
}
int CDBControl::AddToIndex_ForCiDian(const IndexForCiDian &index)
{
CString str;
str.Format("%d %s %ld %ld",index.indexType, index.name, index.startOffset, index.item_len);
fstream file;
file.open("indexForCiDian.txt",ios::in | ios::out | ios::app);
file.seekp(ios::end);
if(file.write((char*)&index, sizeof(IndexForCiDian)))
AfxMessageBox(str);
file<<endl;//////////
file.close();
return false;
}
int CDBControl::AddToDataCiDian(const Data &dataFile, long &start)
{
fstream file;
file.open("CiDian.txt",ios::in | ios::out | ios::app);
char ch;
while(file.read(&ch, 1))
NULL;
file.clear();
start = file.tellp();
file.write(dataFile.name, NAME_LEN);
int i = 0;
while(i <= dataFile.pDataArray_len - 1)
{
file.write((char*)&(dataFile.pDataArray[i]), sizeof(DataItem));
i++;
}
long end = file.tellp();
file<<endl;//////////
file.close();
return (end - start );
}
int CDBControl::initTable()
{
ifstream file;
file.open("IndexForCiDian.txt", ios::nocreate );
if(!file)
{//文件不存在
ofstream fw;
fw.open("IndexForCiDian.txt");
fw.close();
return true;
}
char ch;
while(file.read(&ch,1))
NULL;
int endOfFile = file.tellg();
file.seekg(ios::beg);
// int index = file.tellg();
////由于未知错误,不得不关闭文件再打开。无法在文件内部移动指针。
////此外,移动指针为ios::end时,tellg()返回为2,是错误值。
file.close();
//////////////////////
int count = endOfFile / sizeof(IndexForCiDian);
indexArray_len = count;
if(indexArray == NULL)
indexArray = new IndexForCiDian[count];
else
{
delete indexArray;
indexArray = new IndexForCiDian[count];
}
ASSERT(indexArray);
///////////
file.open("IndexForCiDian.txt", ios::nocreate );
////////////
char buff[10];
memset(buff, 0, 10);
int i = 0;
while(i < count)
{
if(!file.read((char*)(&(indexArray[i])), sizeof(IndexForCiDian)))
{
if(!file.good())
AfxMessageBox("文件读取错误!");
return false;
}
file.read(buff, 1);
// AfxMessageBox(indexArray[i].name);
i++;
}
file.close();
return true;
}
void CDBControl::CheckCMD(int cmdType)
{
switch(cmdType)
{
case CREATE_TABLE:
{
if(CheckRight(CREATE_RIGHT))
CreateTable(m_strCmd, word, len);
else
AfxMessageBox("你没有CREATE权限");
break;
}
case DROP_TABLE:
{
if(CheckRight(DROP_TABLE))
Drop(m_strCmd, word, len);
else
AfxMessageBox("你没有DROP权限");
break;
}
case INSERT:
{
if(CheckRight(INSERT_RIGHT))
InsertIntoValue(m_strCmd, word, len);
else
AfxMessageBox("你没有INSERT权限");
break;
}
case UPDATE:
{
if(CheckRight(UPDATE_RIGHT))
UpdateTable(m_strCmd, word, len);
else
AfxMessageBox("你没有UPDATE权限");
break;
}
case SELECT:
{
if(CheckRight(SELECT_RIGHT)){
CIndex dlg;
if(dlg.DoModal() == IDOK)
{
noIndex = dlg.m_mIndex;
if(!noIndex)
Select_noIndex(m_strCmd, word, len);
else
Select_Index(m_strCmd, word, len);
}
}
else{
AfxMessageBox("你没有SELECT权限");
}
// show(m_strCmd, word, len);
break;
}
case ALTER:
{
if(CheckRight(ALTER_RIGHT))
Alter(m_strCmd, word, len);
else
AfxMessageBox("你没有ALTER权限");
break;
}
case DELETE:
{
if(CheckRight(DELETE_RIGHT))
Delete(m_strCmd, word, len);
else
AfxMessageBox("你没有DELETE权限");
break;
}
case GRANT:
{
if(CheckRight(GRANT_RIGHT))
Grant(m_strCmd, word, len);
else
AfxMessageBox("你没有GRANT权限");
break;
}
case REVOKE:
{
if(CheckRight(REVOKE_RIGHT))
Revoke(m_strCmd, word, len);
else
AfxMessageBox("你没有REVOKE权限");
break;
}
default:
break;
}
}
CDBControl::CDBControl(CString str, Word *word, int len)
{
m_strCmd = str;
this->word = word;
this->len = len;
memset(data.name, 0, 40);
data.pDataArray = NULL;
data.pDataArray_len = 0;
indexArray = NULL;
dataArray_len = 0;
indexArray_len = 0;
}
//数据词典索引文件访问
//穷举数据词典索引文件 IndexForCiDian.txt内容
void CDBControl::ReadFromIndex()
{
char ch;
CString str,tstr;
IndexForCiDian index;
index.indexType= TABLE;
index.item_len=0;
memset(index.name, 0, 40);
index.startOffset=0;
ifstream fileIndex;
fileIndex.open("IndexForCiDian.txt",ios::in );
if(!fileIndex)
return;
// Data data;
while(fileIndex.read(&ch, 1))
{
if(ch != '\n')
fileIndex.seekg(fileIndex.tellg() - 1);
fileIndex.read((char*)&index, sizeof(IndexForCiDian));
fileIndex.read(&ch, 1);
str.Format("%d %s %d %d",index.indexType, index.name, index.startOffset, index.item_len);
tstr+="\n";
tstr+=str;
// str.Empty();
}
AfxMessageBox(tstr);
fileIndex.close();
}
//访问数据词典索引文件,IndexForCiDian.txt,获得索引为indexID的数据词典中的项
//@[in]param indexID = 待查找的数据词典(CiDian.txt)文件中的索引号。
//@[out]param index 返回的参数。返回“数据词典索引”类型的结构
int CDBControl::ReadFromIndex(long indexID, IndexForCiDian &index)
{
ifstream file;
file.open("IndexForCiDian.txt");
file.seekg(0,ios::end);
unsigned long len = file.tellg();
file.close();
file.open("IndexForCiDian.txt");
file.seekg(indexID * (sizeof(IndexForCiDian) + 2));
if(len <= unsigned(indexID * (sizeof(IndexForCiDian) + 2)))
return false;
file.read((char*)&index, sizeof(IndexForCiDian));
/*
if(file.good())
AfxMessageBox(index.name);
else
AfxMessageBox("Error!");
*/
file.close();
return (file.good())?true:false;
}
int CDBControl::Drop(CString CmdLine, Word word[], int LenOfWord)
{
if(!isExistTheKey(word[2].name))
{
CString temp, out;
if(strcmp(word[1].mark, "t") == 0)
temp.Format("表 %s", word[2].name);
else if(strcmp(word[1].mark, "v") == 0)
temp.Format("视图 %s", word[2].name);
else if(strcmp(word[1].mark, "x") == 0)
temp.Format("索引 %s", word[2].name);
else
temp = "错误!";
out.Format("该%s不存在!", temp);
AfxMessageBox(out);
return false;
}
if(strcmp(word[1].name, "TABLE") == 0)
{
//实现表删除
//打开索引文件
fstream file;
file.open("IndexForCiDian.txt", ios::in | ios::out);
IndexForCiDian index;
strcpy(index.name, word[2].name);
index.indexType = TABLE;
CDBControl control;
CString str;
long offsetInIndex = -1;
// if(文件名存在)
//获得词典文件中的位置
if((offsetInIndex = control.findInIndexFile(index)) != -1)
{
//从索引文件中删除
IndexForCiDian tempIndex;
memset(&tempIndex, 0, sizeof(IndexForCiDian));
file.seekp(offsetInIndex);
if(file.write((char*)&tempIndex, sizeof(IndexForCiDian)))
{
#ifdef _DEBUG
AfxMessageBox("删除索引操作成功!");
#else
NULL;
#endif
file.write("\n", 1);
file.flush();
//从写文件
RewriteIndexFile();
}
else
{
#ifdef _DEBUG
AfxMessageBox("删除索引操作失败!");
#else
NULL;
#endif
}
file.close();
}
// else
else
{
// 返回表不存在的提示
str.Format("%s不存在!删除操作失败!", index.name);
AfxMessageBox(str);
file.close();
return false;
}
//打开词典文件,根据索引文件中找到的位置,及相关信息
file.open("CiDian.txt", ios::in | ios::out);
file.seekg(index.startOffset);
char *buffer = new char[index.item_len];
memset(buffer, 0, index.item_len);
if(file.write((char*)buffer, index.item_len))
{
#ifdef _DEBUG
AfxMessageBox("删除模式操作成功!");
#else
NULL;
#endif
file.write("\n", 1);
file.flush();
//从写文件/////////
// RewriteCiDian();
///////////////////
}
else
{
#ifdef _DEBUG
AfxMessageBox("删除模式操作失败!");
#else
NULL;
#endif
}
file.close();
// 读取词典文件。
char filename[20];
memset(filename, 0, 20);
strcpy(filename, index.name);
strcat(filename, ".tab");
char cmd[40];
memset(cmd, 0, 40);
strcat(cmd, "del ");
strcat(cmd, filename);
system(cmd);
}
else if(strcmp(word[1].name, "VIEW") == 0)
{
//实现视图删除
}
return false;
}
/*
从索引表中找到指定名称,类型的indexforCiDian对象
*/
long CDBControl::findInIndexFile(IndexForCiDian &findIndex)
{
ifstream file;
long value = -1;
file.open("IndexForCiDian.txt", ios::in | ios::nocreate);
if(file.fail())
AfxMessageBox("文件打开失败");
IndexForCiDian index;
memset(&index, 0, sizeof(IndexForCiDian));
char ch;
// file.read((char*)&index, sizeof(IndexForCiDian));
long m =file.tellg();
while(file.read((char*)&index, sizeof(IndexForCiDian)))
{
if(strcmp(index.name, findIndex.name) == 0 && index.indexType == findIndex.indexType){
findIndex = index;
value = file.tellg();
file.seekg(-(signed)sizeof(IndexForCiDian), ios::cur);
value = file.tellg();
file.seekg(sizeof(IndexForCiDian), ios::cur);
break;
}
file.read(&ch, 1);//读去回车字符
}
m =file.tellg();
file.close();
return value;
}
/**
多关系的投影 ,但只能投影出第一个关系中元组的长度
*/
int CDBControl::Select_noIndex(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -