From 01842f99b65b06d2647470c3b867719e72dabde7 Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Mon, 5 Oct 2020 21:44:27 +0200 Subject: Introduce some new database wrappers This will allow us to avoid using globals and use the autoloader in the future. --- ratatoeskr/sys/Database.php | 105 ++++++++++++++++++++++++++++++++++ ratatoeskr/sys/DbTransaction.php | 47 ++++++++++++++++ ratatoeskr/sys/Env.php | 9 +++ ratatoeskr/sys/db.php | 119 ++++++++++++++++----------------------- 4 files changed, 208 insertions(+), 72 deletions(-) create mode 100644 ratatoeskr/sys/Database.php create mode 100644 ratatoeskr/sys/DbTransaction.php diff --git a/ratatoeskr/sys/Database.php b/ratatoeskr/sys/Database.php new file mode 100644 index 0000000..7654e46 --- /dev/null +++ b/ratatoeskr/sys/Database.php @@ -0,0 +1,105 @@ +pdo = $pdo; + $this->prefix = $prefix; + } + + /** + * Create a Database object from a config. + * + * @param array $config + * @return self + */ + public static function fromConfig(array $config): self + { + $pdo = new PDO( + "mysql:host=" . $config["mysql"]["server"] . ";dbname=" . $config["mysql"]["db"] . ";charset=utf8", + $config["mysql"]["user"], + $config["mysql"]["passwd"], + [ + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', + ] + ); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + return new self($pdo, $config["mysql"]["prefix"]); + } + + /** + * Gets the wrapped PDO object. + * + * @return PDO + */ + public function getPdo(): PDO + { + return $this->pdo; + } + + /** + * Get the table prefix. + * + * @return string + */ + public function getPrefix(): string + { + return $this->prefix; + } + + /** + * Substitutes "PREFIX_" in the input string with the prefix from the config. + * + * @param string $query + * @return string + */ + public function subPrefix(string $query): string // \mystuff\TODO: or can we make this private? + { + return str_replace("PREFIX_", $this->prefix, $query); + } + + /** + * Prepares a SQL statement for usage with the database. + * This will also replace "PREFIX_" with the prefix defined in 'config.php'. + * + * @param string $query The query / statement to prepare. + * @return PDOStatement + */ + public function prepStmt(string $query): PDOStatement // \mystuff\TODO: or can we make this private? + { + return $this->pdo->prepare($this->subPrefix($query)); + } + + /** + * Prepares a query with {@see Database::prepStmt()} and executes it with the remaining arguments. + * + * @param string $query + * @param mixed ...$args + * @return PDOStatement + */ + public function query(string $query, ...$args): PDOStatement + { + $stmt = $this->prepStmt($query); + $stmt->execute($args); + + return $stmt; + } +} diff --git a/ratatoeskr/sys/DbTransaction.php b/ratatoeskr/sys/DbTransaction.php new file mode 100644 index 0000000..ed1f9ac --- /dev/null +++ b/ratatoeskr/sys/DbTransaction.php @@ -0,0 +1,47 @@ +db = $db; + + $this->startedHere = !$this->db->getPdo()->inTransaction(); + if ($this->startedHere) { + $this->db->getPdo()->beginTransaction(); + } + } + + /** + * Commit the transaction. + */ + public function commit(): void + { + if ($this->startedHere) { + $this->db->getPdo()->commit(); + } + } + + /** + * Roll the transaction back. + */ + public function rollback(): void + { + if ($this->startedHere) { + $this->db->getPdo()->rollBack(); + } + } +} diff --git a/ratatoeskr/sys/Env.php b/ratatoeskr/sys/Env.php index cfe1598..63d079d 100644 --- a/ratatoeskr/sys/Env.php +++ b/ratatoeskr/sys/Env.php @@ -34,4 +34,13 @@ class Env { return $this->lazy("textprocessors", [TextprocessorRepository::class, 'buildDefault']); } + + public function database(): Database + { + return $this->lazy("database", static function () { + global $config; + + return Database::fromConfig($config); + }); + } } diff --git a/ratatoeskr/sys/db.php b/ratatoeskr/sys/db.php index 17a8b8a..a2ccc13 100644 --- a/ratatoeskr/sys/db.php +++ b/ratatoeskr/sys/db.php @@ -10,133 +10,108 @@ * See "ratatoeskr/licenses/ratatoeskr" for more information. */ +use r7r\cms\sys\Database; +use r7r\cms\sys\Env; +use r7r\cms\sys\DbTransaction; + if (!defined("SETUP")) { require_once(dirname(__FILE__) . "/../config.php"); } require_once(dirname(__FILE__) . "/utils.php"); +// The global database connection. +// It's usage is deprecated, use the Database object supplied by Env::database() instead. +/** @var PDO|null $db_con */ $db_con = null; -/* - * Function: db_connect +/** + * Establish the global connection to the MySQL database. + * This sets the global {@see $db_con}. * - * Establish a connection to the MySQL database. + * @deprecated Use the {@see Database} object supplied by {@see Env::database()} instead. */ -function db_connect() +function db_connect(): void { - global $config; global $db_con; - $db_con = new PDO( - "mysql:host=" . $config["mysql"]["server"] . ";dbname=" . $config["mysql"]["db"] . ";charset=utf8", - $config["mysql"]["user"], - $config["mysql"]["passwd"], - [ - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', - ] - ); - $db_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $db_con = Env::getGlobal()->database()->getPdo(); } -/* - * Function: sub_prefix - * +/** * Substitutes "PREFIX_" in the input string with the prefix from the config. + * + * @param mixed|string $q + * @return string + * @deprecated Use {@see Database::subPrefix()} instead. */ -function sub_prefix($q) +function sub_prefix($q): string { - global $config; - return str_replace("PREFIX_", $config["mysql"]["prefix"], $q); + return Env::getGlobal()->database()->subPrefix((string)$q); } -/* - * Function: prep_stmt - * +/** * Prepares a SQL statement using the global DB connection. * This will also replace "PREFIX_" with the prefix defined in 'config.php'. * - * Parameters: - * $q - The query / statement to prepare. + * @param mixed|string $q The query / statement to prepare. + * @return PDOStatement * - * Returns: - * A PDOStatement object. + * @deprecated Use {@see Database::prepStmt()} instead. */ -function prep_stmt($q) +function prep_stmt($q): PDOStatement { - global $db_con; - - return $db_con->prepare(sub_prefix($q)); + return Env::getGlobal()->database()->prepStmt((string)$q); } -/* - * Function: qdb +/** + * Prepares statement (1st argument) with {@see prep_stmt()} and executes it with the remaining arguments. * - * Prepares statement (1st argument) with and executes it with the remaining arguments. + * @param mixed ...$args + * @return PDOStatement * - * Returns: - * A PDOStatement object. + * @deprecated Use {@see Database::query()} instead. */ -function qdb() +function qdb(...$args): PDOStatement { - $args = func_get_args(); if (count($args) < 1) { throw new InvalidArgumentException("qdb needs at least 1 argument"); } - $stmt = prep_stmt($args[0]); - $stmt->execute(array_slice($args, 1)); - return $stmt; + return Env::getGlobal()->database()->query((string)$args[0], ...array_slice($args, 1)); } -/* - * Class: Transaction - * +/** * Makes using transactions easier. + * + * @deprecated Use {@see DbTransaction} instead. */ class Transaction { - public $startedhere; + /** @var DbTransaction */ + private $tx; - /* - * Constructor: __construct - * + /** * Start a new transaction. */ public function __construct() { - global $db_con; - $this->startedhere = !($db_con->inTransaction()); - if ($this->startedhere) { - $db_con->beginTransaction(); - } + $this->tx = new DbTransaction(Env::getGlobal()->database()); } - /* - * Function: commit - * + /** * Commit the transaction. */ - public function commit() + public function commit(): void { - global $db_con; - - if ($this->startedhere) { - $db_con->commit(); - } + $this->tx->commit(); } - /* - * Function: rollback - * - * Toll the transaction back. + /** + * Roll the transaction back. */ - public function rollback() + public function rollback(): void { - global $db_con; - - if ($this->startedhere) { - $db_con->rollBack(); - } + $this->tx->rollback(); } } -- cgit v1.2.3-54-g00ecf