345 lines
7.2 KiB
C++
Executable file
345 lines
7.2 KiB
C++
Executable file
#include <fstream>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include "Condition.h"
|
|
#include "DBEngine.h"
|
|
|
|
DBEngine::DBEngine(){
|
|
size = 0;
|
|
}
|
|
|
|
void DBEngine::createTable(string n){
|
|
Relation r(n);
|
|
tables.push_back(r);
|
|
size++;
|
|
}
|
|
|
|
void DBEngine::createTable(string n, vector<Attribute> a){
|
|
Relation r(n, a);
|
|
tables.push_back(r);
|
|
size++;
|
|
}
|
|
|
|
void DBEngine::createTable(Relation r){
|
|
tables.push_back(r);
|
|
size++;
|
|
}
|
|
|
|
void DBEngine::insertValues(string r, vector<string> v)
|
|
{
|
|
for(int i = 0; i < tables.size(); i++)
|
|
{
|
|
if (tables[i].getTableName() == r)
|
|
{
|
|
tables[i].insertTuple(v);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DBEngine::storeCommands(string s){
|
|
commands.push_back(s);
|
|
}
|
|
|
|
void DBEngine::save(){
|
|
|
|
ofstream file;
|
|
file.open("savefile.txt");
|
|
|
|
for(int i = 0; i < commands.size(); ++i){
|
|
file << commands[i] << endl;
|
|
}
|
|
|
|
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<Relation> DBEngine::getRelations(){
|
|
return tables;
|
|
}
|
|
|
|
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];
|
|
}
|
|
}
|
|
|
|
cout << "FAILURE TO FIND: could not locate a Relation with this name.";
|
|
return tables[0];
|
|
}
|
|
|
|
Relation DBEngine::selection(string attName, string s, Relation r){
|
|
return equality(attName, s, r);
|
|
}
|
|
|
|
//assumes that all attribute titles are unique
|
|
Relation DBEngine::projection(vector<string> input, Relation r){
|
|
|
|
vector<Attribute> v;
|
|
string new_name = r.getTableName() + " Projection";
|
|
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
|
|
Relation temp(new_name, v);
|
|
return temp;
|
|
}
|
|
|
|
Relation DBEngine::rename(vector<string> newnames, Relation &r){
|
|
vector<string> temp;
|
|
if (r.getSize() != newnames.size()) {
|
|
cout << "FAILURE TO RENAME: number of attributes do not match.\n";
|
|
exit(1);
|
|
}
|
|
else
|
|
{
|
|
temp = r.getAttributeNames();
|
|
for(int i = 0; i < temp.size(); ++i)
|
|
{
|
|
r.renameAttribute(temp[i], newnames[i]);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
}
|
|
|
|
Relation DBEngine::setUnion(Relation r1, Relation r2){
|
|
if (r1.getAttributeNames() != r2.getAttributeNames()){
|
|
cout << "Failure to union: the relations are not union-compatible.\nreturning the first relation.\n";
|
|
return r1;
|
|
}
|
|
|
|
else {
|
|
//currently all returned relations are called TEMP
|
|
Relation new_r = r1;
|
|
new_r.setTableName("TEMP");
|
|
vector<string> temp;
|
|
bool duplicate = false;
|
|
|
|
for (int i = 0; i < r2.getAttributes()[0].getSize(); ++i) {
|
|
temp = r2.getTuple(i);
|
|
|
|
for (int j = 0; j < new_r.getAttributes()[0].getSize(); ++j){
|
|
if (temp == new_r.getTuple(j)){
|
|
duplicate = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!duplicate) {
|
|
new_r.insertTuple(temp);
|
|
}
|
|
|
|
duplicate = false;
|
|
}
|
|
|
|
return new_r;
|
|
}
|
|
}
|
|
|
|
Relation DBEngine::setDiff(Relation r1, Relation r2){
|
|
if (r1.getAttributeNames() != r2.getAttributeNames()){
|
|
cout << "Failure to diff: the relations are not union-compatible.\nreturning the first relation.\n";
|
|
return r1;
|
|
}
|
|
|
|
else {
|
|
//currently all returned relations are called TEMP
|
|
Relation new_r = r1;
|
|
new_r.setTableName("TEMP");
|
|
vector<string> temp;
|
|
|
|
int size = 0;
|
|
|
|
for(int x = 0; x < r2.getAttributes().size(); ++x)
|
|
{
|
|
for (int i = 0; i < r2.getAttributes()[x].getSize(); ++i)
|
|
{
|
|
temp = r2.getTuple(i);
|
|
|
|
for(int y = 0; y < new_r.getAttributes().size(); ++y)
|
|
{
|
|
size = new_r.getAttributes()[y].getSize();
|
|
new_r.getAttributes()[y].getSize();
|
|
for (int j = 0; j < size; ++j)
|
|
{
|
|
for(int a = 0; a < temp.size(); ++a)
|
|
{
|
|
for(int b = 0; b < new_r.getTuple(j).size(); ++b)
|
|
{
|
|
if (temp[a] == new_r.getTuple(j)[b])
|
|
{
|
|
new_r.removeFromTuple(b, j);
|
|
}
|
|
}
|
|
}
|
|
size = new_r.getAttributes()[y].getSize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return new_r;
|
|
}
|
|
}
|
|
|
|
Relation DBEngine::crossProduct(Relation r1, Relation r2){
|
|
vector<Attribute> new_atts = r1.getAttributes();
|
|
int r1_attsize = r1.getAttributes()[0].getSize();
|
|
int r2_attsize = r2.getAttributes()[0].getSize();
|
|
|
|
for (int i = 0; i < r2_attsize; ++i) {
|
|
new_atts.push_back(r2.getAttributes()[i]);
|
|
}
|
|
|
|
for (int i = 0; i < new_atts.size(); ++i) {
|
|
new_atts[i].clearAllValues();
|
|
}
|
|
|
|
//currently all returned relations are called TEMP
|
|
Relation new_r("TEMP", new_atts);
|
|
|
|
vector<string> r1_tuple;
|
|
vector<string> r2_tuple;
|
|
vector<string> temp;
|
|
|
|
for (int i = 0; i < r1_attsize; ++i) {
|
|
r1_tuple = r1.getTuple(i);
|
|
|
|
for (int j = 0; j < r2_attsize; ++j) {
|
|
r2_tuple = r2.getTuple(j);
|
|
temp = r1_tuple;
|
|
temp.insert(temp.end(), r2_tuple.begin(), r2_tuple.end());
|
|
|
|
new_r.insertTuple(temp);
|
|
}
|
|
}
|
|
|
|
|
|
return new_r;
|
|
}
|
|
|
|
void DBEngine::updateFromRelationCmd(Relation r, Relation temp, vector<string> attName, vector<string> att){
|
|
string rName = r.getTableName();
|
|
int index = -1;
|
|
|
|
for (int i = 0; i < tables.size(); ++i){
|
|
if (tables[i].getTableName() == rName){
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
vector<string> tuple;
|
|
vector<string> tempTuple;
|
|
for(int i = 0; i < temp.getAttributes()[0].getSize(); ++i){
|
|
tuple = temp.getTuple(i);
|
|
|
|
for (int j = 0; j < tables[index].getSize(); ++j){
|
|
tempTuple = tables[index].getTuple(j);
|
|
if (tables[index].getTuple(j) == tuple){
|
|
for (int k = 0; k < tables[index].getSize(); ++k){
|
|
for (int a = 0; a < attName.size(); ++a){
|
|
if (tables[index][k].getName() == attName[a]){
|
|
cout << "point 7\n";
|
|
cout << "tables[index][k][j]:" << tables[index][k][j] << "\n";
|
|
cout << "att[a]:" << att[a] << "\n";
|
|
tables[index].updateInAttribute(att[a], k, j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DBEngine::deleteFromRelationCmd(Relation r, Relation temp){
|
|
string rName = r.getTableName();
|
|
int index = -1;
|
|
|
|
for (int i = 0; i < tables.size(); ++i){
|
|
if (tables[i].getTableName() == rName){
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
vector<string> tuple;
|
|
vector<string> tempTuple;
|
|
|
|
for(int i = 0; i < temp.getAttributes()[0].getSize(); ++i){
|
|
tuple = temp.getTuple(i);
|
|
|
|
for (int j = 0; j < tables[index].getSize(); ++j){
|
|
tempTuple = tables[index].getTuple(j);
|
|
|
|
if (tempTuple == tuple){
|
|
tables[index].removeTuple(j);
|
|
}
|
|
}
|
|
}
|
|
}
|