Test Failed
Branch main (345e92)
by Rafael
08:42
created

Database::getDbDrivers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/* Copyright (C) 2024      Rafael San José      <[email protected]>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3 of the License, or
8
 * any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace Alxarafe\Base;
20
21
use Alxarafe\Lib\Messages;
22
use Alxarafe\Lib\Trans;
23
use Alxarafe\Tools\Debug;
24
use DebugBar\DataCollector\PDO\PDOCollector;
25
use DebugBar\DebugBarException;
26
use Illuminate\Database\Capsule\Manager as CapsuleManager;
27
use PDO;
28
use PDOException;
29
use stdClass;
30
31
/**
32
 * Create a PDO database connection
33
 *
34
 * @package Alxarafe\Base
35
 */
36
class Database extends CapsuleManager
37
{
38
    /**
39
     * Construct the database access
40
     *
41
     * @param stdClass $db
42
     *
43
     * @throws DebugBarException
44
     */
45
    public function __construct(stdClass $db)
46
    {
47
        parent::__construct();
48
49
        $this->addConnection([
50
            'driver' => $db->type,
51
            'host' => $db->host,
52
            'database' => $db->name,
53
            'username' => $db->user,
54
            'password' => $db->pass,
55
            'charset' => $db->charset,
56
            'collation' => $db->collation,
57
            'prefix' => $db->prefix,
58
        ]);
59
60
        $this->setAsGlobal();
61
        $this->bootEloquent();
62
63
        $debugBar = Debug::getDebugBar();
64
        if (!isset($debugBar) || $debugBar->hasCollector('pdo')) {
65
            return;
66
        }
67
68
        $pdo = $this->getConnection()->getPdo();
69
        $debugBar->addCollector(new PDOCollector($pdo));
70
    }
71
72
    public static function getDbDrivers():array{
73
        return [
74
            'mysql' => 'MySQL',
75
            'pgsql' => 'PostgreSQL',
76
        ];
77
    }
78
79
    /**
80
     * Checks if the connection to the database is possible with the parameters
81
     * defined in the configuration file.
82
     *
83
     * @param stdClass $data
84
     * @param bool $create
85
     * @return bool
86
     */
87
    public static function checkDatabaseConnection(stdClass $data, bool $create = false): bool
88
    {
89
        if (!static::checkIfDatabaseExists($data, true)) {
90
            if (!$create) {
91
                return false;
92
            }
93
            if (!static::createDatabaseIfNotExists($data, true)) {
0 ignored issues
show
Unused Code introduced by
The call to Alxarafe\Base\Database::...teDatabaseIfNotExists() has too many arguments starting with true. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

93
            if (!static::/** @scrutinizer ignore-call */ createDatabaseIfNotExists($data, true)) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
94
                return false;
95
            }
96
        }
97
        return true;
98
    }
99
100
    /**
101
     * Returns true if the database already exists.
102
     *
103
     * @param stdClass $data
104
     * @return bool
105
     */
106
    public static function checkIfDatabaseExists(stdClass $data, bool $quiet = false): bool
107
    {
108
        if (!static::checkConnection($data, true)) {
109
            return false;
110
        }
111
112
        $dsn = "$data->type:host=$data->host;dbname=$data->name;charset=$data->charset";
113
        try {
114
            new PDO($dsn, $data->user, $data->pass);
115
        } catch (PDOException $e) {
116
            if (!$quiet) {
117
                Messages::addError(Trans::_('error_message', ['message' => $e->getMessage()]));
118
            }
119
            return false;
120
        }
121
        return true;
122
    }
123
124
    /**
125
     * Checks if there is a connection to the database engine.
126
     *
127
     * @param stdClass $data
128
     * @param bool $quiet
129
     * @return bool
130
     */
131
    public static function checkConnection(stdClass $data, bool $quiet = false): bool
132
    {
133
        $dsn = "$data->type:host=$data->host";
134
        try {
135
            new PDO($dsn, $data->user, $data->pass);
136
        } catch (PDOException $e) {
137
            if (!$quiet) {
138
                Messages::addError(Trans::_('error_message', ['message' => $e->getMessage()]));
139
            }
140
            return false;
141
        }
142
        return true;
143
    }
144
145
    /**
146
     * Creates the database if it does not exist. Returns true if the creation succeeds.
147
     *
148
     * @param stdClass $data
149
     * @return bool
150
     */
151
    public static function createDatabaseIfNotExists(stdClass $data): bool
152
    {
153
        if (static::checkIfDatabaseExists($data, true)) {
154
            return true;
155
        }
156
157
        $dsn = "$data->type:host=$data->host";
158
        try {
159
            $pdo = new PDO($dsn, $data->user, $data->pass);
160
            $pdo->exec('CREATE DATABASE ' . $data->name);
161
            return true;
162
        } catch (PDOException $e) {
163
            Messages::addError($e->getMessage());
164
            Messages::addError(Trans::_('pdo_fail_db_creation', ['message' => $e->getMessage()]));
165
            return false;
166
        }
167
    }
168
}
169