Completed
Push — master ( 529f36...77a63f )
by Restu
13:12
created

Database::setModel()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 3
eloc 6
c 2
b 0
f 1
nc 3
nop 2
dl 0
loc 11
rs 9.4285
1
<?php
2
namespace JayaCode\Framework\Core\Database;
3
4
use JayaCode\Framework\Core\Database\Connector\Connector;
5
use JayaCode\Framework\Core\Database\Connector\ConnectorMySql;
6
use JayaCode\Framework\Core\Database\Query\Grammar\Grammar;
7
use JayaCode\Framework\Core\Database\Query\Grammar\GrammarMySql;
8
use JayaCode\Framework\Core\Database\Query\Query;
9
use PDO;
10
11
/**
12
 * Class Database
13
 * @package JayaCode\Framework\Core\Database
14
 */
15
class Database
16
{
17
    /**
18
     * @var Connector
19
     */
20
    protected $connector;
21
22
    /**
23
     * @var \PDO
24
     */
25
    protected $pdo;
26
27
    /**
28
     * @var \PDOStatement
29
     */
30
    protected $statement;
31
32
    /**
33
     * @var Query
34
     */
35
    protected $query;
36
37
    /**
38
     * @var Grammar
39
     */
40
    protected $grammar;
41
42
    /**
43
     * @var array
44
     */
45
    protected $driver = [
46
        "mysql" => [
47
            "connector" => ConnectorMySql::class,
48
            "grammar" => GrammarMySql::class,
49
        ]
50
    ];
51
52
    /**
53
     * @var array
54
     */
55
    protected $config = [
56
        "driver" => "mysql",
57
58
        "host" => "",
59
        "username" => "",
60
        "password" => "",
61
62
        "dbname" => "",
63
        "options" => [
64
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
65
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
66
        ]
67
    ];
68
69
    /**
70
     * @var string
71
     */
72
    protected $model = null;
73
74
    /**
75
     * @param $config
76
     */
77
    public function __construct($config)
78
    {
79
        $options = isset($config["options"])?
80
            arr_merge_all($this->config["options"], $config["options"])
81
            :$this->config["options"];
82
83
        $this->config = arr_merge_all($this->config, $config);
84
85
        $this->config['options'] = $options;
86
        $this->initialize();
87
88
        $this->createConnection();
89
    }
90
91
    /**
92
     * @param $config
93
     * @return static
94
     */
95
    public static function create($config)
96
    {
97
        return new static($config);
98
    }
99
100
    /**
101
     *
102
     */
103
    protected function initialize()
104
    {
105
        $connectorClass = $this->driver[$this->config["driver"]]["connector"];
106
        $this->connector = new $connectorClass();
107
108
        $grammarClass = $this->driver[$this->config["driver"]]["grammar"];
109
        $this->grammar = new $grammarClass();
110
111
        $this->query = new Query();
112
    }
113
114
    /**
115
     * @return PDO
116
     */
117
    public function createConnection()
118
    {
119
        $this->pdo = $this->connector->connect($this->config);
120
        return $this->pdo;
121
    }
122
123
    /**
124
     * @param $query
125
     * @param null $params
126
     * @return $this
127
     */
128
    public function sql($query, $params = null)
129
    {
130
        $this->query = $this->query->sql($query, $params);
131
        return $this;
132
    }
133
134
    /**
135
     * @param $table
136
     * @return $this
137
     */
138
    public function table($table)
139
    {
140
        $this->query->setTable($table);
141
        return $this;
142
    }
143
144
    /**
145
     * @param null $columns
146
     * @return $this
147
     */
148
    public function select($columns = null)
149
    {
150
        $this->query->select($columns);
151
        return $this;
152
    }
153
154
    /**
155
     * @param array $columnsVal
156
     * @return bool
157
     */
158
    public function insert(array $columnsVal)
159
    {
160
        $this->query->insert($columnsVal);
161
162
        $status = $this->execute();
163
        $this->clear();
164
165
        return $status;
166
    }
167
168
    /**
169
     * @param $query
170
     * @param string $type
171
     * @return Query
172
     */
173
    public function whereQ($query, $type = "AND")
174
    {
175
        $this->query->whereQ($query, $type);
176
        return $this;
177
    }
178
179
    /**
180
     * @param $column
181
     * @param $value
182
     * @param string $operator
183
     * @param string $type
184
     * @return $this
185
     */
186
    public function where($column, $value, $operator = "=", $type = "AND")
187
    {
188
        $this->query->where($column, $value, $operator, $type);
189
        return $this;
190
    }
191
192
    /**
193
     * @param $column
194
     * @param $value
195
     * @param string $operator
196
     * @return $this
197
     */
198
    public function andWhere($column, $value, $operator = "=")
199
    {
200
        $this->query->andWhere($column, $value, $operator);
201
        return $this;
202
    }
203
204
    /**
205
     * @param $column
206
     * @param $value
207
     * @param string $operator
208
     * @return $this
209
     */
210
    public function orWhere($column, $value, $operator = "=")
211
    {
212
        $this->query->orWhere($column, $value, $operator);
213
        return $this;
214
    }
215
216
    /**
217
     * @param $column
218
     * @param $value
219
     * @param string $type
220
     * @return $this
221
     */
222
    public function like($column, $value, $type = "AND")
223
    {
224
        $this->query->like($column, $value, $type);
225
        return $this;
226
    }
227
228
    /**
229
     * @param $column
230
     * @param $value
231
     * @return $this
232
     */
233
    public function andLike($column, $value)
234
    {
235
        $this->query->andLike($column, $value);
236
        return $this;
237
    }
238
239
    /**
240
     * @param $column
241
     * @param $value
242
     * @return $this
243
     */
244
    public function orLike($column, $value)
245
    {
246
        $this->query->orLike($column, $value);
247
        return $this;
248
    }
249
250
    /**
251
     * @param $column
252
     * @param $value
253
     * @param string $type
254
     * @return $this
255
     */
256
    public function between($column, $value, $type = "AND")
257
    {
258
        $this->query->between($column, $value, $type);
259
        return $this;
260
    }
261
262
    /**
263
     * @param $column
264
     * @param $value
265
     * @return $this
266
     */
267
    public function andBetween($column, $value)
268
    {
269
        $this->query->andBetween($column, $value);
270
        return $this;
271
    }
272
273
    /**
274
     * @param $column
275
     * @param $value
276
     * @return $this
277
     */
278
    public function orBetween($column, $value)
279
    {
280
        $this->query->orBetween($column, $value);
281
        return $this;
282
    }
283
284
    /**
285
     * @return bool
286
     */
287
    public function execute()
288
    {
289
        $qArr = $this->query->build($this->grammar);
290
291
        $this->statement = $this->pdo->prepare($qArr[0]);
292
293
        return $this->statement->execute($qArr[1]);
294
    }
295
296
    /**
297
     * @return array
298
     * @throws \Exception
299
     */
300
    public function all()
301
    {
302
        $this->executeIfNotAlreadyExecutedPreviously();
303
304
        if ($this->model) {
305
            $dataModel = array();
306
            while ($model = $this->get()) {
307
                $dataModel[] = $model;
308
            }
309
310
            $this->clear();
311
312
            return $dataModel;
313
        }
314
        return $this->statement->fetchAll();
315
    }
316
317
    /**
318
     * @return mixed
319
     */
320
    public function first()
321
    {
322
        // TODO: use limit after query builder limit finish
323
        $data = $this->get();
324
        $this->clear();
325
        return $data;
326
    }
327
328
    /**
329
     * @return mixed
330
     * @throws \Exception
331
     */
332
    protected function get()
333
    {
334
        $this->executeIfNotAlreadyExecutedPreviously();
335
336
        if ($this->model) {
337
            $data = $this->statement->fetch();
338
            return $data?new $this->model($data, false):$data;
339
        }
340
341
        return $this->statement->fetch();
342
    }
343
344
    /**
345
     * @throws \Exception
346
     */
347
    protected function executeIfNotAlreadyExecutedPreviously()
348
    {
349
        if (!$this->statement) {
350
            $this->execute();
351
        }
352
    }
353
354
    /**
355
     * Clear statement PDO and query builder
356
     */
357
    public function clear()
358
    {
359
        $this->statement = null;
360
        $this->clearUsingModel();
361
362
        $this->query->clear();
363
        $this->grammar->clear();
364
    }
365
366
    /**
367
     *
368
     */
369
    public function clearUsingModel()
370
    {
371
        $this->model = null;
372
    }
373
374
    /**
375
     * @return string
376
     */
377
    public function getModel()
378
    {
379
        return $this->model;
380
    }
381
382
    /**
383
     * @param string $model
384
     * @param null $table
385
     * @throws \Exception
386
     */
387
    public function setModel($model, $table = null)
388
    {
389
        if (!class_exists($model)) {
390
            throw new \Exception("class {$model} is not exist");
391
        }
392
393
        if ($table) {
394
            $this->table($table);
395
        }
396
        $this->model = $model;
397
    }
398
399
    /**
400
     * @return string
401
     */
402
    public function lastInsertId()
403
    {
404
        return $this->pdo->lastInsertId();
405
    }
406
}
407