Completed
Push — master ( 509987...79a3d2 )
by Rasmus
02:45
created

UpdateQuery::getSQL()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
namespace mindplay\sql\model\query;
4
5
use mindplay\sql\model\components\Conditions;
6
use mindplay\sql\model\Driver;
7
use mindplay\sql\model\schema\Column;
8
use mindplay\sql\model\schema\Table;
9
use mindplay\sql\model\TypeProvider;
10
11
/**
12
 * This class represents an UPDATE query.
13
 */
14
class UpdateQuery extends Query
15
{
16
    use Conditions;
17
18
    /**
19
     * @var Table
20
     */
21
    protected $table;
22
23
    /**
24
     * @var Driver
25
     */
26
    protected $driver;
27
28
    /**
29
     * @var mixed[] map where Column name => literal SQL expression to assign
30
     */
31
    private $assignments = [];
32
33
    /**
34
     * @param Table        $table
35
     * @param TypeProvider $types
36
     */
37 1
    public function __construct(Table $table, Driver $driver, TypeProvider $types)
38
    {
39 1
        parent::__construct($types);
40
41 1
        $this->table = $table;
42 1
        $this->driver = $driver;
43 1
    }
44
45
    /**
46
     * @param Column|string $column Column to update (or Column name)
47
     * @param mixed         $value  value to apply
48
     *
49
     * @return $this
50
     */
51 1
    public function setValue($column, $value)
52
    {
53
        // TODO qualify table-references to support UPDATE queries with JOINs
54
55 1 View Code Duplication
        if ($column instanceof Column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56 1
            $name = $this->getPlaceholder($column);
57
58 1
            $quoted_name = $this->driver->quoteName($column->getName());
59
        } else {
60
            $name = $column;
61
62
            $quoted_name = $this->driver->quoteName($name);
63
        }
64
65 1
        $this->assignments[$name] = "{$quoted_name} = :{$name}";
66
67 1
        $this->bind($name, $value, $column->getType());
0 ignored issues
show
Bug introduced by
It seems like $column is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
68
69 1
        return $this;
70
    }
71
72
    /**
73
     * @param Column|string $column Column to update (or Column name)
74
     * @param string        $expr   literal SQL expression
75
     *
76
     * @return $this
77
     */
78 1
    public function setExpr($column, $expr)
79
    {
80
        // TODO qualify table-references to support UPDATE queries with JOINs
81
82 1 View Code Duplication
        if ($column instanceof Column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83 1
            $name = $this->getPlaceholder($column);
84
85 1
            $quoted_name = $this->driver->quoteName($column->getName());
86
        } else {
87
            $name = $column;
88
89
            $quoted_name = $this->driver->quoteName($name);
90
        }
91
92 1
        $this->assignments[$name] = "{$quoted_name} = {$expr}";
93
94 1
        return $this;
95
    }
96
97
    /**
98
     * @param array $values map where Column name => scalar values to assign
99
     *
100
     * @return $this
101
     */
102 1
    public function assign(array $values)
103
    {
104 1
        $columns = $this->table->listColumns();
105
106 1
        foreach ($columns as $column) {
107 1
            $name = $column->getName();
108
109 1
            if (array_key_exists($name, $values)) {
110 1
                $this->setValue($column, $values[$name]);
111
            }
112
        }
113
114 1
        return $this;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 1
    public function getSQL()
121
    {
122 1
        $update = "UPDATE " . $this->table->getNode();
123
124 1
        $set = "\nSET " . implode(",\n    ", $this->assignments);
125
126 1
        $where = count($this->conditions)
127 1
            ? "\nWHERE " . $this->buildConditions()
128 1
            : ''; // no conditions present
129
130 1
        return "{$update}{$set}{$where}";
131
    }
132
133
    /**
134
     * @param Column $column
135
     *
136
     * @return string
137
     */
138 1
    private function getPlaceholder(Column $column)
139
    {
140 1
        $table = $column->getTable();
141
142 1
        $table_name = $table->getAlias() ?: $table->getName();
143
144 1
        $column_name = $column->getName();
145
146 1
        $name = "{$table_name}_{$column_name}";
147
148 1
        return $name;
149
    }
150
}
151