Dependency(reader)

A. First Edition
This is the first edition of my "dependency" and actually it is a simple "reader". 
B.The problem

"Function dependency" is a very important issue in database theory. And what's more, it is the essence of all.

Because I think it is the key of knowledge: the world is described by relations and relations of relations.

 

C.The idea of program
 
The reader only reads all relations and its attributes. The syntax is like following:
 
R(A,B,C,D);
AB -> C;
C->D,D->A;
 
The first line gives the name of relation "R". Inside parentheses there are attributes. Then comes the function
 
dependencies, separated by "," or ";".  The only outstanding feature of my reader is that I try to recognize the
 
attributes according to the principle of the "longest". i.e. attribute "Ax" and "A" both starts with an "A".
 
If in a relation such as "AB -> AxB". My reader should recognize the LHS is "A" and "B", while the RHS should be
 
"Ax" and "B". How to do this? When searching the first character "A", it returns two results and my program
 
should continue to search for next character until only one result returned.
 
D.The major functions
E.Further improvement
When I read more about the book.
F.File listing
1. reader.h 
2. reader.cpp
3. main.cpp (main)
file name: reader.h
#include <iostream>
#include <bitset>

using namespace std;

//make it simple, the first line must list all variables or attributes
//"relation"(A,B,C...)
const int MaxNameLength=5;
const int MaxAttrNumber=20;
const int MaxRuleNumber=100;

int extractNames(FILE* stream, char nameBuffers[][MaxNameLength+1], char* delimeters, 
				 char endChar='\n');


class Rule
{
private:
	bitset<MaxAttrNumber> lhs;
	bitset<MaxAttrNumber> rhs;
public:
	Rule();
	bool test(int pos, bool isLeft);
	void lhsSet(int pos);
	void rhsSet(int pos);
	void set(int pos, bool isLeft);
};


class Reader
{
private:
	char attributes[MaxAttrNumber][MaxNameLength+1];
	int attrCount;
	int attrFound[MaxAttrNumber];
	int numberFound;
	int searchByChar(char ch, int step);
	void ruleReading(FILE* stream);
	Rule rules[MaxRuleNumber];
	int ruleNumber;
	void displayRule(int index);
public:
	void readFile(const char* fileName);
	void display();
};
 
file name: reader.cpp
#include "reader.h"


void Reader::display()
{
	cout<<"\nnow display\n";
	cout<<attributes[0]<<"(";
	for (int i=1; i<=attrCount; i++)
	{
		cout<<attributes[i];
		if (i!=attrCount)
		{
			cout<<",";
		}
		else
		{
			cout<<")\n";
		}
	}
	for (i=0; i<ruleNumber; i++)
	{
		displayRule(i);
	}
}

bool Rule::test(int pos, bool isLeft)
{
	if (isLeft)
	{
		return lhs.test(pos);
	}
	else
	{
		return rhs.test(pos);
	}
}


void Reader::displayRule(int index)
{
	for (int i=1; i<=attrCount; i++)
	{
		if (rules[index].test(i, true))
		{
			cout<<attributes[i];
		}
	}
	cout<<" -> ";
	for (i=1; i<=attrCount; i++)
	{
		if (rules[index].test(i, false))
		{
			cout<<attributes[i];
		}
	}
	cout<<";\n";
}


void Rule::set(int pos, bool isLeft)
{
	if (isLeft)
	{
		lhsSet(pos);
	}
	else
	{
		rhsSet(pos);
	}
}

void Rule::rhsSet(int pos)
{
	rhs.set(pos);
}

void Rule::lhsSet(int pos)
{
	lhs.set(pos);
}

Rule::Rule()
{
	lhs.reset();
	rhs.reset();
	
}


void Reader::readFile(const char* fileName)
{
	FILE* stream;
	stream=fopen(fileName, "r");
	attrCount=extractNames(stream, attributes, "=,()", ';')-1;//ignore the first relation name
	ruleReading(stream);

}

void Reader::ruleReading(FILE* stream)
{
	char ch;
	int step=0;
	ruleNumber=0;//initialize
	bool isLeft=true;
	while (!feof(stream))
	{		
		ch=fgetc(stream);
		if (ch==';'||ch==',')
		{
			ruleNumber++;		
			isLeft=true;
		}
		else
		{
			if (ch=='-'||ch=='>')
			{
				isLeft=false;
			}
			else
			{
				if (isalpha(ch))
				{
					searchByChar(ch, step);
					if (numberFound!=1)
					{
						if (step<MaxNameLength)
						{
							step++;
						}
						else
						{
							cout<<"illegal attribute stated!\n";
							exit(1);
						}
					}
					else
					{
						step=0;
						rules[ruleNumber].set(attrFound[0], isLeft);
					}
				}
			}
		}
	}
}


int Reader::searchByChar(char ch, int step)
{
	if (step==0)//this is first time, and all attributes are searched
	{
		numberFound=0;
		for (int i=1; i<=attrCount; i++)//because the #1 is relation
		{
			if (ch==attributes[i][step])
			{
				attrFound[numberFound]=i;
				numberFound++;
			}
		}
	}
	else
	{
		int number=0;//new 'attrFound' re-counting
		for (int i=0; i<numberFound; i++)
		{
			if (ch==attributes[attrFound[i]][step])
			{
				attrFound[number]=i;
				number++;
			}
		}
		numberFound=number;
	}
	return numberFound;
}





int findChar(char ch, char* str)
{
	int index=0;
	while (str[index]!='\0')
	{
		if (str[index]==ch)
		{
			return index;
		}
		index++;
	}
	return -1;
}

//extract names from a line delimetered by various chars, like ',','(',')'....
int extractNames(FILE* stream, char nameBuffers[][MaxNameLength+1], char* delimeters, char endChar)
{
	int findChar(char ch, char* str);
	char ch;
	int nameIndex=0;
	char buffer[MaxNameLength+1];
	char* ptr=buffer;

	while (!feof(stream))
	{
		ch=getc(stream);
		if (ch==endChar)
		{
			if (ptr!=buffer)
			{
				*ptr='\0';
				strcpy(nameBuffers[nameIndex], buffer);
			}
			break;
		}

		if (findChar(ch, delimeters)>0)//deli reached
		{
			//skip the consecutive deli
			if (ptr!=buffer)
			{
				*ptr='\0';				
				strcpy(nameBuffers[nameIndex], buffer);
				nameIndex++;
				ptr=buffer;//restart
			}
		}
		else
		{
			*ptr=ch;
			ptr++;
		}
	}
	return nameIndex;
}		


	
file name: main.cpp (main)
#include "reader.h"

int main()
{
	Reader R;
	R.readFile("d:\\rules.txt");
	R.display();

	return 0;
}




                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)