Completed
Push — master ( 949155...ad6d52 )
by Arman
14s queued 10s
created

IdiormDbal::updateOrmModel()   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 1
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 3.0.0
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 Quantum\App\Exceptions\BaseException;
28
use InvalidArgumentException;
29
use ORM;
30
use PDO;
31
32
/**
33
 * Class IdiormDbal
34
 * @package Quantum\Libraries\Database
35
 */
36
class IdiormDbal implements DbalInterface, RelationalInterface
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
    public const DRIVER_SQLITE = 'sqlite';
50
51
    /**
52
     * MySQL driver
53
     */
54
    public const DRIVER_MYSQL = 'mysql';
55
56
    /**
57
     * PostgresSQL driver
58
     */
59
    public const DRIVER_PGSQL = 'pgsql';
60
61
    /**
62
     * Default charset
63
     */
64
    public 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 ORM|null
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 array<string, string|null>
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
        $this->modelName = $modelName;
155
        $this->table = $table;
156
        $this->idColumn = $idColumn;
157
        $this->foreignKeys = $foreignKeys;
158
        $this->hidden = $hidden;
159
    }
160
161
    /**
162
     * @inheritDoc
163
     */
164
    public static function connect(array $config)
165
    {
166
        $driver = $config['driver'] ?? '';
167
        $charset = $config['charset'] ?? self::DEFAULT_CHARSET;
168
169
        $configuration = self::getBaseConfig($driver, $config) + self::getDriverConfig($driver, $config, $charset);
170
171
        (self::$ormClass)::configure($configuration);
172
173
        self::$connection = (self::$ormClass)::get_config();
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179
    public static function getConnection(): ?array
180
    {
181
        return self::$connection;
182
    }
183
184
    /**
185
     * @inheritDoc
186
     */
187
    public static function disconnect()
188
    {
189
        self::$connection = null;
190
        (self::$ormClass)::reset_db();
191
    }
192
193
    /**
194
     * @inheritDoc
195
     */
196
    public function getTable(): string
197
    {
198
        return $this->table;
199
    }
200
201
    /**
202
     * Gets the ORM model
203
     * @return ORM
204
     * @throws BaseException
205
     */
206
    public function getOrmModel(): ORM
207
    {
208
        if (!$this->ormModel) {
209
            if (!self::getConnection()) {
210
                throw DatabaseException::missingConfig('database');
211
            }
212
213
            $this->ormModel = (self::$ormClass)::for_table($this->table)->use_id_column($this->idColumn);
214
        }
215
216
        return $this->ormModel;
217
    }
218
219
    /**
220
     * Gets foreign keys
221
     * @return array
222
     */
223
    public function getForeignKeys(): array
224
    {
225
        return $this->foreignKeys;
226
    }
227
228
    /**
229
     * Gets the associated model name
230
     * @return string
231
     */
232
    public function getModelName(): string
233
    {
234
        return $this->modelName;
235
    }
236
237
    /**
238
     * @inheritDoc
239
     */
240
    public function truncate(): bool
241
    {
242
        try {
243
            $this->getOrmModel()->raw_execute("DELETE FROM {$this->table}");
244
            return true;
245
        } catch (\Exception $e) {
246
            return false;
247
        }
248
    }
249
250
    /**
251
     * @param ORM $ormModel
252
     */
253
    protected function updateOrmModel(ORM $ormModel)
254
    {
255
        $this->ormModel = $ormModel;
256
    }
257
258
    /**
259
     * @param string $driver
260
     * @param array $config
261
     * @return array
262
     */
263
    protected static function getBaseConfig(string $driver, array $config): array
264
    {
265
        return [
266
            'connection_string' => self::buildConnectionString($driver, $config),
267
            'logging' => config()->get('app.debug', false),
268
            'error_mode' => PDO::ERRMODE_EXCEPTION,
269
        ];
270
    }
271
272
    /**
273
     * @param string $driver
274
     * @param array $config
275
     * @param string $charset
276
     * @return array
277
     */
278
    protected static function getDriverConfig(string $driver, array $config, string $charset): array
279
    {
280
        if ($driver === self::DRIVER_MYSQL || $driver === self::DRIVER_PGSQL) {
281
            return [
282
                'username' => $config['username'] ?? null,
283
                'password' => $config['password'] ?? null,
284
                'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $charset],
285
            ];
286
        }
287
288
        if ($driver === self::DRIVER_SQLITE) {
289
            return [];
290
        }
291
292
        throw new InvalidArgumentException("Unsupported driver: $driver");
293
    }
294
295
    /**
296
     * Builds connection string
297
     * @param string $driver
298
     * @param array $config
299
     * @return string
300
     */
301
    protected static function buildConnectionString(string $driver, array $config): string
302
    {
303
        if ($driver === self::DRIVER_SQLITE) {
304
            return $driver . ':' . ($config['database'] ?? '');
305
        }
306
307
        if ($driver === self::DRIVER_MYSQL || $driver === self::DRIVER_PGSQL) {
308
            $parts = [
309
                'host=' . ($config['host'] ?? ''),
310
                'dbname=' . ($config['dbname'] ?? ''),
311
            ];
312
313
            if (!empty($config['port'])) {
314
                $parts[] = 'port=' . $config['port'];
315
            }
316
317
            if (!empty($config['charset'])) {
318
                $parts[] = 'charset=' . $config['charset'];
319
            }
320
321
            return $driver . ':' . implode(';', $parts);
322
        }
323
324
        throw new InvalidArgumentException("Unsupported driver: $driver");
325
    }
326
}
327