Completed
Push — master ( 8dd9a1...8abdd4 )
by Rasmus
02:22
created

SelectQuery::groupBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace mindplay\sql\model;
4
5
use mindplay\sql\framework\Driver;
6
use mindplay\sql\framework\MapperProvider;
7
use mindplay\sql\framework\TypeProvider;
8
use mindplay\sql\model\components\Mappers;
9
use mindplay\sql\model\components\ReturnVars;
10
11
/**
12
 * This class represents a SELECT query.
13
 *
14
 * This class implements `__toString()` magic, enabling the use of this query builder
15
 * in the SELECT, WHERE or ORDER BY clause of a parent SELECT (or other type of) query.
16
 *
17
 * Note that, when constructing nested queries, parameters must be bound against the
18
 * parent query - binding parameters or applying Mappers against a nested query has no effect.
19
 */
20
class SelectQuery extends ProjectionQuery implements MapperProvider
21
{
22
    use Mappers;
23
24
    /**
25
     * @var ReturnVars
26
     */
27
    private $return_vars;
28
29
    /**
30
     * @var string[] list of GROUP BY expressions
31
     */
32
    private $group_by = [];
33
34
    /**
35
     * @param Table        $root
36
     * @param Driver       $driver
37
     * @param TypeProvider $types
38
     */
39 1
    public function __construct(Table $root, Driver $driver, TypeProvider $types)
40
    {
41 1
        parent::__construct($root, $driver, $types);
42
        
43 1
        $this->return_vars = new ReturnVars($root, $driver, $types);
44 1
    }
45
46
    /**
47
     * Add all the Columns of a full Table to be selected and returned
48
     *
49
     * @param Table $table Table to select and return
50
     *
51
     * @return $this
52
     */
53 1
    public function table(Table $table)
54
    {
55 1
        $this->return_vars->addTable($table);
56
57 1
        return $this;
58
    }
59
60
    /**
61
     * Add one or more Columns to select and return
62
     *
63
     * @param Column|Column[] one or more Columns to select and return
64
     *
65
     * @return $this
66
     */
67 1
    public function columns($cols)
68
    {
69 1
        $this->return_vars->addColumns($cols);
70
71 1
        return $this;
72
    }
73
74
    /**
75
     * Add an SQL expression to select and return
76
     *
77
     * @param string           $expr return expression
78
     * @param string|null      $name return variable name (optional, but usually required)
79
     * @param Type|string|null $type optional Type (or Type class-name)
80
     *
81
     * @return $this
82
     */
83 1
    public function value($expr, $name = null, $type = null)
84
    {
85 1
        $this->return_vars->addValue($expr, $name, $type);
86
87 1
        return $this;
88
    }
89
90
    /**
91
     * Add an expression to apply to a GROUP BY clause
92
     *
93
     * @param Column|string $expr SQL expression (or Column object) to apply to the GROUP BY clause
94
     *
95
     * @return $this
96
     */
97 1
    public function groupBy($expr)
98
    {
99 1
        $this->group_by[] = (string) $expr;
100
101 1
        return $this;
102
    }
103
104
    /**
105
     * @inheritdoc
106
     */
107 1
    public function getMappers()
108
    {
109 1
        return array_merge([$this->return_vars->createTypeMapper()], $this->mappers);
110
    }
111
112
    /**
113
     * @inheritdoc
114
     */
115 1
    public function getSQL()
116
    {
117 1
        $select = "SELECT " . $this->return_vars->buildReturnVars();
118
119 1
        $from = "\nFROM " . $this->buildNodes();
120
121 1
        $where = count($this->conditions)
122 1
            ? "\nWHERE " . $this->buildConditions()
123 1
            : ''; // no conditions present
124
        
125 1
        $group_by = count($this->group_by)
126 1
            ? "\nGROUP BY " . implode(", ", $this->group_by)
127 1
            : ""; // no group-by expressions
128
        
129 1
        $order = count($this->order)
130 1
            ? "\nORDER BY " . $this->buildOrderTerms()
131 1
            : ''; // no order terms
132
133 1
        $limit = $this->limit !== null
134 1
            ? "\nLIMIT {$this->limit}"
135 1
            . ($this->offset !== null ? " OFFSET {$this->offset}" : '')
136 1
            : ''; // no limit or offset
137
138 1
        return "{$select}{$from}{$where}{$group_by}{$order}{$limit}";
139
    }
140
    
141
    /**
142
     * @ignore string magic (enables creation of nested SELECT queries)
143
     */
144 1
    public function __toString()
145
    {
146 1
        return "(" . $this->getSQL() . ")";
147
    }
148
}
149