SelectQuery   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
eloc 49
dl 0
loc 175
ccs 69
cts 69
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A joins() 0 24 4
A clauses() 0 24 3
A get() 0 22 5
A group() 0 20 4
A verify() 0 7 3
1
<?php
2
3
namespace Rougin\Windstorm\Doctrine\Builder;
4
5
use Doctrine\DBAL\Platforms\AbstractPlatform;
6
use Doctrine\DBAL\Query\QueryException;
7
8
/**
9
 * Select Query
10
 *
11
 * @package Windstorm
12
 * @author  Rougin Gutib <[email protected]>
13
 */
14
class SelectQuery
15
{
16
    /**
17
     * @var array
18
     */
19
    protected $parts = array();
20
21
    /**
22
     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
23
     */
24
    protected $platform;
25
26
    /**
27
     * @var integer|null
28
     */
29
    protected $max = null;
30
31
    /**
32
     * @var integer|null
33
     */
34
    protected $first = null;
35
36
    /**
37
     * Initializes the query instance.
38
     *
39
     * @param array                                     $parts
40
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
41
     * @param integer|null                              $max
42
     * @param integer|null                              $first
43
     */
44 138
    public function __construct($parts, AbstractPlatform $platform, $max, $first)
45
    {
46 138
        $this->parts = $parts;
47
48 138
        $this->platform = $platform;
49
50 138
        $this->max = $max;
51
52 138
        $this->first = $first;
53 138
    }
54
55
    /**
56
     * Returns the compiled SQL.
57
     *
58
     * @return string
59
     */
60 138
    public function get()
61
    {
62 138
        $query = 'SELECT ' . (string) implode(', ', (array) $this->parts['select']);
63
64 138
        if ($this->parts['from'])
65 92
        {
66 138
            $query .= ' FROM ' . (string) implode(', ', $this->clauses());
67 92
        }
68
69 138
        if ($this->parts['where'] !== null)
70 92
        {
71 57
            $query .= ' WHERE ' . $this->parts['where'];
72 38
        }
73
74 138
        $query .= $this->group();
75
76 138
        if ($this->max !== null || $this->first !== null)
77 92
        {
78 6
            return $this->platform->modifyLimitQuery($query, $this->max, $this->first);
79
        }
80
81 132
        return $query;
82
    }
83
84
    /**
85
     * Verifies and returns the clauses specified.
86
     *
87
     * @return string[]
88
     */
89 138
    protected function clauses()
90
    {
91 138
        list($aliases, $clauses) = array(array(), array());
92
93
        // Loop through all FROM clauses
94 138
        foreach ($this->parts['from'] as $from)
95
        {
96 138
            $sql = $reference = $from['table'];
97
98 138
            if ($from['alias'] !== null)
99 92
            {
100 21
                $sql = $from['table'] . ' ' . $from['alias'];
101
102 21
                $reference = (string) $from['alias'];
103 14
            }
104
105 138
            $aliases[$reference] = true;
106
107 138
            $clauses[$reference] = $sql . $this->joins($reference, $aliases);
108 92
        }
109
110 138
        $this->verify($aliases);
111
112 138
        return $clauses;
113
    }
114
115
    /**
116
     * Returns the query for GROUP BY, HAVING, and ORDER BY.
117
     *
118
     * @return string
119
     */
120 138
    protected function group()
121
    {
122 138
        $query = '';
123
124 138
        if ($this->parts['groupBy'])
125 92
        {
126 6
            $query .= ' GROUP BY ' . implode(', ', $this->parts['groupBy']);
127 4
        }
128
129 138
        if ($this->parts['having'] !== null)
130 92
        {
131 18
            $query .= ' HAVING ' . $this->parts['having'];
132 12
        }
133
134 138
        if ($this->parts['orderBy'])
135 92
        {
136 24
            $query .= ' ORDER BY ' . implode(', ', $this->parts['orderBy']);
137 16
        }
138
139 138
        return $query;
140
    }
141
142
    /**
143
     * Creates JOIN queries on specified tables.
144
     *
145
     * @param  string $alias
146
     * @param  array  $aliases
147
     * @return string
148
     * @throws \Doctrine\DBAL\Query\QueryException
149
     */
150 138
    protected function joins($alias, array &$aliases)
151
    {
152 138
        $sql = '';
153
154 138
        if (! isset($this->parts['join'][$alias]))
155 92
        {
156 138
            return $sql;
157
        }
158
159 18
        foreach ($this->parts['join'][$alias] as $join)
160
        {
161 18
            $sql .= ' ' . strtoupper($join['joinType']) . ' JOIN ' . $join['joinTable'];
162
163 18
            $sql .= ' ' . $join['joinAlias'] . ' ON ' . ((string) $join['joinCondition']);
164
165 18
            $aliases[$join['joinAlias']] = true;
166 12
        }
167
168 18
        foreach ($this->parts['join'][$alias] as $join)
169
        {
170 18
            $sql .= $this->joins($join['joinAlias'], $aliases);
171 12
        }
172
173 18
        return $sql;
174
    }
175
176
    /**
177
     * Verifies the specified aliases.
178
     *
179
     * @param  array $aliases
180
     * @throws \Doctrine\DBAL\Query\QueryException
181
     */
182 138
    protected function verify(array $aliases)
183
    {
184 138
        foreach ($this->parts['join'] as $alias => $joins)
185
        {
186 18
            if (! isset($aliases[$alias]))
187 12
            {
188 6
                throw QueryException::unknownAlias($alias, array_keys($aliases));
189
            }
190 92
        }
191 138
    }
192
}
193