-
Notifications
You must be signed in to change notification settings - Fork 0
/
scientistrepository.cpp
160 lines (134 loc) · 5.15 KB
/
scientistrepository.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "scientistrepository.h"
const char delim = ';';
const char* DATABASE = "database.txt";
//Constructor that makes a new vector of Scientists and reads into it from a file
ScientistRepository::ScientistRepository(){
scientistVector = vector<Scientist>();
read();
}
//Writes one instance of scientist to a file
void ScientistRepository::write(Scientist s){
ofstream write;
write.open(DATABASE, ios::out | ios::app);
write << s.firstName << delim
<< s.lastName << delim
<< s.gender << delim
<< s.birthdate << delim
<< s.deathdate << delim
<< s.nationality << endl;
write.close();
}
//Overwrites the database file with the vector
void ScientistRepository::save(){
ofstream write;
write.open(DATABASE, ios::out);
for(unsigned int i = 0; i < scientistVector.size() ; i++){
write << scientistVector[i].firstName << delim
<< scientistVector[i].lastName << delim
<< scientistVector[i].gender << delim
<< scientistVector[i].birthdate << delim
<< scientistVector[i].deathdate << delim
<< scientistVector[i].nationality << endl;
}
write.close();
}
//Adds an instance of scientist to the vector and writes it to a file
void ScientistRepository::add(Scientist s){
scientistVector.push_back(s);
write(s);
}
void ScientistRepository::update(Scientist &s, Scientist &replace){
//Searches for the name and removes it from the vector.
for(unsigned int i = 0; i < scientistVector.size() ; i++){
if(scientistVector[i] == s){
scientistVector[i] = replace;
break;
}
}
//Overwrites the database.txt with the new vector.
save();
}
//Removes one instance of scientist from the vector
void ScientistRepository::remove(Scientist s){
//Searches for the name and removes it from the vector.
for(unsigned int i = 0; i < scientistVector.size() ; i++){
if(scientistVector[i] == s){
scientistVector.erase(scientistVector.begin() + i);
break;
}
}
//Overwrites the database.txt with the new vector.
save();
}
//Reads all scientist from a file
void ScientistRepository::read(){
ifstream read;
read.open("database.txt");
string s;
while(read >> s){
scientistVector.push_back(Scientist::fromString(s,delim));
}
read.close();
}
//Sorts Scientists by selected field and order
vector<Scientist> ScientistRepository::list(ScientistSort::Field field, ScientistSort::Order order){
vector<Scientist> ret(scientistVector);
// SELECT * FROM scientists ORDER BY field,order
auto cmp = ScientistSort::Comparer(field, order);
stable_sort(ret.begin(), ret.end(), cmp);
return ret;
}
//Searches for default amount of Scientists (1)
vector<Scientist> ScientistRepository::search(ScientistSort::Field field, bool fuzzy, string query){
return search(field, fuzzy, 1, query);
}
//Searches for Scientists after the parameters selected
//If fuzzy is true then it finds everything that is within 2 Levenshtein distance from the original query
vector<Scientist> ScientistRepository::search(ScientistSort::Field field, bool fuzzy, size_t rows, string query){
vector<Scientist> ret;
for(auto it = scientistVector.begin(); it != scientistVector.end(); it++){
switch(field){
case ScientistSort::FIRST_NAME:
if(fuzzy && levenshtein_distance<string>((*it).firstName,query) < 3)
ret.push_back((*it));
else if((*it).firstName == query)
ret.push_back((*it));
break;
case ScientistSort::LAST_NAME:
if(fuzzy && levenshtein_distance<string>((*it).lastName,query) < 3)
ret.push_back((*it));
else if((*it).lastName == query)
ret.push_back((*it));
break;
case ScientistSort::GENDER:
if((*it).gender == query[0])
ret.push_back((*it));
break;
case ScientistSort::BIRTH_DATE:
if(fuzzy && levenshtein_distance<string>((*it).birthdate.toDateString(),query) < 3)
ret.push_back((*it));
else if((*it).birthdate == Date::fromString(query))
ret.push_back((*it));
break;
case ScientistSort::DEATH_DATE:
if(fuzzy && levenshtein_distance<string>((*it).deathdate.toDateString(),query) < 3)
ret.push_back((*it));
else if((*it).deathdate == Date::fromString(query))
ret.push_back((*it));
break;
case ScientistSort::NATIONALITY:
if(fuzzy && levenshtein_distance<string>((*it).nationality,query) < 3)
ret.push_back((*it));
else if((*it).nationality == query)
ret.push_back((*it));
break;
default:
if((*it).firstName == query)
ret.push_back((*it));
break;
}
if(ret.size() > rows)
break;
}
return ret;
}