Completed
Branch feature/split-orm (60a911)
by Anton
03:15
created

SelectQuery::columns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Database\Builders;
10
11
use Spiral\Database\Builders\Prototypes\AbstractSelect;
12
use Spiral\Database\Entities\Driver;
13
use Spiral\Database\Entities\QueryCompiler;
14
use Spiral\Database\Injections\FragmentInterface;
15
16
/**
17
 * SelectQuery extends AbstractSelect with ability to specify selection tables and perform UNION
18
 * of multiple select queries.
19
 */
20
class SelectQuery extends AbstractSelect implements \JsonSerializable
21
{
22
    /**
23
     * Table names to select data from.
24
     *
25
     * @var array
26
     */
27
    protected $tables = [];
28
29
    /**
30
     * Select queries represented by sql fragments or query builders to be united. Stored as
31
     * [UNION TYPE, SELECT QUERY].
32
     *
33
     * @var array
34
     */
35
    protected $unionTokens = [];
36
37
    /**
38
     * {@inheritdoc}
39
     *
40
     * @param array $from    Initial set of table names.
41
     * @param array $columns Initial set of columns to fetch.
42
     */
43
    public function __construct(
44
        Driver $driver,
45
        QueryCompiler $compiler,
46
        array $from = [],
47
        array $columns = []
48
    ) {
49
        parent::__construct($driver, $compiler);
50
51
        $this->tables = $from;
52
        if (!empty($columns)) {
53
            $this->columns = $this->fetchIdentifiers($columns);
54
        }
55
    }
56
57
    /**
58
     * Set table names SELECT query should be performed for. Table names can be provided with
59
     * specified alias (AS construction).
60
     *
61
     * @param array|string|mixed $tables Array of names, comma separated string or set of
62
     *                                   parameters.
63
     *
64
     * @return self|$this
65
     */
66
    public function from($tables): SelectQuery
67
    {
68
        $this->tables = $this->fetchIdentifiers(func_get_args());
69
70
        return $this;
71
    }
72
73
    /**
74
     * Set columns should be fetched as result of SELECT query. Columns can be provided with
75
     * specified alias (AS construction).
76
     *
77
     * @param array|string|mixed $columns Array of names, comma separated string or set of
78
     *                                    parameters.
79
     *
80
     * @return self|$this
81
     */
82
    public function columns($columns): SelectQuery
83
    {
84
        $this->columns = $this->fetchIdentifiers(func_get_args());
85
86
        return $this;
87
    }
88
89
    /**
90
     * Alias for columns() method.
91
     *
92
     * @param array|string|mixed $columns Array of names, comma separated string or set of
93
     *                                    parameters.
94
     *
95
     * @return self|$this
96
     */
97
    public function select($columns): SelectQuery
98
    {
99
        $this->columns = $this->fetchIdentifiers(func_get_args());
100
101
        return $this;
102
    }
103
104
    /**
105
     * Add select query to be united with.
106
     *
107
     * @param FragmentInterface $query
108
     *
109
     * @return self|$this
110
     */
111
    public function union(FragmentInterface $query): SelectQuery
112
    {
113
        $this->unionTokens[] = ['', $query];
114
115
        return $this;
116
    }
117
118
    /**
119
     * Add select query to be united with. Duplicate values will be included in result.
120
     *
121
     * @param FragmentInterface $query
122
     *
123
     * @return self|$this
124
     */
125
    public function unionAll(FragmentInterface $query): SelectQuery
126
    {
127
        $this->unionTokens[] = ['ALL', $query];
128
129
        return $this;
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function getParameters(QueryCompiler $compiler = null): array
136
    {
137
        $compiler = $compiler ?? $this->compiler;
138
139
        $parameters = parent::getParameters($compiler);
140
141
        //Unions always located at the end of query.
142
        foreach ($this->unionTokens as $union) {
143
            if ($union[0] instanceof QueryBuilder) {
144
                $parameters = array_merge($parameters, $union[0]->getParameters($compiler));
145
            }
146
        }
147
148
        return $parameters;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function sqlStatement(QueryCompiler $compiler = null): string
155
    {
156
        if (empty($compiler)) {
157
            $compiler = $this->compiler->resetQuoter();
158
        }
159
160
        //11 parameters!
161
        return $compiler->compileSelect(
162
            $this->tables,
163
            $this->distinct,
164
            $this->columns,
165
            $this->joinTokens,
166
            $this->whereTokens,
167
            $this->havingTokens,
168
            $this->grouping,
169
            $this->ordering,
170
            $this->getLimit(),
171
            $this->getOffset(),
172
            $this->unionTokens
173
        );
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function jsonSerialize()
180
    {
181
        return $this->fetchAll();
182
    }
183
184
    /**
185
     * Request all results as array.
186
     *
187
     * @return array
188
     */
189
    public function fetchAll(): array
190
    {
191
        return $this->getIterator()->fetchAll(\PDO::FETCH_ASSOC);
192
    }
193
}
194