-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseDatos.cpp
277 lines (229 loc) · 10 KB
/
BaseDatos.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#include "BaseDatos.h"
using namespace aed2;
//Cosas que faltan:
//------------------
// AgregarTabla
// vistaJoin tengo problemas con const_
// -> Basicamente el problema con vistaJoin es que no tiene que ser const, lo saque
// generarVistaJoin falta terminar
//~ BaseDatos::BaseDatos(){
//~ Lista vacioL();
//~ Dicc vacioD();
//~ this->tablasBD = vacioD;
//~ this->tablasLista = vacioL;
//~ this->cantAccesoMax = 0;
//~ this->nombreAccesoMax = "";
//~ }
// Agrego una nueva tabla a la BD
void BaseDatos::AgregarTabla(const Tabla& t){
tablaLista.AgregarAtras(t.Nombre());
struct InfoTabla infoTab = InfoTabla(t);
tablasBD.Definir(t.Nombre(), infoTab);
}
// Devuelvo un iterador a los nombres de las tablas de la BD
aed2::Lista<NombreTabla> BaseDatos::Tablas() const{
return tablaLista;
}
// Devuelvo la tabla que me piden
const Tabla& BaseDatos::DameTabla(const NombreTabla& t)const{
return tablasBD.Significado(t).tablaData;
}
Tabla& BaseDatos::DameTabla(const NombreTabla& t){
return tablasBD.Significado(t).tablaData;
}
// Devuelve true si hay joint entra las dos tablas
bool BaseDatos::HayJoin(const NombreTabla& t1, const NombreTabla& t2) const{
return tablasBD.Significado(t1).joins.Definido(t2);
}
// Devuelve el campo para los cuales dos tablas estan vinculadas
const NombreCampo& BaseDatos::CampoJoin(const NombreTabla& t1, const NombreTabla& t2) const{
const InfoTabla& t1Info = tablasBD.Significado(t1);
return t1Info.joins.Significado(t2).campo;
}
// Agrego un Registro a una Tabla
void BaseDatos::InsertarEntrada(const tp3::Registro& r, const NombreTabla& t){
//~ std::cout << "InsertarEntradaSBD" << std::endl;
struct InfoTabla& infoT = tablasBD.Significado(t);
infoT.tablaData.AgregarRegistro(r);
//~ std::cout << "Long InsertarBD"<<DameTabla(t).Registros().Longitud() << std::endl;
Lista<NombreTabla>::Iterador itTablas = tablaLista.CrearIt();
while(itTablas.HaySiguiente()){
struct InfoTabla& infoTabRev = tablasBD.Significado(itTablas.Siguiente());
// Pregunto si hay alguna tabla que tenga join con la tabla que modifique t
if(infoTabRev.joins.Definido(t)){
struct InfoJoin& infoJoinRev = infoTabRev.joins.Significado(t);
Dupla<tp3::Registro, bool> dup;
dup.x = r; dup.y = false;
infoJoinRev.regActualizar.AgregarAtras(dup);
}
// Pregunto si la tabla t tiene join con alguna tabla
if(infoT.joins.Definido(itTablas.Siguiente())){
struct InfoJoin& infoJoinT = infoT.joins.Significado(itTablas.Siguiente());
Dupla<tp3::Registro, bool> dup;
dup.x = r; dup.y = false;
infoJoinT.regActualizar.AgregarAtras(dup);
}
itTablas.Avanzar();
}
if(infoT.tablaData.CantidadDeAccesos() > cantAccesoMax){
cantAccesoMax = infoT.tablaData.CantidadDeAccesos();
nombreAccesoMax = t;
}
}
//borrar un registro de una tabla
void BaseDatos::Borrar(const tp3::Registro& r, const NombreTabla& t){
int Debug = 0;
struct InfoTabla& infoT = tablasBD.Significado(t);
if (Debug==1) std::cout << "Nombre Tabla: " << infoT.tablaData.Nombre() << std::endl;
Lista<NombreTabla>::Iterador itTablas = tablaLista.CrearIt();
while(itTablas.HaySiguiente()){
struct InfoTabla& infoTabRev = tablasBD.Significado(itTablas.Siguiente());
// Pregunto si hay alguna tabla que tenga join con la tabla que modifique t
if(infoTabRev.joins.Definido(t)){
if (Debug==1) std::cout << "Hay una tabla q tiene join con la que borro " << std::endl;
struct InfoJoin& infoJoinRev = infoTabRev.joins.Significado(t);
Dupla<tp3::Registro, bool> dup;
dup.x = r; dup.y = true;
infoJoinRev.regActualizar.AgregarAtras(dup);
}
// Pregunto si la tabla t tiene join con alguna tabla
if(infoT.joins.Definido(itTablas.Siguiente())){
if (Debug==1) std::cout << "Hay join con otra tabla " << std::endl;
struct InfoJoin& infoJoinT = infoT.joins.Significado(itTablas.Siguiente());
Dupla<tp3::Registro, bool> dup;
dup.x = r; dup.y = true;
infoJoinT.regActualizar.AgregarAtras(dup);
}
itTablas.Avanzar();
}
infoT.tablaData.BorrarRegistro(r);
// Actualizo la cantidad de Accesos
if(infoT.tablaData.CantidadDeAccesos() > cantAccesoMax){
if (Debug==1) std::cout << "Actualizo Max Tabla: " << infoT.tablaData.CantidadDeAccesos() << std::endl;
cantAccesoMax = infoT.tablaData.CantidadDeAccesos();
nombreAccesoMax = t;
}
}
// Devuelve la tabla con mayor cantidad de accesos en BD
const NombreTabla& BaseDatos::TablaMaxima() const{
return nombreAccesoMax;
}
// Elimina el Joint entre tablas
void BaseDatos::BorrarJoin(const NombreTabla& t1, const NombreTabla& t2){
struct InfoTabla& t1Info = tablasBD.Significado(t1);
t1Info.joins.Borrar(t2);
//~ struct InfoTabla& t2Info = tablasBD.Significado(t2);
//~ t2Info.joins.Borrar(t1);
}
// Busca los registro que conincidan con r en la tabla de la base de datos
aed2::Lista<const_ItLista> BaseDatos::Buscar(const tp3::Registro& r, const NombreTabla& t) const{
const InfoTabla& t1Info = tablasBD.Significado(t);
return t1Info.tablaData.Coincidencias(r , t1Info.tablaData.Registros());
}
aed2::Lista<ItLista> BaseDatos::Buscar(const tp3::Registro& r, const NombreTabla& t){
InfoTabla& t1Info = tablasBD.Significado(t);
return t1Info.tablaData.Coincidencias(r , t1Info.tablaData.Registros());
}
// Visualiza el Join entre dos tablas
aed2::Lista<tp3::Registro> BaseDatos::VistaJoin( const NombreTabla& t1, const NombreTabla& t2){
struct InfoTabla& t1Info = tablasBD.Significado(t1);
struct InfoJoin& joinsT1T2 = t1Info.joins.Significado(t2);
aed2::Lista<Dupla<tp3::Registro, bool> >::Iterador itRegAct = joinsT1T2.regActualizar.CrearIt();
// Si no hay registro p actualizar devuelvo un it a la lista de reg del join
if(!(itRegAct.HaySiguiente() ) ){
return joinsT1T2.registroJoin.Registros();
} else { // en caso contrario voy revisando cada uno si fueron agregados o borrados
while(itRegAct.HaySiguiente()){
tp3::Registro regCrit = tp3::Registro(joinsT1T2.campo, itRegAct.Siguiente().x.Significado(joinsT1T2.campo));
// Si el registro fue borrado
if( itRegAct.Siguiente().y ){
joinsT1T2.registroJoin.BorrarRegistro(regCrit);
}
else { // Si el registro fue agregado Reviso si esta en las dos tablas, si esta lo agrego a la lista de join
//~ aed2::Lista<ItLista>::Iterador itLista1 = Buscar(regCrit, t1).CrearIt();
//~ aed2::Lista<ItLista>::Iterador itLista2 = Buscar(regCrit, t2).CrearIt();
aed2::Lista<ItLista> b1 = Buscar(regCrit, t1);
aed2::Lista<ItLista>::Iterador itLista1 = b1.CrearIt();
aed2::Lista<ItLista> b2 = Buscar(regCrit, t2);
aed2::Lista<ItLista>::Iterador itLista2 = b2.CrearIt();
if(itLista1.HaySiguiente() && itLista2.HaySiguiente()){
tp3::Registro regAgr = itLista1.Siguiente().Siguiente().agregarCampos(itLista2.Siguiente().Siguiente());
joinsT1T2.registroJoin.AgregarRegistro(regAgr);
}
}
itRegAct.EliminarSiguiente();
}
}
return joinsT1T2.registroJoin.Registros();
}
// Devuelve el nombre de la tabla que tuvo mayor cant de Accesos
const NombreTabla& BaseDatos::EncontrarMaximo( NombreTabla& t, const aed2::Conj<NombreTabla>& conjTab) {
struct InfoTabla& infoT = tablasBD.Significado(t);
aed2::Nat accesosT = infoT.tablaData.CantidadDeAccesos();
Conj<NombreTabla>::const_Iterador itConjCT = conjTab.CrearIt();
aed2::Nat maxAcceso = accesosT;
NombreTabla& stringMaxAcceso = t;
while(itConjCT.HaySiguiente()){
InfoTabla tInfo = tablasBD.Significado(itConjCT.Siguiente());
aed2::Nat accesoT = tInfo.tablaData.CantidadDeAccesos();
if(accesoT > maxAcceso){
maxAcceso = accesoT;
stringMaxAcceso = itConjCT.Siguiente();
}
itConjCT.Avanzar();
}
cantAccesoMax = maxAcceso;
stringMaxAcceso = stringMaxAcceso;
return stringMaxAcceso;
}
// devuelve los registros de una tabla
aed2::Lista<tp3::Registro> BaseDatos::Registros(const NombreTabla& t) const{
return tablasBD.Significado(t).tablaData.Registros();
}
aed2::Conj<aed2::Columna> unionConjuntos(aed2::Conj<aed2::Columna> c1, aed2::Conj<aed2::Columna> c2){
aed2::Conj<aed2::Columna>::Iterador it1 = c1.CrearIt();
while(it1.HaySiguiente()){
c2.Agregar(it1.Siguiente());
it1.Avanzar();
}
return c2;
}
// Genera el Join entre dos tablas
void BaseDatos::GenerarVistaJoin(const NombreTabla& t1, const NombreTabla& t2, const NombreCampo& ca){
struct InfoTabla& infoT1 = tablasBD.Significado(t1);
aed2::Lista<tp3::Registro>::Iterador itRegT1 = infoT1.tablaData.Registros().CrearIt();
aed2::Lista<tp3::Registro>::Iterador itRegT2 = tablasBD.Significado(t2).tablaData.Registros().CrearIt();
// Se crea InfoJoin
aed2::Conj<aed2::Columna> columnasT1 = tablasBD.Significado(t1).tablaData.dameColumnas();
aed2::Conj<aed2::Columna> columnasT2 = tablasBD.Significado(t2).tablaData.dameColumnas();
aed2::Conj<aed2::Columna> columnasUnidas = unionConjuntos(columnasT1, columnasT2);
aed2::Conj<aed2::NombreCampo> claves;
aed2::NombreTabla nombreTablaJoin = "TablaJoin";
//~ aed2::Conj<Dato> datosCamposUnidos;
//~ tp3::Registro registroCamposUnidos(camposUnidos, datosCamposUnidos);
Tabla tablaJoin( nombreTablaJoin, claves, columnasUnidas);
struct InfoJoin infoJoinT = InfoJoin(tablaJoin, ca);
infoT1.joins.Definir(t2, infoJoinT);
//Verifico que ninguna tabla sea vacia
if(!itRegT1.HaySiguiente()) return;
if(!itRegT2.HaySiguiente()) return;
while(itRegT2.HaySiguiente()){
aed2::Conj<aed2::NombreCampo> conjCamp;
conjCamp.AgregarRapido(ca);
aed2::Conj<tp3::Dato> conjDato;
conjDato.AgregarRapido(itRegT2.Siguiente().Significado(ca));
tp3::Registro regCrit = tp3::Registro(conjCamp, conjDato);
tp3::Registro regAux = itRegT2.Siguiente();
aed2::Lista<ItLista>::Iterador itConinciden = Buscar(regAux , t1).CrearIt();
if(itConinciden.HaySiguiente()){
tablaJoin.AgregarRegistro(itRegT2.Siguiente().agregarCampos(itConinciden.Siguiente().Siguiente() ) );
}
itRegT2.Avanzar();
}
}
// devuelve la cantidad de acsesos de una tabla
aed2::Nat BaseDatos::CantidadDeAccesos(const NombreTabla& t) const{
return tablasBD.Significado(t).tablaData.CantidadDeAccesos();
}
BaseDatos::InfoJoin::InfoJoin(const Tabla& tabla, const aed2::NombreCampo& campo): registroJoin(tabla), campo(campo){}
BaseDatos::InfoTabla::InfoTabla(const Tabla& tablaData): tablaData(tablaData){}