Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.78% covered (success)
97.78%
88 / 90
94.44% covered (success)
94.44%
17 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Schema
97.78% covered (success)
97.78%
88 / 90
94.44% covered (success)
94.44%
17 / 18
51
0.00% covered (danger)
0.00%
0 / 1
 create
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createIfNotExists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 drop
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 dropIfExists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 alter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rename
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 truncate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 enableForeignKeyCheck
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 disableForeignKeyCheck
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 render
91.30% covered (success)
91.30%
21 / 23
0.00% covered (danger)
0.00%
0 / 1
12.09
 reset
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
18
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCreateTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getDropTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getAlterTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getRenameTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getTruncateTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Db\Sql;
15
16/**
17 * Sql schema table class
18 *
19 * @category   Pop
20 * @package    Pop\Db
21 * @author     Nick Sagona, III <dev@nolainteractive.com>
22 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
23 * @license    http://www.popphp.org/license     New BSD License
24 * @version    6.5.0
25 */
26class Schema extends AbstractSql
27{
28
29    /**
30     * DROP table schema objects
31     * @var array
32     */
33    protected array $drop = [];
34
35    /**
36     * CREATE table schema objects
37     * @var array
38     */
39    protected array $create = [];
40
41    /**
42     * ALTER table schema objects
43     * @var array
44     */
45    protected array $alter = [];
46
47    /**
48     * RENAME table schema objects
49     * @var array
50     */
51    protected array $rename = [];
52
53    /**
54     * TRUNCATE table schema objects
55     * @var array
56     */
57    protected array $truncate = [];
58
59    /**
60     * Foreign key check flag
61     * @var bool
62     */
63    protected bool $foreignKeyCheck = true;
64
65    /**
66     * Access the CREATE table object
67     *
68     * @param  string $table
69     * @return Schema\Create
70     */
71    public function create(string $table): Schema\Create
72    {
73        return $this->getCreateTable($table);
74    }
75
76    /**
77     * Access the CREATE table object, setting IF NOT EXISTS
78     *
79     * @param  string $table
80     * @return Schema\Create
81     */
82    public function createIfNotExists(string $table): Schema\Create
83    {
84        $this->getCreateTable($table)->ifNotExists();
85        return $this->getCreateTable($table);
86    }
87
88    /**
89     * Access the DROP table object
90     *
91     * @param  string $table
92     * @return Schema\Drop
93     */
94    public function drop(string $table): Schema\Drop
95    {
96        return $this->getDropTable($table);
97    }
98
99    /**
100     * Access the DROP table object, setting IF EXISTS
101     *
102     * @param  string $table
103     * @return Schema\Drop
104     */
105    public function dropIfExists(string $table): Schema\Drop
106    {
107        return $this->getDropTable($table)->ifExists();
108    }
109
110    /**
111     * Access the ALTER table object
112     *
113     * @param  string $table
114     * @return Schema\Alter
115     */
116    public function alter(string $table): Schema\Alter
117    {
118        return $this->getAlterTable($table);
119    }
120
121    /**
122     * Access the RENAME table object
123     *
124     * @param  string $table
125     * @return Schema\Rename
126     */
127    public function rename(string $table): Schema\Rename
128    {
129        return $this->getRenameTable($table);
130    }
131
132    /**
133     * Access the TRUNCATE table object
134     *
135     * @param  string $table
136     * @return Schema\Truncate
137     */
138    public function truncate(string $table): Schema\Truncate
139    {
140        return $this->getTruncateTable($table);
141    }
142
143    /**
144     * Enable the foreign key check
145     *
146     * @return Schema
147     */
148    public function enableForeignKeyCheck(): Schema
149    {
150        $this->foreignKeyCheck = true;
151        return $this;
152    }
153
154    /**
155     * Disable the foreign key check
156     *
157     * @return Schema
158     */
159    public function disableForeignKeyCheck(): Schema
160    {
161        $this->foreignKeyCheck = false;
162        return $this;
163    }
164
165    /**
166     * Render the schema
167     *
168     * @return string
169     */
170    public function render(): string
171    {
172        $sql = '';
173
174        if (!$this->foreignKeyCheck) {
175            if ($this->isMysql()) {
176                $sql .= 'SET foreign_key_checks = 0;' . PHP_EOL . PHP_EOL;
177            } else if ($this->isSqlite()) {
178                $sql .= 'PRAGMA foreign_keys=off;' . PHP_EOL . PHP_EOL;
179            }
180        }
181
182        // Render DROP tables
183        foreach ($this->drop as $drop) {
184            $sql .= $drop->render();
185        }
186
187        // Render CREATE tables
188        foreach ($this->create as $create) {
189            $sql .= $create->render();
190        }
191
192        // Render ALTER tables
193        foreach ($this->alter as $alter) {
194            $sql .= $alter->render();
195        }
196
197        // Render RENAME tables
198        foreach ($this->rename as $rename) {
199            $sql .= $rename->render();
200        }
201
202        // Render TRUNCATE tables
203        foreach ($this->truncate as $truncate) {
204            $sql .= $truncate->render();
205        }
206
207        if (!$this->foreignKeyCheck) {
208            if ($this->isMysql()) {
209                $sql .= 'SET foreign_key_checks = 1;' . PHP_EOL . PHP_EOL;
210            } else if ($this->isSqlite()) {
211                $sql .= 'PRAGMA foreign_keys=on;' . PHP_EOL . PHP_EOL;
212            }
213        }
214
215        $this->reset();
216
217        return $sql;
218    }
219
220    /**
221     * Reset and clear the schema object
222     *
223     * @return Schema
224     */
225    public function reset(): Schema
226    {
227        $this->drop            = [];
228        $this->create          = [];
229        $this->alter           = [];
230        $this->rename          = [];
231        $this->truncate        = [];
232        $this->foreignKeyCheck = true;
233
234        return $this;
235    }
236
237    /**
238     * Execute the schema directly
239     *
240     * @param  bool $reset
241     * @return void
242     */
243    public function execute(bool $reset = true): void
244    {
245        if (!$this->foreignKeyCheck) {
246            if ($this->isMysql()) {
247                $this->db->query('SET foreign_key_checks = 0');
248            } else if ($this->isSqlite()) {
249                $this->db->query('PRAGMA foreign_keys=off');
250            }
251        }
252
253        // Execute DROP tables
254        foreach ($this->drop as $drop) {
255            $dropStatements = $drop->renderToStatements();
256            foreach ($dropStatements as $statement) {
257                $this->db->query($statement);
258            }
259        }
260
261        // Execute CREATE tables
262        foreach ($this->create as $create) {
263            $createStatements = $create->renderToStatements();
264            foreach ($createStatements as $statement) {
265                $this->db->query($statement);
266            }
267        }
268
269        // Execute ALTER tables
270        foreach ($this->alter as $alter) {
271            $alterStatements = $alter->renderToStatements();
272            foreach ($alterStatements as $statement) {
273                $this->db->query($statement);
274            }
275        }
276
277        // Execute RENAME tables
278        foreach ($this->rename as $rename) {
279            $renameStatements = $rename->renderToStatements();
280            foreach ($renameStatements as $statement) {
281                $this->db->query($statement);
282            }
283        }
284
285        // Execute TRUNCATE tables
286        foreach ($this->truncate as $truncate) {
287            $truncateStatements = $truncate->renderToStatements();
288            foreach ($truncateStatements as $statement) {
289                $this->db->query($statement);
290            }
291        }
292
293        if (!$this->foreignKeyCheck) {
294            if ($this->isMysql()) {
295                $this->db->query('SET foreign_key_checks = 1');
296            } else if ($this->isSqlite()) {
297                $this->db->query('PRAGMA foreign_keys=on');
298            }
299        }
300
301        if ($reset) {
302            $this->reset();
303        }
304    }
305
306    /**
307     * Render the schema to string
308     *
309     * @return string
310     */
311    public function __toString(): string
312    {
313        return $this->render();
314    }
315
316    /**
317     * Get the CREATE table object
318     *
319     * @param  string $table
320     * @return Schema\Create
321     */
322    protected function getCreateTable(string $table): Schema\Create
323    {
324        if (!isset($this->create[$table])) {
325            $this->create[$table] = new Schema\Create($table, $this->db);
326        }
327        return $this->create[$table];
328    }
329
330    /**
331     * Get the DROP table object
332     *
333     * @param  string $table
334     * @return Schema\Drop
335     */
336    protected function getDropTable(string $table): Schema\Drop
337    {
338        if (!isset($this->drop[$table])) {
339            $this->drop[$table] = new Schema\Drop($table, $this->db);
340        }
341        return $this->drop[$table];
342    }
343
344    /**
345     * Get the ALTER table object
346     *
347     * @param  string $table
348     * @return Schema\Alter
349     */
350    protected function getAlterTable(string $table): Schema\Alter
351    {
352        if (!isset($this->alter[$table])) {
353            $this->alter[$table] = new Schema\Alter($table, $this->db);
354        }
355        return $this->alter[$table];
356    }
357
358    /**
359     * Get the RENAME table object
360     *
361     * @param  string $table
362     * @return Schema\Rename
363     */
364    protected function getRenameTable(string $table): Schema\Rename
365    {
366        if (!isset($this->rename[$table])) {
367            $this->rename[$table] = new Schema\Rename($table, $this->db);
368        }
369        return $this->rename[$table];
370    }
371
372    /**
373     * Get the TRUNCATE table object
374     *
375     * @param  string $table
376     * @return Schema\Truncate
377     */
378    protected function getTruncateTable(string $table): Schema\Truncate
379    {
380        if (!isset($this->truncate[$table])) {
381            $this->truncate[$table] = new Schema\Truncate($table, $this->db);
382        }
383        return $this->truncate[$table];
384    }
385
386}