Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Enzo Bonggio
aed2-2c2017-tp2
Commits
0d231da9
Commit
0d231da9
authored
7 years ago
by
Enzo Bonggio
Browse files
Options
Download
Email Patches
Plain Diff
string_map + esqueleto
parent
e6aec85b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
849 additions
and
267 deletions
+849
-267
CMakeLists.txt
CMakeLists.txt
+1
-1
src/BaseDeDatos.cpp
src/BaseDeDatos.cpp
+115
-80
src/BaseDeDatos.h
src/BaseDeDatos.h
+187
-137
src/string_map.h
src/string_map.h
+524
-28
tests/base_de_datos_test.cpp
tests/base_de_datos_test.cpp
+21
-21
tests/string_map_test.cpp
tests/string_map_test.cpp
+1
-0
No files found.
CMakeLists.txt
View file @
0d231da9
...
...
@@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 11)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=gnu++11 -ggdb3 -g"
)
# Leemos todos los archivos fuentes en ./src
file
(
GLOB SOURCE_FILES src/*.cpp src/*.h
)
file
(
GLOB SOURCE_FILES src/*.cpp src/*.h
src/*.hpp
)
# Leemos todos los archivos de test en ./tests
file
(
GLOB TEST_SOURCES tests/*.cpp
)
...
...
This diff is collapsed.
Click to expand it.
src/BaseDeDatos.cpp
View file @
0d231da9
...
...
@@ -3,140 +3,175 @@
#include <tuple>
#include <algorithm>
BaseDeDatos
::
BaseDeDatos
(){};
BaseDeDatos
::
BaseDeDatos
()
{};
void
BaseDeDatos
::
crearTabla
(
const
string
&
nombre
,
void
BaseDeDatos
::
crearTabla
(
const
string
&
nombre
,
const
linear_set
<
string
>
&
claves
,
const
vector
<
string
>
&
campos
,
const
vector
<
Dato
>
&
tipos
)
{
_nombres_tablas
.
fast_insert
(
nombre
);
_tablas
.
fast_insert
(
make_pair
(
nombre
,
Tabla
(
claves
,
campos
,
tipos
)));
_nombres_tablas
.
fast_insert
(
nombre
);
_tablas
.
fast_insert
(
make_pair
(
nombre
,
Tabla
(
claves
,
campos
,
tipos
)));
}
void
BaseDeDatos
::
agregarRegistro
(
const
Registro
&
r
,
const
string
&
nombre
)
{
Tabla
&
t
=
_tablas
.
at
(
nombre
);
t
.
agregarRegistro
(
r
);
Tabla
&
t
=
_tablas
.
at
(
nombre
);
t
.
agregarRegistro
(
r
);
}
const
linear_set
<
string
>
&
BaseDeDatos
::
tablas
()
const
{
return
_nombres_tablas
;
}
const
Tabla
&
BaseDeDatos
::
dameTabla
(
const
string
&
nombre
)
const
{
return
_tablas
.
at
(
nombre
);
return
_tablas
.
at
(
nombre
);
}
int
BaseDeDatos
::
uso_criterio
(
const
BaseDeDatos
::
Criterio
&
criterio
)
const
{
if
(
_uso_criterios
.
count
(
criterio
))
{
return
_uso_criterios
.
at
(
criterio
);
}
else
{
return
0
;
}
if
(
_uso_criterios
.
count
(
criterio
))
{
return
_uso_criterios
.
at
(
criterio
);
}
else
{
return
0
;
}
}
bool
BaseDeDatos
::
registroValido
(
const
Registro
&
r
,
const
string
&
nombre
)
const
{
const
Tabla
&
t
=
_tablas
.
at
(
nombre
);
const
Tabla
&
t
=
_tablas
.
at
(
nombre
);
return
(
t
.
campos
()
==
r
.
campos
()
and
_mismos_tipos
(
r
,
t
)
and
_no_repite
(
r
,
t
));
return
(
t
.
campos
()
==
r
.
campos
()
and
_mismos_tipos
(
r
,
t
)
and
_no_repite
(
r
,
t
));
}
bool
BaseDeDatos
::
_mismos_tipos
(
const
Registro
&
r
,
const
Tabla
&
t
)
const
{
for
(
auto
c
:
t
.
campos
())
{
if
(
r
.
dato
(
c
).
esNat
()
!=
t
.
tipoCampo
(
c
).
esNat
())
{
return
false
;
for
(
auto
c
:
t
.
campos
())
{
if
(
r
.
dato
(
c
).
esNat
()
!=
t
.
tipoCampo
(
c
).
esNat
())
{
return
false
;
}
}
}
return
true
;
return
true
;
}
bool
BaseDeDatos
::
_no_repite
(
const
Registro
&
r
,
const
Tabla
&
t
)
const
{
list
<
Registro
>
filtrados
(
t
.
registros
().
begin
(),
t
.
registros
().
end
());
for
(
auto
clave
:
t
.
claves
())
{
_filtrar_registros
(
clave
,
r
.
dato
(
clave
),
filtrados
);
}
return
filtrados
.
empty
();
list
<
Registro
>
filtrados
(
t
.
registros
().
begin
(),
t
.
registros
().
end
());
for
(
auto
clave
:
t
.
claves
())
{
_filtrar_registros
(
clave
,
r
.
dato
(
clave
),
filtrados
);
}
return
filtrados
.
empty
();
}
list
<
Registro
>
&
BaseDeDatos
::
_filtrar_registros
(
const
string
&
campo
,
const
Dato
&
valor
,
list
<
Registro
>
&
registros
)
const
{
return
_filtrar_registros
(
campo
,
valor
,
registros
,
true
);
return
_filtrar_registros
(
campo
,
valor
,
registros
,
true
);
}
list
<
Registro
>
&
BaseDeDatos
::
_filtrar_registros
(
const
string
&
campo
,
const
Dato
&
valor
,
list
<
Registro
>
&
registros
,
bool
igualdad
)
const
{
auto
iter
=
registros
.
begin
();
while
(
iter
!=
registros
.
end
())
{
auto
now
=
iter
;
iter
++
;
if
((
not
igualdad
)
xor
now
->
dato
(
campo
)
!=
valor
)
{
registros
.
erase
(
now
);
auto
iter
=
registros
.
begin
();
while
(
iter
!=
registros
.
end
())
{
auto
now
=
iter
;
iter
++
;
if
((
not
igualdad
)
xor
now
->
dato
(
campo
)
!=
valor
)
{
registros
.
erase
(
now
);
}
}
}
return
registros
;
return
registros
;
}
pair
<
vector
<
string
>
,
vector
<
Dato
>
>
BaseDeDatos
::
_tipos_tabla
(
const
Tabla
&
t
)
{
vector
<
string
>
res_campos
;
vector
<
Dato
>
res_tipos
;
for
(
auto
c
:
t
.
campos
())
{
res_campos
.
push_back
(
c
);
res_tipos
.
push_back
(
t
.
tipoCampo
(
c
));
}
return
make_pair
(
res_campos
,
res_tipos
);
vector
<
string
>
res_campos
;
vector
<
Dato
>
res_tipos
;
for
(
auto
c
:
t
.
campos
())
{
res_campos
.
push_back
(
c
);
res_tipos
.
push_back
(
t
.
tipoCampo
(
c
));
}
return
make_pair
(
res_campos
,
res_tipos
);
}
bool
BaseDeDatos
::
criterioValido
(
const
Criterio
&
c
,
const
string
&
nombre
)
const
{
const
Tabla
&
t
=
_tablas
.
at
(
nombre
);
for
(
auto
restriccion
:
c
)
{
if
(
not
t
.
campos
().
count
(
restriccion
.
campo
()))
{
return
false
;
}
if
(
t
.
tipoCampo
(
restriccion
.
campo
()).
esNat
()
!=
restriccion
.
dato
().
esNat
())
{
return
false
;
const
Tabla
&
t
=
_tablas
.
at
(
nombre
);
for
(
auto
restriccion
:
c
)
{
if
(
not
t
.
campos
().
count
(
restriccion
.
campo
()))
{
return
false
;
}
if
(
t
.
tipoCampo
(
restriccion
.
campo
()).
esNat
()
!=
restriccion
.
dato
().
esNat
())
{
return
false
;
}
}
}
return
true
;
return
true
;
}
Tabla
BaseDeDatos
::
busqueda
(
const
BaseDeDatos
::
Criterio
&
c
,
const
string
&
nombre
)
{
if
(
_uso_criterios
.
count
(
c
))
{
_uso_criterios
.
at
(
c
)
++
;
}
else
{
_uso_criterios
.
fast_insert
(
make_pair
(
c
,
1
));
}
const
Tabla
&
ref
=
dameTabla
(
nombre
);
auto
campos_datos
=
_tipos_tabla
(
ref
);
Tabla
res
(
ref
.
claves
(),
campos_datos
.
first
,
campos_datos
.
second
);
list
<
Registro
>
regs
(
ref
.
registros
().
begin
(),
ref
.
registros
().
end
());
for
(
auto
restriccion
:
c
)
{
_filtrar_registros
(
restriccion
.
campo
(),
restriccion
.
dato
(),
regs
,
restriccion
.
igual
());
}
for
(
auto
r
:
regs
)
{
res
.
agregarRegistro
(
r
);
}
return
res
;
if
(
_uso_criterios
.
count
(
c
))
{
_uso_criterios
.
at
(
c
)
++
;
}
else
{
_uso_criterios
.
fast_insert
(
make_pair
(
c
,
1
));
}
const
Tabla
&
ref
=
dameTabla
(
nombre
);
auto
campos_datos
=
_tipos_tabla
(
ref
);
Tabla
res
(
ref
.
claves
(),
campos_datos
.
first
,
campos_datos
.
second
);
list
<
Registro
>
regs
(
ref
.
registros
().
begin
(),
ref
.
registros
().
end
());
for
(
auto
restriccion
:
c
)
{
_filtrar_registros
(
restriccion
.
campo
(),
restriccion
.
dato
(),
regs
,
restriccion
.
igual
());
}
for
(
auto
r
:
regs
)
{
res
.
agregarRegistro
(
r
);
}
return
res
;
}
linear_set
<
BaseDeDatos
::
Criterio
>
BaseDeDatos
::
top_criterios
()
const
{
linear_set
<
Criterio
>
ret
;
int
max
=
0
;
for
(
auto
crit_count
:
_uso_criterios
)
{
if
(
crit_count
.
second
>=
max
)
{
if
(
crit_count
.
second
>
max
)
{
ret
=
linear_set
<
Criterio
>
();
max
=
crit_count
.
second
;
}
ret
.
fast_insert
(
crit_count
.
first
);
linear_set
<
Criterio
>
ret
;
int
max
=
0
;
for
(
auto
crit_count
:
_uso_criterios
)
{
if
(
crit_count
.
second
>=
max
)
{
if
(
crit_count
.
second
>
max
)
{
ret
=
linear_set
<
Criterio
>
();
max
=
crit_count
.
second
;
}
ret
.
fast_insert
(
crit_count
.
first
);
}
}
}
return
ret
;
return
ret
;
}
void
BaseDeDatos
::
crearIndice
(
const
string
tabla
,
const
string
columna
)
{
}
BaseDeDatos
::
joinIterator
BaseDeDatos
::
join
(
string
tabla1
,
string
tabla2
,
string
campo
)
{
// Tabla t1 = _tablas.at(tabla1);
// Tabla t2 = _tablas.at(tabla2);
//
// linear_set<string> resultClaves;
// vector<string> campos;
// vector<Dato> tipos;
//
// for(auto &c:t1.campos()) {
// campos.push_back(c);
// tipos.push_back(t1.tipoCampo(c));
// }
// for(auto &c:t2.campos()) {
// campos.push_back(c);
// tipos.push_back(t2.tipoCampo(c));
// }
//
// Tabla *joinTabla = new Tabla(resultClaves, campos, tipos);
//
// for (auto it = t1.registros_begin(); it != it.; ++it) {
//
// }
return
*
(
new
BaseDeDatos
::
joinIterator
());
}
BaseDeDatos
::
joinIterator
BaseDeDatos
::
join_end
()
{
return
*
(
new
BaseDeDatos
::
joinIterator
());
}
This diff is collapsed.
Click to expand it.
src/BaseDeDatos.h
View file @
0d231da9
...
...
@@ -27,143 +27,151 @@ using namespace std;
class
BaseDeDatos
{
public:
/** @brief Criterio de búsqueda para una base de datos */
typedef
linear_set
<
Restriccion
>
Criterio
;
/**
* @brief Inicializa una base de datos sin tablas.
*
* \pre true
* \post \P{this} = nuevaDB
*
* \complexity{\O(1)}
*/
BaseDeDatos
();
/**
* @brief Crea una nueva tabla en la base de datos.
*
* @param nombre Nombre identificador de la tabla
* @param claves Claves de la tabla a crear
* @param campos Campos de la tabla a crear
* @param tipos Tipos para los campos de la tabla a crear
*
* \pre db = \P{this} \LAND
* \LNOT (nombre \IN tablas(\P{this})) \LAND
* \LAND \LNOT \EMPTYSET?(claves) \LAND
* \FORALL (c: campo) c \IN claves \IMPLICA c \IN campos \LAND
* long(campos) = long(tipos) \LAND sinRepetidos(campos)
* \post \P{this} = agregarTabla(nuevaTabla(claves, nuevoRegistro(campos, tipos)), db)
*
* \complexity{\O(C)}
*/
void
crearTabla
(
const
string
&
nombre
,
const
linear_set
<
string
>
&
claves
,
const
vector
<
string
>
&
campos
,
const
vector
<
Dato
>
&
tipos
);
/**
* @brief Agrega un registro a la tabla parámetro
*
* @param r Registro a agregar
* @param nombre Nombre de la tabla donde se agrega el registro
*
* \pre db = \P{this} \LAND nombre \IN tablas(\P{this}) \LAND
* puedoInsertar?(r, dameTabla(\P{this}))
* \post \P{this} = insertarEntrada(r, nombre, db)
*
* \complexity{\O(T + copy(reg))}
*/
void
agregarRegistro
(
const
Registro
&
r
,
const
string
&
nombre
);
/**
* @brief Devuelve el conjunto de tablas existentes en la base.
*
* El conjunto de nombres se devuelve por referencia no-modificable.
*
* \pre true
* \post \P{res} = tablas(\P{this})
*
* \complexity{\O(1)}
*/
const
linear_set
<
string
>
&
tablas
()
const
;
/**
* @brief Devuelve la tabla asociada al nombre.
*
* La tabla se devuelve por referencia no modificable.
*
* @param nombre Nombre de la tabla buscada.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = dameTabla(nombre, \P{this})
*
* \complexity{O(T)}
*/
const
Tabla
&
dameTabla
(
const
string
&
nombre
)
const
;
/**
* @brief Devuelve la cantidad de usos que tiene un criterio
*
* @param criterio Criterio por el cual se consulta.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = usoCriterio(criterio, \P{this})
*
* \complexity{\O(#cs * cmp(Criterio))}
*/
int
uso_criterio
(
const
Criterio
&
criterio
)
const
;
/**
* @brief Evalúa si un registro puede ingresarse en la tabla parámetro.
*
* @param r Registro a ingresar en la tabla.
* @param nombre Nombre de la tabla.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = puedoInsertar?(r, dameTabla(nombre, \P{this}))
*
* \complexity{\O(T + C^2 + (c * C + c * n * (C + L)))}
*/
bool
registroValido
(
const
Registro
&
r
,
const
string
&
nombre
)
const
;
/**
* @brief Evalúa si un criterio puede aplicarse en la tabla parámetro.
*
* @param c Criterio a utilizar.
* @param nombre Nombre de la tabla.
*
* \pre tabla \IN tablas(\P{this})
* \post \P{res} = criterioValido(c, nombre, \P{this})
*
* \complexity{\O(T + cr * C)}
*/
bool
criterioValido
(
const
Criterio
&
c
,
const
string
&
nombre
)
const
;
/**
* @brief Devuelve el resultado de buscar en una tabla con un criterio.
*
* @param c Criterio de búsqueda utilizado.
* @param nombre Nombre de la tabla.
*
* \pre nombre \IN tablas(\P{this}) \LAND criterioValido(c, nombre, \P{this})
* \post \P{res} = buscar(c, nombre, \P{this})
*
* \complexity{\O(T + cs * cmp(Criterio) + cr * n * (C + L + copy(reg)))}
*/
Tabla
busqueda
(
const
Criterio
&
c
,
const
string
&
nombre
);
/**
* @brief Devuelve los criterios de máximo uso.
*
* \pre true
* \post \FORALL (c : Criterio) [c \IN \P{res} \IFF
* \FORALL (c' : Criterio) usoCriterio(c, db) >= usoCriterio(c', db)]
*
* \complexity{\O(cs * copy(Criterio))}
*/
linear_set
<
Criterio
>
top_criterios
()
const
;
/** @brief Criterio de búsqueda para una base de datos */
typedef
linear_set
<
Restriccion
>
Criterio
;
class
joinIterator
;
/**
* @brief Inicializa una base de datos sin tablas.
*
* \pre true
* \post \P{this} = nuevaDB
*
* \complexity{\O(1)}
*/
BaseDeDatos
();
/**
* @brief Crea una nueva tabla en la base de datos.
*
* @param nombre Nombre identificador de la tabla
* @param claves Claves de la tabla a crear
* @param campos Campos de la tabla a crear
* @param tipos Tipos para los campos de la tabla a crear
*
* \pre db = \P{this} \LAND
* \LNOT (nombre \IN tablas(\P{this})) \LAND
* \LAND \LNOT \EMPTYSET?(claves) \LAND
* \FORALL (c: campo) c \IN claves \IMPLICA c \IN campos \LAND
* long(campos) = long(tipos) \LAND sinRepetidos(campos)
* \post \P{this} = agregarTabla(nuevaTabla(claves, nuevoRegistro(campos, tipos)), db)
*
* \complexity{\O(C)}
*/
void
crearTabla
(
const
string
&
nombre
,
const
linear_set
<
string
>
&
claves
,
const
vector
<
string
>
&
campos
,
const
vector
<
Dato
>
&
tipos
);
/**
* @brief Agrega un registro a la tabla parámetro
*
* @param r Registro a agregar
* @param nombre Nombre de la tabla donde se agrega el registro
*
* \pre db = \P{this} \LAND nombre \IN tablas(\P{this}) \LAND
* puedoInsertar?(r, dameTabla(\P{this}))
* \post \P{this} = insertarEntrada(r, nombre, db)
*
* \complexity{\O(T + copy(reg))}
*/
void
agregarRegistro
(
const
Registro
&
r
,
const
string
&
nombre
);
/**
* @brief Devuelve el conjunto de tablas existentes en la base.
*
* El conjunto de nombres se devuelve por referencia no-modificable.
*
* \pre true
* \post \P{res} = tablas(\P{this})
*
* \complexity{\O(1)}
*/
const
linear_set
<
string
>
&
tablas
()
const
;
/**
* @brief Devuelve la tabla asociada al nombre.
*
* La tabla se devuelve por referencia no modificable.
*
* @param nombre Nombre de la tabla buscada.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = dameTabla(nombre, \P{this})
*
* \complexity{O(T)}
*/
const
Tabla
&
dameTabla
(
const
string
&
nombre
)
const
;
/**
* @brief Devuelve la cantidad de usos que tiene un criterio
*
* @param criterio Criterio por el cual se consulta.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = usoCriterio(criterio, \P{this})
*
* \complexity{\O(#cs * cmp(Criterio))}
*/
int
uso_criterio
(
const
Criterio
&
criterio
)
const
;
/**
* @brief Evalúa si un registro puede ingresarse en la tabla parámetro.
*
* @param r Registro a ingresar en la tabla.
* @param nombre Nombre de la tabla.
*
* \pre nombre \IN tablas(\P{this})
* \post \P{res} = puedoInsertar?(r, dameTabla(nombre, \P{this}))
*
* \complexity{\O(T + C^2 + (c * C + c * n * (C + L)))}
*/
bool
registroValido
(
const
Registro
&
r
,
const
string
&
nombre
)
const
;
/**
* @brief Evalúa si un criterio puede aplicarse en la tabla parámetro.
*
* @param c Criterio a utilizar.
* @param nombre Nombre de la tabla.
*
* \pre tabla \IN tablas(\P{this})
* \post \P{res} = criterioValido(c, nombre, \P{this})
*
* \complexity{\O(T + cr * C)}
*/
bool
criterioValido
(
const
Criterio
&
c
,
const
string
&
nombre
)
const
;
/**
* @brief Devuelve el resultado de buscar en una tabla con un criterio.
*
* @param c Criterio de búsqueda utilizado.
* @param nombre Nombre de la tabla.
*
* \pre nombre \IN tablas(\P{this}) \LAND criterioValido(c, nombre, \P{this})
* \post \P{res} = buscar(c, nombre, \P{this})
*
* \complexity{\O(T + cs * cmp(Criterio) + cr * n * (C + L + copy(reg)))}
*/
Tabla
busqueda
(
const
Criterio
&
c
,
const
string
&
nombre
);
/**
* @brief Devuelve los criterios de máximo uso.
*
* \pre true
* \post \FORALL (c : Criterio) [c \IN \P{res} \IFF
* \FORALL (c' : Criterio) usoCriterio(c, db) >= usoCriterio(c', db)]
*
* \complexity{\O(cs * copy(Criterio))}
*/
linear_set
<
Criterio
>
top_criterios
()
const
;
void
crearIndice
(
string
tabla
,
string
columna
);
joinIterator
join
(
string
tabla1
,
string
tabla2
,
string
columna
);
joinIterator
join_end
();
private:
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
/** \name Representación
* rep: basededatos \TO bool\n
* rep(bd) \EQUIV
...
...
@@ -226,8 +234,8 @@ private:
* nueva(campo, valor, igualdad), registros)
*/
list
<
Registro
>
&
_filtrar_registros
(
const
string
&
campo
,
const
Dato
&
valor
,
list
<
Registro
>
&
registros
,
bool
igualdad
)
const
;
list
<
Registro
>
&
registros
,
bool
igualdad
)
const
;
/**
* @brief Filtra la lista de registros parametro según el criterio.
...
...
@@ -253,6 +261,48 @@ private:
*/
pair
<
vector
<
string
>
,
vector
<
Dato
>
>
_tipos_tabla
(
const
Tabla
&
t
);
/** @} */
public:
class
joinIterator
{
public:
joinIterator
()
{
}
joinIterator
operator
++
(
int
n
)
{
return
(
*
this
);
}
joinIterator
&
operator
++
()
{
return
(
*
this
);
}
Registro
&
operator
*
()
const
{
return
*
(
new
Registro
({
"NONE"
},
{
datoStr
(
"NOT IMPLEMENTED"
)}));
}
Registro
*
operator
->
()
const
{
return
(
new
Registro
({
"NONE"
},
{
datoStr
(
"NOT IMPLEMENTED"
)}));
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
stream
,
const
joinIterator
&
it
)
{
stream
<<
"NOT IMPLEMENTED YET"
;
}
bool
operator
==
(
const
joinIterator
&
other
)
const
{
return
true
;
}
bool
operator
!=
(
const
joinIterator
&
otro
)
const
{
return
!
(
*
this
==
otro
);
}
friend
class
string_map
;
private:
};
};
#endif
This diff is collapsed.
Click to expand it.
src/string_map.h
View file @
0d231da9
...
...
@@ -4,6 +4,7 @@
#include <cassert>
#include <string>
#include <vector>
#include <ostream>
using
std
::
string
;
using
std
::
vector
;
...
...
@@ -16,7 +17,7 @@ using std::pair;
* - tiene operador == (con complejidad cmp(T))
* - solo permite utilizar el operator[] si T tiene constructor por defecto
*/
template
<
typename
T
>
template
<
typename
T
>
class
string_map
{
public:
typedef
string
key_type
;
...
...
@@ -26,52 +27,118 @@ public:
class
iterator
;
class
const_iterator
;
/** @brief Construye mapa vacio
*
* \complexity{\O(1)}
*/
string_map
();
string_map
()
{
root
=
new
Nodo
();
cantKeys
=
0
;
}
/** @brief Destruye mapa
*
* \complexity{\O(sn * S)}
*/
~
string_map
();
~
string_map
()
{
clear
();
delete
(
root
);
}
/** @brief Constructor por copia
*
* \complexity{\O(sn * S * copy(T))}
*/
string_map
(
const
string_map
&
);
string_map
(
const
string_map
&
toCopy
)
{
root
=
new
Nodo
;
cantKeys
=
0
;
for
(
const_iterator
it
=
toCopy
.
begin
();
it
!=
toCopy
.
end
();
++
it
)
{
insert
((
*
it
));
}
}
void
printAll
()
{
for
(
auto
it
=
begin
();
it
!=
end
();
++
it
)
{
auto
element
=
(
*
it
);
std
::
cout
<<
element
.
first
<<
std
::
endl
;
}
}
/** @brief Operador de asignacion
*
* \complexity{\O(sn * S * copy(T))}
*/
string_map
&
operator
=
(
const
string_map
&
);
string_map
&
operator
=
(
const
string_map
&
toCopy
)
{
root
=
new
Nodo
;
cantKeys
=
0
;
for
(
const_iterator
it
=
toCopy
.
begin
();
it
!=
toCopy
.
end
();
++
it
)
{
insert
((
*
it
));
}
return
(
*
this
);
}
/** @brief Operadores de comparacion
*
* \complexity{\O(sn * S * cmp(T))}
*/
bool
operator
==
(
const
string_map
&
otro
)
const
;
bool
operator
!=
(
const
string_map
&
otro
)
const
{
return
!
(
*
this
==
otro
);}
bool
operator
==
(
const
string_map
&
other
)
const
{
if
(
cantKeys
==
other
.
cantKeys
)
{
const_iterator
it
=
begin
();
const_iterator
itOther
=
other
.
begin
();
key_type
first
,
firstOther
;
mapped_type
second
,
secondOther
;
while
(
it
!=
end
())
{
first
=
it
->
first
;
firstOther
=
itOther
->
first
;
second
=
it
->
second
;
secondOther
=
itOther
->
second
;
if
(
first
.
compare
(
firstOther
)
!=
0
||
second
!=
secondOther
)
return
false
;
++
it
;
++
itOther
;
}
return
true
;
}
return
false
;
}
bool
operator
!=
(
const
string_map
&
otro
)
const
{
return
!
(
*
this
==
otro
);
}
/** @brief Cantidad de apariciones de la clave (0 o 1)
* @param key clave a buscar
*
* \complexity{\O(S)}
*/
size_type
count
(
const
key_type
&
key
)
const
;
size_type
count
(
const
key_type
&
key
)
const
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
if
(
tmp
->
children
[
it
-
FIRST_CHAR
]
==
NULL
)
{
return
0
;
}
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
return
static_cast
<
size_type
>
(
tmp
->
isEndOfWord
);
}
/** @brief Devuelve cantidad de claves definidas */
size_t
size
()
const
;
size_t
size
()
const
{
return
cantKeys
;
}
/** @brief devuelve true si size() == 0 */
bool
empty
()
const
;
bool
empty
()
const
{
return
size
()
==
0
;
}
/** @brief Acceso / definición de pares clave/valor
...
...
@@ -79,11 +146,28 @@ public:
* @returns una referencia a la definicion.
*
* \complexity{
* * \O(S) si la clave esta definida
* * \O(S) si la clave esta definida
* * \O(S) + copy(T) sino
* }
*/
mapped_type
&
operator
[](
const
key_type
&
key
);
mapped_type
&
operator
[](
const
key_type
&
key
)
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
auto
letterPosition
=
static_cast
<
size_type
>
(
it
-
FIRST_CHAR
);
if
(
tmp
->
children
[
letterPosition
]
==
NULL
)
{
tmp
->
children
[
letterPosition
]
=
new
Nodo
();
tmp
->
children
[
letterPosition
]
->
parent
=
tmp
;
}
tmp
=
tmp
->
children
[
letterPosition
];
}
if
(
!
(
tmp
->
isEndOfWord
))
{
tmp
->
isEndOfWord
=
true
;
tmp
->
value
=
new
mapped_type
();
++
cantKeys
;
}
return
*
(
tmp
->
value
);
}
/** @brief Acceso a una clave sin modificar mapa
* @param key clave a acceder que debe existir previamente
...
...
@@ -91,18 +175,42 @@ public:
*
* \complexity{\O(S)}
*/
mapped_type
&
at
(
const
key_type
&
key
);
mapped_type
&
at
(
const
key_type
&
key
)
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
return
*
(
tmp
->
value
);
}
/** @brief Acceso a una clave sin modificar mapa
* @param key clave a acceder que debe existir previamente
* @returns una referencia const a la definicion.
*
* \complexity{\O(S)}
*/
const
mapped_type
&
at
(
const
key_type
&
key
)
const
;
*/
const
mapped_type
&
at
(
const
key_type
&
key
)
const
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
return
*
(
tmp
->
value
);
}
/** @brief Vacia el mapa */
void
clear
();
void
clear
()
{
auto
tmp
=
begin
();
for
(;
tmp
!=
end
();)
{
std
::
cout
<<
"VOY A BORRAR "
<<
tmp
<<
std
::
endl
;
tmp
=
erase
(
tmp
);
}
if
(
root
->
isEndOfWord
)
{
root
->
isEndOfWord
=
false
;
--
cantKeys
;
}
}
// Accesos con iteradores
...
...
@@ -111,19 +219,34 @@ public:
*
* \complexity{\O(S)}
*/
iterator
begin
();
iterator
begin
()
{
return
iterator
(
this
->
root
);
}
/* @brief iterador al fin de la coleccion
*
* \complexity{\O(S)}
*/
iterator
end
();
iterator
end
()
{
return
iterator
(
this
->
root
,
""
);
}
/// Versiones const de begin/end
const_iterator
begin
()
const
;
const_iterator
end
()
const
;
const_iterator
cbegin
()
const
;
const_iterator
cend
()
const
;
const_iterator
begin
()
const
{
return
const_iterator
(
this
->
root
);
}
const_iterator
end
()
const
{
return
const_iterator
(
this
->
root
,
""
);
}
const_iterator
cbegin
()
const
{
return
const_iterator
(
this
->
root
);
}
const_iterator
cend
()
const
{
return
const_iterator
(
NULL
);
}
/** @brief busca una clave
* @param key clave a buscar
...
...
@@ -131,7 +254,14 @@ public:
*
* \complexity{\O(S)}
*/
iterator
find
(
const
key_type
&
key
);
iterator
find
(
const
key_type
&
key
)
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
return
iterator
(
tmp
,
key
);
}
/** @brief busca una clave
* @param key clave a buscar
...
...
@@ -139,7 +269,14 @@ public:
*
* \complexity{\O(S)}
*/
const_iterator
find
(
const
key_type
&
key
)
const
;
const_iterator
find
(
const
key_type
&
key
)
const
{
auto
tmp
=
root
;
for
(
auto
it
:
key
)
{
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
return
const_iterator
(
tmp
,
key
);
}
/** @brief insercion
*
...
...
@@ -150,7 +287,28 @@ public:
*
* \complexity{\O(S + copy(T))}
*/
pair
<
iterator
,
bool
>
insert
(
const
value_type
&
value
);
pair
<
iterator
,
bool
>
insert
(
const
value_type
&
value
)
{
auto
tmp
=
root
;
bool
isInserted
=
false
;
for
(
auto
it
:
value
.
first
)
{
if
(
tmp
->
children
[
it
-
FIRST_CHAR
]
==
NULL
)
{
tmp
->
children
[
it
-
FIRST_CHAR
]
=
new
Nodo
();
tmp
->
children
[
it
-
FIRST_CHAR
]
->
parent
=
tmp
;
}
tmp
=
tmp
->
children
[
it
-
FIRST_CHAR
];
}
if
(
!
(
tmp
->
isEndOfWord
))
{
tmp
->
isEndOfWord
=
true
;
++
cantKeys
;
isInserted
=
true
;
}
tmp
->
value
=
new
mapped_type
(
value
.
second
);
iterator
it
=
iterator
(
tmp
,
value
.
first
);
return
pair
<
iterator
,
bool
>
(
it
,
isInserted
);
};
/** @brief eliminar una clave
* @param key clave a eliminar
...
...
@@ -158,7 +316,14 @@ public:
*
* \complexity{\O(S)}
*/
size_type
erase
(
const
key_type
&
key
);
size_type
erase
(
const
key_type
&
key
)
{
if
(
count
(
key
))
{
find
(
key
).
erase
();
--
cantKeys
;
return
1
;
}
return
0
;
}
/** @brief eliminar una clave mediante irerador
* @param pos iterador apuntando a clave a eliminar
...
...
@@ -166,9 +331,340 @@ public:
*
* \complexity{\O(S)}
*/
iterator
erase
(
iterator
pos
);
iterator
erase
(
iterator
pos
)
{
--
cantKeys
;
return
pos
.
erase
();
}
private:
static
const
int
ALPHABET_SIZE
=
94
;
static
const
char
FIRST_CHAR
=
' '
;
unsigned
int
cantKeys
;
struct
Nodo
{
Nodo
*
children
[
ALPHABET_SIZE
];
Nodo
*
parent
;
T
*
value
;
bool
isEndOfWord
;
Nodo
()
{
isEndOfWord
=
false
;
parent
=
NULL
;
for
(
int
i
=
0
;
i
<
ALPHABET_SIZE
;
i
++
)
{
children
[
i
]
=
NULL
;
}
value
=
NULL
;
}
};
Nodo
*
root
;
public:
class
const_iterator
{
public:
const_iterator
(
Nodo
*
root
)
{
auto
tmp
=
root
;
actual
=
findLeftestWord
(
tmp
);
}
const_iterator
(
Nodo
*
root
,
key_type
str
)
{
actual
=
root
;
printUtilVector
=
std
::
vector
<
char
>
(
str
.
begin
(),
str
.
end
());
}
const_iterator
&
operator
=
(
const
const_iterator
&
other
)
{
this
->
printUtilVector
=
other
.
printUtilVector
;
this
->
actual
=
other
.
actual
;
return
(
*
this
);
}
bool
operator
==
(
const
const_iterator
&
other
)
const
{
bool
isSameActual
=
this
->
actual
==
other
.
actual
;
bool
isSamePrintUtilVector
=
this
->
printUtilVector
==
other
.
printUtilVector
;
return
isSameActual
&&
isSamePrintUtilVector
;
}
bool
operator
!=
(
const
const_iterator
&
otro
)
const
{
return
!
(
*
this
==
otro
);
}
const
const_iterator
&
operator
++
()
{
if
(
actual
->
parent
==
NULL
)
{
return
(
*
this
);
}
actual
=
actual
->
parent
;
char
last
;
last
=
printUtilVector
.
back
();
printUtilVector
.
pop_back
();
int
leftOne
=
leftestOne
(
actual
,
static_cast
<
char
>
(
last
+
1
));
if
(
leftOne
==
-
1
)
{
if
(
actual
->
isEndOfWord
)
{
return
(
*
this
);
}
// recursion
return
++
(
*
this
);
}
printUtilVector
.
push_back
(
FIRST_CHAR
+
leftOne
);
actual
=
findLeftestWord
(
actual
->
children
[
leftOne
]);
return
(
*
this
);
}
const
const_iterator
operator
++
(
int
n
)
{
const_iterator
final
=
NULL
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
final
=
++
(
*
this
);
}
return
final
;
}
const_iterator
erase
()
{
if
(
leftestOne
(
actual
,
FIRST_CHAR
)
!=
-
1
)
{
actual
->
isEndOfWord
=
false
;
return
++
(
*
this
);
}
char
last
;
Nodo
*
tmp
;
while
(
true
)
{
tmp
=
actual
->
parent
;
// llegue al final
if
(
tmp
==
NULL
)
{
return
(
*
this
);
}
//borro y me quedo con el ultimo char y cambio actual y popeo
last
=
printUtilVector
.
back
();
printUtilVector
.
pop_back
();
delete
(
actual
);
actual
=
tmp
;
actual
->
children
[
last
-
FIRST_CHAR
]
=
NULL
;
if
(
actual
->
isEndOfWord
)
{
return
(
*
this
);
}
auto
leftOne
=
leftestOne
(
actual
,
last
);
if
(
leftOne
!=
-
1
)
{
actual
=
actual
->
children
[
leftOne
];
printUtilVector
.
push_back
(
leftOne
+
FIRST_CHAR
);
return
findLeftestWord
(
actual
);
}
}
}
value_type
&
operator
*
()
const
{
key_type
key
=
key_type
(
printUtilVector
.
begin
(),
printUtilVector
.
end
());
mapped_type
value
=
*
(
actual
->
value
);
auto
*
pair
=
new
value_type
(
key
,
value
);
return
*
pair
;
}
value_type
*
operator
->
()
const
{
key_type
key
=
key_type
(
printUtilVector
.
begin
(),
printUtilVector
.
end
());
mapped_type
value
=
*
(
actual
->
value
);
auto
*
pair
=
new
value_type
(
key
,
value
);
return
pair
;
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
stream
,
const
const_iterator
&
it
)
{
if
(
it
.
actual
->
parent
!=
NULL
)
{
stream
<<
"primero: "
<<
it
->
first
;
}
else
stream
<<
"es el fin"
;
return
stream
;
}
friend
class
string_map
;
private:
Nodo
*
actual
;
std
::
vector
<
char
>
printUtilVector
;
Nodo
*
findLeftestWord
(
Nodo
*
tmp
)
{
int
leftOne
=
0
;
while
(
tmp
!=
NULL
&&
leftOne
!=
-
1
)
{
leftOne
=
leftestOne
(
tmp
,
FIRST_CHAR
);
if
(
leftOne
!=
-
1
)
{
printUtilVector
.
push_back
(
static_cast
<
char
&&>
(
FIRST_CHAR
+
leftOne
));
tmp
=
tmp
->
children
[
leftOne
];
}
}
return
tmp
;
}
int
leftestOne
(
Nodo
*
tmp
,
char
last
)
{
for
(
int
i
=
last
-
FIRST_CHAR
;
i
<
ALPHABET_SIZE
;
i
++
)
{
if
((
tmp
->
children
[
i
])
!=
NULL
)
return
i
;
}
return
-
1
;
}
};
class
iterator
{
public:
iterator
(
Nodo
*
root
)
{
auto
tmp
=
root
;
actual
=
findLeftestWord
(
tmp
);
}
iterator
(
Nodo
*
root
,
key_type
str
)
{
actual
=
root
;
printUtilVector
=
std
::
vector
<
char
>
(
str
.
begin
(),
str
.
end
());
}
iterator
&
operator
=
(
const
iterator
&
other
)
{
this
->
printUtilVector
=
other
.
printUtilVector
;
this
->
actual
=
other
.
actual
;
return
(
*
this
);
}
bool
operator
==
(
const
iterator
&
other
)
const
{
bool
isSameActual
=
this
->
actual
==
other
.
actual
;
bool
isSamePrintUtilVector
=
this
->
printUtilVector
==
other
.
printUtilVector
;
return
isSameActual
&&
isSamePrintUtilVector
;
}
bool
operator
!=
(
const
iterator
&
otro
)
const
{
return
!
(
*
this
==
otro
);
}
iterator
&
operator
++
()
{
if
(
actual
->
parent
==
NULL
)
{
return
(
*
this
);
}
actual
=
actual
->
parent
;
char
last
;
last
=
printUtilVector
.
back
();
printUtilVector
.
pop_back
();
int
leftOne
=
leftestOne
(
actual
,
static_cast
<
char
>
(
last
+
1
));
if
(
leftOne
==
-
1
)
{
if
(
actual
->
isEndOfWord
)
{
return
(
*
this
);
}
// recursion
return
++
(
*
this
);
}
printUtilVector
.
push_back
(
FIRST_CHAR
+
leftOne
);
actual
=
findLeftestWord
(
actual
->
children
[
leftOne
]);
return
(
*
this
);
}
iterator
operator
++
(
int
n
)
{
iterator
final
=
NULL
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
final
=
++
(
*
this
);
}
return
final
;
}
iterator
erase
()
{
if
(
leftestOne
(
actual
,
FIRST_CHAR
)
!=
-
1
)
{
actual
->
isEndOfWord
=
false
;
return
++
(
*
this
);
}
char
last
;
Nodo
*
tmp
;
while
(
true
)
{
tmp
=
actual
->
parent
;
// llegue al final
if
(
tmp
==
NULL
)
{
return
(
*
this
);
}
//borro y me quedo con el ultimo char y cambio actual y popeo
last
=
printUtilVector
.
back
();
printUtilVector
.
pop_back
();
delete
(
actual
->
value
);
delete
(
actual
);
actual
=
tmp
;
actual
->
children
[
last
-
FIRST_CHAR
]
=
NULL
;
if
(
actual
->
isEndOfWord
)
{
return
(
*
this
);
}
auto
leftOne
=
leftestOne
(
actual
,
last
);
if
(
leftOne
!=
-
1
)
{
actual
=
actual
->
children
[
leftOne
];
printUtilVector
.
push_back
(
leftOne
+
FIRST_CHAR
);
actual
=
findLeftestWord
(
actual
);
return
(
*
this
);
}
}
}
value_type
&
operator
*
()
const
{
key_type
key
=
key_type
(
printUtilVector
.
begin
(),
printUtilVector
.
end
());
mapped_type
value
=
*
(
actual
->
value
);
auto
*
pair
=
new
value_type
(
key
,
value
);
return
*
pair
;
}
value_type
*
operator
->
()
const
{
key_type
key
=
key_type
(
printUtilVector
.
begin
(),
printUtilVector
.
end
());
mapped_type
value
=
*
(
actual
->
value
);
auto
*
pair
=
new
value_type
(
key
,
value
);
return
pair
;
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
stream
,
const
iterator
&
it
)
{
if
(
it
.
actual
->
parent
!=
NULL
)
{
stream
<<
"primero: "
<<
it
->
first
;
}
else
stream
<<
"es el fin"
;
return
stream
;
}
friend
class
string_map
;
private:
Nodo
*
actual
;
std
::
vector
<
char
>
printUtilVector
;
Nodo
*
findLeftestWord
(
Nodo
*
tmp
)
{
int
leftOne
=
0
;
while
(
tmp
!=
NULL
&&
leftOne
!=
-
1
)
{
leftOne
=
leftestOne
(
tmp
,
FIRST_CHAR
);
if
(
leftOne
!=
-
1
)
{
printUtilVector
.
push_back
(
static_cast
<
char
&&>
(
FIRST_CHAR
+
leftOne
));
tmp
=
tmp
->
children
[
leftOne
];
}
}
return
tmp
;
}
int
leftestOne
(
Nodo
*
tmp
,
char
last
)
{
for
(
int
i
=
last
-
FIRST_CHAR
;
i
<
ALPHABET_SIZE
;
i
++
)
{
if
((
tmp
->
children
[
i
])
!=
NULL
)
return
i
;
}
return
-
1
;
}
};
};
...
...
This diff is collapsed.
Click to expand it.
tests/base_de_datos_test.cpp
View file @
0d231da9
...
...
@@ -693,7 +693,7 @@ TEST_F(DBAlumnos, crit_doble_otro_bool) {
TEST_F
(
DBAlumnos
,
join_vacio
)
{
db
.
crearIndice
(
"alumnos"
,
"LU"
);
auto
begin
=
db
.
join
(
"alumnos"
,
"ex_alumnos"
,
"LU"
);
auto
end
=
db
.
join_end
();
auto
end
=
db
.
join_end
();
EXPECT_EQ
(
begin
,
end
);
}
...
...
@@ -756,15 +756,15 @@ TEST_F(DBAlumnos, join_repetidos_ambos) {
db2
.
agregarRegistro
(
Registro
({
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
"B"
)}),
"T2"
);
db2
.
agregarRegistro
(
Registro
({
"Y"
,
"Z"
},
{
Dato
(
2
),
Dato
(
"C"
)}),
"T2"
);
Tabla
t_join
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
Tabla
t_join
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
{
tipoNat
,
tipoNat
,
tipoStr
});
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
1
),
Dato
(
"A"
)}));
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
1
),
Dato
(
"B"
)}));
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
2
),
Dato
(
2
),
Dato
(
"C"
)}));
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
3
),
Dato
(
2
),
Dato
(
"C"
)}));
db2
.
crearIndice
(
"T1"
,
"Y"
);
...
...
@@ -784,44 +784,44 @@ TEST_F(DBAlumnos, join_repetidos_ambos) {
TEST_F
(
DBAlumnos
,
join_campos_repetidos
)
{
BaseDeDatos
db2
;
db2
.
crearTabla
(
"T1"
,
{
"X"
,
"Y"
},
{
"X"
,
"Y"
},
{
tipoNat
,
tipoNat
});
db2
.
crearTabla
(
"T2"
,
{
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
db2
.
crearTabla
(
"T2"
,
{
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
{
tipoNat
,
tipoNat
,
tipoStr
});
/*
* T1 T2
* | X | Y | | X | Y | Z |
* | X | Y | | X | Y | Z |
* | 1 | 1 | | 1 | 1 | A |
* | 2 | 2 | | 3 | 2 | C |
* | 2 | 2 | | 3 | 2 | C |
*
* T1 ~ T2 (Y)
* | X | Y | Z |
* | 1 | 1 | A |
* | 2 | 2 | C |
*
*
* T2 ~ T1 (Y)
* | X | Y | Z |
* | 1 | 1 | A |
* | 3 | 2 | C |
*
*
*/
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
},
{
Dato
(
1
),
Dato
(
1
)}),
"T1"
);
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
},
{
Dato
(
2
),
Dato
(
2
)}),
"T1"
);
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
1
),
Dato
(
"A"
)}),
"T2"
);
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
db2
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
3
),
Dato
(
2
),
Dato
(
"C"
)}),
"T2"
);
Tabla
t_join_a
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
Tabla
t_join_a
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
{
tipoNat
,
tipoNat
,
tipoStr
});
t_join_a
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join_a
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
1
),
Dato
(
"A"
)}));
t_join_a
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join_a
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
2
),
Dato
(
2
),
Dato
(
"C"
)}));
Tabla
t_join_b
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
Tabla
t_join_b
=
Tabla
({
"X"
,
"Y"
,
"Z"
},
{
"X"
,
"Y"
,
"Z"
},
{
tipoNat
,
tipoNat
,
tipoStr
});
t_join_b
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join_b
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
1
),
Dato
(
1
),
Dato
(
"A"
)}));
t_join_b
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
t_join_b
.
agregarRegistro
(
Registro
({
"X"
,
"Y"
,
"Z"
},
{
Dato
(
3
),
Dato
(
2
),
Dato
(
"C"
)}));
db2
.
crearIndice
(
"T1"
,
"X"
);
...
...
@@ -832,7 +832,7 @@ TEST_F(DBAlumnos, join_campos_repetidos) {
linear_set
<
Registro
>
join
(
begin
,
end
);
EXPECT_EQ
(
join
,
t_join_a
.
registros
());
begin
=
db2
.
join
(
"T2"
,
"T1"
,
"Y"
);
end
=
db2
.
join_end
();
...
...
This diff is collapsed.
Click to expand it.
tests/string_map_test.cpp
View file @
0d231da9
...
...
@@ -69,6 +69,7 @@ TEST(string_map_test, test_comparar) {
EXPECT_FALSE
(
m1
==
m2
);
}
TEST
(
string_map_test
,
test_copiar
)
{
string_map
<
int
>
m1
;
m1
[
"hola"
]
=
123
;
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment