Skip to content

Commit 21cf5e6

Browse files
author
Ian Jenkins
committed
Use Query Builder for better support across platforms.
Not all drivers supported FOR UPDATE queries so this changes changes the raw SQL to use the query builder thus allowing DBAL to construct hte appropriate query per platform. It then grabs the SQL and appends the read lock SQL but grabs the SQL part from the correct platform thus as to not break portability.
1 parent b10ca08 commit 21cf5e6

File tree

3 files changed

+149
-8
lines changed

3 files changed

+149
-8
lines changed

Diff for: pkg/dbal/DbalConsumer.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,18 @@ protected function receiveMessage()
169169
try {
170170
$now = time();
171171

172-
$sql = sprintf(
173-
'SELECT * FROM %s WHERE queue=:queue AND '.
174-
'(delayed_until IS NULL OR delayed_until<=:delayedUntil) '.
175-
'ORDER BY priority DESC, id ASC LIMIT 1 FOR UPDATE',
176-
$this->context->getTableName()
177-
);
172+
$query = $this->dbal->createQueryBuilder();
173+
$query
174+
->select('*')
175+
->from($this->context->getTableName())
176+
->where('queue = :queue')
177+
->andWhere('(delayed_until IS NULL OR delayed_until <= :delayedUntil)')
178+
->orderBy('priority', 'desc')
179+
->orderBy('id', 'asc')
180+
->setMaxResults(1)
181+
;
182+
183+
$sql = $query->getSQL().' '.$this->dbal->getDatabasePlatform()->getWriteLockSQL();
178184

179185
$dbalMessage = $this->dbal->executeQuery(
180186
$sql,

Diff for: pkg/dbal/Tests/DbalConsumerTest.php

+135
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Enqueue\Dbal\Tests;
44

55
use Doctrine\DBAL\Connection;
6+
use Doctrine\DBAL\Platforms\AbstractPlatform;
7+
use Doctrine\DBAL\Query\QueryBuilder;
68
use Doctrine\DBAL\Statement;
79
use Enqueue\Dbal\DbalConsumer;
810
use Enqueue\Dbal\DbalContext;
@@ -148,7 +150,41 @@ public function testShouldReceiveMessage()
148150
->will($this->returnValue($dbalMessage))
149151
;
150152

153+
$queryBuilder = $this->createQueryBuilderMock();
154+
$queryBuilder
155+
->expects($this->once())
156+
->method('select')
157+
->will($this->returnSelf())
158+
;
159+
$queryBuilder
160+
->expects($this->once())
161+
->method('from')
162+
->will($this->returnSelf())
163+
;
164+
$queryBuilder
165+
->expects($this->once())
166+
->method('where')
167+
->will($this->returnSelf())
168+
;
169+
$queryBuilder
170+
->expects($this->once())
171+
->method('andWhere')
172+
->will($this->returnSelf())
173+
;
174+
$queryBuilder
175+
->expects($this->exactly(2))
176+
->method('orderBy')
177+
->will($this->returnSelf())
178+
;
179+
180+
$platform = $this->createPlatformMock();
181+
151182
$dbal = $this->createConnectionMock();
183+
$dbal
184+
->expects($this->once())
185+
->method('createQueryBuilder')
186+
->willReturn($queryBuilder)
187+
;
152188
$dbal
153189
->expects($this->once())
154190
->method('executeQuery')
@@ -163,6 +199,11 @@ public function testShouldReceiveMessage()
163199
->expects($this->once())
164200
->method('commit')
165201
;
202+
$dbal
203+
->expects($this->once())
204+
->method('getDatabasePlatform')
205+
->willReturn($platform)
206+
;
166207

167208
$context = $this->createContextMock();
168209
$context
@@ -201,7 +242,41 @@ public function testShouldReturnNullIfThereIsNoNewMessage()
201242
->will($this->returnValue(null))
202243
;
203244

245+
$queryBuilder = $this->createQueryBuilderMock();
246+
$queryBuilder
247+
->expects($this->once())
248+
->method('select')
249+
->will($this->returnSelf())
250+
;
251+
$queryBuilder
252+
->expects($this->once())
253+
->method('from')
254+
->will($this->returnSelf())
255+
;
256+
$queryBuilder
257+
->expects($this->once())
258+
->method('where')
259+
->will($this->returnSelf())
260+
;
261+
$queryBuilder
262+
->expects($this->once())
263+
->method('andWhere')
264+
->will($this->returnSelf())
265+
;
266+
$queryBuilder
267+
->expects($this->exactly(2))
268+
->method('orderBy')
269+
->will($this->returnSelf())
270+
;
271+
272+
$platform = $this->createPlatformMock();
273+
204274
$dbal = $this->createConnectionMock();
275+
$dbal
276+
->expects($this->once())
277+
->method('createQueryBuilder')
278+
->willReturn($queryBuilder)
279+
;
205280
$dbal
206281
->expects($this->once())
207282
->method('executeQuery')
@@ -216,6 +291,11 @@ public function testShouldReturnNullIfThereIsNoNewMessage()
216291
->expects($this->once())
217292
->method('commit')
218293
;
294+
$dbal
295+
->expects($this->once())
296+
->method('getDatabasePlatform')
297+
->willReturn($platform)
298+
;
219299

220300
$context = $this->createContextMock();
221301
$context
@@ -250,7 +330,41 @@ public function testShouldThrowIfMessageWasNotRemoved()
250330
->will($this->returnValue(['id' => '2134']))
251331
;
252332

333+
$queryBuilder = $this->createQueryBuilderMock();
334+
$queryBuilder
335+
->expects($this->once())
336+
->method('select')
337+
->will($this->returnSelf())
338+
;
339+
$queryBuilder
340+
->expects($this->once())
341+
->method('from')
342+
->will($this->returnSelf())
343+
;
344+
$queryBuilder
345+
->expects($this->once())
346+
->method('where')
347+
->will($this->returnSelf())
348+
;
349+
$queryBuilder
350+
->expects($this->once())
351+
->method('andWhere')
352+
->will($this->returnSelf())
353+
;
354+
$queryBuilder
355+
->expects($this->exactly(2))
356+
->method('orderBy')
357+
->will($this->returnSelf())
358+
;
359+
360+
$platform = $this->createPlatformMock();
361+
253362
$dbal = $this->createConnectionMock();
363+
$dbal
364+
->expects($this->once())
365+
->method('createQueryBuilder')
366+
->willReturn($queryBuilder)
367+
;
254368
$dbal
255369
->expects($this->once())
256370
->method('executeQuery')
@@ -269,6 +383,11 @@ public function testShouldThrowIfMessageWasNotRemoved()
269383
->expects($this->once())
270384
->method('rollBack')
271385
;
386+
$dbal
387+
->expects($this->once())
388+
->method('getDatabasePlatform')
389+
->willReturn($platform)
390+
;
272391

273392
$context = $this->createContextMock();
274393
$context
@@ -318,6 +437,22 @@ private function createContextMock()
318437
{
319438
return $this->createMock(DbalContext::class);
320439
}
440+
441+
/**
442+
* @return \PHPUnit_Framework_MockObject_MockObject|QueryBuilder
443+
*/
444+
private function createQueryBuilderMock()
445+
{
446+
return $this->createMock(QueryBuilder::class);
447+
}
448+
449+
/**
450+
* @return \PHPUnit_Framework_MockObject_MockObject|AbstractPlatform
451+
*/
452+
private function createPlatformMock()
453+
{
454+
return $this->createMock(AbstractPlatform::class);
455+
}
321456
}
322457

323458
class InvalidMessage implements PsrMessage

Diff for: pkg/redis/RedisConsumer.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public function receive($timeout = 0)
4848
$timeout = (int) ($timeout / 1000);
4949
if (empty($timeout)) {
5050
// Caused by
51-
// Predis\Response\ServerException: ERR timeout is not an integer or out of range
52-
// /mqdev/vendor/predis/predis/src/Client.php:370
51+
// Predis\Response\ServerException: ERR timeout is not an integer or out of range
52+
// /mqdev/vendor/predis/predis/src/Client.php:370
5353

5454
return $this->receiveNoWait();
5555
}

0 commit comments

Comments
 (0)