aboutsummaryrefslogtreecommitdiff
path: root/ratatoeskr/sys/Database.php
blob: d9fc3279d97557fae1c4cebc814b7c8e7c4e889a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php


namespace r7r\cms\sys;

use PDO;
use PDOStatement;

class Database
{
    /** @var PDO */
    private $pdo;

    /** @var string */
    private $prefix;

    /**
     * @param PDO $pdo
     * @param string $prefix
     */
    public function __construct(PDO $pdo, string $prefix)
    {
        $this->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;
    }

    /**
     * @return int
     */
    public function lastInsertId(): int
    {
        return (int)$this->pdo->lastInsertId();
    }

    /**
     * Get the version of the database structure currently used.
     * @return int
     */
    public function dbversion(): int
    {
        $tableName = $this->subPrefix("PREFIX_meta");

        /* Is the meta table present? If no, the version is 0. */
        $stmt = $this->query("SHOW TABLES LIKE ?", $tableName);
        list($table) = $stmt->fetch();
        if ($table != $tableName) {
            return 0;
        }

        $stmt = $this->query("SELECT `value` FROM `PREFIX_meta` WHERE `key` = 'dbversion'");
        $sqlrow = $stmt->fetch();
        return (int)unserialize(base64_decode($sqlrow["value"]));
    }
}