PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); } return self::$instance; } // Convenience wrappers public static function query(string $sql, array $params = []): \PDOStatement { $stmt = self::get()->prepare($sql); $stmt->execute($params); return $stmt; } public static function fetchAll(string $sql, array $params = []): array { return self::query($sql, $params)->fetchAll(); } public static function fetchOne(string $sql, array $params = []): array|false { return self::query($sql, $params)->fetch(); } public static function execute(string $sql, array $params = []): int { $stmt = self::query($sql, $params); return $stmt->rowCount(); } public static function lastInsertId(): string { return self::get()->lastInsertId(); } public static function beginTransaction(): void { if (self::$txDepth === 0) { self::get()->beginTransaction(); } self::$txDepth++; } public static function commit(): void { if (self::$txDepth > 0) { self::$txDepth--; } if (self::$txDepth === 0 && self::get()->inTransaction()) { self::get()->commit(); } } public static function rollBack(): void { self::$txDepth = 0; if (self::get()->inTransaction()) { self::get()->rollBack(); } } }