Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
73.75% covered (success)
73.75%
59 / 80
87.50% covered (success)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Database
73.75% covered (success)
73.75%
59 / 80
87.50% covered (success)
87.50%
7 / 8
14.60
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setDb
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDb
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 save
50.00% covered (warning)
50.00%
21 / 42
0.00% covered (danger)
0.00%
0 / 1
6.00
 clear
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 createTable
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (https://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@noladev.com>
7 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
8 * @license    https://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Debug\Storage;
15
16use Pop\Db\Adapter\AbstractAdapter;
17use Pop\Debug\Handler\AbstractHandler;
18
19/**
20 * Debug database storage class
21 *
22 * @category   Pop
23 * @package    Pop\Debug
24 * @author     Nick Sagona, III <dev@noladev.com>
25 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    3.0.0
28 */
29class Database extends AbstractStorage
30{
31
32    /**
33     * DB adapter
34     * @var ?AbstractAdapter
35     */
36    protected ?AbstractAdapter $db = null;
37
38    /**
39     * Table
40     * @var string
41     */
42    protected string $table = 'pop_debug';
43
44    /**
45     * Constructor
46     *
47     * Instantiate the DB writer object
48     *
49     * The DB table requires the following fields at a minimum:
50
51     *     id    INT
52     *     value TEXT, VARCHAR, etc.
53     *
54     * @param  AbstractAdapter $db
55     * @param  string          $table
56     */
57    public function __construct(AbstractAdapter $db, string $table = 'pop_debug')
58    {
59        $this->setDb($db);
60        $this->setTable($table);
61
62        if (!$db->hasTable($this->table)) {
63            $this->createTable();
64        }
65    }
66
67    /**
68     * Set the current debug db adapter.
69     *
70     * @param  AbstractAdapter $db
71     * @return Database
72     */
73    public function setDb(AbstractAdapter $db): Database
74    {
75        $this->db = $db;
76        return $this;
77    }
78
79    /**
80     * Get the current debug db adapter.
81     *
82     * @return ?AbstractAdapter
83     */
84    public function getDb(): ?AbstractAdapter
85    {
86        return $this->db;
87    }
88
89    /**
90     * Get the current debug db table.
91     *
92     * @return string
93     */
94    public function getTable(): string
95    {
96        return $this->table;
97    }
98
99    /**
100     * Set the debug db table
101     *
102     * @param  string $table
103     * @return Database
104     */
105    public function setTable(string $table): Database
106    {
107        $this->table = $table;
108        return $this;
109    }
110
111    /**
112     * Save debug data
113     *
114     * @param  string          $id
115     * @param  string          $name
116     * @param  AbstractHandler $handler
117     * @return void
118     */
119    public function save(string $id, string $name, AbstractHandler $handler): void
120    {
121        $sql         = $this->db->createSql();
122        $placeholder = $sql->getPlaceholder();
123
124        if ($placeholder == ':') {
125            $placeholders = [
126                'key'     => ':key',
127                'handler' => ':handler',
128                'start'   => ':start',
129                'end'     => ':end',
130                'elapsed' => ':elapsed',
131                'type'    => ':type',
132                'message' => ':message',
133                'context' => ':context',
134            ];
135        } else if ($placeholder == '$') {
136            $placeholders = [
137                'key'     => '$1',
138                'handler' => '$2',
139                'start'   => '$3',
140                'end'     => '$4',
141                'elapsed' => '$5',
142                'type'    => '$6',
143                'message' => '$7',
144                'context' => '$8',
145            ];
146        } else {
147            $placeholders = [
148                'key'     => '?',
149                'handler' => '?',
150                'start'   => '?',
151                'end'     => '?',
152                'elapsed' => '?',
153                'type'    => '?',
154                'message' => '?',
155                'context' => '?',
156            ];
157        }
158
159        $events = $this->prepareEvents($id, $name, $handler);
160
161        foreach ($events as $event) {
162            $sql->reset()
163                ->insert($this->table)
164                ->values($placeholders);
165
166            // Save value
167            $this->db->prepare($sql)
168                ->bindParams($event)
169                ->execute();
170        }
171    }
172
173    /**
174     * Clear all debug data
175     *
176     * @return void
177     */
178    public function clear(): void
179    {
180        $sql = $this->db->createSql();
181        $sql->delete($this->table);
182        $this->db->query($sql);
183    }
184
185    /**
186     * Create table in database
187     *
188     * @return void
189     */
190    protected function createTable(): void
191    {
192        $schema = $this->db->createSchema();
193        $schema->create($this->table)
194            ->int('id')->increment()
195            ->varchar('key', 255)
196            ->varchar('handler', 255)
197            ->decimal('start', 16, 6)->nullable()
198            ->decimal('end', 16, 6)->nullable()
199            ->decimal('elapsed', 16, 6)->nullable()
200            ->varchar('type', 255)
201            ->text('message')->nullable()
202            ->text('context')->nullable()
203            ->primary('id');
204
205        $schema->execute();
206
207        $schema->alter($this->table)->index('key');
208        $schema->execute();
209
210        $schema->alter($this->table)->index('handler');
211        $schema->execute();
212
213        $schema->alter($this->table)->index('start');
214        $schema->execute();
215
216        $schema->alter($this->table)->index('end');
217        $schema->execute();
218
219        $schema->alter($this->table)->index('elapsed');
220        $schema->execute();
221
222        $schema->alter($this->table)->index('type');
223        $schema->execute();
224    }
225
226}