Skip to content

Commit eae540f

Browse files
committed
Added Support for Virtual Tables
1 parent c131baa commit eae540f

File tree

7 files changed

+92
-15
lines changed

7 files changed

+92
-15
lines changed

src/Builder/Traits/TableNameBuilder.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
namespace Kir\MySQL\Builder\Traits;
33

4-
use Kir\MySQL\Database;
4+
use Kir\MySQL\Databases\MySQL;
55

66
trait TableNameBuilder {
77
use AbstractAliasReplacer;
@@ -32,6 +32,10 @@ protected function buildTableName($alias, $name) {
3232
}
3333
$name = '(' . join("\n\tUNION\n\t", $parts) . ')';
3434
}
35+
if($this->db()->getVirtualTables()->has($name)) {
36+
$select = (string )$this->db()->getVirtualTables()->get($name);
37+
$name = sprintf('(%s)', join("\n\t", explode("\n", trim($select))));
38+
}
3539
$name = $this->aliasReplacer()->replace($name);
3640
if($alias !== null) {
3741
return sprintf("%s %s", $name, $alias);
@@ -40,7 +44,7 @@ protected function buildTableName($alias, $name) {
4044
}
4145

4246
/**
43-
* @return Database
47+
* @return MySQL
4448
*/
4549
abstract protected function db();
4650
}

src/Databases/MySQL.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Kir\MySQL\Databases\MySQL\MySQLExceptionInterpreter;
1313
use Kir\MySQL\QueryLogger\QueryLoggers;
1414
use Kir\MySQL\Tools\AliasRegistry;
15+
use Kir\MySQL\Tools\VirtualTables;
1516

