Completed
Push — master ( f707f5...a08928 )
by Rasmus
02:27
created

UpdateQuery::getSQL()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.246

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 21
ccs 11
cts 14
cp 0.7856
rs 8.7624
cc 5
eloc 14
nc 16
nop 0
crap 5.246
1
<?php
2
3
namespace mindplay\sql\model\query;
4
5
use mindplay\sql\model\schema\Column;
6
7
/**
8
 * This class represents an UPDATE query.
9
 */
10
class UpdateQuery extends ProjectionQuery
11
{
12
    /**
13
     * @var mixed[] map where Column name => literal SQL expression to assign
14
     */
15
    private $assignments = [];
16
17
    /**
18
     * @param Column|string $column Column to update (or Column name)
19
     * @param mixed         $value  value to apply
20
     *
21
     * @return $this
22
     */
23 1
    public function setValue($column, $value)
24
    {
25 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...
26 1
            $name = $this->getPlaceholder($column);
27
28 1
            $quoted_name = $this->driver->quoteName($column->getName());
29
        } else {
30
            $name = $column;
31
32
            $quoted_name = $this->driver->quoteName($name);
33
        }
34
35 1
        $this->assignments[$name] = "{$quoted_name} = :{$name}";
36
37 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...
38
39 1
        return $this;
40
    }
41
42
    /**
43
     * @param Column|string $column Column to update (or Column name)
44
     * @param string        $expr   literal SQL expression
45
     *
46
     * @return $this
47
     */
48 1
    public function setExpr($column, $expr)
49
    {
50 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...
51 1
            $name = $this->getPlaceholder($column);
52
53 1
            $quoted_name = $this->driver->quoteName($column->getName());
54
        } else {
55
            $name = $column;
56
57
            $quoted_name = $this->driver->quoteName($name);
58
        }
59
60 1
        $this->assignments[$name] = "{$quoted_name} = {$expr}";
61
62 1
        return $this;
63
    }
64
65
    /**
66
     * @param array $values map where Column name => scalar values to assign
67
     *
68
     * @return $this
69
     */
70 1
    public function assign(array $values)
71
    {
72 1
        $columns = $this->root->listColumns();
73
74 1
        foreach ($columns as $column) {
75 1
            $name = $column->getName();
76
77 1
            if (array_key_exists($name, $values)) {
78 1
                $this->setValue($column, $values[$name]);
79
            }
80
        }
81
82 1
        return $this;
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88 1
    public function getSQL()
89
    {
90 1
        $update = "UPDATE " . $this->buildNodes();
91
92 1
        $set = "\nSET " . implode(",\n    ", $this->assignments);
93
94 1
        $where = count($this->conditions)
95 1
            ? "\nWHERE " . $this->buildConditions()
96 1
            : ''; // no conditions present
97
98 1
        $order = count($this->order)
99
            ? "\nORDER BY " . $this->buildOrderTerms()
100 1
            : ''; // no order terms
101
102 1
        $limit = $this->limit !== null
103
            ? "\nLIMIT {$this->limit}"
104
            . ($this->offset !== null ? " OFFSET {$this->offset}" : '')
105 1
            : ''; // no limit or offset
106
107 1
        return "{$update}{$set}{$where}{$order}{$limit}";
108
    }
109
110
    /**
111
     * @param Column $column
112
     *
113
     * @return string
114
     */
115 1
    private function getPlaceholder(Column $column)
116
    {
117 1
        $table = $column->getTable();
118
119 1
        $table_name = $table->getAlias() ?: $table->getName();
120
121 1
        $column_name = $column->getName();
122
123 1
        $name = "{$table_name}_{$column_name}";
124
125 1
        return $name;
126
    }
127
}
128