//файл DBTableTxt.h
//============ "Описание таблицы макета СУБД"==============
//======TableDataType-перечисление типов полей таблиц БД======
enum TableDataType {
NoType,
Int32,
Double,
String,
Date
};
const int LENGTH = 24;//размер полей для имени таблицы и имени столбца.
//Для выравнивания длин имён используются ведущие пробелы.
//ColumnDesc - описание данных в столбце таблицы
//данные типа string имеют одинаковую длину (length) внутри одного столбца,
//но в разных столбцах их длина может отличаться.
struct ColumnDesc {
char colName[LENGTH];//имя столбца
TableDataType colType;//тип данных в столбце таблицы
int length; //максимальное число символов в текстовом представлении
//данных столбца, включая обязятельный '\0' для типа String
ColumnDesc(){};
ColumnDesc(char * name, TableDataType type, int len){
strcpy_s(colName,name);
colType=type;
length=len;
}
};
struct Strip{//полоса распечатки таблицы
int nField;//число полей
int* fieldWidth;//ширина полей в столбцах полосы
}; //с учетом интервалов и длины имени столбца
typedef map<string, void*> Row;
typedef map<string, ColumnDesc> Header;
enum Condition{Undefined,Equal,NotEqual,Less,Greater,LessOrEqual,GreaterOrEqual};
TableDataType GetType(string columnName,Header hdr);
string GetTabNameFromPath(string path);
string ignoreBlanc(const string str);
void* GetValue(string value, string columnName,Header hdr);
bool comparator(TableDataType type,void *obj1,Condition condition,void *obj);
class DBTableTxt;
Row CreateRow(DBTableTxt tab);
//--------------------класс DBTableTxt-----------------------------
class DBTableTxt
{
private:
string tableName;
string primaryKey;//имя столбца, являющегося первичным ключом (значения полей
//в этом столбце должны быть уникальными). Необходим только в "основных" таблицах.
//При удалении записи из таблицы значение первичного ключа в новых записях не повторяется.
//Во "вспомогательных" таблицах, включаемых в реляционные БД для создания связей
//между таблицами типа "многие-ко-многим", он не используется (в файле его нет).
//Примеры "вспомогательных" таблиц: Abonements, OrderDetails. В них записи
//идентифицируются комбинацией ключей связываемых таблиц.
//Значение по умолчанию "NoPrimaryKey" будем использовать как признак того, что в объекте
//DBTableTxt хранится вспомогательная таблица.
//Имя таблицы и имя первичного ключа таблицы будем хранить в первой строке
//табличного файла. Вторая строка табличного файла содержит заголок таблицы.
//В файле "DBTables" будем хранить имена файлов с таблицами БД.
string fileName;
Header columnHeaders;
vector<Row> data;
public:
DBTableTxt(){}
DBTableTxt(string tabName): tableName(tabName){}
~DBTableTxt(){}
string valueToString(Row& row,string columnName);
void ReadTableTxt(string tabName);//tabName=path+tableName
void ReadTableBin(string tabName);//чтение таблицы из бинарного файла
void PrintTable(int screenWidth,string dbName);
void WriteTableTxt(string tabName);//tabName=path+tableName
void WriteTableBin(string tabName);//запись таблицы в бинарный файл
int GetSize();
Row& operator[](int ind);
string GetTableName();
string GetPrimaryKey(){return primaryKey;}
Header GetHeader();
void SetHeader(Header& hdr);
void SetFileName(string path){fileName=path+"//"+tableName+".txt";}
string GetFileName(){return fileName;}
Row CreateRow();
void AddRow(Row row);
DBTableTxt SelfRows(string columnName,Condition cond, void* value);
//Макет распечатки таблицы:
//screenWidth - ширина экрана (входной параметр)
//nStrips - число полос в распечатке (выходной параметр)
//strips[nStrips] - описание полос таблицы:
//число столбцов и ширина каждого столбца в полосе (выходной параметр)
void CreateTableMaket(Strip* &strips,int &nStrips,int screenWidth);
};
2.1 Чтение заголовка в columnHeaders.
Рассмотрим фрагмент кода, который может помочь вам прочитать заголовок таблицы из файла БД при разработке метода ReadDBTable1().
Предупреждение. Прежде чем вставлять код в программу, нужно разобраться в нем и внести необходимые дополнения.
vector<ColumnDesc> strArray;//буфер для чтения строки заголовка таблицы из файла
char line[200];
char *token, *next_token;
fin.getline(line, 200); //чтение заголовка таблицы
next_token=line;
//цикл по словам (лексемам) в строке
ColumnDesc colHdr;//буфер для чтения заголовка одного столбца таблицы
while((token = strtok_s(next_token, delims, &next_token))!= NULL)
{
strcpy_s(colHdr.colName,token);
token = strtok_s(next_token, delims, &next_token);
colHdr.colType=GetType(token);
token = strtok_s(next_token, delims, &next_token);
colHdr.length=atoi(token);
strArray.push_back(colHdr); //выделяет память с помощью new, копирует в //неё заголовок столбца (colHdr) и добавляет указатель на копию в конец вектора }
Header hdr;
for (unsigned int j = 0; j < strArray.size(); j ++)
{
hdr[strArray[j].colName]=strArray[j];//!!! использование операции индексации
}
SetHeader(hdr);//
Чтение строк данных.
//читаем строки в line (до EOF) и записываем их в table.data
data.clear();//вызов метода контейнера vector (для обеспечения повторного чтения)
while (fin.getline(line, 200))
{
Row row=*(new Row());//буфер для формирования строки таблицы
//выделяется память под корневой узел map
int j = 0;
token = strtok_s(line, delims, &next_token);
//цикл по столбцам (словам) в строке
while(token)
{
string value=token;
//добавление поля в строку с преобразованием типа
//strArray[j] - имя столбца в заголовке таблицы
row[strArray[j].colName]=GetValue(value,strArray[j].colName,columnHeaders); j=j++;//индекс следующего столбца в векторе strArray
token = strtok_s(next_token, delims, &next_token);
}
data.push_back(row);//добавить строку данных в таблицу