Skip to content

Commit 35ee4a5

Browse files
author
Greg Bowler
committed
Initial implementation of #191
1 parent c12eb08 commit 35ee4a5

File tree

9 files changed

+249
-6
lines changed

9 files changed

+249
-6
lines changed

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"type": "library",
55

66
"require": {
7-
"php": "^7.2",
7+
"php": "^7.4",
88
"ext-PDO": "*",
9-
"phpgt/config": "*"
9+
"phpgt/config": "^1.0.0",
10+
"phpgt/sqlbuilder": "^v0.1.0"
1011
},
1112

1213
"require-dev": {

composer.lock

Lines changed: 31 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Query/PhpQuery.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
namespace Gt\Database\Query;
3+
4+
use Gt\Database\Result\ResultSet;
5+
6+
class PhpQuery extends SqlQuery {
7+
private string $namespace = "App";
8+
9+
public function setBaseNamespace(string $namespace):void {
10+
$this->namespace = $namespace;
11+
}
12+
13+
public function getSql(array $bindings = []):string {
14+
require_once($this->getFilePath());
15+
$classBaseName = ucfirst(
16+
pathinfo(
17+
$this->getFilePath(),
18+
PATHINFO_FILENAME
19+
)
20+
);
21+
$className = "\\" . $this->namespace . "\\Database\\$classBaseName";
22+
if(!class_exists($className)) {
23+
throw new PhpQueryClassNotLoadedException($className);
24+
}
25+
26+
$object = new $className();
27+
return (string)($object);
28+
}
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace Gt\Database\Query;
3+
4+
use Gt\Database\DatabaseException;
5+
6+
class PhpQueryClassNotLoadedException extends DatabaseException {}

test/phpunit/Helper/Helper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ public static function recursiveRemove(string $dir) {
3838
@rmdir($dir);
3939
}
4040

41+
public static function queryPathPhpExistsProvider() {
42+
return self::queryPathProvider(true, "php");
43+
}
44+
45+
public static function queryPathPhpNotExistsProvider() {
46+
return self::queryPathProvider(false, "php");
47+
}
4148

4249
public static function queryPathExistsProvider() {
4350
return self::queryPathProvider(true);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
namespace App\Database;
3+
4+
class GetByName extends \Gt\SqlBuilder\Query\SelectQuery {
5+
public function select():array {
6+
return [
7+
"id",
8+
"name",
9+
];
10+
}
11+
12+
public function from():array {
13+
return [
14+
"test_table",
15+
];
16+
}
17+
18+
public function where():array {
19+
return [
20+
"name = ?",
21+
];
22+
}
23+
24+
public function limit():array {
25+
return [1];
26+
}
27+
}

test/phpunit/Query/PhpQueryTest.php

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
namespace Gt\Database\Test\Query;
3+
4+
use Gt\Database\Connection\Driver;
5+
use Gt\Database\Connection\Settings;
6+
use Gt\Database\Query\PhpQuery;
7+
use Gt\Database\Query\PhpQueryClassNotLoadedException;
8+
use Gt\Database\Query\QueryNotFoundException;
9+
use Gt\Database\Test\Helper\Helper;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class PhpQueryTest extends TestCase {
13+
private Driver $driver;
14+
15+
public function setUp():void {
16+
$driver = $this->driverSingleton();
17+
$connection = $driver->getConnection();
18+
$output = $connection->exec("CREATE TABLE test_table ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(32), timestamp DATETIME DEFAULT current_timestamp); CREATE UNIQUE INDEX test_table_name_uindex ON test_table (name);");
19+
static::assertNotFalse($output);
20+
21+
$insertStatement = $connection->prepare(
22+
"INSERT INTO test_table (name) VALUES
23+
('one'),
24+
('two'),
25+
('three')"
26+
);
27+
$success = $insertStatement->execute();
28+
static::assertTrue($success, "Success inserting fake data");
29+
}
30+
31+
/** @dataProvider \Gt\Database\Test\Helper\Helper::queryPathPhpNotExistsProvider */
32+
public function testQueryNotFound(
33+
string $queryName,
34+
string $queryCollectionPath,
35+
string $queryPath
36+
) {
37+
self::expectException(QueryNotFoundException::class);
38+
new PhpQuery($queryPath, $this->driverSingleton());
39+
}
40+
41+
/** @dataProvider \Gt\Database\Test\Helper\Helper::queryPathPhpExistsProvider */
42+
public function testQueryFound(
43+
string $queryName,
44+
string $queryCollectionPath,
45+
string $queryPath
46+
) {
47+
$query = new PhpQuery($queryPath, $this->driverSingleton());
48+
static::assertFileExists($query->getFilePath());
49+
}
50+
51+
/**
52+
* @dataProvider \Gt\Database\Test\Helper\Helper::queryPathPhpExistsProvider
53+
*@runInSeparateProcess
54+
*/
55+
public function testBadPhpNamespace(
56+
string $queryName,
57+
string $queryCollectionPath,
58+
string $queryPath
59+
) {
60+
$php = <<<PHP
61+
<?php
62+
namespace Somewhere\Database;
63+
64+
class ThisIsWrong {}
65+
PHP;
66+
file_put_contents($queryPath, $php);
67+
$query = new PhpQuery($queryPath, $this->driverSingleton());
68+
self::expectException(PhpQueryClassNotLoadedException::class);
69+
$query->getSql(["two"]);
70+
}
71+
72+
/**
73+
* @dataProvider \Gt\Database\Test\Helper\Helper::queryCollectionPathExistsProvider
74+
* @runInSeparateProcess
75+
*/
76+
public function testSqlGenerated(
77+
string $queryName,
78+
string $queryCollectionPath
79+
) {
80+
$queryPath = "$queryCollectionPath/getByName.php";
81+
copy(__DIR__ . "/../Helper/PhpQueryExample/GetByName.php", $queryPath);
82+
$query = new PhpQuery($queryPath, $this->driverSingleton());
83+
$sql = $query->getSql(["two"]);
84+
85+
self::assertStringContainsStringIgnoreWhitespace(
86+
"select id, name from test_table where name = ? limit 1",
87+
$sql
88+
);
89+
}
90+
91+
private function driverSingleton():Driver {
92+
if(!isset($this->driver)) {
93+
$settings = new Settings(
94+
Helper::getTmpDir(),
95+
Settings::DRIVER_SQLITE,
96+
Settings::SCHEMA_IN_MEMORY
97+
);
98+
$this->driver = new Driver($settings);
99+
}
100+
101+
return $this->driver;
102+
}
103+
104+
private static function assertStringContainsStringIgnoreWhitespace(
105+
string $expected,
106+
string $actual
107+
):void {
108+
$expected = str_replace(["\t", "\n"], " ", $expected);
109+
$actual = str_replace(["\t", "\n"], " ", $actual);
110+
while(strstr($expected, " ")) {
111+
$expected = str_replace(" ", " ", $expected);
112+
}
113+
while(strstr($actual, " ")) {
114+
$actual = str_replace(" ", " ", $actual);
115+
}
116+
self::assertEquals(trim($expected), trim($actual));
117+
}
118+
}

test/phpunit/Query/QueryFactoryTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,30 @@ public function testSelectsCorrectFile() {
9292
$queryFileList[$queryName] = $query->getFilePath();
9393
}
9494
}
95+
96+
public function testSelectsCorrectFilePhp() {
97+
$queryCollectionData = Helper::queryCollectionPathExistsProvider();
98+
$queryCollectionPath = $queryCollectionData[0][1];
99+
100+
$queryFactory = new QueryFactory(
101+
$queryCollectionPath,
102+
new Driver(new DefaultSettings())
103+
);
104+
105+
$queryNames = [
106+
uniqid("q1-"),
107+
uniqid("q2-"),
108+
uniqid("q3-"),
109+
uniqid("q4-")
110+
];
111+
$queryFileList = [];
112+
foreach($queryNames as $queryName) {
113+
$queryPath = $queryCollectionPath . "/$queryName.php";
114+
touch($queryPath);
115+
116+
$query = $queryFactory->create($queryName);
117+
static::assertNotContains($query->getFilePath(), $queryFileList);
118+
$queryFileList[$queryName] = $query->getFilePath();
119+
}
120+
}
95121
}

test/phpunit/Query/SqlQueryTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
use Gt\Database\Test\Helper\Helper;
1111

1212
class SqlQueryTest extends TestCase {
13-
/** @var Driver */
14-
private $driver;
13+
private Driver $driver;
1514

1615
public function setUp():void {
1716
$driver = $this->driverSingleton();
@@ -341,7 +340,7 @@ public function testPrepareBindingsWithArray(
341340
}
342341

343342
private function driverSingleton():Driver {
344-
if(is_null($this->driver)) {
343+
if(!isset($this->driver)) {
345344
$settings = new Settings(
346345
Helper::getTmpDir(),
347346
Settings::DRIVER_SQLITE,

0 commit comments

Comments
 (0)