diff --git a/Attribute.cpp b/Attribute.cpp index a87ee9e..a2ae7f6 100755 --- a/Attribute.cpp +++ b/Attribute.cpp @@ -7,6 +7,7 @@ Attribute::Attribute(){ type = ""; key = 0; size = 0; + limit = 0; } Attribute::Attribute(string n, string t, bool k){ @@ -14,13 +15,15 @@ Attribute::Attribute(string n, string t, bool k){ type = t; key = k; size = 0; + limit = 20; } Attribute::Attribute(string n, string t, bool k, int s){ name = n; type = t; key = k; - size = s; + size = 0; + limit = s; } void Attribute::addCell(string v){ @@ -66,7 +69,7 @@ void Attribute::display(){ cout << name << "\n" << type; if(type == "VARCHAR") { - cout << "(" << size << ")"; + cout << "(" << limit << ")"; } cout << "\n\n"; diff --git a/Attribute.h b/Attribute.h index 19881ce..72b97d6 100755 --- a/Attribute.h +++ b/Attribute.h @@ -10,6 +10,7 @@ class Attribute{ string type; bool key; int size; + int limit; public: Attribute(); diff --git a/DBApp.cpp b/DBApp.cpp index eacadaa..cb9dc19 100755 --- a/DBApp.cpp +++ b/DBApp.cpp @@ -3,7 +3,7 @@ #include // std::stringstream #include #include -#include "Parserv3.h" +#include "Parser.h" #include "DBEngine.h" using namespace std; diff --git a/DBEngine.cpp b/DBEngine.cpp index 4e8ffb9..32a06ef 100755 --- a/DBEngine.cpp +++ b/DBEngine.cpp @@ -25,7 +25,7 @@ void DBEngine::createTable(Relation r){ size++; } -void DBEngine::insertValues(string r, vector v) +void DBEngine::insertValues(string r, vector v) { for(int i = 0; i < tables.size(); i++) { @@ -51,12 +51,70 @@ void DBEngine::save(){ file.close(); } + +void DBEngine::deleteRelation(string n) +{ + // to conserve memory after closing a file. + for(int i = 0; i < tables.size(); i++) + { + if (tables[i].getTableName() == n) + { + tables.erase(tables.begin() + i); + } + } +} + +void DBEngine::save(string n){ + + ofstream file; + string name = n + ".txt"; + file.open(name); + + for(int i = 0; i < commands.size() - 1; ++i) + { + if(commands[i].substr(0, 4) == "SAVE") + { + continue; + } + if(commands[i].substr(0, 4) == "SHOW") + { + continue; + } + if(commands[i].substr(0, 4) == "OPEN") + { + continue; + } + if(commands[i].substr(0, 5) == "CLOSE") + { + continue; + } + else + { + file << commands[i] << endl; + } + } + + //file.close(); +} vector DBEngine::getRelations(){ return tables; } -Relation& DBEngine::getTableFromName(string n){ +bool DBEngine::isRelation(string n) +{ + for(int i = 0; i < tables.size(); i++) + { + if (tables[i].getTableName() == n) + { + return true; + } + } + return false; +} + +Relation& DBEngine::getTableFromName(string n) +{ for(int i = 0; i < tables.size(); i++){ if (tables[i].getTableName() == n){ return tables[i]; @@ -68,7 +126,7 @@ Relation& DBEngine::getTableFromName(string n){ } Relation DBEngine::selection(string attName, string s, Relation r){ - equality(attName, s, r); + return equality(attName, s, r); } //assumes that all attribute titles are unique @@ -77,11 +135,14 @@ Relation DBEngine::projection(vector input, Relation r){ vector v; string new_name = r.getTableName() + " Projection"; - for(int i = 0; i < input.size(); ++i) { - - for(int j = 0; j < r.getSize(); ++j) { + for(int i = 0; i < input.size(); ++i) + { + for(int j = 0; j < r.getSize(); ++j) + { if((r.getAttributes())[j].getName() == input[i]) + { v.push_back((r.getAttributes())[j]); + } } } @@ -90,12 +151,23 @@ Relation DBEngine::projection(vector input, Relation r){ } //test error matching -void DBEngine::rename(Relation& r, vector oldnames, vector newnames){ - if (oldnames.size() != newnames.size()) { +Relation DBEngine::rename(vector newnames, Relation &r) +{ + vector temp; + if (r.getSize() != newnames.size()) { cout << "FAILURE TO RENAME: number of attributes do not match.\n"; - return; + exit(1); } - + else + { + temp = r.getAttributeNames(); + for(int i = 0; i < temp.size(); ++i) + { + r.renameAttribute(temp[i], newnames[i]); + } + return r; + } + /* else if (oldnames != r.getAttributeNames()) { cout << "FAILURE TO RENAME: the attributes to be renamed do not exist in the relation.\n"; return; @@ -106,6 +178,8 @@ void DBEngine::rename(Relation& r, vector oldnames, vector newna r.renameAttribute(oldnames[i], newnames[i]); } } + */ + } Relation DBEngine::setUnion(Relation r1, Relation r2){ @@ -153,31 +227,67 @@ Relation DBEngine::setDiff(Relation r1, Relation r2){ Relation new_r = r1; new_r.setTableName("TEMP"); vector temp; - bool duplicate = false; - - for (int i = 0; i < r1.getAttributes()[0].getSize(); ++i){ - new_r.removeTuple(i); + //bool duplicate = false; + + /* + for (int i = 0; i < r1.getAttributes()[0].getSize(); ++i) + { + new_r.removeTuple(0); } + */ + int size = 0; + + //cout << "test1" << endl; + + for(int x = 0; x < r2.getAttributes().size(); ++x) + { + + //cout << "test2" << endl; + for (int i = 0; i < r2.getAttributes()[x].getSize(); ++i) + { + + //cout << "test3" << endl; + temp = r2.getTuple(i); - for (int i = 0; i < r1.getAttributes()[0].getSize(); ++i) { - temp = r1.getTuple(i); - - for (int j = 0; j < r2.getAttributes()[0].getSize(); ++j){ - if (temp == r2.getTuple(j)){ - duplicate = true; - break; + for(int y = 0; y < new_r.getAttributes().size(); ++y) + { + size = new_r.getAttributes()[y].getSize(); + //cout << "test4" << endl; + new_r.getAttributes()[y].getSize(); + for (int j = 0; j < size; ++j) + { + //cout << "test5" << endl; + for(int a = 0; a < temp.size(); ++a) + { + //cout << "test6" << endl; + for(int b = 0; b < new_r.getTuple(j).size(); ++b) + { + //cout << "test7" << endl; + //cout << temp[a] << " " << new_r.getTuple(j)[b] << " " << b << endl; + if (temp[a] == new_r.getTuple(j)[b]) + { + new_r.removeFromTuple(b, j); + //cout << "test" << endl; + //duplicate = true; + //break; + } + } + } + size = new_r.getAttributes()[y].getSize(); + } + /* + if (!duplicate) + { + new_r.insertTuple(temp); + } + */ + //duplicate = false; } } - - if (!duplicate){ - new_r.insertTuple(temp); - } - - duplicate = false; } //make this one for loop later! - + /* for (int i = 0; i < r2.getAttributes()[0].getSize(); ++i) { temp = r2.getTuple(i); @@ -194,6 +304,7 @@ Relation DBEngine::setDiff(Relation r1, Relation r2){ duplicate = false; } + */ return new_r; } @@ -233,4 +344,4 @@ Relation DBEngine::crossProduct(Relation r1, Relation r2){ return new_r; -} \ No newline at end of file +} diff --git a/DBEngine.h b/DBEngine.h index 3d95a7d..81009d3 100755 --- a/DBEngine.h +++ b/DBEngine.h @@ -17,15 +17,19 @@ public: void createTable(Relation r); void insertValues(string r, vector v); vector getRelations(); + bool isRelation(string n); //void showTable(Relation r); Relation& getTableFromName(string n); void saveToFile(vector cmds); Relation selection(string attName, string s, Relation r); - Relation projection(vector input, Relation r); + Relation projection(vector input, Relation r); + Relation product(string s1, Relation r1, Relation r2); + void deleteRelation(string n); void save(); + void save(string n); void storeCommands(string s); - void rename(Relation& r, vector oldnames, vector newnames); + Relation rename(vector newnames, Relation &r); Relation setUnion(Relation r1, Relation r2); Relation setDiff(Relation r1, Relation r2); - Relation crossProduct(Relation r1, Relation r2); + Relation crossProduct(Relation r1, Relation r2); }; diff --git a/Parser.cpp b/Parser.cpp new file mode 100644 index 0000000..2716df4 --- /dev/null +++ b/Parser.cpp @@ -0,0 +1,1217 @@ +#include // std::string +#include // std::cout +#include // std::ofstream +#include // std::stringstream +#include +#include +#include "Parser.h" +#include + +using namespace std; + +vector tokenize(string ss) +{ + string tempString; + stringstream lineStream(ss); + vector output; + + while (lineStream >> tempString) + { + output.push_back(tempString); + } + + //testing--------------- + //cout<<"TokenList: "; + + // for (int i = 0; i input) +{ + cout<<"TokenList: "< input, Relation &r) +{ + Relation rfinal = r; + Attribute a1 = r.getAttributeByName(input[0]); + input.erase(input.begin()); + string op = input[0]; + input.erase(input.begin()); + Attribute a2; + string c; + //cout << input[0] << endl; + if(input[0].at(0) == '\"') + { + c = input[0].substr(1, input[0].find_last_of("\"") - 1); + //cout << c << endl; + } + if(r.isAttribute(input[0])) + { + a2 = r.getAttributeByName(input[0]); + input.erase(input.begin()); + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + /* + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size; ++j) + { + if(r.getAttributeByName(a1.getName()).getValues()[j] == ) + { + rfinal.insertTuple(r.getTuple(j)); + } + }*/ + if(op == "==") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(r.getAttributeByName(a1.getName()).getValues()[x] != r.getAttributeByName(a2.getName()).getValues()[x]) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else if(op == "!=") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(r.getAttributeByName(a1.getName()).getValues()[x] == r.getAttributeByName(a2.getName()).getValues()[x]) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else if(op == ">=") + { + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER" && r.getAttributeByName(a2.getName()).getType() == "INTEGER") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[x]) < stoi(r.getAttributeByName(a2.getName()).getValues()[x])) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == "<=") + { + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER" && r.getAttributeByName(a2.getName()).getType() == "INTEGER") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[x]) > stoi(r.getAttributeByName(a2.getName()).getValues()[x])) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == ">") + { + + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER" && r.getAttributeByName(a2.getName()).getType() == "INTEGER") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[x]) <= stoi(r.getAttributeByName(a2.getName()).getValues()[x])) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == "<") + { + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER" && r.getAttributeByName(a2.getName()).getType() == "INTEGER") + { + for(int x = 0; x < r.getAttributeByName(a1.getName()).getSize(); ++x) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[x]) >= stoi(r.getAttributeByName(a2.getName()).getValues()[x])) + { + rfinal.removeTuple(x); + //rfinal.insertAttributes(a); + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + } + } + } + else + { + input.erase(input.begin()); + if(op == "==") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(r.getAttributeByName(a1.getName()).getValues()[j] != c) + { + rfinal.removeTuple(j); + } + } + } + } + } + else if(op == "!=") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(r.getAttributeByName(a1.getName()).getValues()[j] == c) + { + rfinal.removeTuple(j); + } + } + } + } + } + else if(op == ">=") + { + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[j]) < stoi(c)) + { + rfinal.removeTuple(j); + } + } + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == "<=") + { + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[j]) > stoi(c)) + { + rfinal.removeTuple(j); + } + } + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == ">") + { + + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[j]) <= stoi(c)) + { + rfinal.removeTuple(j); + } + } + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + else if(op == "<") + { + + if(r.getAttributeByName(a1.getName()).getType() == "INTEGER") + { + for(int i = 0; i < r.getAttributes().size(); ++i) + { + if(r.getAttributes()[i].getName() == a1.getName()) + { + for(int j = 0; j < r.getAttributeByName(a1.getName()).getValues().size(); ++j) + { + if(stoi(r.getAttributeByName(a1.getName()).getValues()[j]) >= stoi(c)) + { + rfinal.removeTuple(j); + } + } + } + } + } + else + { + cout << "Attribute type is not an INTEGER." << endl; + exit(1); + } + } + } + return rfinal; +} + +tuple, Relation> expression(vector input, DBEngine &engine) +{ + Relation rfinal("TEMP"); + tuple, Relation> t(input, rfinal); + if(input[0] == "select") + { + /* + cout << "Not yet implemented." << endl; + exit(1); + */ + input.erase(input.begin()); + vector s; + Relation r("TEMP"); + if(input[0] == "(") + { + input.erase(input.begin()); + while(input[0] != ")") + { + s.push_back(input[0]); + input.erase(input.begin()); + } + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + r = condition(s, engine.getTableFromName(input[0])); + input.erase(input.begin()); + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + r = condition(s, get<1>(t)); + input.erase(input.begin()); + } + } + get<0>(t) = input; + get<1>(t) = r; + return t; + } + + else if(input[0] == "project") + { + input.erase(input.begin()); + if(input[0] == "(") + { + input.erase(input.begin()); + vector temp; + while(input[0] != ")") + { + temp.push_back(input[0]); + input.erase(input.begin()); + } + input.erase(input.begin()); + Relation rfinal("TEMP"); + if(engine.isRelation(input[0])) + { + rfinal = engine.projection(temp, engine.getTableFromName(input[0])); + input.erase(input.begin()); + get<0>(t) = input; + get<1>(t) = rfinal; + //cout << rfinal.getSize() << endl; + return t; + } + else if(input[0] == "(") + { + t = expression(input, engine); + rfinal = engine.projection(temp, get<1>(t)); + //get<0>(t) = input; + get<1>(t) = rfinal; + //cout << rfinal.getSize() << endl; + return t; + } + } + else + { + cout << "Projection syntax incorrect." << endl; + exit(1); + } + } + + else if(input[0] == "rename") + { + input.erase(input.begin()); + if(input[0] == "(") + { + input.erase(input.begin()); + vector temp; + while(input[0] != ")") + { + if(input[0] == ",") + { + input.erase(input.begin()); + } + temp.push_back(input[0]); + input.erase(input.begin()); + } + input.erase(input.begin()); + Relation rfinal("TEMP"); + if(engine.isRelation(input[0])) + { + rfinal = engine.rename(temp, engine.getTableFromName(input[0])); + input.erase(input.begin()); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + input.erase(input.begin()); + t = expression(input, engine); + input.erase(input.begin()); + rfinal = engine.rename(temp, get<1>(t)); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + else + { + cout << "Rename syntax incorrect." << endl; + exit(1); + } + } + + else if(engine.isRelation(input[0])) + { + Relation r1(engine.getTableFromName(input[0])); + input.erase(input.begin()); + + if(input[0] == "+") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.setUnion(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.setUnion(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + + else if(input[0] == "-") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.setDiff(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.setDiff(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + + else if(input[0] == "*") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.crossProduct(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.crossProduct(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + } + + else if(input[0] == "(") + { + input.erase(input.begin()); + + Relation r1(engine.getTableFromName(input[0])); + input.erase(input.begin()); + + if(input[0] == "+") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.setUnion(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.setUnion(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + + else if(input[0] == "-") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.setDiff(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.setDiff(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + + else if(input[0] == "*") + { + input.erase(input.begin()); + if(engine.isRelation(input[0])) + { + Relation r2(engine.getTableFromName(input[0])); + rfinal = engine.crossProduct(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + else if(input[0] == "(") + { + tuple, Relation> t = expression(input, engine); + Relation r2 = get<1>(t); + rfinal = engine.crossProduct(r1, r2); + get<0>(t) = input; + get<1>(t) = rfinal; + return t; + } + } + } + + get<0>(t) = input; + get<1>(t) = rfinal; + return t; +} + +vector showCMD(vector input, DBEngine &engine) +{ + /* + if (input.size() > 3) + { + cout<<"Syntax error!"<, Relation> t = expression(input, engine); + get<1>(t).display(); + } + + return input; +} + +vector saveCMD(vector input, DBEngine &engine) +{ + if (input.size() > 2) + { + cout<<"Syntax error!"< att = r.getAttributes(); + for (int i = 0; i < att.size(); ++i) + { + output << "-------------\n"; + output << att[i].getName() << "\n" << att[i].getType(); + if(att[i].getType() == "VARCHAR") + { + output << "(" << att[i].getSize() << ")"; + } + output << "\n\n"; + + vector values = att[i].getValues(); + vector::iterator it = values.begin(); + while (it != values.end()) + { + output << *it << "\n"; + it++; + } + output << "-------------\n"; + } + output << "\n--------------------------"; + */ + input.erase(input.begin()); + + return input; +} + +vector closeCMD(vector input, DBEngine &engine) +{ + if (input.size() > 3) + { + cout<<"Syntax error!"< openCMD(vector input, DBEngine &engine) +{ + if (input.size() > 2) + { + cout<<"Syntax error!"< exitCMD(vector input, DBEngine &engine) +{ + + exit(0); + + return input; +} + + +vector createCMD(vector input, DBEngine &engine) +{ + //relation name will be the first element of the vector of data returned by this function + + if (input[0] == "TABLE") + { + input.erase(input.begin()); + + PRelation r; + r.setPRelation(input[0]); + + input.erase(input.begin()); + + if(input[0] == "(") + { + input.erase(input.begin()); + + //vector e1; + + vector a; + + while(input[0] != ")") //inserting all values to relation + { + PAttribute temp; + + if (input[0] == ",") + { + input.erase(input.begin()); + } + + temp.setPAttributeName(input[0]); + + input.erase(input.begin()); + + if(input[0] == "INTEGER") + { + temp.setPAttributeType(input[0]); + input.erase(input.begin()); + } + else + { + temp.setPAttributeType(input[0].substr(0,input[0].find("("))); + temp.setPAttributeSize(stoi(input[0].substr(input[0].find("(") + 1, input[0].find(")")))); + input.erase(input.begin()); + } + + a.push_back(temp); + } + + //vector apk; //save primary keys temp storage + + if(input[0] == "PRIMARY" && input[1] == "KEY") + { + input.erase(input.begin()); + input.erase(input.begin()); + + if(input[0] == "(") + { + + while(input[0] != ")") //inserting all values to relation + { + //PAttribute temp; + + if (input[0] == ",") + { + input.erase(input.begin()); + } + + //temp.setPAttributeName(input[0]); + + //apk.push_back(temp); + + for(int i = 0; i < a.size(); ++i) + { + if(input[0] == a[i].getPAttribute()) + { + a[i].setPAttributeKey(); + } + } + + input.erase(input.begin()); + } + } + } + + vector dba; + + for(int x = 0; x < a.size(); ++x) + { + Attribute temp(a[x].getPAttribute(), a[x].getPAttributeType(), a[x].getPAttributeKey(), a[x].getPAttributeSize()); + dba.push_back(temp); + } + + engine.createTable(r.getName(), dba); + + return input; + } + + else cout<<"Syntax error! 2"< insertCMD(vector input, DBEngine &engine) +{ + //relation name will be the first element of the vector of data returned by this function + + if (input[0] == "INTO") + { + input.erase(input.begin()); + + PRelation pr(input[0]); + Relation r = engine.getTableFromName(input[0]); + + input.erase(input.begin()); + + vector s; + + if (input[0] == "VALUES" && input[1] == "FROM") + { + input.erase(input.begin()); + input.erase(input.begin()); + + + vector a = r.getAttributes(); + + if(input[0] == "(") + { + input.erase(input.begin()); + + for(int i = 0; i < a.size(); ++i) + { + if(a[i].getType() == "INTEGER") + { + if(input[0].at(0) == '\"') + { + cout << "Incorrect type matching. Tried to insert string." << endl; + cout << "The values should be: "; + for(int x = 0; x < a.size(); ++i) + { + cout << a[x].getType(); + if(a[x].getType() == "VARCHAR") + { + cout << "(" << a[x].getSize() << ")"; + } + cout << endl; + } + exit(1); + } + s.push_back(input[0]); + input.erase(input.begin()); + } + + else + { + if(input[0].at(0) == '\"') + { + s.push_back(input[0].substr(1,input[0].find_last_of("\"") - 1 )); + //engine.getTableFromName(pr.getName()).getAttributes()[i].display(); + input.erase(input.begin()); + } + else + { + cout << "Incorrect type matching. Tried to insert integer." << endl; + cout << "The values should be: "; + for(int x = 0; x < a.size(); ++x) + { + cout << a[x].getType(); + if(a[x].getType() == "VARCHAR") + { + cout << "(" << a[x].getSize() << ")"; + } + cout << endl; + } + exit(1); + } + } + + if (input[0] == ",") + { + input.erase(input.begin()); + } + } + if(input[0] != ")") + { + cout << "Too many values trying to be inserted. Only insert " << a.size() << " values."; + cout << "The values should be: "; + for(int x = 0; x < a.size(); ++x) + { + cout << a[x].getType(); + if(a[x].getType() == "VARCHAR") + { + cout << "(" << a[x].getSize() << ")"; + } + cout << endl; + } + exit(1); + } + engine.insertValues(r.getTableName(), s); + input.erase(input.begin()); + return input; + } + + else if (input[0] == "RELATION") + { + input.erase(input.begin()); + + tuple, Relation> t = expression(input, engine); + vector a = get<1>(t).getAttributes(); + for(int y = 0; y < a[0].getSize(); ++y) + { + for(int x = 0; x < a.size(); ++x) + { + s.push_back(a[x].getValues()[y]); + engine.insertValues(r.getTableName(), s); + s.clear(); + } + } + + input = get<0>(t); + + return input; + } + + else cout<<"Syntax error! 3"< updateCMD(vector input, DBEngine &engine) +{ + PRelation r(input[0]); + + input.erase(input.begin()); + + if(input[0] == "SET") + { + input.erase(input.begin()); + + //parse out ( and send everything until ) into an Expression vector + if(input[0] == "(") + { + + vector a; + PAttribute temp; + + vector s; + + //vector e; + + input.erase(input.begin()); + + while(input[0] != ")") + { + temp.setPAttributeName(input[0]); + a.push_back(temp); + temp.setPAttributeName("~"); + + input.erase(input.begin()); + + if(input[0] == "=") + { + input.erase(input.begin()); + + s.push_back(input[0]); + } + + else + { + cout<<"Syntax error! 2"< deleteCMD(vector input, DBEngine &engine) +{ + if (input[0] == "DELETE" && input[1] == "FROM") + { + input.erase(input.begin()); + input.erase(input.begin()); + + PRelation r(input[0]); + + if(input[0] == "WHERE") + { + if(input[0] == "(") + { + //PCondition c; + + PComparison c; + POperand oops1; + POperand oops2; + POp op; + + while(input[0] != ")") + { + oops1.setPOperand(input[0]); + input.erase(input.begin()); + + oops2.setPOperand(input[0]); + input.erase(input.begin()); + + op.setPOp(input[0]); + input.erase(input.begin()); + + c.setPComparison(oops1.getPOperand(), op.getPOp(), oops2.getPOperand()); + } + } + } + + // send delete command to DBEngine + } + else cout<<"Syntax error!"< query(vector input, DBEngine &engine) +{ + PRelation pr(input[0]); + + input.erase(input.begin()); + input.erase(input.begin()); + + tuple, Relation> t = expression(input, engine); + Relation r = get<1>(t); + r.setTableName(pr.getName()); + //r.display(); + input = get<0>(t); + + engine.createTable(r); + + return input; +} + +void par_line(vector input, DBEngine &engine) //calls par_command() or par_query() depending on first item from token list +{ +/* +• Match the first item in the token list and determine weather this is a command or a query. +• Call functions par_command() or par_query(); +• After either par_command() or par_query() returns, make sure the line ends properly with “;” token +*/ + string tempChar = input.back(); + + if (tempChar != ";") + { + cout<<"ERROR! missing semicolon "< insertInput = insertCMD(input, engine); + //cout<<"arguments: "< insertInput = createCMD(input, engine); + //cout<<"arguments: "< insertInput = deleteCMD(input, engine); + //cout<<"arguments: "< insertInput = updateCMD(input, engine); + //cout<<"arguments: "< listOfTokens = tokenize(input); + par_line(listOfTokens, engine); +} +/* +int main () { + + + string ss = "INSERT INTO animals VALUES FROM ( Joe , cat , 4 ) ;"; + string ss2 = "SHOW Dogs ;"; + string ss3 = "EXIT ; "; + + vector listOfTokens = tokenize(ss); + vector listOfTokens2 = tokenize(ss2); + vector listOfTokens3 = tokenize(ss3); + + par_line(listOfTokens); + par_line(listOfTokens2); + par_line(listOfTokens3); + + +} +*/ \ No newline at end of file diff --git a/Parserv3.h b/Parser.h similarity index 100% rename from Parserv3.h rename to Parser.h diff --git a/Parserv4.cpp b/Parserv4.cpp deleted file mode 100644 index 38571d7..0000000 --- a/Parserv4.cpp +++ /dev/null @@ -1,619 +0,0 @@ -#include // std::string -#include // std::cout -#include // std::ofstream -#include // std::stringstream -#include -#include -#include "Parserv3.h" - -using namespace std; - -vector tokenize(string ss) -{ - string tempString; - stringstream lineStream(ss); - vector output; - - while (lineStream >> tempString) - { - output.push_back(tempString); - } - - //testing--------------- - cout<<"TokenList: "; - - for (int i = 0; i input) -{ - cout<<"TokenList: "< showCMD(vector input, DBEngine &engine) -{ - if (input.size() > 3) - { - cout<<"Syntax error!"< saveCMD(vector input, DBEngine &engine) -{ - if (input.size() > 2) - { - cout<<"Syntax error!"< att = r.getAttributes(); - for (int i = 0; i < att.size(); ++i) - { - output << "-------------\n"; - output << att[i].getName() << "\n" << att[i].getType(); - if(att[i].getType() == "VARCHAR") - { - output << "(" << att[i].getSize() << ")"; - } - output << "\n\n"; - - vector values = att[i].getValues(); - vector::iterator it = values.begin(); - while (it != values.end()) - { - output << *it << "\n"; - it++; - } - output << "-------------\n"; - } - output << "\n--------------------------"; - - input.erase(input.begin()); - - return input; -} - -vector closeCMD(vector input, DBEngine &engine) -{ - if (input.size() > 3) - { - cout<<"Syntax error!"< openCMD(vector input, DBEngine &engine) -{ - if (input.size() > 2) - { - cout<<"Syntax error!"< exitCMD(vector input, DBEngine &engine) -{ - - exit(0); - - return input; -} - - -vector createCMD(vector input, DBEngine &engine) -{ - //relation name will be the first element of the vector of data returned by this function - - if (input[0] == "TABLE") - { - input.erase(input.begin()); - - PRelation r; - r.setPRelation(input[0]); - - input.erase(input.begin()); - - if(input[0] == "(") - { - input.erase(input.begin()); - - //vector e1; - - vector a; - - while(input[0] != ")") //inserting all values to relation - { - PAttribute temp; - - if (input[0] == ",") - { - input.erase(input.begin()); - } - - temp.setPAttributeName(input[0]); - - input.erase(input.begin()); - - if(input[0] == "INTEGER") - { - temp.setPAttributeType(input[0]); - input.erase(input.begin()); - } - else - { - temp.setPAttributeType(input[0].substr(0,input[0].find("("))); - temp.setPAttributeSize(stoi(input[0].substr(input[0].find("(") + 1, input[0].find(")")))); - input.erase(input.begin()); - } - - a.push_back(temp); - } - - //vector apk; //save primary keys temp storage - - if(input[0] == "PRIMARY" && input[1] == "KEY") - { - input.erase(input.begin()); - input.erase(input.begin()); - - if(input[0] == "(") - { - - while(input[0] != ")") //inserting all values to relation - { - //PAttribute temp; - - if (input[0] == ",") - { - input.erase(input.begin()); - } - - //temp.setPAttributeName(input[0]); - - //apk.push_back(temp); - - for(int i = 0; i < a.size(); ++i) - { - if(input[0] == a[i].getPAttribute()) - { - a[i].setPAttributeKey(); - } - } - - input.erase(input.begin()); - } - } - } - - vector dba; - - for(int x = 0; x < a.size(); ++x) - { - Attribute temp(a[x].getPAttribute(), a[x].getPAttributeType(), a[x].getPAttributeKey(), a[x].getPAttributeSize()); - dba.push_back(temp); - } - - engine.createTable(r.getName(), dba); - - return input; - } - - else cout<<"Syntax error! 2"< insertCMD(vector input, DBEngine &engine) -{ - //relation name will be the first element of the vector of data returned by this function - - if (input[0] == "INTO") - { - input.erase(input.begin()); - - PRelation pr(input[0]); - Relation r = engine.getTableFromName(input[0]); - - input.erase(input.begin()); - - vector s; - - if (input[0] == "VALUES" && input[1] == "FROM") - { - input.erase(input.begin()); - input.erase(input.begin()); - - - vector a = r.getAttributes(); - - if(input[0] == "(") - { - input.erase(input.begin()); - - for(int i = 0; i < a.size(); ++i) - { - if(a[i].getType() == "INTEGER") - { - if(input[0].at(0) == '\"') - { - cout << "Incorrect type matching. Tried to insert string." << endl; - cout << "The values should be: "; - for(int x = 0; x < a.size(); ++i) - { - cout << a[x].getType(); - if(a[x].getType() == "VARCHAR") - { - cout << "(" << a[x].getSize() << ")"; - } - cout << endl; - } - exit(1); - } - s.push_back(input[0]); - input.erase(input.begin()); - } - - else - { - if(input[0].at(0) == '\"') - { - s.push_back(input[0].substr(1,input[0].find_last_of("\"") - 1 )); - //engine.getTableFromName(pr.getName()).getAttributes()[i].display(); - input.erase(input.begin()); - } - else - { - cout << "Incorrect type matching. Tried to insert integer." << endl; - cout << "The values should be: "; - for(int x = 0; x < a.size(); ++x) - { - cout << a[x].getType(); - if(a[x].getType() == "VARCHAR") - { - cout << "(" << a[x].getSize() << ")"; - } - cout << endl; - } - exit(1); - } - } - - if (input[0] == ",") - { - input.erase(input.begin()); - } - } - if(input[0] != ")") - { - cout << "Too many values trying to be inserted. Only insert " << a.size() << " values."; - cout << "The values should be: "; - for(int x = 0; x < a.size(); ++x) - { - cout << a[x].getType(); - if(a[x].getType() == "VARCHAR") - { - cout << "(" << a[x].getSize() << ")"; - } - cout << endl; - } - exit(1); - } - engine.insertValues(r.getTableName(), s); - input.erase(input.begin()); - return input; - } - - else if (input[0] == "RELATION") - { - input.erase(input.begin()); - - //PExpression e; - - // while(input[0] != ";") - // { - // e.setPExpression(e.getPExpression() + input[0]); - // } - - //cout << "Inserting: " << e.getPExpression() << " into " << r.getName() << ".\n"; - - cout << "Not yet implemented." << endl; - - return input; - } - - else cout<<"Syntax error! 3"< updateCMD(vector input, DBEngine &engine) -{ - PRelation r(input[0]); - - input.erase(input.begin()); - - if(input[0] == "SET") - { - input.erase(input.begin()); - - //parse out ( and send everything until ) into an Expression vector - if(input[0] == "(") - { - - vector a; - PAttribute temp; - - vector s; - - //vector e; - - input.erase(input.begin()); - - while(input[0] != ")") - { - temp.setPAttributeName(input[0]); - a.push_back(temp); - temp.setPAttributeName("~"); - - input.erase(input.begin()); - - if(input[0] == "=") - { - input.erase(input.begin()); - - s.push_back(input[0]); - } - - else - { - cout<<"Syntax error! 2"< deleteCMD(vector input, DBEngine &engine) -{ - if (input[0] == "DELETE" && input[1] == "FROM") - { - input.erase(input.begin()); - input.erase(input.begin()); - - PRelation r(input[0]); - - if(input[0] == "WHERE") - { - if(input[0] == "(") - { - //PCondition c; - - PComparison c; - POperand oops1; - POperand oops2; - POp op; - - while(input[0] != ")") - { - oops1.setPOperand(input[0]); - input.erase(input.begin()); - - oops2.setPOperand(input[0]); - input.erase(input.begin()); - - op.setPOp(input[0]); - input.erase(input.begin()); - - c.setPComparison(oops1.getPOperand(), op.getPOp(), oops2.getPOperand()); - } - } - } - - // send delete command to DBEngine - } - else cout<<"Syntax error!"< input, DBEngine &engine) //calls par_command() or par_query() depending on first item from token list -{ -/* -• Match the first item in the token list and determine weather this is a command or a query. -• Call functions par_command() or par_query(); -• After either par_command() or par_query() returns, make sure the line ends properly with “;” token -*/ - string tempChar = input.back(); - - if (tempChar != ";") - { - cout<<"ERROR! missing semicolon "< insertInput = insertCMD(input, engine); - cout<<"arguments: "< insertInput = createCMD(input, engine); - cout<<"arguments: "< insertInput = deleteCMD(input, engine); - cout<<"arguments: "< insertInput = updateCMD(input, engine); - cout<<"arguments: "< listOfTokens = tokenize(input); - par_line(listOfTokens, engine); -} -/* -int main () { - - - string ss = "INSERT INTO animals VALUES FROM ( Joe , cat , 4 ) ;"; - string ss2 = "SHOW Dogs ;"; - string ss3 = "EXIT ; "; - - vector listOfTokens = tokenize(ss); - vector listOfTokens2 = tokenize(ss2); - vector listOfTokens3 = tokenize(ss3); - - par_line(listOfTokens); - par_line(listOfTokens2); - par_line(listOfTokens3); - - -} -*/ \ No newline at end of file diff --git a/Relation.cpp b/Relation.cpp index 4a7dd9c..bf32b20 100755 --- a/Relation.cpp +++ b/Relation.cpp @@ -63,6 +63,16 @@ Attribute& Relation::getAttributeByName(string s) { cout << "Failure to return: the requested attribute does not exist."; } +bool Relation::isAttribute(string s) { + for(int i = 0; i < size; ++i){ + if (att[i].getName() == s) { + return true; + } + } + return false; + //cout << "Failure to return: the requested attribute does not exist."; +} + void Relation::renameAttribute(string oldstr, string newstr){ this->getAttributeByName(oldstr).setName(newstr); } @@ -82,6 +92,8 @@ void Relation::display(){ } void Relation::insertTuple(vector tuple){ + cout << name << " " << size << endl; + cout << tuple.size() << endl; if (tuple.size() != this->size) { cout << "Failure to insert: the sizes do not match."; } @@ -116,13 +128,29 @@ void Relation::insertFromRelation(Relation r){ } void Relation::removeTuple(int index){ - if (index >= this->size) { - cout << "Failure to delete: the requested index is out of bounds."; + if (index >= this->size) + { + cout << "Failure to delete: the requested index is out of bounds." << endl; } - else { - for (int i = 0; i < att.size(); ++i) { + else + { + for (int i = 0; i < att.size(); ++i) + { att[i].removeCell(index); } } +} + +void Relation::removeFromTuple(int rindex, int aindex) +{ + if (rindex >= this->size) + { + cout << "Failure to delete: the requested index is out of bounds." << endl; + } + + else + { + att[rindex].removeCell(aindex); + } } \ No newline at end of file diff --git a/Relation.h b/Relation.h index 172627f..4c7e1e2 100755 --- a/Relation.h +++ b/Relation.h @@ -19,10 +19,12 @@ public: vector getAttributes(); vector getAttributeNames(); Attribute& getAttributeByName(string s); + bool isAttribute(string s); void renameAttribute(string oldstr, string newstr); int getSize(); void display(); void insertTuple(vector tuple); //assuming they are in order void insertFromRelation(Relation r); void removeTuple(int index); + void removeFromTuple(int rindex, int aindex); }; \ No newline at end of file diff --git a/test b/test new file mode 100755 index 0000000..9b3ff7f Binary files /dev/null and b/test differ diff --git a/test.cpp b/test.cpp index 2c85d22..710b098 100755 --- a/test.cpp +++ b/test.cpp @@ -1,6 +1,6 @@ #include #include -#include "Parserv3.h" +#include "Parser.h" //#include "Condition.h" #include "DBEngine.h" @@ -48,4 +48,12 @@ int main () { //engine.getTableFromName("MoarFood").display(); engine.crossProduct(engine.getTableFromName("Food"), engine.getTableFromName("MoarFood")).display(); + string x; + cout << "Enter DBMS Commands: "; + while(getline(cin, x)) + { + //cout << x << endl; + parse(x, engine); + cout << "Enter DBMS Commands: "; + } }