Skip to content

Commit 6361e62

Browse files
committed
implement Trim methods in platform
1 parent b6f8e3c commit 6361e62

File tree

2 files changed

+130
-48
lines changed

2 files changed

+130
-48
lines changed

src/ClickHousePlatform.php

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
use Doctrine\DBAL\Schema\Index;
3636
use Doctrine\DBAL\Schema\TableDiff;
3737

38-
3938
/**
4039
* Provides the behavior, features and SQL dialect of the ClickHouse database platform.
4140
*/
@@ -243,25 +242,36 @@ public function getModExpression($expression1, $expression2) : string
243242
/**
244243
* {@inheritDoc}
245244
*/
246-
public function getTrimExpression($str, $pos = TrimMode::UNSPECIFIED, $char = false)
245+
public function getTrimExpression($str, $pos = TrimMode::UNSPECIFIED, $char = false) : string
247246
{
248-
throw DBALException::notSupported(__METHOD__);
247+
if (! $char) {
248+
switch ($pos) {
249+
case TrimMode::LEADING:
250+
return $this->getLtrimExpression($str);
251+
case TrimMode::TRAILING:
252+
return $this->getRtrimExpression($str);
253+
default:
254+
return sprintf("replaceRegexpAll(%s, '(^\\\s+|\\\s+$)', '')", $str);
255+
}
256+
}
257+
258+
return sprintf("replaceRegexpAll(%s, '(^%s+|%s+$)', '')", $str, $char, $char);
249259
}
250260

251261
/**
252262
* {@inheritDoc}
253263
*/
254-
public function getRtrimExpression($str)
264+
public function getRtrimExpression($str) : string
255265
{
256-
throw DBALException::notSupported(__METHOD__);
266+
return sprintf("replaceRegexpAll(%s, '(\\\s+$)', '')", $str);
257267
}
258268

259269
/**
260270
* {@inheritDoc}
261271
*/
262-
public function getLtrimExpression($str)
272+
public function getLtrimExpression($str) : string
263273
{
264-
throw DBALException::notSupported(__METHOD__);
274+
return sprintf("replaceRegexpAll(%s, '(^\\\s+)', '')", $str);
265275
}
266276

