See More

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