Test Failed
Push — main ( a17396...e328ab )
by Rafael
05:43
created

DB::_connect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (C) 2022-2023  Rafael San José Tovar   <[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
 * (at your option) 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\Database;
20
21
use Alxarafe\Core\Singletons\Config;
22
use Alxarafe\Core\Singletons\Debug;
23
use Alxarafe\Core\Singletons\Translator;
24
use DebugBar\DebugBarException;
25
use Exception;
26
27
/**
28
 * Class DB
29
 *
30
 * Esta clase proporciona acceso directo a la base de datos.
31
 *
32
 * @author  Rafael San José Tovar <[email protected]>
33
 * @version 2022.0721
34
 *
35
 */
36
abstract class DB
37
{
38
    /**
39
     * Motor utilizado, puede ser MySql, MariaDB, PostgreSql o cualquier otro PDO
40
     *
41
     * @var Engine
42
     */
43
    public static Engine $engine;
44
45
    /**
46
     * Instancia de la clase con el código SQL específico del motor.
47
     *
48
     * @var SqlHelper
49
     */
50
    public static SqlHelper $helper;
51
52
    /**
53
     * Prefijo de la base de datos en uso
54
     *
55
     * @var string
56
     */
57
    public static string $dbPrefix;
58
59
    /**
60
     * Nombre de la base de datos en uso
61
     *
62
     * @var string
63
     */
64
    public static string $dbName;
65
66
    public static $user;
67
    public static $username;
68
69
    /**
70
     * Establece conexión con una base de datos.
71
     *
72
     * TODO: La idea en un futuro, es que se pueda establecer conexión con múltiples
73
     *       bases de datos pasándole el nombre de la conexión.
74
     *       El problema es, cómo invocar de forma fácil qué conexión queremos.
75
     *       Si se mantiene como clase abstracta es complicado, lo más fácil sería
76
     *       creando una instancia para cada conexión, pero no se podría utilizar como
77
     *       clase abstracta (o ahora mismo, no caigo en cómo hacerlo).
78
     *
79
     * @param string $db
80
     *
81
     * @return bool
82
     * @throws DebugBarException
83
     */
84
    public static function connectToDatabase(string $db = 'main'): bool
85
    {
86
        // TODO: Revisar ésto, porque debe de haber una conexión para cada base de datos según $db
87
        if (isset(self::$engine)) {
88
            return true;
89
        }
90
91
        $dbInfo = Config::getModuleVar('database');
92
        if (!isset($dbInfo[$db])) {
93
            Debug::sqlMessage(Translator::trans('empty-database-config', ['%name%' => $db]));
94
            return false;
95
        }
96
97
        self::$dbPrefix = strtolower($dbInfo[$db]['dbPrefix'] ?? '');
98
        self::$dbName = strtolower($dbInfo[$db]['dbName']);
99
100
        $engineName = $dbInfo[$db]['dbEngineName'] ?? 'PdoMySql';
101
        $helperName = 'Sql' . substr($engineName, 3);
102
103
        Debug::sqlMessage("Using '$engineName' engine.");
104
        Debug::sqlMessage("Using '$helperName' SQL helper engine.");
105
106
        $sqlEngine = '\\Alxarafe\\Database\\SqlHelpers\\' . $helperName;
107
        $engine = '\\Alxarafe\\Database\\Engines\\' . $engineName;
108
        try {
109
            self::$helper = new $sqlEngine();
110
            self::$engine = new $engine([
111
                'dbUser' => $dbInfo[$db]['dbUser'],
112
                'dbPass' => $dbInfo[$db]['dbPass'],
113
                'dbName' => self::$dbName,
114
                'dbHost' => $dbInfo[$db]['dbHost'],
115
                'dbPort' => $dbInfo[$db]['dbPort'],
116
            ]);
117
            return isset(self::$engine) && self::$engine->connect() && self::$engine->checkConnection();
118
        } catch (Exception $e) {
119
            Debug::addException($e);
120
        }
121
        return false;
122
    }
123
124
    public static function _connect()
125
    {
126
        return self::$engine[$db]->connect();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
127
    }
128
129
    public static function _disconnect()
130
    {
131
        return self::$engine[$db]->disconnect();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
132
    }
133
134
    public static function _connected()
135
    {
136
        return self::$engine[$db]->connected();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
137
    }
138
139
    public static function _getDataTypes()
140
    {
141
        return self::$helper[$db]->getDataTypes();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
142
    }
143
144
    /**
145
     * Ejecuta una sentencia SQL retornando TRUE si ha tenido éxito
146
     *
147
     * @author  Rafael San José Tovar <[email protected]>
148
     * @version 2022.0721
149
     *
150
     * @param string $query
151
     * @param array  $vars
152
     *
153
     * @return bool
154
     */
155
    public static function exec(string $query, array $vars = []): bool
156
    {
157
        return self::$engine->exec($query, $vars);
0 ignored issues
show
Unused Code introduced by
The call to Alxarafe\Database\Engine::exec() has too many arguments starting with $vars. ( Ignorable by Annotation )

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

157
        return self::$engine->/** @scrutinizer ignore-call */ exec($query, $vars);

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...
158
    }
159
160
    /**
161
     * Ejecuta una sentencia SELECT, retornando false si hay error, o un array
162
     * con el resultado de la consulta.
163
     *
164
     * @author  Rafael San José Tovar <[email protected]>
165
     * @version 2022.0721
166
     *
167
     * @param string $query
168
     * @param array  $vars
169
     *
170
     * @return array|false
171
     */
172
    public static function select(string $query, array $vars = [])
173
    {
174
        return self::$engine->select($query, $vars);
0 ignored issues
show
Unused Code introduced by
The call to Alxarafe\Database\Engine::select() has too many arguments starting with $vars. ( Ignorable by Annotation )

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

174
        return self::$engine->/** @scrutinizer ignore-call */ select($query, $vars);

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...
175
    }
176
177
    /**
178
     * Retorna el tipo de datos que se utiliza para los índices
179
     *
180
     * @author Rafael San José Tovar <[email protected]>
181
     *
182
     * @return string
183
     */
184
    public static function getIndexType(): string
185
    {
186
        return self::$helper->getIndexType();
187
    }
188
189
    public static function _getErrors()
190
    {
191
        return self::$engine[$db]->getErrors();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
192
    }
193
194
    public static function _beginTransaction()
195
    {
196
        return self::$engine[$db]->beginTransaction();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
197
    }
198
199
    public static function _commit()
200
    {
201
        return self::$engine[$db]->commit();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
202
    }
203
204
    public static function _close()
205
    {
206
        return self::$engine[$db]->close();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
207
    }
208
209
    public static function _rollback()
210
    {
211
        return self::$engine[$db]->rollback();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
212
    }
213
214
    public static function _version()
215
    {
216
        return self::$engine[$db]->server_info();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
217
    }
218
219
    public static function tableExists(string $tableName)
220
    {
221
        return self::$helper->tableExists(self::$dbPrefix . $tableName);
222
    }
223
224
    public static function getColumns(string $tableName)
225
    {
226
        return self::$helper->getColumns(self::$dbPrefix . $tableName);
227
    }
228
229
    public static function _yamlFieldToDb(array $data): array
230
    {
231
        return self::$helper[$db]::yamlFieldToDb($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
232
    }
233
234
    public static function _dbFieldToSchema(array $data): array
235
    {
236
        return self::$helper[$db]::dbFieldToSchema($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
237
    }
238
239
    public static function _dbFieldToYaml(array $data): array
240
    {
241
        return self::$helper[$db]::dbFieldToYaml($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
242
    }
243
244
    public static function _normalizeFromDb(array $data)
245
    {
246
        $result = self::$helper[$db]::normalizeDbField($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
247
        dump([
248
            'normalizeFromDb',
249
            'data' => $data,
250
            'result' => $result,
251
        ]);
252
        return $result;
253
    }
254
255
    public static function _normalizeFromYaml(array $yamlFields)
256
    {
257
        $result = [];
258
        foreach ($yamlFields as $field => $yamlField) {
259
            $result[$field] = self::$helper[$db]::normalizeYamlField($yamlField);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
260
        }
261
        dump([
262
            'normalizeFromYaml',
263
            'data' => $yamlFields,
264
            'result' => $result,
265
        ]);
266
        return $result;
267
    }
268
269
    public static function _normalize(array $data)
270
    {
271
        return self::$helper[$db]->normalizeField($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $db seems to be never defined.
Loading history...
272
    }
273
274
    public static function modify(string $tableName, array $oldField, array $newField): string
275
    {
276
        return self::$helper->modify(self::$dbPrefix . $tableName, $oldField, $newField);
277
    }
278
279
    public static function _getUsername()
280
    {
281
        return self::$username;
282
    }
283
284
    public static function _connectToDatabaseAndAuth(): bool
285
    {
286
        if (!self::connectToDataBase()) {
287
            FlashMessages::setError('Database Connection error...');
0 ignored issues
show
Bug introduced by
The type Alxarafe\Database\FlashMessages was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
288
            return false;
289
        }
290
        if (!isset(self::$user)) {
291
            self::$user = new Auth();
0 ignored issues
show
Bug introduced by
The type Alxarafe\Database\Auth was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
292
            self::$username = self::$user->getUser();
293
            if (self::$username === null) {
294
                self::$user->login();
295
            }
296
        }
297
        return true;
298
    }
299
300
}
301