commit basic

This commit is contained in:
2026-03-02 00:50:14 +01:00
parent a56501bc63
commit a543a79c83
38 changed files with 2663 additions and 1 deletions

View File

@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use PDO;
final class UserRepository
{
public function __construct(private PDO $pdo) {}
public function findByEmail(string $email): ?array
{
$stmt = $this->pdo->prepare(
'SELECT id, email, name, created_at
FROM users
WHERE email = :email
LIMIT 1'
);
$stmt->execute(['email' => $email]);
$row = $stmt->fetch();
return $row ?: null;
}
public function create(string $email, string $name): int
{
// DB-agnostischer INSERT
$stmt = $this->pdo->prepare(
'INSERT INTO users (email, name, created_at)
VALUES (:email, :name, :created_at)'
);
$stmt->execute([
'email' => $email,
'name' => $name,
'created_at' => date('Y-m-d H:i:s'),
]);
// ID-Ermittlung: DB-spezifische Unterschiede gekapselt
return $this->lastInsertIdSafe();
}
public function listLatest(int $limit = 10): array
{
// LIMIT ist bei mysql/pgsql/sqlite gleich
$stmt = $this->pdo->prepare(
'SELECT id, email, name, created_at
FROM users
ORDER BY id DESC
LIMIT :limit'
);
// SQLite/MySQL/PG verstehen ints hier, aber PDO braucht oft PARAM_INT
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll();
}
private function driver(): string
{
return (string)$this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
}
private function lastInsertIdSafe(): int
{
$driver = $this->driver();
if ($driver === 'pgsql') {
// Option A: Sequenzname (wenn du ihn kennst)
// Standard wäre oft users_id_seq, kann aber anders heißen.
// Wenn du "GENERATED ... AS IDENTITY" nutzt, ist RETURNING meist die bessere Option.
$id = $this->pdo->lastInsertId();
if ($id !== '') {
return (int)$id;
}
// Fallback: versuche typische Sequenz
$id = $this->pdo->lastInsertId('users_id_seq');
return (int)$id;
}
// mysql + sqlite
return (int)$this->pdo->lastInsertId();
}
}