Passed
Pull Request — master (#312)
by Arman
03:34
created

IdiormDbal::getForeignKeys()   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 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.8
13
 */
14
15
namespace Quantum\Libraries\Database\Adapters\Idiorm;
16
17
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Transaction;
18
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Criteria;
19
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Reducer;
20
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Result;
21
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Query;
22
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Model;
23
use Quantum\Libraries\Database\Adapters\Idiorm\Statements\Join;
24
use Quantum\Libraries\Database\Contracts\RelationalInterface;
25
use Quantum\Libraries\Database\Exceptions\DatabaseException;
26
use Quantum\Libraries\Database\Contracts\DbalInterface;
27
use InvalidArgumentException;
28
use ORM;
29
use PDO;
30
31
/**
32
 * Class IdiormDbal
33
 * @package Quantum\Libraries\Database
34
 */
35
class IdiormDbal implements DbalInterface, RelationalInterface
36
{
37
38
    use Transaction;
39
    use Model;
40
    use Result;
41
    use Criteria;
42
    use Reducer;
43
    use Join;
44
    use Query;
45
46
    /**
47
     * SQLite driver
48
     */
49
    const DRIVER_SQLITE = 'sqlite';
50
51
    /**
52
     * MySQL driver
53
     */
54
    const DRIVER_MYSQL = 'mysql';
55
56
    /**
57
     * PostgresSQL driver
58
     */
59
    const DRIVER_PGSQL = 'pgsql';
60
61
    /**
62
     * Default charset
63
     */
64
    const DEFAULT_CHARSET = 'utf8';
65
66
    /**
67
     * Associated model name
68
     * @var string
69
     */
70
    private $modelName;
71
72
    /**
73
     * The database table associated with model
74
     * @var string
75
     */
76
    private $table;
77
78
    /**
79
     * Id column of table
80
     * @var string
81
     */
82
    private $idColumn;
83
84
    /**
85
     * Foreign keys
86
     * @var array
87
     */
88
    private $foreignKeys;
89
90
    /**
91
     * Hidden fields
92
     * @var array
93
     */
94
    private $hidden;
95
96
    /**
97
     * Idiorm Patch object
98
     * @var IdiormPatch
99
     */
100
    private $ormPatch = null;
0 ignored issues
show
introduced by
The private property $ormPatch is not used, and could be removed.
Loading history...
101
102
    /**
103
     * ORM Model
104
     * @var object
105
     */
106
    private $ormModel;
107
108
    /**
109
     * Active connection
110
     * @var array|null
111
     */
112
    private static $connection = null;
113
114
    /**
115
     * Operators map
116
     * @var string[]
117
     */
118
    private $operators = [
0 ignored issues
show
introduced by
The private property $operators is not used, and could be removed.
Loading history...
119
        '=' => 'where_equal',
120
        '!=' => 'where_not_equal',
121
        '>' => 'where_gt',
122
        '>=' => 'where_gte',
123
        '<' => 'where_lt',
124
        '<=' => 'where_lte',
125
        'IN' => 'where_in',
126
        'NOT IN' => 'where_not_in',
127
        'LIKE' => 'where_like',
128
        'NOT LIKE' => 'where_not_like',
129
        'NULL' => 'where_null',
130
        'NOT NULL' => 'where_not_null',
131
        '#=#' => null,
132
    ];
133
134
    /**
135
     * ORM Class
136
     * @var string
137
     */
138
    private static $ormClass = ORM::class;
139
140
    /**
141
     * @param string $table
142
     * @param string|null $modelName
143
     * @param string $idColumn
144
     * @param array $foreignKeys
145
     * @param array $hidden
146
     */
147
    public function __construct(
148
        string $table,
149
        string $modelName = null,
150
        string $idColumn = 'id',
151
        array $foreignKeys = [],
152
        array $hidden = []
153
    )
154
    {
155
        $this->modelName = $modelName;
156
        $this->table = $table;
157
        $this->idColumn = $idColumn;
158
        $this->foreignKeys = $foreignKeys;
159
        $this->hidden = $hidden;
160
    }
161
162
    /**
163
     * @inheritDoc
164
     */
165
    public static function connect(array $config)
166
    {
167
        $driver = $config['driver'] ?? '';
168
        $charset = $config['charset'] ?? self::DEFAULT_CHARSET;
169
170
        $configuration = self::getBaseConfig($driver, $config) + self::getDriverConfig($driver, $config, $charset);
171
172
        (self::$ormClass)::configure($configuration);
173
174
        self::$connection = (self::$ormClass)::get_config();
175
    }
176
177
    /**
178
     * @inheritDoc
179
     */
180
    public static function getConnection(): ?array
181
    {
182
        return self::$connection;
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    public static function disconnect()
189
    {
190
        self::$connection = null;
191
        (self::$ormClass)::reset_db();
192
    }
193
194
    /**
195
     * @inheritDoc
196
     */
197
    public function getTable(): string
198
    {
199
        return $this->table;
200
    }
201
202
    /**
203
     * Gets the ORM model
204
     * @return ORM
205
     * @throws DatabaseException
206
     */
207
    public function getOrmModel(): ORM
208
    {
209
        if (!$this->ormModel) {
210
            if (!self::getConnection()) {
211
                throw DatabaseException::missingConfig();
212
            }
213
214
            $this->ormModel = (self::$ormClass)::for_table($this->table)->use_id_column($this->idColumn);
215
        }
216
217
        return $this->ormModel;
218
    }
219
220
    /**
221
     * Gets foreign keys
222
     * @return array
223
     */
224
    public function getForeignKeys(): array
225
    {
226
        return $this->foreignKeys;
227
    }
228
229
    /**
230
     * Gets the associated model name
231
     * @return string
232
     */
233
    public function getModelName(): string
234
    {
235
        return $this->modelName;
236
    }
237
238
    /**
239
     * @param ORM $ormModel
240
     */
241
    protected function updateOrmModel(ORM $ormModel)
242
    {
243
        $this->ormModel = $ormModel;
244
    }
245
246
    /**
247
     * @param string $driver
248
     * @param array $config
249
     * @return array
250
     */
251
    protected static function getBaseConfig(string $driver, array $config): array
252
    {
253
        return [
254
            'connection_string' => self::buildConnectionString($driver, $config),
255
            'logging' => config()->get('debug', false),
256
            'error_mode' => PDO::ERRMODE_EXCEPTION,
257
        ];
258
    }
259
260
    /**
261
     * @param string $driver
262
     * @param array $config
263
     * @param string $charset
264
     * @return array
265
     */
266
    protected static function getDriverConfig(string $driver, array $config, string $charset): array
267
    {
268
        if ($driver === self::DRIVER_MYSQL || $driver === self::DRIVER_PGSQL) {
269
            return [
270
                'username' => $config['username'] ?? null,
271
                'password' => $config['password'] ?? null,
272
                'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $charset],
273
            ];
274
        }
275
276
        if ($driver === self::DRIVER_SQLITE) {
277
            return [];
278
        }
279
280
        throw new InvalidArgumentException("Unsupported driver: $driver");
281
    }
282
283
    /**
284
     * Builds connection string
285
     * @param string $driver
286
     * @param array $config
287
     * @return string
288
     */
289
    protected static function buildConnectionString(string $driver, array $config): string
290
    {
291
        if ($driver === self::DRIVER_SQLITE) {
292
            return $driver . ':' . ($config['database'] ?? '');
293
        }
294
295
        if ($driver === self::DRIVER_MYSQL || $driver === self::DRIVER_PGSQL) {
296
            $parts = [
297
                'host=' . ($config['host'] ?? ''),
298
                'dbname=' . ($config['dbname'] ?? ''),
299
            ];
300
301
            if (!empty($config['port'])) {
302
                $parts[] = 'port=' . $config['port'];
303
            }
304
305
            if (!empty($config['charset'])) {
306
                $parts[] = 'charset=' . $config['charset'];
307
            }
308
309
            return $driver . ':' . implode(';', $parts);
310
        }
311
312
        throw new InvalidArgumentException("Unsupported driver: $driver");
313
    }
314
}