H. Carpeta « srv / bd »

Versión para imprimir.

1. srv / bd / bdCrea.php

1<?php
2
3function bdCrea(PDO $con)
4{
5 $con->exec(
6 'CREATE TABLE IF NOT EXISTS ARCHIVO (
7 ARCH_ID INTEGER,
8 ARCH_BYTES BLOB NOT NULL,
9 CONSTRAINT ARCH_PK
10 PRIMARY KEY(ARCH_ID)
11 )'
12 );
13 $con->exec(
14 'CREATE TABLE IF NOT EXISTS PRODUCTO (
15 PROD_ID INTEGER,
16 PROD_NOMBRE TEXT NOT NULL,
17 ARCH_ID INTEGER NOT NULL,
18 CONSTRAINT PROD_PK
19 PRIMARY KEY(PROD_ID),
20 CONSTRAINT PROD_NOM_UNQ
21 UNIQUE(PROD_NOMBRE)
22 CONSTRAINT PROD_ARCH_FK
23 FOREIGN KEY (ARCH_ID) REFERENCES ARCHIVO(ARCH_ID)
24 )'
25 );
26}
27

2. srv / bd / Bd.php

1<?php
2
3require_once __DIR__ . "/bdCrea.php";
4
5class Bd
6{
7
8 private static ?PDO $conexion = null;
9
10 static function getConexion(): PDO
11 {
12 if (self::$conexion === null) {
13
14 self::$conexion = new PDO(
15 // cadena de conexión
16 "sqlite:srvarchivos.db",
17 // usuario
18 null,
19 // contraseña
20 null,
21 // Opciones: conexiones persistentes y lanza excepciones.
22 [PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
23 );
24
25 bdCrea(self::$conexion);
26 }
27
28 return self::$conexion;
29 }
30}
31

3. srv / bd / archivoAgrega.php

1<?php
2
3require_once __DIR__ . "/../modelo/Archivo.php";
4require_once __DIR__ . "/Bd.php";
5
6function archivoAgrega(Archivo $modelo)
7{
8 $modelo->valida();
9 $con = Bd::getConexion();
10 $stmt = $con->prepare(
11 "INSERT INTO ARCHIVO
12 (ARCH_BYTES)
13 VALUES
14 (:bytes)"
15 );
16 $stmt->execute([
17 ":bytes" => $modelo->bytes
18 ]);
19 /* Si usas una secuencia para generar el id,
20 * pasa como parámetro de lastInsertId el
21 * nombre de dicha secuencia, debes
22 * ejecutarlo antes del INSERT y pasarle el
23 * id generado al SQL. */
24 $modelo->id = $con->lastInsertId();
25}
26

4. srv / bd / archivoBusca.php

1<?php
2
3require_once __DIR__ . "/../modelo/Archivo.php";
4require_once __DIR__ . "/Bd.php";
5
6function archivoBusca(int $id): false|Archivo
7{
8 $con = Bd::getConexion();
9 $stmt = $con->prepare(
10 "SELECT
11 ARCH_ID AS id,
12 ARCH_BYTES AS bytes
13 FROM ARCHIVO
14 WHERE ARCH_ID = :id"
15 );
16 $stmt->execute([":id" => $id]);
17 $stmt->setFetchMode(
18 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,
19 Archivo::class
20 );
21 return $stmt->fetch();
22}
23

5. srv / bd / archivoElimina.php

1<?php
2
3require_once __DIR__ . "/Bd.php";
4
5function archivoElimina(int $id)
6{
7 $con = Bd::getConexion();
8 $stmt = $con->prepare(
9 "DELETE FROM ARCHIVO
10 WHERE ARCH_ID = :id"
11 );
12 $stmt->execute([":id" => $id]);
13}
14

6. srv / bd / archivoModifica.php

1<?php
2
3require_once __DIR__ . "/../modelo/Archivo.php";
4require_once __DIR__ . "/Bd.php";
5
6function archivoModifica(Archivo $modelo)
7{
8 $modelo->valida();
9 $con = Bd::getConexion();
10 $stmt = $con->prepare(
11 "UPDATE ARCHIVO
12 SET ARCH_BYTES = :bytes
13 WHERE ARCH_ID = :id"
14 );
15 $stmt->execute([
16 ":bytes" => $modelo->bytes,
17 ":id" => $modelo->id
18 ]);
19}
20

7. srv / bd / productoAgrega.php

1<?php
2
3require_once __DIR__ . "/../modelo/Archivo.php";
4require_once __DIR__ . "/Bd.php";
5require_once __DIR__ . "/archivoAgrega.php";
6
7function productoAgrega(Producto $modelo)
8{
9 $modelo->validaNuevo();
10 $con = Bd::getConexion();
11 $con->beginTransaction();
12 archivoAgrega($modelo->archivo);
13 $stmt = $con->prepare(
14 "INSERT INTO PRODUCTO
15 (PROD_NOMBRE, ARCH_ID)
16 VALUES
17 (:nombre, :archId)"
18 );
19 $stmt->execute([
20 ":nombre" => $modelo->nombre,
21 ":archId" => $modelo->archivo->id
22 ]);
23 /* Si usas una secuencia para generar el id,
24 * pasa como parámetro de lastInsertId el
25 * nombre de dicha secuencia, debes
26 * ejecutarlo antes del INSERT y pasarle el
27 * id generado al SQL. */
28 $modelo->id = $con->lastInsertId();
29 $con->commit();
30}
31

8. srv / bd / productoBusca.php

1<?php
2
3require_once __DIR__ . "/../modelo/Archivo.php";
4require_once __DIR__ . "/../modelo/Producto.php";
5require_once __DIR__ . "/Bd.php";
6
7function productoBusca(int $prodId)
8{
9 $con = Bd::getConexion();
10 $stmt = $con->prepare(
11 "SELECT
12 P.PROD_ID AS prodId,
13 P.PROD_NOMBRE AS prodNombre,
14 A.ARCH_ID AS archId
15 FROM PRODUCTO P
16 LEFT JOIN ARCHIVO A
17 ON P.ARCH_ID = A.ARCH_ID
18 WHERE P.PROD_ID = :prodId"
19 );
20 $stmt->execute([
21 ":prodId" => $prodId
22 ]);
23 $stmt->setFetchMode(PDO::FETCH_OBJ);
24 $obj = $stmt->fetch();
25 if ($obj === false) {
26 return false;
27 } else {
28 $id = $obj->prodId;
29 $nombre = $obj->prodNombre;
30 $archId = $obj->archId;
31 $archivo = $archId === null ? null : new Archivo(id: $archId);
32 $producto = new Producto(
33 id: $id,
34 nombre: $nombre,
35 archivo: $archivo
36 );
37 return $producto;
38 }
39}
40

9. srv / bd / productoConsulta.php

1<?php
2
3require_once __DIR__ . "/../../lib/php/recibeFetchAll.php";
4require_once __DIR__ . "/../modelo/Producto.php";
5require_once __DIR__ . "/Bd.php";
6
7function productoConsulta()
8{
9 $con = Bd::getConexion();
10 $stmt = $con->query(
11 "SELECT
12 P.PROD_ID AS prodId,
13 P.PROD_NOMBRE AS prodNombre,
14 A.ARCH_ID AS archId
15 FROM PRODUCTO P
16 LEFT JOIN ARCHIVO A
17 ON P.ARCH_ID = A.ARCH_ID
18 ORDER BY P.PROD_NOMBRE"
19 );
20 $resultado = $stmt->fetchAll(PDO::FETCH_OBJ);
21 return recibeFetchAll($resultado);
22}
23

10. srv / bd / productoElimina.php

1<?php
2
3require_once __DIR__ . "/Bd.php";
4require_once __DIR__ . "/archivoElimina.php";
5require_once __DIR__ . "/productoBusca.php";
6
7function productoElimina(int $id)
8{
9 $con = Bd::getConexion();
10 $con->beginTransaction();
11 $modelo = productoBusca($id);
12 if ($modelo === false) {
13 $con->rollBack();
14 } else {
15 archivoElimina($modelo->archivo->id);
16 $stmt = $con->prepare(
17 "DELETE FROM PRODUCTO
18 WHERE PROD_ID = :id"
19 );
20 $stmt->execute([":id" => $modelo->id]);
21 $con->commit();
22 }
23}
24

11. srv / bd / productoModifica.php

1<?php
2
3require_once __DIR__ . "/../modelo/Producto.php";
4require_once __DIR__ . "/Bd.php";
5require_once __DIR__ . "/productoBusca.php";
6require_once __DIR__ . "/archivoModifica.php";
7
8function productoModifica(Producto $modelo)
9{
10 $modelo->valida();
11 $con = Bd::getConexion();
12 $con->beginTransaction();
13 $archivo = $modelo->archivo;
14 $anterior = productoBusca($modelo->id);
15 if ($anterior === false) {
16 throw new Exception("Producto no encontrado.");
17 }
18 if ($anterior->archivo === null) {
19 throw new Exception("Falta el archivo anterior.");
20 }
21 if ($archivo === null) {
22 $archivo = $anterior->archivo;
23 $modelo->archivo = $archivo;
24 } else {
25 $archivo->id = $anterior->archivo->id;
26 archivoModifica($archivo);
27 }
28 $stmt = $con->prepare(
29 "UPDATE PRODUCTO
30 SET
31 PROD_NOMBRE = :nombre,
32 ARCH_ID = :archId
33 WHERE PROD_ID = :id"
34 );
35 $stmt->execute([
36 ":id" => $modelo->id,
37 ":nombre" => $modelo->nombre,
38 ":archId" => $archivo->id
39 ]);
40 $con->commit();
41}
42