MariaDBDatabase.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. /*
  3. * Part of Shuzanne - An extensible sequel to an open-source imageboard.
  4. *
  5. * @package Shuzanne
  6. * @author MisleadingName, Shuzanne Contributors
  7. * @license MPL v2.0
  8. *
  9. * This Source Code Form is subject to the terms of the Mozilla Public
  10. * License, v. 2.0. If a copy of the MPL was not distributed with this
  11. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  12. */
  13. namespace app\Types;
  14. use app\Interfaces\IDatabase;
  15. use app\Logger;
  16. use PDO;
  17. use PDOStatement;
  18. use PDOException;
  19. class MariaDBDatabase implements IDatabase
  20. {
  21. private ?PDO $pdo;
  22. private PDOStatement $stmt;
  23. private array $parameters = [];
  24. public function __construct(array $engineConfig)
  25. {
  26. $host = $engineConfig["Host"];
  27. $port = $engineConfig["Port"] ?? 3306;
  28. $username = $engineConfig["Username"];
  29. $password = $engineConfig["Password"];
  30. $dbname = $engineConfig["Database"];
  31. $charset = $engineConfig["Charset"] ?? "utf8mb4";
  32. $dsn = "mysql:host=$host;dbname=$dbname;port=$port;charset=$charset";
  33. $options = [
  34. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  35. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  36. PDO::ATTR_EMULATE_PREPARES => false,
  37. ];
  38. try {
  39. $this->pdo = new PDO($dsn, $username, $password, $options);
  40. } catch (PDOException $e) {
  41. Logger::Error("Database connection failed: " . $e->getMessage());
  42. throw $e;
  43. }
  44. }
  45. public function CloseConnection(): void
  46. {
  47. $this->pdo = null;
  48. }
  49. public function Bind(string $param, mixed $value): void
  50. {
  51. $this->parameters[$param] = $value;
  52. }
  53. public function BindMore(array $params): void
  54. {
  55. foreach ($params as $param => $value) {
  56. $this->Bind($param, $value);
  57. }
  58. }
  59. private function executeStatement(string $query, ?array $params = null): PDOStatement
  60. {
  61. try {
  62. $this->stmt = $this->pdo->prepare($query);
  63. if ($params) {
  64. foreach ($params as $param => $value) {
  65. $paramType = match (gettype($value)) {
  66. 'integer' => PDO::PARAM_INT,
  67. 'boolean' => PDO::PARAM_BOOL,
  68. 'NULL' => PDO::PARAM_NULL,
  69. default => PDO::PARAM_STR
  70. };
  71. $this->stmt->bindValue(is_numeric($param) ? $param + 1 : $param, $value, $paramType);
  72. }
  73. }
  74. $this->stmt->execute();
  75. return $this->stmt;
  76. } catch (PDOException $e) {
  77. Logger::Error("Query execution failed: " . $e->getMessage() . " - Query: $query");
  78. throw $e;
  79. }
  80. }
  81. public function Query(string $query, ?array $params = null, int $fetchMode = PDO::FETCH_ASSOC): mixed
  82. {
  83. $stmt = $this->executeStatement($query, $params ?? $this->parameters);
  84. $this->parameters = [];
  85. return $stmt->fetchAll($fetchMode);
  86. }
  87. public function QueryRowCount(string $query, ?array $params = null, int $fetchMode = PDO::FETCH_ASSOC): int
  88. {
  89. $stmt = $this->executeStatement($query, $params ?? $this->parameters);
  90. $this->parameters = [];
  91. return $stmt->rowCount();
  92. }
  93. public function LastInsertId(): string
  94. {
  95. return $this->pdo->lastInsertId();
  96. }
  97. public function BeginTransaction(): bool
  98. {
  99. return $this->pdo->beginTransaction();
  100. }
  101. public function ExecuteTransaction(): bool
  102. {
  103. return $this->pdo->commit();
  104. }
  105. public function Rollback(): bool
  106. {
  107. return $this->pdo->rollBack();
  108. }
  109. public function Column(string $query, ?array $params = null): array
  110. {
  111. $stmt = $this->executeStatement($query, $params ?? $this->parameters);
  112. $this->parameters = [];
  113. return $stmt->fetchAll(PDO::FETCH_COLUMN);
  114. }
  115. public function Row(string $query, ?array $params = null, int $fetchMode = PDO::FETCH_ASSOC): array
  116. {
  117. $stmt = $this->executeStatement($query, $params ?? $this->parameters);
  118. $this->parameters = [];
  119. $result = $stmt->fetch($fetchMode);
  120. return $result ?: [];
  121. }
  122. public function Single(string $query, ?array $params = null): mixed
  123. {
  124. $stmt = $this->executeStatement($query, $params ?? $this->parameters);
  125. $this->parameters = [];
  126. $result = $stmt->fetchColumn();
  127. return $result !== false ? $result : null;
  128. }
  129. }