267277
/**
@@ -1133,16 +1143,16 @@ public function getDefaultValueDeclarationSQL($field) : string
11331143
}
11341144

11351145
$default = " DEFAULT '" . $field['default'] . "'";
1136-
if ($fieldType = (string)($field['type'] ?? null)) {
1146+
if ($fieldType = (string) ($field['type'] ?? null)) {
11371147
if (\in_array($fieldType, [
11381148
'Integer',
11391149
'SmallInt',
1140-
'Float'
1141-
]) || ('BigInt' === $fieldType && ParameterType::INTEGER === Type::getType('BigInt')->getBindingType())) {
1150+
'Float',
1151+
]) || ($fieldType === 'BigInt' && Type::getType('BigInt')->getBindingType() === ParameterType::INTEGER)) {
11421152
$default = ' DEFAULT ' . $field['default'];
1143-
} elseif ('DateTime' === $fieldType && $field['default'] === $this->getCurrentTimestampSQL()) {
1153+
} elseif ($fieldType === 'DateTime' && $field['default'] === $this->getCurrentTimestampSQL()) {
11441154
$default = ' DEFAULT ' . $this->getCurrentTimestampSQL();
1145-
} elseif ('Date' === $fieldType) { // TODO check if string matches constant date like 'dddd-yy-mm' and quote it
1155+
} elseif ($fieldType === 'Date') { // TODO check if string matches constant date like 'dddd-yy-mm' and quote it
11461156
$default = ' DEFAULT ' . $field['default'];
11471157
}
11481158
}

tests/SelectTest.php

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace FOD\DBALClickHouse\Tests;
1313

1414
use Doctrine\DBAL\FetchMode;
15+
use Doctrine\DBAL\Platforms\TrimMode;
1516
use FOD\DBALClickHouse\Connection;
1617
use PHPUnit\Framework\TestCase;
1718

@@ -44,7 +45,7 @@ public function setUp()
4445
$this->connection->exec($sql);
4546
}
4647

47-
$this->connection->exec("INSERT INTO test_select_table(id, payload, hits) VALUES (1, 'v1', 101), (2, 'v2', 202), (3, 'v3', 303), (4, 'v4', 404), (5, 'v4', 505)");
48+
$this->connection->exec("INSERT INTO test_select_table(id, payload, hits) VALUES (1, 'v1', 101), (2, 'v2', 202), (3, 'v3', 303), (4, 'v4', 404), (5, 'v4', 505), (6, ' t1 ', 606), (7, 'aat2aaa', 707)");
4849
}
4950

5051
public function tearDown()
@@ -76,14 +77,14 @@ public function testFetchNumSelect()
7677
{
7778
$stmt = $this->connection->query('SELECT MAX(hits) FROM test_select_table');
7879
$result = $stmt->fetch(FetchMode::ASSOCIATIVE);
79-
$this->assertEquals(['MAX(hits)' => 505], $result);
80+
$this->assertEquals(['MAX(hits)' => 707], $result);
8081
}
8182

8283
public function testFetchObjSelect()
8384
{
8485
$stmt = $this->connection->query('SELECT MAX(hits) as maxHits FROM test_select_table');
8586
$result = $stmt->fetch(FetchMode::STANDARD_OBJECT);
86-
$this->assertEquals((object)['maxHits' => 505], $result);
87+
$this->assertEquals((object)['maxHits' => 707], $result);
8788
}
8889

8990
public function testFetchKeyPairSelect()
@@ -98,51 +99,60 @@ public function testFetchAllBothSelect()
9899
$stmt = $this->connection->query("SELECT * FROM test_select_table WHERE id IN (1, 3)");
99100
$result = $stmt->fetchAll();
100101

101-
$this->assertEquals([[
102-
'id' => 1,
103-
'payload' => 'v1',
104-
'hits' => 101,
105-
], [
106-
'id' => 3,
107-
'payload' => 'v3',
108-
'hits' => 303,
109-
]], $result);
102+
$this->assertEquals([
103+
[
104+
'id' => 1,
105+
'payload' => 'v1',
106+
'hits' => 101,
107+
],
108+
[
109+
'id' => 3,
110+
'payload' => 'v3',
111+
'hits' => 303,
112+
]
113+
], $result);
110114
}
111115

112116
public function testFetchAllNumSelect()
113117
{
114118
$stmt = $this->connection->query("SELECT AVG(hits) FROM test_select_table");
115119
$result = $stmt->fetchAll(FetchMode::NUMERIC);
116120

117-
$this->assertEquals([[303]], $result);
121+
$this->assertEquals([[404]], $result);
118122
}
119123

120124
public function testFetchAllObjSelect()
121125
{
122126
$stmt = $this->connection->query("SELECT * FROM test_select_table WHERE id IN (2, 4)");
123127
$result = $stmt->fetchAll(FetchMode::STANDARD_OBJECT);
124128

125-
$this->assertEquals([(object)[
126-
'id' => 2,
127-
'payload' => 'v2',
128-
'hits' => 202,
129-
], (object)[
130-
'id' => 4,
131-
'payload' => 'v4',
132-
'hits' => 404,
133-
]], $result);
129+
$this->assertEquals([
130+
(object)[
131+
'id' => 2,
132+
'payload' => 'v2',
133+
'hits' => 202,
134+
],
135+
(object)[
136+
'id' => 4,
137+
'payload' => 'v4',
138+
'hits' => 404,
139+
]
140+
], $result);
134141
}
135142

136143
public function testFetchAllKeyPairSelect()
137144
{
138145
$stmt = $this->connection->query("SELECT payload, hits FROM test_select_table WHERE id IN (2, 4) ORDER BY id");
139146
$result = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
140147

141-
$this->assertEquals([[
142-
'v2' => 202,
143-
], [
144-
'v4' => 404,
145-
]], $result);
148+
$this->assertEquals([
149+
[
150+
'v2' => 202,
151+
],
152+
[
153+
'v4' => 404,
154+
]
155+
], $result);
146156
}
147157

148158
public function testFetchColumnValidOffsetSelect()
@@ -163,8 +173,7 @@ public function testFetchColumnInvalidOffsetSelect()
163173
while ($result = $stmt->fetchColumn(2)) {
164174
$results[] = $result;
165175
}
166-
167-
$this->assertEquals(['v2', 'v3', 'v4', 'v4'], $results);
176+
$this->assertEquals(['v2', 'v3', 'v4', 'v4', ' t1 ', 'aat2aaa'], $results);
168177
}
169178

170179
public function testQueryBuilderSelect()
@@ -181,13 +190,16 @@ public function testQueryBuilderSelect()
181190
->execute()
182191
->fetchAll();
183192

184-
$this->assertEquals([[
185-
'payload' => 'v3',
186-
'uniques' => '1',
187-
], [
188-
'payload' => 'v4',
189-
'uniques' => '2',
190-
]], $result);
193+
$this->assertEquals([
194+
[
195+
'payload' => ' t1 ',
196+
'uniques' => '1',
197+
],
198+
[
199+
'payload' => 'aat2aaa',
200+
'uniques' => '1',
201+
]
202+
], $result);
191203
}
192204

193205
public function testDynamicParametersSelect()
@@ -201,6 +213,14 @@ public function testDynamicParametersSelect()
201213
[
202214
'payload' => 'v4',
203215
'avg_hits' => 454.5,
216+
],
217+
[
218+
'payload' => ' t1 ',
219+
'avg_hits' => 606,
220+
],
221+
[
222+
'payload' => 'aat2aaa',
223+
'avg_hits' => 707,
204224
]
205225
], $stmt->fetchAll());
206226
}
@@ -212,5 +232,57 @@ public function testColumnCount()
212232

213233
$this->assertEquals(3, $stmt->columnCount());
214234
}
235+
236+
public function testTrim()
237+
{
238+
$stmt = $this->connection->prepare(
239+
sprintf(
240+
'SELECT %s FROM test_select_table WHERE id = 6',
241+
$this->connection->getDatabasePlatform()->getTrimExpression('payload')
242+
)
243+
);
244+
$stmt->execute();
245+
246+
$this->assertEquals('t1', $stmt->fetchColumn());
247+
}
248+
249+
public function testTrimLeft()
250+
{
251+
$stmt = $this->connection->prepare(
252+
sprintf(
253+
'SELECT %s FROM test_select_table WHERE id = 6',
254+
$this->connection->getDatabasePlatform()->getTrimExpression('payload', TrimMode::LEADING)
255+
)
256+
);
257+
$stmt->execute();
258+
259+
$this->assertEquals('t1 ', $stmt->fetchColumn());
260+
}
261+
262+
public function testTrimRight()
263+
{
264+
$stmt = $this->connection->prepare(
265+
sprintf(
266+
'SELECT %s FROM test_select_table WHERE id = 6',
267+
$this->connection->getDatabasePlatform()->getTrimExpression('payload', TrimMode::TRAILING)
268+
)
269+
);
270+
$stmt->execute();
271+
272+
$this->assertEquals(' t1', $stmt->fetchColumn());
273+
}
274+
275+
public function testTrimChar()
276+
{
277+
$stmt = $this->connection->prepare(
278+
sprintf(
279+
'SELECT %s FROM test_select_table WHERE id = 7',
280+
$this->connection->getDatabasePlatform()->getTrimExpression('payload', TrimMode::UNSPECIFIED, 'a')
281+
)
282+
);
283+
$stmt->execute();
284+
285+
$this->assertEquals('t2', $stmt->fetchColumn());
286+
}
215287
}
216288

0 commit comments

Comments
 (0)