Skip to content

Commit 0c776b6

Browse files
committed
MySQL-Quoter can now handle datetime values with automatic time-zone conversion
1 parent e680d4a commit 0c776b6

File tree

4 files changed

+92
-83
lines changed

4 files changed

+92
-83
lines changed

src/Databases/MySQL.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?php
22
namespace Kir\MySQL\Databases;
33

4+
use DateTimeZone;
45
use Kir\MySQL\Builder;
56
use Kir\MySQL\Builder\DBExpr;
67
use Kir\MySQL\Builder\QueryStatement;
78
use Kir\MySQL\Builder\Select;
89
use Kir\MySQL\Database;
910
use Kir\MySQL\Databases\MySQL\MySQLExceptionInterpreter;
10-
use Kir\MySQL\Databases\MySQL\MySQLExpressionQuoter;
1111
use Kir\MySQL\Databases\MySQL\MySQLFieldQuoter;
1212
use Kir\MySQL\Databases\MySQL\MySQLRunnableSelect;
1313
use Kir\MySQL\Databases\MySQL\MySQLUUIDGenerator;
14-
use Kir\MySQL\Databases\MySQL\MySQLValueQuoter;
14+
use Kir\MySQL\Databases\MySQL\MySQLQuoter;
1515
use Kir\MySQL\QueryLogger\QueryLoggers;
1616
use Kir\MySQL\Tools\AliasRegistry;
1717
use Kir\MySQL\Tools\VirtualTables;
@@ -42,6 +42,8 @@ class MySQL implements Database {
4242
private $exceptionInterpreter;
4343
/** @var array<string, mixed> */
4444
private $options;
45+
/** @var MySQLQuoter */
46+
private $quoter;
4547

4648
/**
4749
* @param PDO $pdo
@@ -62,6 +64,11 @@ public function __construct(PDO $pdo, array $options = []) {
6264
'delete-options' => [],
6365
];
6466
$this->options = array_merge($defaultOptions, $options);
67+
$this->options['timezone'] = $this->options['timezone'] ?? date_default_timezone_get();
68+
if(!($this->options['timezone'] instanceof DateTimeZone)) {
69+
$this->options['timezone'] = new DateTimeZone((string) $this->options['timezone']);
70+
}
71+
$this->quoter = new MySQLQuoter($pdo, $this->options['timezone']);
6572
}
6673

6774
/**
@@ -172,15 +179,15 @@ public function getTableFields(string $table): array {
172179
* @return string
173180
*/
174181
public function quoteExpression(string $expression, array $arguments = []): string {
175-
return MySQLExpressionQuoter::quoteExpression($this->pdo, $expression, $arguments);
182+
return $this->quoter->quoteExpression($expression, $arguments);
176183
}
177184

178185
/**
179186
* @param null|scalar|array<int, string>|DBExpr|Select $value
180187
* @return string
181188
*/
182189
public function quote($value): string {
183-
return MySQLValueQuoter::quote($this->pdo, $value);
190+
return $this->quoter->quote($value);
184191
}
185192

186193
/**

src/Databases/MySQL/MySQLExpressionQuoter.php

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/Databases/MySQL/MySQLQuoter.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
namespace Kir\MySQL\Databases\MySQL;
3+
4+
use DateTimeInterface;
5+
use DateTimeZone;
6+
use Kir\MySQL\Builder\DBExpr;
7+
use Kir\MySQL\Builder\Select;
8+
use PDO;
9+
use phpDocumentor\Reflection\Types\Scalar;
10+
11+
class MySQLQuoter {
12+
/** @var PDO */
13+
private $pdo;
14+
/** @var DateTimeZone */
15+
private $timeZone;
16+
17+
public function __construct(PDO $pdo, DateTimeZone $timeZone) {
18+
$this->timeZone = $timeZone;
19+
$this->pdo = $pdo;
20+
}
21+
22+
/**
23+
* @param null|bool|int|float|string|array<int, null|scalar>|DBExpr|Select|DateTimeInterface $value
24+
* @return string
25+
*/
26+
public function quote($value): string {
27+
if(is_null($value)) {
28+
return 'NULL';
29+
}
30+
31+
if(is_bool($value)) {
32+
return $value ? '1' : '0';
33+
}
34+
35+
if(is_array($value)) {
36+
return implode(', ', array_map([$this, __FUNCTION__], $value));
37+
}
38+
39+
if($value instanceof DBExpr) {
40+
return $value->getExpression();
41+
}
42+
43+
if($value instanceof Select) {
44+
return sprintf('(%s)', (string) $value);
45+
}
46+
47+
if(is_int($value) || is_float($value)) {
48+
return (string) $value;
49+
}
50+
51+
if($value instanceof DateTimeInterface) {
52+
$value = date_create_immutable($value->format('c'))->setTimezone($this->timeZone)->format('Y-m-d H:i:s');
53+
}
54+
55+
return $this->pdo->quote($value);
56+
}
57+
58+
/**
59+
* @param string $expression
60+
* @param array<int, null|scalar|array<int, string>|DBExpr|Select> $arguments
61+
* @return string
62+
*/
63+
public function quoteExpression(string $expression, array $arguments = []): string {
64+
$index = -1;
65+
$func = function () use ($arguments, &$index) {
66+
$index++;
67+
if(array_key_exists($index, $arguments)) {
68+
$argument = $arguments[$index];
69+
$value = $this->quote($argument);
70+
} elseif(count($arguments) > 0) {
71+
$args = $arguments;
72+
$value = array_pop($args);
73+
$value = $this->quote($value);
74+
} else {
75+
$value = 'NULL';
76+
}
77+
return $value;
78+
};
79+
return (string) preg_replace_callback('{(\\?)}', $func, $expression);
80+
}
81+
}

src/Databases/MySQL/MySQLValueQuoter.php

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)