Skip to content

Commit 7f4ca1a

Browse files
authored
fix: allow working on live query files closes #248 (#391)
* fix: allow working on live query files closes #248 * tidy: reduce complexity * test: increase coverage of key areas
1 parent 4043700 commit 7f4ca1a

2 files changed

Lines changed: 172 additions & 18 deletions

File tree

src/Query/QueryFactory.php

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,34 @@ protected function findQueryFilePathInDirectory(
6060
string $directory,
6161
string $name,
6262
):?string {
63+
$invalidMatchExtension = null;
64+
$validQueryFilePath = null;
65+
6366
foreach(new DirectoryIterator($directory) as $fileInfo) {
64-
if($fileInfo->isDot()
65-
|| $fileInfo->isDir()) {
67+
if(!$fileInfo->isFile()) {
6668
continue;
6769
}
6870

69-
$this->getExtensionIfValid($fileInfo);
7071
$fileNameNoExtension = strtok($fileInfo->getFilename(), ".");
7172
if($fileNameNoExtension !== $name) {
7273
continue;
7374
}
7475

75-
return $fileInfo->getRealPath();
76+
try {
77+
$this->getExtensionIfValid($fileInfo);
78+
$validQueryFilePath ??= $fileInfo->getRealPath();
79+
}
80+
catch(QueryFileExtensionException) {
81+
$invalidMatchExtension = strtolower($fileInfo->getExtension());
82+
}
83+
}
84+
85+
if(!is_null($validQueryFilePath)) {
86+
return $validQueryFilePath;
87+
}
88+
89+
if(!is_null($invalidMatchExtension)) {
90+
throw new QueryFileExtensionException($invalidMatchExtension);
7691
}
7792

7893
return null;
@@ -81,7 +96,7 @@ protected function findQueryFilePathInDirectory(
8196
protected function locateOverrideDirectory(string $classFilePath):?string {
8297
$baseName = pathinfo($classFilePath, PATHINFO_FILENAME);
8398
foreach(new DirectoryIterator(dirname($classFilePath)) as $fileInfo) {
84-
if($fileInfo->isDot() || !$fileInfo->isDir()) {
99+
if(!$fileInfo->isDir()) {
85100
continue;
86101
}
87102

@@ -207,20 +222,12 @@ protected function getExtensionIfValid(SplFileInfo $fileInfo):string {
207222

208223
protected function throwCorrectException(Exception $exception):void {
209224
$message = $exception->getMessage();
210-
211-
switch(get_class($exception)) {
212-
case InvalidArgumentException::class:
213-
$matches = [];
214-
if(1 !== preg_match(
215-
"/Database \[(.+)\] not configured/", $message, $matches)) {
216-
throw $exception;
217-
}
218-
219-
$connectionName = $matches[1];
220-
throw new ConnectionNotConfiguredException($connectionName);
221-
222-
default:
225+
$matches = [];
226+
if(1 !== preg_match("/Database \[(.+)\] not configured/", $message, $matches)) {
223227
throw $exception;
224228
}
229+
230+
$connectionName = $matches[1];
231+
throw new ConnectionNotConfiguredException($connectionName);
225232
}
226233
}

test/phpunit/Query/QueryFactoryTest.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use Gt\Database\Connection\DefaultSettings;
55
use Gt\Database\Connection\Driver;
6+
use Gt\Database\Connection\ConnectionNotConfiguredException;
67
use Gt\Database\Query\PhpQuery;
78
use Gt\Database\Query\Query;
89
use Gt\Database\Query\QueryFactory;
@@ -214,6 +215,52 @@ public function testCreatePhpPrefersOverrideDirectoryWhenClassIsLowerCase():void
214215
}
215216
}
216217

218+
public function testCreatePhpPrefersOverrideDirectoryWhenMethodIsNotPublic():void {
219+
$basePath = Helper::getTmpDir();
220+
$classPath = implode(DIRECTORY_SEPARATOR, [
221+
$basePath,
222+
"query",
223+
"User.php",
224+
]);
225+
$overrideDirectory = implode(DIRECTORY_SEPARATOR, [
226+
$basePath,
227+
"query",
228+
"User",
229+
]);
230+
mkdir($overrideDirectory, 0775, true);
231+
file_put_contents(
232+
$classPath,
233+
<<<PHP
234+
<?php
235+
namespace App\Query;
236+
237+
class User {
238+
protected function getById():string {
239+
return "select 1";
240+
}
241+
}
242+
PHP
243+
);
244+
file_put_contents(
245+
"$overrideDirectory/getById.sql",
246+
"select :id as id"
247+
);
248+
249+
try {
250+
$sut = new QueryFactory($classPath, new Driver(new DefaultSettings()));
251+
$query = $sut->create("getById");
252+
253+
self::assertInstanceOf(SqlQuery::class, $query);
254+
self::assertSame(
255+
realpath("$overrideDirectory/getById.sql"),
256+
$query->getFilePath()
257+
);
258+
}
259+
finally {
260+
Helper::deleteDir($basePath);
261+
}
262+
}
263+
217264
public function testCreatePhpThrowsWhenOverrideConflictsWithPublicMethod():void {
218265
$basePath = Helper::getTmpDir();
219266
$classPath = implode(DIRECTORY_SEPARATOR, [
@@ -255,4 +302,104 @@ public function getById():string {
255302
Helper::deleteDir($basePath);
256303
}
257304
}
305+
306+
public function testCreateTranslatesConnectionNotConfiguredException():void {
307+
$basePath = Helper::getTmpDir();
308+
$queryDirectory = implode(DIRECTORY_SEPARATOR, [
309+
$basePath,
310+
"query",
311+
]);
312+
mkdir($queryDirectory, 0775, true);
313+
file_put_contents("$queryDirectory/users.sql", "select 1");
314+
315+
$driver = $this->createMock(Driver::class);
316+
$driver->method("getConnection")
317+
->willThrowException(
318+
new \InvalidArgumentException("Database [reporting] not configured")
319+
);
320+
321+
try {
322+
$sut = new QueryFactory($queryDirectory, $driver);
323+
324+
self::expectException(ConnectionNotConfiguredException::class);
325+
self::expectExceptionMessage("reporting");
326+
$sut->create("users");
327+
}
328+
finally {
329+
Helper::deleteDir($basePath);
330+
}
331+
}
332+
333+
public function testCreateRethrowsUnexpectedInvalidArgumentException():void {
334+
$basePath = Helper::getTmpDir();
335+
$queryDirectory = implode(DIRECTORY_SEPARATOR, [
336+
$basePath,
337+
"query",
338+
]);
339+
mkdir($queryDirectory, 0775, true);
340+
file_put_contents("$queryDirectory/users.sql", "select 1");
341+
342+
$driver = $this->createMock(Driver::class);
343+
$driver->method("getConnection")
344+
->willThrowException(new \InvalidArgumentException("Unexpected error"));
345+
346+
try {
347+
$sut = new QueryFactory($queryDirectory, $driver);
348+
349+
self::expectException(\InvalidArgumentException::class);
350+
self::expectExceptionMessage("Unexpected error");
351+
$sut->create("users");
352+
}
353+
finally {
354+
Helper::deleteDir($basePath);
355+
}
356+
}
357+
358+
public function testFindQueryFilePathIgnoresUnrelatedInvalidExtensions():void {
359+
$basePath = Helper::getTmpDir();
360+
$queryDirectory = implode(DIRECTORY_SEPARATOR, [
361+
$basePath,
362+
"query",
363+
]);
364+
mkdir($queryDirectory, 0775, true);
365+
file_put_contents("$queryDirectory/valid.sql", "select 1");
366+
file_put_contents("$queryDirectory/other.sql~", "select 2");
367+
368+
try {
369+
$sut = new QueryFactory($queryDirectory, new Driver(new DefaultSettings()));
370+
$queryFilePath = $sut->findQueryFilePath("valid");
371+
372+
self::assertSame(
373+
realpath("$queryDirectory/valid.sql"),
374+
$queryFilePath
375+
);
376+
}
377+
finally {
378+
Helper::deleteDir($basePath);
379+
}
380+
}
381+
382+
public function testFindQueryFilePathPrefersSupportedExtensionOverEditorBackup():void {
383+
$basePath = Helper::getTmpDir();
384+
$queryDirectory = implode(DIRECTORY_SEPARATOR, [
385+
$basePath,
386+
"query",
387+
]);
388+
mkdir($queryDirectory, 0775, true);
389+
file_put_contents("$queryDirectory/report.sql", "select 1");
390+
file_put_contents("$queryDirectory/report.sql~", "select 2");
391+
392+
try {
393+
$sut = new QueryFactory($queryDirectory, new Driver(new DefaultSettings()));
394+
$queryFilePath = $sut->findQueryFilePath("report");
395+
396+
self::assertSame(
397+
realpath("$queryDirectory/report.sql"),
398+
$queryFilePath
399+
);
400+
}
401+
finally {
402+
Helper::deleteDir($basePath);
403+
}
404+
}
258405
}

0 commit comments

Comments
 (0)