Skip to content

Commit c5e3500

Browse files
committed
ensure listener cannot override read write type
1 parent 0dcb881 commit c5e3500

File tree

2 files changed

+82
-11
lines changed

2 files changed

+82
-11
lines changed

src/Illuminate/Database/Connection.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -858,20 +858,16 @@ protected function isUniqueConstraintError(Exception $exception)
858858
public function logQuery($query, $bindings, $time = null)
859859
{
860860
$this->totalQueryDuration += $time ?? 0.0;
861+
$readWriteType = $this->latestPdoTypeUsed();
861862

862-
$this->event(new QueryExecuted($query, $bindings, $time, $this, $this->latestPdoTypeUsed()));
863+
$this->event(new QueryExecuted($query, $bindings, $time, $this, $readWriteType));
863864

864865
$query = $this->pretending === true
865866
? $this->queryGrammar?->substituteBindingsIntoRawSql($query, $bindings) ?? $query
866867
: $query;
867868

868869
if ($this->loggingQueries) {
869-
$this->queryLog[] = [
870-
'query' => $query,
871-
'bindings' => $bindings,
872-
'time' => $time,
873-
'readWriteType' => $this->latestPdoTypeUsed(),
874-
];
870+
$this->queryLog[] = compact('query', 'bindings', 'time', 'readWriteType');
875871
}
876872
}
877873

tests/Integration/Database/DatabaseConnectionsTest.php

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Database\QueryException;
1010
use Illuminate\Database\SQLiteConnection;
1111
use Illuminate\Events\Dispatcher;
12+
use Illuminate\Support\Arr;
1213
use Illuminate\Support\Facades\Config;
1314
use Illuminate\Support\Facades\DB;
1415
use InvalidArgumentException;
@@ -177,7 +178,7 @@ public function testDynamicConnectionWithNoNameDoesntFailOnReconnect()
177178
}
178179

179180
#[DataProvider('readWriteExpectations')]
180-
public function testItCanAccessLastReadWriteConnectionTypeRetrieved(string $connectionName, array $expectedTypes)
181+
public function testItCanAccessLastReadWriteConnectionTypeRetrieved(string $connectionName, array $expectedTypes, ?string $loggedType)
181182
{
182183
$readPath = __DIR__.'/read.sqlite';
183184
$writePath = __DIR__.'/write.sqlite';
@@ -198,6 +199,7 @@ public function testItCanAccessLastReadWriteConnectionTypeRetrieved(string $conn
198199
touch($writePath);
199200

200201
$connection = DB::connection($connectionName);
202+
$connection->enableQueryLog();
201203

202204
$connection->statement('select 1');
203205
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
@@ -210,6 +212,15 @@ public function testItCanAccessLastReadWriteConnectionTypeRetrieved(string $conn
210212

211213
$connection->select('select 1');
212214
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
215+
216+
$this->assertSame([
217+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],
218+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],
219+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],
220+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],
221+
], Arr::select($connection->getQueryLog(), [
222+
'query', 'readWriteType',
223+
]));
213224
} finally {
214225
@unlink($readPath);
215226
@unlink($writePath);
@@ -218,9 +229,9 @@ public function testItCanAccessLastReadWriteConnectionTypeRetrieved(string $conn
218229

219230
public static function readWriteExpectations(): iterable
220231
{
221-
yield 'sqlite' => ['sqlite', ['write', 'read', 'write', 'read']];
222-
yield 'sqlite::read' => ['sqlite::read', ['read', 'read', 'read', 'read']];
223-
yield 'sqlite::write' => ['sqlite::write', ['write', 'write', 'write', 'write']];
232+
yield 'sqlite' => ['sqlite', ['write', 'read', 'write', 'read'], null];
233+
yield 'sqlite::read' => ['sqlite::read', ['read', 'read', 'read', 'read'], 'read'];
234+
yield 'sqlite::write' => ['sqlite::write', ['write', 'write', 'write', 'write'], 'write'];
224235
}
225236

226237
public function testNonReadWriteConnectionsAlwaysUseWrite()
@@ -290,4 +301,68 @@ public function testQueryExceptionsCaptureReadWriteType()
290301
@unlink($readPath);
291302
}
292303
}
304+
305+
#[DataProvider('readWriteExpectations')]
306+
public function testQueryInEventListenerCannotInterfereWithReadWriteType(string $connectionName, array $expectedTypes, ?string $loggedType)
307+
{
308+
$readPath = __DIR__.'/read.sqlite';
309+
$writePath = __DIR__.'/write.sqlite';
310+
Config::set('database.connections.sqlite', [
311+
'driver' => 'sqlite',
312+
'read' => [
313+
'database' => $readPath,
314+
],
315+
'write' => [
316+
'database' => $writePath,
317+
],
318+
]);
319+
$events = collect();
320+
DB::listen($events->push(...));
321+
322+
try {
323+
touch($readPath);
324+
touch($writePath);
325+
326+
$connection = DB::connection($connectionName);
327+
$connection->enableQueryLog();
328+
329+
$connection->listen(function ($query) use ($connection) {
330+
if ($query->sql === 'select 1') {
331+
$connection->select('select 2');
332+
}
333+
});
334+
335+
$connection->statement('select 1');
336+
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
337+
$this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);
338+
339+
$connection->select('select 1');
340+
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
341+
$this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);
342+
343+
$connection->statement('select 1');
344+
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
345+
$this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);
346+
347+
$connection->select('select 1');
348+
$this->assertSame(array_shift($expectedTypes), $events->shift()->readWriteType);
349+
$this->assertSame($loggedType ?? 'read', $events->shift()->readWriteType);
350+
351+
$this->assertSame([
352+
['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],
353+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],
354+
['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],
355+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],
356+
['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],
357+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'write'],
358+
['query' => 'select 2', 'readWriteType' => $loggedType ?? 'read'],
359+
['query' => 'select 1', 'readWriteType' => $loggedType ?? 'read'],
360+
], Arr::select($connection->getQueryLog(), [
361+
'query', 'readWriteType',
362+
]));
363+
} finally {
364+
@unlink($readPath);
365+
@unlink($writePath);
366+
}
367+
}
293368
}

0 commit comments

Comments
 (0)