#include
#include //for find method used to check for a value in a vector.
#include
#include
#include
#include
#include
#include
using namespace std;
struct tableList { //this is synonym to database used in sql which contains multiple tables.
vector database;
};
struct tableList* db1 = new(tableList); //creating only one database and all tables will be populated in same.
struct table { //datastructure for tables.
string tableName;
vector headings;
vector headingType; //using without the data type for attributes
vector > tuple;
};
int fileInput(string fileName) { //the fileName should be present at same
ifstream in (fileName); // location where this program is executed.
if(!in) {
cout<<"cannot open file\n"<database.push_back(temp);
cout<<"size of db1"<database.size()<tableName);
cout<<"name for this entered table is "<tableName< head;
string heads, token;
getline(in, heads);
for(unsigned int i = 0; i < heads.size(); ++i) {
if(heads[i] != ' ')
token += heads[i];
else {
head.push_back(token);
token.erase(token.begin(), token.end());
}
}
head.push_back(token); //to get last value which doesnot hava a tailing space
for(unsigned int i = 0; i < head.size(); i += 2) {
temp->headings.push_back(head[i]);
// cout<headingType.push_back(head[i+1]);
}
for(auto i = temp->headings.begin(); i != temp->headings.end(); ++i)
cout<<*i<<"\t\t";
cout< row;
while(!in.eof()) {
token.erase(token.begin(), token.end());
getline(in, heads);
for (unsigned int i = 0; i < heads.size(); ++i) {
if(heads[i] != ',')
token += heads[i];
else {
row.push_back(token);
token.erase(token.begin(), token.end());
}
}
row.push_back(token);
temp->tuple.push_back(row);
row.clear();
}
for(unsigned int i = 0 ; i < temp->tuple.size(); ++i) {
for(unsigned int j = 0; j < temp->tuple[i].size(); ++j)
cout<tuple[i][j]<<"\t";
cout<database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == tableName)
return 1;
}
return 0;
}
struct table* assignTable(string tableName) { //this returns pointer to an existing table from the collection.
struct table* temp;
for(unsigned int I = 0; I != db1->database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == tableName)
return temp;
}
return nullptr;
}
int renameTable(string tableName, string newTableName) {
struct table* temp;
for(unsigned int I = 0; I != db1->database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == tableName) {
temp->tableName = newTableName;
return 1;
}
}
return 0;
}
string Union(string table1, string table2) {
if(table1 == table2) {
cout<<"Names of both tables are same"<tableName = table1+table2;
cout<<"new name for newly created table is "<tableName<database.size()<database.push_back(temp);
// cout<<"size of db1"<database.size()<headings.begin(); i != tab1->headings.end(); ++i) {
cout<<*i<<"\t\t";
temp->headings.push_back(*i);
}
cout<headingType.begin(); i != tab1->headingType.end(); ++i)
temp->headingType.push_back(*i);
vector row;
for(unsigned int i = 0 ; i < tab1->tuple.size(); ++i) {
for(unsigned int j = 0; j < tab1->tuple[i].size(); ++j)
// cout<tuple[i][j]<<"\t";
row.push_back(tab1->tuple[i][j]);
temp->tuple.push_back(row);
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tuple.size(); ++i) {
for(unsigned int j = 0; j < tab2->tuple[i].size(); ++j)
// cout<tuple[i][j]<<"\t";
row.push_back(tab2->tuple[i][j]);
if (find(temp->tuple.begin(), temp->tuple.end(), row) == temp->tuple.end()) {
temp->tuple.push_back(row);
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tableName;
}
return string();
}
string intersection(string table1, string table2) {
if(table1 == table2) {
cout<<"Names of both tables are same"<tableName = table1+table2;
cout<<"new name for newly created table is "<tableName<database.push_back(temp);
// making heading vector for new table by headings of parent table.
// and printing headings for display.
for(auto i = tab1->headings.begin(); i != tab1->headings.end(); ++i) {
cout<<*i<<"\t\t";
temp->headings.push_back(*i);
}
cout<headingType.begin(); i != tab1->headingType.end(); ++i)
temp->headingType.push_back(*i);
vector row;
for(unsigned int i = 0 ; i < tab2->tuple.size(); ++i) {
for(unsigned int j = 0; j < tab2->tuple[i].size(); ++j)
row.push_back(tab2->tuple[i][j]);
if (find(tab1->tuple.begin(), tab1->tuple.end(), row) != tab1->tuple.end()) {
temp->tuple.push_back(row);
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tableName;
}
return string();
}
string setDifference(string table1, string table2, string table3) {
if(table1 == table2) {
cout<<"Names of both tables are same"<tableName = table3;
cout<<"new name for newly created table is "<tableName<database.push_back(temp);
// making heading vector for new table by headings of parent table.
for(auto i = tab1->headings.begin(); i != tab1->headings.end(); ++i) {
cout<<*i<<"\t\t";
temp->headings.push_back(*i);
}
cout<headingType.begin(); i != tab1->headingType.end(); ++i)
temp->headingType.push_back(*i);
vector row;
for(unsigned int i = 0 ; i < tab1->tuple.size(); ++i) {
for(unsigned int j = 0; j < tab1->tuple[i].size(); ++j)
// cout<tuple[i][j]<<"\t";
row.push_back(tab1->tuple[i][j]);
temp->tuple.push_back(row);
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tuple.size(); ++i) {
for(unsigned int j = 0; j < tab2->tuple[i].size(); ++j)
// cout<tuple[i][j]<<"\t";
row.push_back(tab2->tuple[i][j]);
auto iter = find(temp->tuple.begin(), temp->tuple.end(), row);
if(iter != temp->tuple.end())
temp->tuple.erase(iter);
cout<<"deleted";
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tuple.size()<tableName;
}
return string();
}
string cartesianProduct(vector query) {
string table1 = query[1];
string table2 = query[2];
if(table1 == table2) {
cout<<"Names of both tables are same"<tableName = table1+table2;
cout<<"new name for newly created table is "<tableName<database.push_back(temp);
// making heading vector for new table by combining two headings of parent tables.
for(auto i = tab1->headings.begin(); i != tab1->headings.end(); ++i) {
cout<<*i<<"\t\t";
temp->headings.push_back(*i);
}
for(auto i = tab2->headings.begin(); i != tab2->headings.end(); ++i) {
cout<<*i<<"\t\t";
temp->headings.push_back(*i);
}
cout<headingType.begin(); i != tab1->headingType.end(); ++i)
temp->headingType.push_back(*i);
for(auto i = tab2->headingType.begin(); i != tab2->headingType.end(); ++i)
temp->headingType.push_back(*i);
for(unsigned int i = 0 ; i < tab1->tuple.size() - 1; ++i) //-1 is substracted because an extra empty line is present in all tables of collection of tables.
for(unsigned int ii = 0 ; ii < tab2->tuple.size() - 1; ++ii) {
vector row;
for(unsigned int j = 0; j < tab1->tuple[i].size(); ++j)
row.push_back(tab1->tuple[i][j]);
for(unsigned int jj = 0; jj < tab2->tuple[ii].size(); ++jj)
row.push_back(tab2->tuple[ii][jj]);
temp->tuple.push_back(row);
}
for(unsigned int ii = 0 ; ii < temp->tuple.size(); ++ii) {
for(unsigned int ij = 0 ; ij < temp->tuple[ii].size(); ++ij)
cout<tuple[ii][ij]<<"\t";
cout<tableName;
}
else {
cout<<"Requested table/tables donot exist"< query) {
string RequiredTableName;
vector attributes;
auto i = query.begin(); ++i; //to move from select to 1st attribute
for(; i != query.end(); ++i) {
if(*i != "from") {
if(*i != "") {
attributes.push_back(*i);
}
}
else
break;
}
i++; // to move forward from "from" clause in query vector
RequiredTableName = *i;
// cout<<"Using data from tableName "<<*i<database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == RequiredTableName) {
flag = 1;
break;
}
}
if(flag == 0) {
cout<<"Requested table doesnot exist"< clause;
vector > conditions;
for(unsigned int i = 0; i < attributes.size(); ++i) {
if(attributes[i] != "and") {
clause.push_back(attributes[i]);
cout<headings.size(); ++j) {
if(conditions[i][0] == temp->headings[j]) {
// cout<<"checked "<headings.size() && conditions[i][0] != temp->headings[j]) {
flag = 1;
//cout<<"problemo at"<tableName = temp->tableName;
selectedTable->tableName += "sel";
cout<<"name of newly created table is "<tableName<headings = temp->headings;
selectedTable->headingType = temp->headingType;
db1->database.push_back(selectedTable); // adding new table to collection of tables.
int flags[temp->tuple.size()];
fill_n(flags, temp->tuple.size(), -1);
for(unsigned int i = 0; i < temp->tuple.size(); ++i)
for(unsigned int k = 0; k < conditions.size(); ++k) {
for(unsigned int j = 0; j < temp->tuple[i].size(); ++j) {
if(temp->headings[j] == conditions[k][0]) {
// cout<headings[i]<tuple[i][j] == conditions[k][2]) {
if(flags[i] == -1 or flags[i] == 1) //when it's uninitialized or when it's already valid keep it valid for now.
flags[i] = 1;
}
else //when this condition has been already violated.
flags[i] = 0;
}
else if(conditions[k][1] == "!=") {
if(temp->tuple[i][j] != conditions[k][2]) {
if(flags[i] == -1 or flags[i] == 1)
flags[i] = 1;
else // when the given condition was calculated as false, make it false so it's never needed in future to take of. Though with use of "or" this will fail drastically.
flags[i] = 0;
}
}
//below conditions are fruitful for int and decimal data types only.
else if(conditions[k][1] == ">" and (temp->headingType[j] == "1" or temp->headingType[j] == "2")) {
if(stod(temp->tuple[i][j]) > stod(conditions[k][2])) { //converting to double precision number for proper comparison.
if(flags[i] == -1 or flags[i] == 1)
flags[i] = 1;
else
flags[i] = 0;
}
else
flags[i] = 0;
}
else if(conditions[k][1] == "<" and (temp->headingType[j] == "1" or temp->headingType[j] == "2")) {
if(std::stod(temp->tuple[i][j]) < stod(conditions[k][2])) {
if(flags[i] == -1 or flags[i] == 1)
flags[i] = 1;
else
flags[i] = 0;
}
else
flags[i] = 0;
}
else {
cout<<"conditional not supported"<headingType[j]<tuple.size(); ++i) {
cout<tuple.push_back(temp->tuple[i]);
}
cout<tuple.size()<tableName;
}
}
void rename(vector query) { //format: rename prevAttr newAttr in tableName
string RequiredTableName;
auto i = query.begin(); ++i; //to move from rename to prevAttr
string prevAttrName = *i;
++i;
string newAttrName = *i;
i++; i++; // to move forward from "in" clause in query vector
RequiredTableName = *i;
bool flag = 0; //getting the required table from list of all tables present in the tables collection.
struct table* temp;
for(unsigned int I = 0; I != db1->database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == RequiredTableName) {
flag = 1;
break;
}
}
if(flag == 0) {
cout<<"Requested table doesnot exist"<headings.begin();
bool flag = 0;
for(; i != temp->headings.end(); ++i)
if(*i == prevAttrName) {
*i = newAttrName;
flag = 1;
cout< query) {
string RequiredTableName;
vector attributes;
auto i = query.begin(); ++i; //to move from select to 1st attribute
for(; i != query.end(); ++i) {
if(*i != "from") {
if(*i != "") {
attributes.push_back(*i);
}
}
else
break;
}
cout<database.size(); ++I) {
temp = db1->database[I];
if(temp->tableName == RequiredTableName) {
flag = 1;
break;
}
}
if(flag == 0) {
cout<<"Requested table doesnot exist"< temp->headings.size()) { //if no. of attributes entered is more than that present in the table
cout<<"excess attributes asked"<tableName = RequiredTableName;
projected->tableName += "proj";
cout<<"name of new table is "<tableName<database.size()<database.push_back(projected);
// cout<<"size of db1"<database.size()<headings.push_back(attributes[i]);
}
cout< indexes;
flag = 0;
for(unsigned int i = 0; i < attributes.size(); ++i)
for(unsigned int j = 0; j < temp->headings.size(); ++j) {
if(attributes[i] == temp->headings[j]) {
projected->headingType.push_back(temp->headingType[j]); //entering the corresponding value type for attributes.
indexes.push_back(j);
break;
}
else if(j == temp->headings.size() && attributes[i] != temp->headings[j]) {
flag = 1;
// cout<<"problemo at"< row;
for(unsigned int i = 0 ; i < temp->tuple.size(); ++i) {
for(unsigned int j = 0; j < temp->tuple[i].size(); ++j)
if(find(indexes.begin(), indexes.end(), j) != indexes.end()) { //find is used to find a particular value in a vector.defined in algorithm header.
// cout<tuple[i][j]<<"\t";
row.push_back(temp->tuple[i][j]);
}
if (find(projected->tuple.begin(), projected->tuple.end(), row) == projected->tuple.end()) {
projected->tuple.push_back(row);
for(auto it = row.begin(); it != row.end(); ++it)
cout<<*it<<"\t\t";
cout<tableName;
}
}
string readLine() {
string line;
getline(cin, line);
return line;
}
vector splitLine(string line) {
vector tokens;
string token;
line += " f"; // to overcome error of not getting last chunk of chars
int t = (line.end() - line.begin())/sizeof(line[0]);
for(int i = 0; i < t; ++i) {
if(line[i]!=' ' and line[i]!='(' and line[i]!=')' and line[i]!=',' and line[i]!=';') { //this is causing proble when " ," or combination of other such characters is used together, segmentation fault occurs.
token += line[i];
}
else {
tokens.push_back(token);
token.erase(token.begin(), token.end());
}
}
return tokens;
}
void invalid() {
cout<<"Invalid syntax"< tokens) {
if (tokens[0] == "exit") {
cout<<"bye"< 5)
select(tokens);
else
invalid();
}
else if (tokens[0] == "rename" or tokens[0] == "re") {
rename(tokens);
}
else if (tokens[0] == "project" or tokens[0] == "proj") {
project(tokens);
}
else if (tokens[0] == "cartesian product" or tokens[0] == "cp") {
if(tokens.size() == 3)
cartesianProduct(tokens);
else
invalid();
}
else if (tokens[0] == "check" or tokens[0] == "ch") {
if(tokens.size() == 2 and tokens[1] != "") {
if(checkPresenceOfTable(tokens[1]))
cout<<"table exist with name"< args;
int status = 1;
do {
cout<<"> ";
line = readLine(); //each line is read
args = splitLine(line); //split into tokens using(" ",",",";") as seperators.
status = execute(args);
} while(status);
}
int main(int argc, char *argv[]) {
printf("This parser now have following working commands\n");
printf(" > fileIn\n");
printf(" > exit\n");
printf(" > rename\n");
printf(" > select\n");
printf(" > project\n");
printf(" > cartesian product\n");
printf(" > renameTable \n");
printf(" > union \n");
printf(" > setDifference \n");
printf(" > intersection \n");
loop(); //main function to act like command prompt
}