Test Failed
Push — main ( a047e2...82fe17 )
by Rafael
05:55
created

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

138
        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...
139
    }
140
141
    /**
142
     * Ejecuta una sentencia SELECT, retornando false si hay error, o un array
143
     * con el resultado de la consulta.
144
     *
145
     * @author  Rafael San José Tovar <[email protected]>
146
     * @version 2022.0721
147
     *
148
     * @param string $query
149
     * @param array  $vars
150
     *
151
     * @return array|false
152
     */
153
    public static function select(string $query, array $vars = [])
154
    {
155
        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

155
        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...
156
    }
157
158
    public static function getIndexes(string $tableName): array
159
    {
160
        return self::$helper::getIndexes(DB::$dbPrefix . $tableName);
161
    }
162
163
    public static function tableExists(string $tableName)
164
    {
165
        return self::$helper->tableExists(self::$dbPrefix . $tableName);
166
    }
167
168
    public static function getColumns(string $tableName)
169
    {
170
        return self::$helper->getColumns(self::$dbPrefix . $tableName);
171
    }
172
173
    public static function createIndex(string $tableName, string $index, array $data): string
174
    {
175
        return self::$helper->createIndex(self::$dbPrefix . $tableName, $index, $data);
176
    }
177
178
    public static function changeIndex(string $tableName, string $index, array $oldData, array $newData): string
179
    {
180
        return self::$helper->changeIndex($tableName, $index, $oldData, $newData);
181
    }
182
183
    public static function removeIndex(string $tableName, string $index): string
184
    {
185
        return self::$helper->removeIndex(self::$dbPrefix . $tableName, $index);
186
    }
187
188
    public static function _yamlFieldToDb(array $data): array
189
    {
190
        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...
191
    }
192
193
    public static function _dbFieldToSchema(array $data): array
194
    {
195
        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...
196
    }
197
198
    public static function _dbFieldToYaml(array $data): array
199
    {
200
        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...
201
    }
202
203
    public static function _normalizeFromDb(array $data)
204
    {
205
        $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...
206
        dump([
207
            'normalizeFromDb',
208
            'data' => $data,
209
            'result' => $result,
210
        ]);
211
        return $result;
212
    }
213
214
    public static function _normalizeFromYaml(array $yamlFields)
215
    {
216
        $result = [];
217
        foreach ($yamlFields as $field => $yamlField) {
218
            $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...
219
        }
220
        dump([
221
            'normalizeFromYaml',
222
            'data' => $yamlFields,
223
            'result' => $result,
224
        ]);
225
        return $result;
226
    }
227
228
    public static function _normalize(array $data)
229
    {
230
        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...
231
    }
232
233
    public static function modify(string $tableName, array $oldField, array $newField): string
234
    {
235
        return self::$helper->modify(self::$dbPrefix . $tableName, $oldField, $newField);
236
    }
237
238
    public static function _getUsername()
239
    {
240
        return self::$username;
241
    }
242
243
    public static function _connectToDatabaseAndAuth(): bool
244
    {
245
        if (!self::connectToDataBase()) {
246
            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...
247
            return false;
248
        }
249
        if (!isset(self::$user)) {
250
            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...
251
            self::$username = self::$user->getUser();
252
            if (self::$username === null) {
253
                self::$user->login();
254
            }
255
        }
256
        return true;
257
    }
258
259
}
260