Esta página de ejercicios está en elaboración.
Para facilitar la realización de los ejercicios, se proporcionan unas plantillas de los ejercicios Bases de datos (3 C) (Bases de datos).
Para ayudarle en la realización de estos ejercicios puede consultar una página de comentarios con fragmentos de código.
Puede descargar unas posibles soluciones completas de estos ejercicios.
Esta aplicación es la aplicación que se puede utilizar de base para el resto de ejercicios (es idéntica al ejercicio Bases de datos (3) 5).
Implemente estas mejoras en la aplicación:
Añadir a la aplicación del ejercicio 1 la posibilidad de trabajar con una sistema gestor de bases de datos distinto, por ejemplo PostgreSQL.
En PostgreSQL para realizar la conexión se deben proporcionar cinco parámetros (host, puerto, base de datos, usuario y contraseña).
// Configuración para PostgreSQL
$cfg["pgsqlHost"] = "localhost"; // Nombre de host
$cfg["pgsqlPort"] = "5432"; // Número de puerto
$cfg["pgsqlDatabase"] = "iaw"; // Nombre de la base de datos
$cfg["pgsqlUser"] = "iaw"; // Nombre de usuario
$cfg["pgsqlPassword"] = ""; // Contraseña de usuario
En PostgreSQL, cuando nos conectamos a la base de datos nos conectamos con alguna base de datos ya existente. Esa base de datos no la podemos borrar puesto que es la base de datos activa y la que nos permite estar conectados. Por eso la función borraTodo() para PostgreSQL es como la función borraTodo() para SQLite, que borra y crea las tablas, y no como la función borraTodo() para MySQL, que borra y crea la base de datos.
Esta puede ser la función de conexión para PostgreSQL:
// POSTGRESQL: Conexión con la base de datos
function conectaDb()
{
global $cfg;
try {
$tmp = new PDO("pgsql:host=$cfg[pgsqlHost];port=$cfg[pgsqlPort];dbname=$cfg[pgsqlDatabase];user=$cfg[pgsqlUser];password=$cfg[pgsqlPassword]");
$tmp->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
return $tmp;
} catch (PDOException $e) {
print " <p class=\"aviso\">Error: No puede conectarse con la base de datos. {$e->getMessage()}</p>\n";
exit;
}
}
Nota: El DSN para PostgreSQL permite indicar el servidor en el que se encuentra la base de datos, su puerto, el nombre de la base de datos, el nombre de usuario de la base de datos y su contraseña.
Para crear un campo autonumérico en PostgreSQL, se suele utilizar el pseudo-tipo SERIAL, como muestra el siguiente ejemplo:
// POSTGRESQL: Borrado y creación de tablas
$consulta = "CREATE TABLE $cfg[tablaUsuarios] (
id SERIAL,
usuario VARCHAR($cfg[tablaUsuariosTamUsuario]),
password VARCHAR($cfg[tablaUsuariosTamPassword]),
nivel INTEGER NOT NULL,
PRIMARY KEY(id)
)";
La consulta para comprobar la existencia de una tabla en PostgreSQL sería la siguiente:
// POSTGRESQL: Comprobación de existencia de las tablas
$consulta = "SELECT COUNT(*) FROM information_schema.tables WHERE table_name='$tabla'";
Para que después de insertar los registros de prueba, el contador autonumérico de las claves principales se actualice, realice las siguientes consultas:
if ($cfg["dbMotor"] == POSTGRESQL) {
foreach ($cfg["dbTablas"] as $tabla) {
$consulta = "SELECT setval(pg_get_serial_sequence('$tabla', 'id'), coalesce(max(id),0) + 1, false) FROM $tabla";
$resultado = $pdo->query($consulta);
if (!$resultado) {
print " <p class=\"aviso\">Error al ejecutar la consulta. SQLSTATE[{$pdo->errorCode()}]: {$pdo->errorInfo()[2]}</p>\n";
} else {
print " <p>Contador autonumérico restablecido.</p>\n";
print "\n";
}
}
}
Modifique la aplicación de la aplicación de ejemplo de manera que cada usuario básico de la aplicación sólo pueda trabajar con sus propios registros de Personas (listar, borrar, buscar, modificar).
// SQLITE:
$consulta = "CREATE TABLE $cfg[tablaPersonas] (
id INTEGER PRIMARY KEY,
nombre VARCHAR($cfg[tablaPersonasTamNombre]) COLLATE NOCASE,
apellidos VARCHAR($cfg[tablaPersonasTamApellidos]) COLLATE NOCASE,
telefono VARCHAR($cfg[tablaPersonasTamTelefono]) COLLATE NOCASE,
correo VARCHAR($cfg[tablaPersonasTamCorreo]) COLLATE NOCASE,
id_usuario INTEGER,
FOREIGN KEY(id_usuario) REFERENCES $cfg[tablaUsuarios](id) ON DELETE CASCADE ON UPDATE CASCADE
)";
// MYSQL:
$consulta = "CREATE TABLE $cfg[tablaPersonas] (
id INTEGER UNSIGNED AUTO_INCREMENT,
nombre VARCHAR($cfg[tablaPersonasTamNombre]),
apellidos VARCHAR($cfg[tablaPersonasTamApellidos]),
telefono VARCHAR($cfg[tablaPersonasTamTelefono]),
correo VARCHAR($cfg[tablaPersonasTamCorreo]),
id_usuario INTEGER UNSIGNED,
FOREIGN KEY(id_usuario) REFERENCES $cfg[tablaUsuarios](id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(id)
)";
$_SESSION["id_usuario"] = $registro["id"];
Basta con añadir en las consultas la condición de que el campo de usuario (que indica el usuario que creó el registro) coincide con el usuario conectado. Por ejemplo:
$consulta = "SELECT * FROM $cfg[tablaPersonas]
WHERE id_usuario = $_SESSION[id_usuario]
ORDER BY $ordena";
Las consultas deberá ser diferentes en función del nivel del usuario conectado. Si el nivel es administrador, las consultas deberán combinar la tabla Personas con la tabla Usuarios para mostrar el nombre de usuario del usuario que creó el registro. Por ejemplo:
if ($_SESSION["nivel"] == NIVEL_ADMINISTRADOR) {
$consulta = "SELECT
personas.id,
personas.nombre,
personas.apellidos,
personas.correo,
personas.telefono,
usuarios.usuario
FROM $cfg[tablaPersonas] as personas
JOIN $cfg[tablaUsuarios] as usuarios
ON personas.id_usuario = usuarios.id
ORDER BY $ordena";
} else {
$consulta = "SELECT * FROM $cfg[tablaPersonas]
WHERE id_usuario = $_SESSION[id_usuario]
ORDER BY $ordena";
}
La columna Usuario se mostrará cuando el nivel del usuario conectado sea el nivel administrador.
if ($_SESSION["nivel"] == NIVEL_ADMINISTRADOR) {
print " <th>\n";
print " <button name=\"ordena\" value=\"usuario ASC\" class=\"boton-invisible\">\n";
print " <img src=\"../../img/abajo.svg\" alt=\"A-Z\" title=\"A-Z\" width=\"15\" height=\"12\">\n";
print " </button>\n";
print " Usuario\n";
print " <button name=\"ordena\" value=\"usuario DESC\" class=\"boton-invisible\">\n";
print " <img src=\"../../img/arriba.svg\" alt=\"Z-A\" title=\"Z-A\" width=\"15\" height=\"12\">\n";
print " </button>\n";
print " </th>\n";
}
...
if ($_SESSION["nivel"] == NIVEL_ADMINISTRADOR) {
print " <td>$registro[usuario]</td>\n";
}
Modifique la aplicación del ejercicio anterior.
Modifique la aplicación de ejemplo, añadiendo un campo de tipo fecha en la tabla Personas, por ejemplo para guardar la fecha de nacimiento de la persona.
if ($nacido == "") {
$nacido = "0000-00-00";
$nacidoOk = true;
} elseif (!compruebaFecha($nacido)) {
print " <p class=\"aviso\">La fecha no es correcta.</p>\n";
print "\n";
} else {
$nacidoOk = true;
}
function compruebaFecha($fecha)
{
if (strlen($fecha) != 10) {
return false;
}
return checkdate(substr($fecha, 5, 2), substr($fecha, 8, 2), substr($fecha, 0, 4));
}