Dependency

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;
    }