1617
/**
1718
*/
@@ -28,6 +29,8 @@ class MySQL implements Database {
2829
private $transactionLevel = 0;
2930
/** @var QueryLoggers */
3031
private $queryLoggers = 0;
32+
/** @var VirtualTables */
33+
private $virtualTables = null;
3134
/** @var MySQLExceptionInterpreter */
3235
private $exceptionInterpreter = 0;
3336
/** @var array */
@@ -68,6 +71,16 @@ public function getAliasRegistry() {
6871
return $this->aliasRegistry;
6972
}
7073

74+
/**
75+
* @return VirtualTables
76+
*/
77+
public function getVirtualTables() {
78+
if($this->virtualTables === null) {
79+
$this->virtualTables = new VirtualTables();
80+
}
81+
return $this->virtualTables;
82+
}
83+
7184
/**
7285
* @param string $query
7386
* @throws Exception
@@ -279,11 +292,9 @@ public function transactionRollback() {
279292
* @return mixed
280293
* @throws \Exception
281294
* @throws \Error
282-
* @throws null
283295
*/
284296
public function dryRun($callback = null) {
285297
$result = null;
286-
$exception = null;
287298
if(!$this->pdo->inTransaction()) {
288299
$this->transactionStart();
289300
try {

src/Tools/VirtualTables.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
namespace Kir\MySQL\Tools;
3+
4+
use Kir\MySQL\Builder\Select;
5+
6+
class VirtualTables {
7+
/** @var Select[] */
8+
private $virtualTables = [];
9+
10+
/**
11+
* @param string $tableName
12+
* @param Select $select
13+
* @return $this
14+
*/
15+
public function add($tableName, Select $select) {
16+
$this->virtualTables[$tableName] = $select;
17+
return $this;
18+
}
19+
20+
/**
21+
* @param string $tableName
22+
* @return bool
23+
*/
24+
public function has($tableName) {
25+
return array_key_exists($tableName, $this->virtualTables);
26+
}
27+
28+
/**
29+
* @param string $tableName
30+
* @return Select|null
31+
*/
32+
public function get($tableName) {
33+
if($this->has($tableName)) {
34+
return $this->virtualTables[$tableName];
35+
}
36+
return null;
37+
}
38+
}

tests/Builder/SelectTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,4 +341,28 @@ public function testSortSpecification() {
341341

342342
$this->assertEquals("SELECT\n\tt.field1,\n\tt.field2\nFROM\n\ttest t\nORDER BY\n\tREVERSE(t.field2) ASC,\n\tfield1 DESC\n", $query);
343343
}
344+
345+
public function testVirtualTables() {
346+
$vt1 = TestSelect::create()
347+
->field('a.field1')
348+
->from('a', 'tableA');
349+
350+
$vt2 = TestSelect::create()
351+
->field('a.field1')
352+
->from('a', 'tableA');
353+
354+
$db = new TestDB();
355+
$db->getVirtualTables()->add('virt_table1', $vt1);
356+
$db->getVirtualTables()->add('virt_table2', $vt2);
357+
358+
$query = TestSelect::create($db)
359+
->field('t.field1')
360+
->field('t.field2')
361+
->from('t', 'test')
362+
->joinInner('vt1', 'virt_table1', 'vt1.field1=t.field1')
363+
->joinInner('vt2', 'virt_table2', 'vt2.field2=t.field2')
364+
->asString();
365+
366+
$this->assertEquals("SELECT\n\tt.field1,\n\tt.field2\nFROM\n\ttest t\nINNER JOIN\n\t(SELECT\n\t\ta.field1\n\tFROM\n\t\ttableA a) vt1 ON vt1.field1=t.field1\nINNER JOIN\n\t(SELECT\n\t\ta.field1\n\tFROM\n\t\ttableA a) vt2 ON vt2.field2=t.field2\n", $query);
367+
}
344368
}

tests/Builder/SelectTest/TestSelect.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
namespace Kir\MySQL\Builder\SelectTest;
33

44
use Kir\MySQL\Builder\RunnableSelect;
5+
use Kir\MySQL\Database;
56
use Kir\MySQL\Databases\TestDB;
67

78
class TestSelect extends RunnableSelect {
89
/**
10+
* @param Database|null $db
911
* @return $this
1012
*/
11-
public static function create() {
12-
$db = new TestDB();
13+
public static function create(Database $db = null) {
14+
if($db === null) {
15+
$db = new TestDB();
16+
}
1317
return new static($db);
1418
}
1519

@@ -19,4 +23,4 @@ public static function create() {
1923
public function asString() {
2024
return $this->__toString();
2125
}
22-
}
26+
}

tests/Builder/UpdateTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ public function testSetAll1() {
7474
public function testSetAll2() {
7575
$db = Phake::mock('Kir\\MySQL\\Databases\\MySQL');
7676
$reg = Phake::mock('Kir\\MySQL\\Tools\\AliasRegistry');
77+
$vt = Phake::mock('Kir\\MySQL\\Tools\\VirtualTables');
7778
Phake::when($db)->__call('getTableFields', ['test1'])->thenReturn(['field1', 'field2']);
7879
Phake::when($db)->__call('quoteField', [Phake::anyParameters()])->thenGetReturnByLambda(function ($fieldName) { return "`{$fieldName}`"; });
7980
Phake::when($db)->__call('quote', [Phake::anyParameters()])->thenGetReturnByLambda(function ($value) { return "'{$value}'"; });
8081
Phake::when($db)->__call('getAliasRegistry', [])->thenReturn($reg);
82+
Phake::when($db)->__call('getVirtualTables', [])->thenReturn($vt);
8183
$sql = (new TestUpdate($db))
8284
->table('test1')
8385
->setAll(['field1' => 1, 'field2' => 2, 'field3' => 3])

tests/Builder/UpdateTest/TestUpdate.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,7 @@ class TestUpdate extends Update {
99
* @return $this
1010
*/
1111
public static function create() {
12-
$functions = array(
13-
'getTableFields' => function ($tableName) {
14-
return array();
15-
}
16-
);
17-
18-
$db = new TestDB($functions);
12+
$db = new TestDB();
1913
return new static($db);
2014
}
2115

@@ -25,4 +19,4 @@ public static function create() {
2519
public function asString() {
2620
return $this->__toString();
2721
}
28-
}
22+
}

0 commit comments

Comments
 (0)