Passed
Push — hypernext ( d6fe90...3cd606 )
by Nico
11:16
created

Db::fetchAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 1
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Nicolas CARPi <[email protected]>
4
 * @copyright 2012 Nicolas CARPi
5
 * @see https://www.elabftw.net Official website
6
 * @license AGPL-3.0
7
 * @package elabftw
8
 */
9
declare(strict_types=1);
10
11
namespace Elabftw\Elabftw;
12
13
use Elabftw\Exceptions\DatabaseErrorException;
14
use PDO;
15
use PDOException;
16
use PDOStatement;
17
18
/**
19
 * Connect to the database with a singleton class
20
 */
21
final class Db
22
{
23
    private PDO $connection;
24
25
    // store the single instance of the class
26
    private static ?Db $instance = null;
27
28
    // total number of queries
29
    private int $nq = 0;
30
31
    /**
32
     * Construct of a singleton is private
33
     *
34
     * @throws PDOException If it cannot connect to the database
35
     */
36 1
    private function __construct()
37
    {
38 1
        $pdo_options = array();
39
        // throw exception if error
40 1
        $pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
41
        // use persistent mode for connection to MySQL
42 1
        $pdo_options[PDO::ATTR_PERSISTENT] = true;
43
        // only return a named array
44 1
        $pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_ASSOC;
45
        if (defined('DB_CERT_PATH') && !empty(\DB_CERT_PATH)) {
1 ignored issue
show
Bug introduced by
The constant DB_CERT_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
46
            $pdo_options[PDO::MYSQL_ATTR_SSL_CA] = \DB_CERT_PATH;
47 1
        }
48 1
49
        // be backward compatible
50
        if (!defined('DB_PORT')) {
51 1
            define('DB_PORT', '3306');
52 1
        }
53 1
54 1
        $this->connection = new PDO(
55 1
            'mysql:host=' . \DB_HOST . ';port=' . \DB_PORT . ';dbname=' .
0 ignored issues
show
Bug introduced by
The constant DB_HOST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
56
            \DB_NAME,
0 ignored issues
show
Bug introduced by
The constant DB_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
57
            \DB_USER,
0 ignored issues
show
Bug introduced by
The constant DB_USER was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
58 1
            \DB_PASSWORD,
0 ignored issues
show
Bug introduced by
The constant DB_PASSWORD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
59
            $pdo_options
60
        );
61
    }
62
63
    /**
64
     * Disallow cloning the class
65
     * @norector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
66
     */
67
    private function __clone()
68
    {
69
    }
70
71
    /**
72
     * Disallow wakeup also
73
     * @norector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
74
     */
75
    public function __wakeup()
76
    {
77
    }
78
79
    /**
80 100
     * Return the instance of the class
81
     *
82 100
     * @throws PDOException If connection to database failed
83 1
     * @return Db The instance of the class
84
     */
85
    public static function getConnection(): self
86 100
    {
87
        if (self::$instance === null) {
88
            self::$instance = new self();
89
        }
90
91
        return self::$instance;
92
    }
93
94
    /**
95 100
     * Prepare a query
96
     *
97 100
     * @param string $sql The SQL query
98 100
     */
99
    public function prepare(string $sql): PDOStatement
100
    {
101
        $this->nq++;
102
        return $this->connection->prepare($sql);
103
    }
104
105
    /**
106
     * Execute a prepared statement and throw exception if it doesn't return true
107
     *
108
     * @param array<mixed>|null $arr optional array to execute
109
     */
110
    public function execute(PDOStatement $req, ?array $arr = null): bool
111
    {
112
        try {
113
            $res = $req->execute($arr);
114
        } catch (PDOException $e) {
115
            throw new DatabaseErrorException($e);
116
        }
117
        if (!$res) {
118
            throw new DatabaseErrorException();
119
        }
120
        return $res;
121
    }
122 21
123
    /**
124 21
     * Force fetchAll to return an array or throw exception if result is false
125
     * because this is hard to test
126
     */
127
    public function fetchAll(PDOStatement $req): array
128
    {
129
        $res = $req->fetchAll();
130
        if ($res === false) {
131
            throw new DatabaseErrorException();
132
        }
133
        return $res;
134
    }
135
136
    /**
137
     * Make a simple query
138
     *
139
     * @param string $sql The SQL query
140
     */
141
    public function q(string $sql): PDOStatement
142
    {
143
        $res = $this->connection->query($sql);
144
        if ($res === false) {
145
            throw new DatabaseErrorException();
146
        }
147
148
        return $res;
149
    }
150
151
    /**
152
     * Return the last id inserted
153
     */
154
    public function lastInsertId(): int
155
    {
156
        return (int) $this->connection->lastInsertId();
157
    }
158
159
    /**
160
     * Get number of SQL queries for the page
161
     */
162
    public function getNumberOfQueries(): int
163
    {
164
        return $this->nq;
165
    }
166
}
167