#include "StdAfx.h"
DBTable::DBTable(string name) : m_strTableName(name), m_TableHead(NULL), m_TableBody(NULL)
{
m_indexNumber = 0;
memset(m_index,0,SINGLE_TABLE_INDEX_NUMBER);
m_TableHead = new TableHead;
m_TableBody = new TableBody;
Column* pCol;
char t;
int col(-1);
cout << "Insert a Column(y/n)?";
cin >> t;
while(t == 'y' || t == 'Y')
{
col++;
string str;
cout << "Please Input the New Column's Name:";
cin >> str;
int coll;
while(m_TableHead->isFindColumn(str,coll))
{
cout << "This Column Exsited, Please Input Again:";
cin >> str;
}
pCol = new Column(str);
m_TableHead->append(pCol);
cout << "Create a Index on This Column?(y/n)";
char kk;
cin >> kk;
if(kk=='y' || kk=='Y')
{
if(CreateIndex(col))
{
cout << "Create Index Successfully!" << endl;
}
else
{
cout << "Create Index Failed!" << endl;
}
}
cout << "Insert a Column(y/n)?";
cin >> t;
}
cout << "Insert Rows?(y/n)";
cin >> t;
if(t=='y' || t=='Y')
{
InsertRows();
}
}
DBTable::~DBTable()
{
if (m_TableHead != NULL)
delete m_TableHead;
if (m_TableBody != NULL)
delete m_TableBody;
for(int i=0;i<m_TableHead->getTableHeadSize();i++)
{
if (m_index[i] != NULL)
delete m_index[i];
}
}
bool DBTable::FindData(string & colname, string & value, int & row, int & col)
{
if(!m_TableHead->isFindColumn(colname, col))
{
cerr << "Column not Existed!" << endl;
return false;
}
/////////////////////////////////////////////////////////////////////////////
// 如果已创建该列上的索引,通过索引查找,否则顺序遍历查找
if(m_TableHead->getColumn(col).Indexed())
{
return m_index[col]->find(&value, row);
}
else
{
int flag(0);
for(row=0;row<m_TableBody->getMaxSize();row++)
{
if(m_TableBody->m_listArray[row].NextAvailableItem() == -1
&& value == *m_TableBody->m_listArray[row].m_listArray[col])
{
for(int j=0;j<m_TableHead->getTableHeadSize();j++)
{
cout << " " << setw(10) << *m_TableBody->m_listArray[row].m_listArray[j];
}
cout << endl;
flag = 1;
}
}
if(flag == 1) return true;
else return false;
}
}
bool DBTable::InsertRow(int &row)
{
if (m_TableBody->m_freeMem == m_TableBody->getMaxSize()) // 表满,扩大一倍
{
m_TableBody->setMaxSize(2 * m_TableBody->getMaxSize() + 1);
Row* temp = m_TableBody->m_listArray;
m_TableBody->m_listArray = new Row[m_TableBody->getMaxSize()];
if (m_TableBody->m_listArray == NULL) return false;
for (int i = 0; i < m_TableBody->getListSize(); i++)
{
m_TableBody->m_listArray[i].NextAvailableItem(temp[i].NextAvailableItem());
for(int j=0; j != m_TableHead->getTableHeadSize(); j++)
m_TableBody->m_listArray[i].m_listArray[j] = temp[i].m_listArray[j];
}
for (int i = m_TableBody->getListSize(); i < m_TableBody->getMaxSize(); i++)
{
if(m_TableBody->m_listArray[i].NextAvailableItem() == -1)
for(int j=0; j != m_TableHead->getTableHeadSize(); j++)
{
delete m_TableBody->m_listArray[i].m_listArray[j];
m_TableBody->m_listArray[i].m_listArray[j] = NULL;
}
}
for (int i = m_TableBody->getListSize(); i < m_TableBody->getMaxSize(); i++)
{
m_TableBody->m_listArray[i].NextAvailableItem(i + 1);
for(int j=0; j != m_TableHead->getTableHeadSize(); j++)
m_TableBody->m_listArray[i].m_listArray[j] = NULL;
}
}
string str;
string* pstr;
cout << "请依次输入每一列的值:" << endl;
int k = m_TableBody->m_listArray[m_TableBody->m_freeMem].NextAvailableItem();
for(int i=0; i<m_TableHead->getTableHeadSize(); i++)
{
cin >> str;
pstr = new string(str);
if(!pstr) { cerr << "插入行失败!" << endl; return false; }
m_TableBody->m_listArray[m_TableBody->m_freeMem].m_listArray[i] = pstr;
}
row = m_TableBody->m_freeMem; //
m_TableBody->m_listArray[m_TableBody->m_freeMem].NextAvailableItem(-1);
m_TableBody->m_freeMem = k;
m_TableBody->m_listSize++;
return true;
}
bool DBTable::InsertRows()
{
int number;
int row;
cout << "Please Input the Row Numbers You Want to Insert at Once:";
cin >> number;
for(int i=0;i<number;i++)
{
if(!InsertRow(row))
return false;
IndexInsert(row);
}
return true;
}
bool DBTable::DeleteRow(int & row) // 逻辑删除
{
int col;
string colname, value;
cout << "Please Input the Column's Name You Want:";
cin >> colname;
if(!m_TableHead->isFindColumn(colname, col))
{
cerr << "Column not Existed!" << endl;
return false;
}
cout << "Please Input the Value:";
cin >> value;
if(!FindData(colname, value, row, col))
{
cerr << "未找到!" << endl;
return false;
}
m_TableBody->m_listArray[row].NextAvailableItem(m_TableBody->m_freeMem);
m_TableBody->m_freeMem = row;
/*for( int i=0;i<m_TableHead->getTableHeadSize();i++)
{
delete m_TableBody->m_listArray[row].m_listArray[i];
m_TableBody->m_listArray[row].m_listArray[i] = NULL;
}*/
m_TableBody->m_listSize--;
return true;
}
bool DBTable::UpdateData(int & row)
{
int col;
string colname, value;
cout << "Please Input the Column's Name You Want:";
cin >> colname;
cout << "Please Input the Value:";
cin >> value;
if(!FindData(colname, value, row, col))
{
cerr << "Can't Find!" << endl;
return false;
}
cout << "Please Input the New Value:";
cin >> *m_TableBody->m_listArray[row].m_listArray[col];
return true;
}
bool DBTable::CreateIndex(int col)
{
if(m_indexNumber == SINGLE_TABLE_INDEX_NUMBER)
{
cerr << "Memery Full!" << endl;
return false;
}
if(m_TableHead->getColumn(col).Indexed())
{
cerr << "Index on This Column Existed!" << endl;
return false;
}
int y;
cout << "Please Choose a Index Type 1.BST 2.AVL 3.Hash 4.B Tree:";
cin >> y;
switch(y)
{
case 1:
m_index[col] = new BST<string*, string*>;
break;
case 2:
m_index[col] = new AVL<string*, string*>;
break;
case 3:
m_index[col] = new Hash<string*, string*>;
break;
case 4:
m_index[col] = new BTree<string*, string*>;
break;
default: return false;
}
if(m_index[col] == NULL)
{
cerr << "Memery Full!" << endl;
return false;
}
m_index[col]->ColumnName(m_TableHead->getColumn(col).Name());
for(int i=0; i<m_TableBody->getMaxSize(); i++)
{
if(m_TableBody->m_listArray[i].NextAvailableItem() == -1)
m_index[col]->insert(m_TableBody->m_listArray[i].m_listArray[col],i);
}
m_indexNumber++;
bool in = true;
m_TableHead->getColumn(col).Indexed(in);
return true;
}
bool DBTable::DeleteIndex(int col)
{
if(m_indexNumber == 0) return false;
delete m_index[col];
m_index[col] = NULL;
m_indexNumber--;
return true;
}
void DBTable::IndexInsert(int r)
{
for(int i=0;i<m_TableHead->getTableHeadSize();i++)
{
if(m_TableHead->getColumn(i).Indexed())
{
m_index[i]->insert(m_TableBody->m_listArray[r].m_listArray[i], r);
}
}
}
void DBTable::IndexDelete(int r)
{
for(int i=0;i<m_TableHead->getTableHeadSize();i++)
{
if(m_TableHead->getColumn(i).Indexed())
{
m_index[i]->remove(m_TableBody->m_listArray[r].m_listArray[i], r);
}
}
}
void DBTable::print()
{
cout << endl;
cout << "Table Name:" << TableName();
m_TableHead->print();
for(int j=0; j<m_TableBody->getMaxSize(); j++)
{
if(m_TableBody->m_listArray[j].NextAvailableItem() == -1)
{
cout << endl;
for(int i=0; i<m_TableHead->getTableHeadSize(); i++)
{
if(m_TableBody->m_listArray[j].m_listArray[i] != NULL)
cout << " " << setw(10) << *m_TableBody->m_listArray[j].m_listArray[i];
}
}
}
cout<<endl;
cout<<endl;
}
bool DBTable::InsertColumn(int & col)
{
if(m_TableHead->InsertColumn(col))
{
string str;
string* pstr;
int tt(0);
for(int i=0; i<m_TableBody->getMaxSize(); i++)
{
for(int j = m_TableHead->getTableHeadSize();j>col;j--)
m_TableBody->m_listArray[i].m_listArray[j] = m_TableBod