1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
<?php
namespace ipl\Sql\Adapter;
use DateTime;
use DateTimeZone;
use ipl\Sql\Config;
use ipl\Sql\Connection;
use ipl\Sql\Contract\Adapter;
use ipl\Sql\QueryBuilder;
use ipl\Sql\Select;
use PDO;
use UnexpectedValueException;
abstract class BaseAdapter implements Adapter
{
/**
* Quote character to use for quoting identifiers
*
* The default quote character is the double quote (") which is used by databases that behave close to ANSI SQL.
*
* @var array
*/
protected $quoteCharacter = ['"', '"'];
/** @var string Character to use for escaping quote characters */
protected $escapeCharacter = '\\"';
/** @var array Default PDO connect options */
protected $options = [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false
];
public function getDsn(Config $config)
{
$dsn = "{$config->db}:";
$parts = [];
foreach (['host', 'dbname', 'port'] as $part) {
if (! empty($config->$part)) {
$parts[] = "{$part}={$config->$part}";
}
}
return $dsn . implode(';', $parts);
}
public function getOptions(Config $config)
{
if (is_array($config->options)) {
return $config->options + $this->options;
}
return $this->options;
}
public function setClientTimezone(Connection $db)
{
return $this;
}
public function quoteIdentifier($identifiers)
{
if (is_string($identifiers)) {
$identifiers = explode('.', $identifiers);
}
foreach ($identifiers as $i => $identifier) {
if ($identifier === '*') {
continue;
}
$identifiers[$i] = $this->quoteCharacter[0]
. str_replace($this->quoteCharacter[0], $this->escapeCharacter, $identifier)
. $this->quoteCharacter[1];
}
return implode('.', $identifiers);
}
public function registerQueryBuilderCallbacks(QueryBuilder $queryBuilder)
{
$queryBuilder->on(QueryBuilder::ON_ASSEMBLE_SELECT, function (Select $select): void {
if ($select->hasOrderBy()) {
foreach ($select->getOrderBy() as list($_, $direction)) {
switch (strtolower($direction ?? '')) {
case '':
case 'asc':
case 'desc':
break;
default:
throw new UnexpectedValueException(
sprintf('Invalid direction "%s" in ORDER BY', $direction)
);
}
}
}
});
return $this;
}
protected function getTimezoneOffset()
{
$tz = new DateTimeZone(date_default_timezone_get());
$offset = $tz->getOffset(new DateTime());
$prefix = $offset >= 0 ? '+' : '-';
$offset = abs($offset);
$hours = (int) floor($offset / 3600);
$minutes = (int) floor(($offset % 3600) / 60);
return sprintf('%s%d:%02d', $prefix, $hours, $minutes);
}
}
|