Création de l'api
This commit is contained in:
commit
0a6c8ec05d
4 changed files with 885 additions and 0 deletions
19
.htaccess
Normal file
19
.htaccess
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Activation de la réécriture d'URL pour rediriger vers index.php
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteBase /voitureAPI/
|
||||||
|
|
||||||
|
# Ne pas réécrire si le fichier ou dossier existe déjà
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
|
||||||
|
# Rediriger toutes les autres requêtes vers index.php
|
||||||
|
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# En-têtes CORS globaux
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
Header set Access-Control-Allow-Origin "*"
|
||||||
|
Header set Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
|
||||||
|
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
|
||||||
|
</IfModule>
|
||||||
43
config.php
Normal file
43
config.php
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration de la base de données WampServer (MySQL / phpMyAdmin)
|
||||||
|
*/
|
||||||
|
define('DB_HOST', '127.0.0.1');
|
||||||
|
define('DB_PORT', '3306');
|
||||||
|
define('DB_NAME', 'voituresapi');
|
||||||
|
define('DB_USER', 'root');
|
||||||
|
define('DB_PASS', '');
|
||||||
|
define('DB_CHARSET', 'utf8mb4');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une instance PDO connectée à la base de données
|
||||||
|
*/
|
||||||
|
function getDB(): PDO
|
||||||
|
{
|
||||||
|
static $pdo = null;
|
||||||
|
|
||||||
|
if ($pdo === null) {
|
||||||
|
$dsn = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s', DB_HOST, DB_PORT, DB_NAME, DB_CHARSET);
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
header('Content-Type: application/json; charset=UTF-8');
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Erreur de connexion à la base de données: ' . $e->getMessage()
|
||||||
|
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pdo;
|
||||||
|
}
|
||||||
635
index.php
Normal file
635
index.php
Normal file
|
|
@ -0,0 +1,635 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
require_once __DIR__ . '/config.php';
|
||||||
|
|
||||||
|
// En-têtes HTTP pour API REST JSON & CORS
|
||||||
|
header('Content-Type: application/json; charset=UTF-8');
|
||||||
|
header('Access-Control-Allow-Origin: *');
|
||||||
|
header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS');
|
||||||
|
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
|
||||||
|
|
||||||
|
// Gestion des requêtes de pré-vérification OPTIONS (CORS)
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||||
|
http_response_code(204);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Réponse JSON standardisée
|
||||||
|
*/
|
||||||
|
function sendJson(int $statusCode, array $data): void
|
||||||
|
{
|
||||||
|
http_response_code($statusCode);
|
||||||
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère le corps de la requête (JSON ou FormData)
|
||||||
|
*/
|
||||||
|
function getBody(): array
|
||||||
|
{
|
||||||
|
$raw = file_get_contents('php://input');
|
||||||
|
if (!empty($raw)) {
|
||||||
|
if (!mb_check_encoding($raw, 'UTF-8')) {
|
||||||
|
$raw = mb_convert_encoding($raw, 'UTF-8', 'ISO-8859-1');
|
||||||
|
}
|
||||||
|
$decoded = json_decode($raw, true);
|
||||||
|
if (is_array($decoded)) {
|
||||||
|
return $decoded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_POST ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Résolution du chemin de la requête
|
||||||
|
*/
|
||||||
|
function getPathSegments(): array
|
||||||
|
{
|
||||||
|
// Si passé en paramètre d'URL direct (ex: ?route=/cars)
|
||||||
|
if (!empty($_GET['route'])) {
|
||||||
|
$path = trim($_GET['route'], '/');
|
||||||
|
return $path === '' ? [] : explode('/', $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si PATH_INFO est fourni (ex: index.php/cars)
|
||||||
|
if (!empty($_SERVER['PATH_INFO'])) {
|
||||||
|
$path = trim($_SERVER['PATH_INFO'], '/');
|
||||||
|
return $path === '' ? [] : explode('/', $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyse depuis REQUEST_URI
|
||||||
|
$uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
|
||||||
|
$scriptDir = dirname($_SERVER['SCRIPT_NAME'] ?? '');
|
||||||
|
|
||||||
|
// Nettoie le préfixe du dossier du script si présent
|
||||||
|
if ($scriptDir !== '/' && $scriptDir !== '\\' && strpos($uri, $scriptDir) === 0) {
|
||||||
|
$uri = substr($uri, strlen($scriptDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supprime "index.php" si présent
|
||||||
|
$uri = preg_replace('#^/?index\.php#i', '', $uri);
|
||||||
|
$path = trim($uri, '/');
|
||||||
|
|
||||||
|
return $path === '' ? [] : explode('/', $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = getDB();
|
||||||
|
$method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
|
||||||
|
$segments = getPathSegments();
|
||||||
|
|
||||||
|
// Route racine: Documentation sommaire des points d'accès
|
||||||
|
if (empty($segments)) {
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'API Voitures opérationnelle',
|
||||||
|
'database' => DB_NAME,
|
||||||
|
'endpoints' => [
|
||||||
|
'Voitures' => [
|
||||||
|
'GET /cars' => 'Liste toutes les voitures',
|
||||||
|
'GET /cars/{id}' => 'Détails d\'une voiture',
|
||||||
|
'GET /cars/{id}/etat' => 'État complet (voiture, dernier km, entretiens, notes)',
|
||||||
|
'POST /cars' => 'Créer une voiture (marque, modele, annee, dateAchat, VIN)',
|
||||||
|
'PUT /cars/{id}' => 'Modifier les paramètres d\'une voiture',
|
||||||
|
'DELETE /cars/{id}' => 'Supprimer une voiture (et ses données associées)'
|
||||||
|
],
|
||||||
|
'Kilométrage' => [
|
||||||
|
'GET /cars/{id}/kilometrage' => 'Historique des relevés kilométriques',
|
||||||
|
'POST /cars/{id}/kilometrage' => 'Ajouter un relevé kilométrique (valeur, date_releve)',
|
||||||
|
'DELETE /kilometrage/{id}' => 'Supprimer un relevé kilométrique'
|
||||||
|
],
|
||||||
|
'Entretiens (Maintenance)' => [
|
||||||
|
'GET /cars/{id}/maintenance' => 'Historique des entretiens d\'une voiture',
|
||||||
|
'POST /cars/{id}/maintenance' => 'Ajouter un entretien (type_entretien, date_evenement, kilometrage, description, prix)',
|
||||||
|
'PUT /maintenance/{id}' => 'Modifier un entretien',
|
||||||
|
'DELETE /maintenance/{id}' => 'Supprimer un entretien'
|
||||||
|
],
|
||||||
|
'Notes' => [
|
||||||
|
'GET /cars/{id}/notes' => 'Notes associées à une voiture',
|
||||||
|
'POST /cars/{id}/notes' => 'Ajouter une note (titre, contenu)',
|
||||||
|
'PUT /notes/{id}' => 'Modifier une note',
|
||||||
|
'DELETE /notes/{id}' => 'Supprimer une note'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$resource = strtolower($segments[0]);
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// RESSOURCE: CARS (/cars ...)
|
||||||
|
// =========================================================================
|
||||||
|
if ($resource === 'cars' || $resource === 'voitures') {
|
||||||
|
$carId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||||
|
$subResource = $segments[2] ?? null;
|
||||||
|
|
||||||
|
// --- SOUS-RESSOURCES DE CARS ---
|
||||||
|
|
||||||
|
// 1. /cars/{id}/etat (État complet via la procédure sp_getEtatVoiture)
|
||||||
|
if ($carId && $subResource === 'etat' && $method === 'GET') {
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare('CALL sp_getEtatVoiture(:id)');
|
||||||
|
$stmt->execute([':id' => $carId]);
|
||||||
|
|
||||||
|
$car = $stmt->fetch();
|
||||||
|
if (!$car) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$maintenances = [];
|
||||||
|
if ($stmt->nextRowset()) {
|
||||||
|
$maintenances = $stmt->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
$notes = [];
|
||||||
|
if ($stmt->nextRowset()) {
|
||||||
|
$notes = $stmt->fetchAll();
|
||||||
|
}
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'data' => [
|
||||||
|
'voiture' => $car,
|
||||||
|
'maintenances' => $maintenances,
|
||||||
|
'notes' => $notes
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Fallback si la procédure stockée a un souci
|
||||||
|
$stmtCar = $db->prepare('
|
||||||
|
SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c WHERE c.id = ?
|
||||||
|
');
|
||||||
|
$stmtCar->execute([$carId]);
|
||||||
|
$car = $stmtCar->fetch();
|
||||||
|
if (!$car) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmtMaint = $db->prepare('SELECT * FROM maintenance_logs WHERE car_id = ? ORDER BY date_evenement DESC');
|
||||||
|
$stmtMaint->execute([$carId]);
|
||||||
|
|
||||||
|
$stmtNotes = $db->prepare('SELECT * FROM notes WHERE car_id = ? ORDER BY date_creation DESC');
|
||||||
|
$stmtNotes->execute([$carId]);
|
||||||
|
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'data' => [
|
||||||
|
'voiture' => $car,
|
||||||
|
'maintenances' => $stmtMaint->fetchAll(),
|
||||||
|
'notes' => $stmtNotes->fetchAll()
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. /cars/{id}/kilometrage
|
||||||
|
if ($carId && $subResource === 'kilometrage') {
|
||||||
|
if ($method === 'GET') {
|
||||||
|
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 50;
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare('CALL sp_getKilometrages(:id, :limit)');
|
||||||
|
$stmt->execute([':id' => $carId, ':limit' => $limit]);
|
||||||
|
$data = $stmt->fetchAll();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$stmt = $db->prepare('SELECT * FROM kilometrage WHERE car_id = ? ORDER BY date_releve DESC, id DESC LIMIT ?');
|
||||||
|
$stmt->bindValue(1, $carId, PDO::PARAM_INT);
|
||||||
|
$stmt->bindValue(2, $limit, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
$data = $stmt->fetchAll();
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'data' => $data]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'POST') {
|
||||||
|
$body = getBody();
|
||||||
|
if (!isset($body['valeur'])) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Le champ valeur (kilométrage) est obligatoire']);
|
||||||
|
}
|
||||||
|
$dateReleve = $body['date_releve'] ?? date('Y-m-d');
|
||||||
|
$valeur = (int)$body['valeur'];
|
||||||
|
|
||||||
|
$stmt = $db->prepare('INSERT INTO kilometrage (car_id, date_releve, valeur) VALUES (?, ?, ?)');
|
||||||
|
$stmt->execute([$carId, $dateReleve, $valeur]);
|
||||||
|
$newId = (int)$db->lastInsertId();
|
||||||
|
|
||||||
|
sendJson(201, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Relevé kilométrique enregistré',
|
||||||
|
'data' => [
|
||||||
|
'id' => $newId,
|
||||||
|
'car_id' => $carId,
|
||||||
|
'date_releve' => $dateReleve,
|
||||||
|
'valeur' => $valeur
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => 'Méthode non autorisée pour cette sous-ressource']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. /cars/{id}/maintenance
|
||||||
|
if ($carId && ($subResource === 'maintenance' || $subResource === 'entretiens')) {
|
||||||
|
if ($method === 'GET') {
|
||||||
|
$stmt = $db->prepare('SELECT * FROM maintenance_logs WHERE car_id = ? ORDER BY date_evenement DESC');
|
||||||
|
$stmt->execute([$carId]);
|
||||||
|
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'POST') {
|
||||||
|
$body = getBody();
|
||||||
|
if (empty($body['type_entretien']) || empty($body['date_evenement']) || !isset($body['kilometrage'])) {
|
||||||
|
sendJson(400, [
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Les champs type_entretien, date_evenement et kilometrage sont obligatoires'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare('
|
||||||
|
INSERT INTO maintenance_logs (car_id, type_entretien, date_evenement, kilometrage, description, prix)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
|
');
|
||||||
|
$stmt->execute([
|
||||||
|
$carId,
|
||||||
|
trim((string)$body['type_entretien']),
|
||||||
|
(string)$body['date_evenement'],
|
||||||
|
(int)$body['kilometrage'],
|
||||||
|
isset($body['description']) ? trim((string)$body['description']) : null,
|
||||||
|
isset($body['prix']) ? (float)$body['prix'] : null
|
||||||
|
]);
|
||||||
|
|
||||||
|
$newId = (int)$db->lastInsertId();
|
||||||
|
$stmtGet = $db->prepare('SELECT * FROM maintenance_logs WHERE id = ?');
|
||||||
|
$stmtGet->execute([$newId]);
|
||||||
|
|
||||||
|
sendJson(201, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Entretien enregistré avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => 'Méthode non autorisée pour cette sous-ressource']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. /cars/{id}/notes
|
||||||
|
if ($carId && $subResource === 'notes') {
|
||||||
|
if ($method === 'GET') {
|
||||||
|
$stmt = $db->prepare('SELECT * FROM notes WHERE car_id = ? ORDER BY date_creation DESC');
|
||||||
|
$stmt->execute([$carId]);
|
||||||
|
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'POST') {
|
||||||
|
$body = getBody();
|
||||||
|
if (empty($body['contenu'])) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Le champ contenu est obligatoire']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$titre = isset($body['titre']) ? trim((string)$body['titre']) : null;
|
||||||
|
$contenu = trim((string)$body['contenu']);
|
||||||
|
|
||||||
|
$stmt = $db->prepare('INSERT INTO notes (car_id, titre, contenu) VALUES (?, ?, ?)');
|
||||||
|
$stmt->execute([$carId, $titre, $contenu]);
|
||||||
|
|
||||||
|
$newId = (int)$db->lastInsertId();
|
||||||
|
$stmtGet = $db->prepare('SELECT * FROM notes WHERE id = ?');
|
||||||
|
$stmtGet->execute([$newId]);
|
||||||
|
|
||||||
|
sendJson(201, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Note enregistrée avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => 'Méthode non autorisée pour cette sous-ressource']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- OPÉRATIONS PRINCIPALES SUR LES VOITURES (/cars ou /cars/{id}) ---
|
||||||
|
|
||||||
|
// GET /cars : Liste toutes les voitures
|
||||||
|
if ($carId === null && $method === 'GET') {
|
||||||
|
$sql = 'SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c
|
||||||
|
ORDER BY c.id ASC';
|
||||||
|
$stmt = $db->query($sql);
|
||||||
|
sendJson(200, ['success' => true, 'data' => $stmt->fetchAll()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET /cars/{id} : Consulter une voiture
|
||||||
|
if ($carId !== null && $subResource === null && $method === 'GET') {
|
||||||
|
$stmt = $db->prepare('
|
||||||
|
SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c
|
||||||
|
WHERE c.id = ?
|
||||||
|
');
|
||||||
|
$stmt->execute([$carId]);
|
||||||
|
$car = $stmt->fetch();
|
||||||
|
if (!$car) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'data' => $car]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST /cars : Créer une voiture
|
||||||
|
if ($carId === null && $method === 'POST') {
|
||||||
|
$body = getBody();
|
||||||
|
|
||||||
|
// Validation des champs obligatoires
|
||||||
|
$required = ['marque', 'modele', 'annee', 'dateAchat'];
|
||||||
|
foreach ($required as $field) {
|
||||||
|
if (empty($body[$field])) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => "Le champ '$field' est obligatoire"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$marque = trim((string)$body['marque']);
|
||||||
|
$modele = trim((string)$body['modele']);
|
||||||
|
$annee = (int)$body['annee'];
|
||||||
|
$dateAchat = (string)$body['dateAchat'];
|
||||||
|
$vin = !empty($body['VIN']) ? trim((string)$body['VIN']) : null;
|
||||||
|
|
||||||
|
// Utilisation de la procédure stockée sp_insertVoiture
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare('CALL sp_insertVoiture(:marque, :modele, :annee, :dateAchat, :vin)');
|
||||||
|
$stmt->execute([
|
||||||
|
':marque' => $marque,
|
||||||
|
':modele' => $modele,
|
||||||
|
':annee' => $annee,
|
||||||
|
':dateAchat' => $dateAchat,
|
||||||
|
':vin' => $vin
|
||||||
|
]);
|
||||||
|
$res = $stmt->fetch();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
$newId = isset($res['new_id']) ? (int)$res['new_id'] : (int)$db->lastInsertId();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Fallback direct INSERT si la procédure a une incompatibilité
|
||||||
|
$stmt = $db->prepare('INSERT INTO cars (marque, modele, annee, dateAchat, VIN) VALUES (?, ?, ?, ?, ?)');
|
||||||
|
$stmt->execute([$marque, $modele, $annee, $dateAchat, $vin]);
|
||||||
|
$newId = (int)$db->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si un kilométrage initial est fourni
|
||||||
|
if (!empty($body['kilometrage_initial'])) {
|
||||||
|
$kmStmt = $db->prepare('INSERT INTO kilometrage (car_id, date_releve, valeur) VALUES (?, ?, ?)');
|
||||||
|
$kmStmt->execute([$newId, $dateAchat, (int)$body['kilometrage_initial']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupère l'enregistrement créé
|
||||||
|
$stmtGet = $db->prepare('
|
||||||
|
SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c
|
||||||
|
WHERE c.id = ?
|
||||||
|
');
|
||||||
|
$stmtGet->execute([$newId]);
|
||||||
|
|
||||||
|
sendJson(201, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Voiture créée avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT / PATCH /cars/{id} : Mettre à jour les paramètres d'une voiture
|
||||||
|
if ($carId !== null && $subResource === null && ($method === 'PUT' || $method === 'PATCH')) {
|
||||||
|
// Vérifier si la voiture existe
|
||||||
|
$check = $db->prepare('SELECT id FROM cars WHERE id = ?');
|
||||||
|
$check->execute([$carId]);
|
||||||
|
if (!$check->fetch()) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = getBody();
|
||||||
|
$allowedFields = ['marque', 'modele', 'annee', 'dateAchat', 'VIN'];
|
||||||
|
$updates = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
foreach ($allowedFields as $field) {
|
||||||
|
if (array_key_exists($field, $body)) {
|
||||||
|
$updates[] = "`$field` = ?";
|
||||||
|
$params[] = $body[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($updates)) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Aucun paramètre valide à mettre à jour']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$params[] = $carId;
|
||||||
|
$sql = 'UPDATE cars SET ' . implode(', ', $updates) . ' WHERE id = ?';
|
||||||
|
$stmt = $db->prepare($sql);
|
||||||
|
$stmt->execute($params);
|
||||||
|
|
||||||
|
// Récupère la voiture mise à jour
|
||||||
|
$stmtGet = $db->prepare('
|
||||||
|
SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c
|
||||||
|
WHERE c.id = ?
|
||||||
|
');
|
||||||
|
$stmtGet->execute([$carId]);
|
||||||
|
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Paramètres de la voiture mis à jour avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE /cars/{id} : Supprimer une voiture
|
||||||
|
if ($carId !== null && $subResource === null && $method === 'DELETE') {
|
||||||
|
// Vérifier existence
|
||||||
|
$check = $db->prepare('SELECT id FROM cars WHERE id = ?');
|
||||||
|
$check->execute([$carId]);
|
||||||
|
if (!$check->fetch()) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Voiture #{$carId} introuvable"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exécution de la procédure stockée sp_deleteVoiture
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare('CALL sp_deleteVoiture(:id)');
|
||||||
|
$stmt->execute([':id' => $carId]);
|
||||||
|
$stmt->closeCursor();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$stmt = $db->prepare('DELETE FROM cars WHERE id = ?');
|
||||||
|
$stmt->execute([$carId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => "Voiture #{$carId} ainsi que toutes ses données associées ont été supprimées avec succès"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => "Méthode HTTP non autorisée pour cette URL"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// RESSOURCE: KILOMETRAGE DIRECT (/kilometrage/{id})
|
||||||
|
// =========================================================================
|
||||||
|
if ($resource === 'kilometrage') {
|
||||||
|
$kmId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||||
|
|
||||||
|
if ($kmId && $method === 'DELETE') {
|
||||||
|
$stmt = $db->prepare('DELETE FROM kilometrage WHERE id = ?');
|
||||||
|
$stmt->execute([$kmId]);
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Relevé kilométrique #{$kmId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'message' => "Relevé kilométrique #{$kmId} supprimé"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => "Méthode non autorisée sur /kilometrage"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// RESSOURCE: MAINTENANCE DIRECT (/maintenance/{id})
|
||||||
|
// =========================================================================
|
||||||
|
if ($resource === 'maintenance' || $resource === 'entretiens') {
|
||||||
|
$maintId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||||
|
|
||||||
|
if (!$maintId) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Identifiant d\'entretien requis']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'GET') {
|
||||||
|
$stmt = $db->prepare('SELECT * FROM maintenance_logs WHERE id = ?');
|
||||||
|
$stmt->execute([$maintId]);
|
||||||
|
$item = $stmt->fetch();
|
||||||
|
if (!$item) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Entretien #{$maintId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'data' => $item]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'PUT' || $method === 'PATCH') {
|
||||||
|
$body = getBody();
|
||||||
|
$allowed = ['type_entretien', 'date_evenement', 'kilometrage', 'description', 'prix'];
|
||||||
|
$updates = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
foreach ($allowed as $f) {
|
||||||
|
if (array_key_exists($f, $body)) {
|
||||||
|
$updates[] = "`$f` = ?";
|
||||||
|
$params[] = $body[$f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($updates)) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Aucun paramètre à modifier']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$params[] = $maintId;
|
||||||
|
$stmt = $db->prepare('UPDATE maintenance_logs SET ' . implode(', ', $updates) . ' WHERE id = ?');
|
||||||
|
$stmt->execute($params);
|
||||||
|
|
||||||
|
$stmtGet = $db->prepare('SELECT * FROM maintenance_logs WHERE id = ?');
|
||||||
|
$stmtGet->execute([$maintId]);
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Entretien mis à jour avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'DELETE') {
|
||||||
|
$stmt = $db->prepare('DELETE FROM maintenance_logs WHERE id = ?');
|
||||||
|
$stmt->execute([$maintId]);
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Entretien #{$maintId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'message' => "Entretien #{$maintId} supprimé avec succès"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => "Méthode non autorisée sur /maintenance/{id}"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// RESSOURCE: NOTES DIRECT (/notes/{id})
|
||||||
|
// =========================================================================
|
||||||
|
if ($resource === 'notes') {
|
||||||
|
$noteId = isset($segments[1]) && is_numeric($segments[1]) ? (int)$segments[1] : null;
|
||||||
|
|
||||||
|
if (!$noteId) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Identifiant de note requis']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'GET') {
|
||||||
|
$stmt = $db->prepare('SELECT * FROM notes WHERE id = ?');
|
||||||
|
$stmt->execute([$noteId]);
|
||||||
|
$item = $stmt->fetch();
|
||||||
|
if (!$item) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Note #{$noteId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'data' => $item]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'PUT' || $method === 'PATCH') {
|
||||||
|
$body = getBody();
|
||||||
|
$allowed = ['titre', 'contenu'];
|
||||||
|
$updates = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
foreach ($allowed as $f) {
|
||||||
|
if (array_key_exists($f, $body)) {
|
||||||
|
$updates[] = "`$f` = ?";
|
||||||
|
$params[] = $body[$f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($updates)) {
|
||||||
|
sendJson(400, ['success' => false, 'error' => 'Aucun paramètre à modifier']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$params[] = $noteId;
|
||||||
|
$stmt = $db->prepare('UPDATE notes SET ' . implode(', ', $updates) . ' WHERE id = ?');
|
||||||
|
$stmt->execute($params);
|
||||||
|
|
||||||
|
$stmtGet = $db->prepare('SELECT * FROM notes WHERE id = ?');
|
||||||
|
$stmtGet->execute([$noteId]);
|
||||||
|
sendJson(200, [
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Note mise à jour avec succès',
|
||||||
|
'data' => $stmtGet->fetch()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($method === 'DELETE') {
|
||||||
|
$stmt = $db->prepare('DELETE FROM notes WHERE id = ?');
|
||||||
|
$stmt->execute([$noteId]);
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
sendJson(404, ['success' => false, 'error' => "Note #{$noteId} introuvable"]);
|
||||||
|
}
|
||||||
|
sendJson(200, ['success' => true, 'message' => "Note #{$noteId} supprimée avec succès"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendJson(405, ['success' => false, 'error' => "Méthode non autorisée sur /notes/{id}"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ressource inconnue
|
||||||
|
sendJson(404, [
|
||||||
|
'success' => false,
|
||||||
|
'error' => "Ressource '/$resource' non reconnue. Consultez la racine '/' pour la documentation des routes."
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
sendJson(500, [
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Erreur SQL: ' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
sendJson(500, [
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Erreur serveur: ' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
188
voituresapi (1).sql
Normal file
188
voituresapi (1).sql
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
-- phpMyAdmin SQL Dump
|
||||||
|
-- version 5.2.3
|
||||||
|
-- https://www.phpmyadmin.net/
|
||||||
|
--
|
||||||
|
-- Hôte : 127.0.0.1:3306
|
||||||
|
-- Généré le : mer. 16 sep. 2026 à 08:43
|
||||||
|
-- Version du serveur : 8.4.7
|
||||||
|
-- Version de PHP : 8.3.28
|
||||||
|
|
||||||
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||||
|
START TRANSACTION;
|
||||||
|
SET time_zone = "+00:00";
|
||||||
|
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Base de données : `voituresapi`
|
||||||
|
--
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
--
|
||||||
|
-- Procédures
|
||||||
|
--
|
||||||
|
DROP PROCEDURE IF EXISTS `sp_deleteVoiture`$$
|
||||||
|
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_deleteVoiture` (IN `p_id` INT) BEGIN
|
||||||
|
DELETE FROM cars WHERE id = p_id;
|
||||||
|
SELECT ROW_COUNT() AS affected;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS `sp_getEtatVoiture`$$
|
||||||
|
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_getEtatVoiture` (IN `p_id` INT) BEGIN
|
||||||
|
SELECT c.*,
|
||||||
|
(SELECT valeur FROM kilometrage WHERE car_id = c.id ORDER BY date_releve DESC, id DESC LIMIT 1) AS dernier_km
|
||||||
|
FROM cars c
|
||||||
|
WHERE c.id = p_id;
|
||||||
|
|
||||||
|
SELECT * FROM maintenance_logs WHERE car_id = p_id ORDER BY date_evenement DESC;
|
||||||
|
|
||||||
|
SELECT * FROM notes WHERE car_id = p_id ORDER BY date_creation DESC;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS `sp_getKilometrages`$$
|
||||||
|
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_getKilometrages` (IN `p_id` INT, IN `p_limit` INT) BEGIN
|
||||||
|
SELECT id, car_id, valeur, date_releve
|
||||||
|
FROM kilometrage
|
||||||
|
WHERE car_id = p_id
|
||||||
|
ORDER BY date_releve DESC, id DESC
|
||||||
|
LIMIT p_limit;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS `sp_insertVoiture`$$
|
||||||
|
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_insertVoiture` (IN `p_marque` VARCHAR(255), IN `p_modele` VARCHAR(255), IN `p_annee` INT, IN `p_dateAchat` DATE, IN `p_VIN` VARCHAR(255)) BEGIN
|
||||||
|
INSERT INTO cars (marque, modele, annee, dateAchat, VIN)
|
||||||
|
VALUES (p_marque, p_modele, p_annee, p_dateAchat, p_VIN);
|
||||||
|
SELECT LAST_INSERT_ID() AS new_id;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Structure de la table `cars`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `cars`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `cars` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`marque` varchar(50) NOT NULL,
|
||||||
|
`modele` varchar(50) NOT NULL,
|
||||||
|
`annee` int NOT NULL,
|
||||||
|
`dateAchat` date NOT NULL,
|
||||||
|
`VIN` varchar(17) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Déchargement des données de la table `cars`
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `cars` (`id`, `marque`, `modele`, `annee`, `dateAchat`, `VIN`) VALUES
|
||||||
|
(1, 'Peugeot', '207', 2009, '2025-05-20', 'VF3WA8HZCXXXXXXXX'),
|
||||||
|
(2, 'Peugeot', '208', 2010, '2025-05-20', 'VF3WA8HZCXXXXXXXX');
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Structure de la table `kilometrage`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `kilometrage`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `kilometrage` (
|
||||||
|
`car_id` int NOT NULL,
|
||||||
|
`date_releve` date NOT NULL,
|
||||||
|
`valeur` int NOT NULL,
|
||||||
|
KEY `fk_km_car_id` (`car_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Déchargement des données de la table `kilometrage`
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `kilometrage` (`car_id`, `date_releve`, `valeur`) VALUES
|
||||||
|
(1, '2026-04-20', 133000),
|
||||||
|
(1, '2026-04-20', 133200);
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Structure de la table `maintenance_logs`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `maintenance_logs`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `maintenance_logs` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`car_id` int NOT NULL,
|
||||||
|
`type_entretien` varchar(100) NOT NULL,
|
||||||
|
`date_evenement` date NOT NULL,
|
||||||
|
`kilometrage` int NOT NULL,
|
||||||
|
`description` text,
|
||||||
|
`prix` decimal(10,2) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `fk_car_id` (`car_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Déchargement des données de la table `maintenance_logs`
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `maintenance_logs` (`id`, `car_id`, `type_entretien`, `date_evenement`, `kilometrage`, `description`, `prix`) VALUES
|
||||||
|
(1, 1, 'Vidange', '2023-10-15', 145000, 'Huile 5W40 + Filtre à huile', 85.00),
|
||||||
|
(2, 1, 'Pneus', '2024-02-01', 152000, 'Changement pneus avant Michelin', 160.00);
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Structure de la table `notes`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `notes`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `notes` (
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
`car_id` int NOT NULL,
|
||||||
|
`titre` varchar(100) DEFAULT NULL,
|
||||||
|
`contenu` text NOT NULL,
|
||||||
|
`date_creation` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `fk_notes_car_id` (`car_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Déchargement des données de la table `notes`
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `notes` (`id`, `car_id`, `titre`, `contenu`, `date_creation`) VALUES
|
||||||
|
(2, 1, 'Clé', 'Ne pas oublier de faire revenir légèrement la clé vers la gauche une fois démarrée', '2026-04-20 14:58:46'),
|
||||||
|
(3, 1, 'Batterie', 'Recharger la batterie', '2026-04-20 15:03:01');
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Contraintes pour les tables déchargées
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Contraintes pour la table `kilometrage`
|
||||||
|
--
|
||||||
|
ALTER TABLE `kilometrage`
|
||||||
|
ADD CONSTRAINT `fk_km_car_id` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Contraintes pour la table `maintenance_logs`
|
||||||
|
--
|
||||||
|
ALTER TABLE `maintenance_logs`
|
||||||
|
ADD CONSTRAINT `fk_car_id` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Contraintes pour la table `notes`
|
||||||
|
--
|
||||||
|
ALTER TABLE `notes`
|
||||||
|
ADD CONSTRAINT `fk_notes_car_id` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
Loading…
Reference in a new issue