Passed
Pull Request — master (#172)
by David
02:16
created

ManyToOnePartialQuery::getMagicQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
4
namespace TheCodingMachine\TDBM\QueryFactory\SmartEagerLoad\Query;
5
6
use Doctrine\DBAL\Connection;
7
use Doctrine\DBAL\Platforms\MySqlPlatform;
8
use Mouf\Database\MagicQuery;
9
use TheCodingMachine\TDBM\QueryFactory\SmartEagerLoad\ManyToOneDataLoader;
10
use TheCodingMachine\TDBM\QueryFactory\SmartEagerLoad\StorageNode;
11
12
class ManyToOnePartialQuery implements PartialQuery
13
{
14
    /**
15
     * @var string
16
     */
17
    private $mainTable;
18
    /**
19
     * @var string
20
     */
21
    private $key;
22
    /**
23
     * @var string
24
     */
25
    private $pk;
26
    /**
27
     * @var PartialQuery
28
     */
29
    private $partialQuery;
30
    /**
31
     * @var string
32
     */
33
    private $originTableName;
34
    /**
35
     * @var string
36
     */
37
    private $columnName;
38
39
    public function __construct(PartialQuery $partialQuery, string $originTableName, string $tableName, string $pk, string $columnName)
40
    {
41
        // TODO: move this in a separate function. The constructor is called for every bean.
42
        $this->partialQuery = $partialQuery;
43
        $this->mainTable = $tableName;
44
        $this->key = $partialQuery->getKey().'__'.$columnName;
45
        $this->pk = $pk;
46
        $this->originTableName = $originTableName;
47
        $this->columnName = $columnName;
48
    }
49
50
    /**
51
     * Returns the SQL of the query, starting at the FROM keyword.
52
     */
53
    public function getQueryFrom(): string
54
    {
55
        $mysqlPlatform = new MySqlPlatform();
56
        return 'FROM ' .$mysqlPlatform->quoteIdentifier($this->mainTable).
57
            ' WHERE ' .$mysqlPlatform->quoteIdentifier($this->mainTable).'.'.$mysqlPlatform->quoteIdentifier($this->pk).' IN '.
58
            '(SELECT '.$mysqlPlatform->quoteIdentifier($this->originTableName).'.'.$mysqlPlatform->quoteIdentifier($this->columnName).' '.$this->partialQuery->getQueryFrom().')';
59
    }
60
61
    /**
62
     * Returns the object in charge of storing the dataloader associated to this query.
63
     */
64
    public function getStorageNode(): StorageNode
65
    {
66
        return $this->partialQuery->getStorageNode();
67
    }
68
69
    /**
70
     * Returns a key representing the "path" to this query. This is meant to be used as a cache key.
71
     */
72
    public function getKey(): string
73
    {
74
        return $this->key;
75
    }
76
77
    /**
78
     * Registers a dataloader for this query, if needed.
79
     */
80
    public function registerDataLoader(Connection $connection): void
81
    {
82
        $storageNode = $this->getStorageNode();
83
        if ($storageNode->hasManyToOneDataLoader($this->key)) {
84
            return;
85
        }
86
87
        $mysqlPlatform = new MySqlPlatform();
88
        $sql = 'SELECT DISTINCT ' .$mysqlPlatform->quoteIdentifier($this->mainTable).'.* '.$this->getQueryFrom();
89
90
        if (!$connection->getDatabasePlatform() instanceof MySqlPlatform) {
91
            // We need to convert the query from MySQL dialect to something else
92
            $sql = $this->getMagicQuery()->buildPreparedStatement($sql);
93
        }
94
95
        $storageNode->setManyToOneDataLoader($this->key, new ManyToOneDataLoader($connection, $sql, $this->pk));
96
    }
97
98
    public function getMagicQuery(): MagicQuery
99
    {
100
        return $this->partialQuery->getMagicQuery();
101
    }
102
}
103