source: trunk/Packages/Common/Database.php

Last change on this file was 95, checked in by chronos, 3 years ago
  • Modified: Updated Common package.
  • Added: Explicit types for better type checking.
  • Fixed: Support for php 8.0.
File size: 7.7 KB
Line 
1<?php
2
3// Extended database class
4// Date: 2020-11-10
5
6function microtime_float()
7{
8 list($usec, $sec) = explode(" ", microtime());
9 return (float)$usec + (float)$sec;
10}
11
12class DatabaseResult
13{
14 public PDOStatement $PDOStatement;
15 public int $num_rows = 0;
16
17 function fetch_assoc()
18 {
19 return $this->PDOStatement->fetch(PDO::FETCH_ASSOC);
20 }
21
22 function fetch_array()
23 {
24 return $this->PDOStatement->fetch(PDO::FETCH_BOTH);
25 }
26
27 function fetch_row()
28 {
29 return $this->PDOStatement->fetch(PDO::FETCH_NUM);
30 }
31}
32
33class Database
34{
35 public string $Prefix;
36 public array $Functions;
37 public string $Type;
38 public PDO $PDO;
39 public string $Error;
40 public string $insert_id;
41 public string $LastQuery;
42 public bool $ShowSQLError;
43 public bool $ShowSQLQuery;
44 public bool $LogSQLQuery;
45 public string $LogFile;
46 public string $Database;
47
48 function __construct()
49 {
50 $this->Prefix = '';
51 $this->Functions = array('NOW(', 'CURDATE(', 'CURTIME(', 'UUID(', 'SHA1(');
52 $this->Type = 'mysql'; // mysql, pgsql
53 $this->Error = '';
54 $this->LastQuery = '';
55 $this->ShowSQLError = false;
56 $this->ShowSQLQuery = false;
57 $this->LogSQLQuery = false;
58 $this->LogFile = dirname(__FILE__).'/../../Query.log';
59 $this->Database = '';
60 }
61
62 function Connect(string $Host, string $User, string $Password, string $Database): void
63 {
64 if ($this->Type == 'mysql') $ConnectionString = 'mysql:host='.$Host.';dbname='.$Database;
65 else if ($this->Type == 'pgsql') $ConnectionString = 'pgsql:dbname='.$Database.';host='.$Host;
66 else $ConnectionString = '';
67 $this->Database = $Database;
68 try {
69 $this->PDO = new PDO($ConnectionString, $User, $Password);
70 } catch (Exception $E)
71 {
72 unset($this->PDO);
73 throw new Exception($E->getMessage());
74 }
75 }
76
77 function Disconnect(): void
78 {
79 unset($this->PDO);
80 }
81
82 function Connected(): bool
83 {
84 return isset($this->PDO);
85 }
86
87 function select_db(string $Database)
88 {
89 $this->query('USE `'.$Database.'`');
90 }
91
92 function query($Query): DatabaseResult
93 {
94 if (!$this->Connected()) throw new Exception(T('Not connected to database'));
95 if (($this->ShowSQLQuery == true) or ($this->LogSQLQuery == true)) $QueryStartTime = microtime_float();
96 $this->LastQuery = $Query;
97 //echo('a'.$this->ShowSQLQuery.'<'.$QueryStartTime.', '.microtime_float());
98 if (($this->ShowSQLQuery == true) or ($this->LogSQLQuery == true))
99 {
100 $Time = round(microtime_float() - $QueryStartTime, 4);
101 $Duration = ' ; '.$Time. ' s';
102 }
103 if (($this->LogSQLQuery == true) and ($Time != 0))
104 file_put_contents($this->LogFile, $Query.$Duration."\n", FILE_APPEND);
105 if ($this->ShowSQLQuery == true)
106 echo('<div style="border-bottom-width: 1px; border-bottom-style: solid; '.
107 'padding-bottom: 3px; padding-top: 3px; font-size: 12px; font-family: Arial;">'.$Query.$Duration.'</div>'."\n");
108 $Result = new DatabaseResult();
109 $Statement = $this->PDO->query($Query);
110 if ($Statement)
111 {
112 $Result->PDOStatement = $Statement;
113 $Result->num_rows = $Statement->rowCount();
114 $this->insert_id = $this->PDO->lastInsertId();
115 } else
116 {
117 $Error = $this->PDO->errorInfo();
118 $this->Error = $Error[2];
119 if (($this->Error != '') and ($this->ShowSQLError == true))
120 echo('<div><strong>SQL Error: </strong>'.$this->Error.'<br />'.$Query.'</div>');
121 throw new Exception('SQL Error: '.$this->Error.', Query: '.$Query);
122 }
123 return $Result;
124 }
125
126 function select(string $Table, string $What = '*', string $Condition = '1'): DatabaseResult
127 {
128 return $this->query('SELECT '.$What.' FROM `'.$this->Prefix.$Table.'` WHERE '.$Condition);
129 }
130
131 function delete(string $Table, string $Condition): void
132 {
133 $this->query('DELETE FROM `'.$this->Prefix.$Table.'` WHERE '.$Condition);
134 }
135
136 function insert(string $Table, array $Data): int
137 {
138 $this->query($this->GetInsert($Table, $Data));
139 $this->insert_id = $this->PDO->lastInsertId();
140 return $this->insert_id;
141 }
142
143 function IsFunction(string $Text): bool
144 {
145 $Pos = strpos($Text, '(');
146 return ($Pos !== false) && in_array(substr($Text, 0, $Pos + 1), $this->Functions);
147 }
148
149 function GetInsert(string $Table, array $Data): string
150 {
151 $Name = '';
152 $Values = '';
153 foreach ($Data as $Key => $Value)
154 {
155 $Name .= ',`'.$Key.'`';
156 if (is_null($Value)) $Value = 'NULL';
157 else if (!$this->IsFunction($Value))
158 {
159 $Value = $this->PDO->quote($Value);
160 }
161 $Values .= ','.$Value;
162 }
163 $Name = substr($Name, 1);
164 $Values = substr($Values, 1);
165 return 'INSERT INTO `'.$this->Prefix.$Table.'` ('.$Name.') VALUES('.$Values.')';
166 }
167
168 function update(string $Table, string $Condition, array $Data): void
169 {
170 $this->query($this->GetUpdate($Table, $Condition, $Data));
171 }
172
173 function GetUpdate(string $Table, string $Condition, array $Data): string
174 {
175 $Values = '';
176 foreach ($Data as $Key => $Value)
177 {
178 if (is_null($Value)) $Value = 'NULL';
179 else if (!$this->IsFunction($Value))
180 {
181 $Value = $this->PDO->quote($Value);
182 }
183 $Values .= ', `'.$Key.'`='.$Value;
184 }
185 $Values = substr($Values, 2);
186 return 'UPDATE `'.$this->Prefix.$Table.'` SET '.$Values.' WHERE ('.$Condition.')';
187 }
188
189 function replace(string $Table, array $Data): void
190 {
191 $Name = '';
192 $Values = '';
193 foreach ($Data as $Key => $Value)
194 {
195 if (is_null($Value)) $Value = 'NULL';
196 else if (!$this->IsFunction($Value))
197 {
198 $Value = $this->PDO->quote($Value);
199 }
200 $Name .= ',`'.$Key.'`';
201 $Values .= ','.$Value;
202 }
203 $Name = substr($Name, 1);
204 $Values = substr($Values, 1);
205 //echo('REPLACE INTO `'.$this->Prefix.$Table.'` ('.$Name.') VALUES ('.$Values.')<br />');
206 $this->query('REPLACE INTO `'.$this->Prefix.$Table.'` ('.$Name.') VALUES('.$Values.')');
207 //echo($this->error().'<br>');
208 }
209
210 function charset(string $Charset): void
211 {
212 $this->query('SET NAMES "'.$Charset.'"');
213 }
214
215 function real_escape_string(string $Text): string
216 {
217 return addslashes($Text);
218 }
219
220 function quote(string $Text): string
221 {
222 return $this->PDO->quote($Text);
223 }
224
225 public function __sleep(): array
226 {
227 return array('LastQuery');
228 }
229
230 public function __wakeup(): void
231 {
232 }
233
234 public function Transaction(array $Queries): void
235 {
236 //echo('|'."\n");
237 $this->PDO->beginTransaction();
238 foreach ($Queries as $Query)
239 {
240 //echo('|'.$Query."\n");
241 $Statement = $this->PDO->prepare($Query);
242 $Statement->execute();
243 }
244 $this->PDO->commit();
245 }
246
247 public function TableExists(string $Name): bool
248 {
249 $DbResult = $this->query('SELECT * FROM information_schema.tables WHERE table_schema = "'.$this->Database.
250 '" AND table_name = "'.$Name.'" LIMIT 1');
251 return $DbResult->num_rows != 0;
252 }
253}
254
255function TimeToMysqlDateTime($Time)
256{
257 if ($Time == NULL) return NULL;
258 else return date('Y-m-d H:i:s', $Time);
259}
260
261function TimeToMysqlDate($Time)
262{
263 if ($Time == NULL) return NULL;
264 else return date('Y-m-d', $Time);
265}
266
267function TimeToMysqlTime($Time)
268{
269 if ($Time == NULL) return NULL;
270 else return date('H:i:s', $Time);
271}
272
273function MysqlDateTimeToTime($DateTime)
274{
275 if ($DateTime == '') return NULL;
276 $Parts = explode(' ', $DateTime);
277 $DateParts = explode('-', $Parts[0]);
278 $TimeParts = explode(':', $Parts[1]);
279 $Result = mktime($TimeParts[0], $TimeParts[1], $TimeParts[2], $DateParts[1], $DateParts[2], $DateParts[0]);
280 return $Result;
281}
282
283function MysqlDateToTime($Date)
284{
285 if ($Date == '') return NULL;
286 return MysqlDateTimeToTime($Date.' 0:0:0');
287}
288
289function MysqlTimeToTime($Time)
290{
291 if ($Time == '') return NULL;
292 return MysqlDateTimeToTime('0000-00-00 '.$Time);
293}
Note: See TracBrowser for help on using the repository browser.