Passed
Pull Request — master (#134)
by David
05:50
created

FindObjectsQueryFactory::compute()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 44
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 44
rs 8.8337
c 0
b 0
f 0
cc 6
nc 9
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace TheCodingMachine\TDBM\QueryFactory;
5
6
use Doctrine\Common\Cache\Cache;
7
use Doctrine\DBAL\Platforms\MySqlPlatform;
8
use Doctrine\DBAL\Schema\Schema;
9
use TheCodingMachine\TDBM\OrderByAnalyzer;
10
use TheCodingMachine\TDBM\TDBMService;
11
12
/**
13
 * This class is in charge of creating the MagicQuery SQL based on parameters passed to findObjects method.
14
 */
15
class FindObjectsQueryFactory extends AbstractQueryFactory
16
{
17
    private $mainTable;
18
    private $additionalTablesFetch;
19
    private $filterString;
20
    /**
21
     * @var Cache
22
     */
23
    private $cache;
24
25
    public function __construct(string $mainTable, array $additionalTablesFetch, $filterString, $orderBy, TDBMService $tdbmService, Schema $schema, OrderByAnalyzer $orderByAnalyzer, Cache $cache)
26
    {
27
        parent::__construct($tdbmService, $schema, $orderByAnalyzer, $orderBy);
28
        $this->mainTable = $mainTable;
29
        $this->additionalTablesFetch = $additionalTablesFetch;
30
        $this->filterString = $filterString;
31
        $this->cache = $cache;
32
    }
33
34
    protected function compute(): void
35
    {
36
        $key = 'FindObjectsQueryFactory_'.$this->mainTable.'__'.implode('_/_',$this->additionalTablesFetch).'__'.$this->filterString.'__'.$this->orderBy;
37
        if ($this->cache->contains($key)) {
38
            [
39
                $this->magicSql,
40
                $this->magicSqlCount,
41
                $this->columnDescList
42
            ] = $this->cache->fetch($key);
43
            return;
44
        }
45
46
        list($columnDescList, $columnsList, $orderString) = $this->getColumnsList($this->mainTable, $this->additionalTablesFetch, $this->orderBy, true);
47
48
        $sql = 'SELECT DISTINCT '.implode(', ', $columnsList).' FROM MAGICJOIN('.$this->mainTable.')';
49
50
        $pkColumnNames = $this->tdbmService->getPrimaryKeyColumns($this->mainTable);
51
        $pkColumnNames = array_map(function ($pkColumn) {
52
            return $this->tdbmService->getConnection()->quoteIdentifier($this->mainTable).'.'.$this->tdbmService->getConnection()->quoteIdentifier($pkColumn);
53
        }, $pkColumnNames);
54
55
        if (count($pkColumnNames) === 1 || $this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) {
56
            $countSql = 'SELECT COUNT(DISTINCT '.implode(', ', $pkColumnNames).') FROM MAGICJOIN('.$this->mainTable.')';
57
        } else {
58
            $countSql = 'SELECT COUNT(*) FROM (SELECT DISTINCT '.implode(', ', $pkColumnNames).' FROM MAGICJOIN('.$this->mainTable.')) tmp';
59
        }
60
61
        if (!empty($this->filterString)) {
62
            $sql .= ' WHERE '.$this->filterString;
63
            $countSql .= ' WHERE '.$this->filterString;
64
        }
65
66
        if (!empty($orderString)) {
67
            $sql .= ' ORDER BY '.$orderString;
68
        }
69
70
        $this->magicSql = $sql;
71
        $this->magicSqlCount = $countSql;
72
        $this->columnDescList = $columnDescList;
73
74
        $this->cache->save($key, [
75
            $this->magicSql,
76
            $this->magicSqlCount,
77
            $this->columnDescList,
78
        ]);
79
    }
80
}
81