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

UpdateQuery   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 137
Duplicated Lines 13.14 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 90.48%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 5
dl 18
loc 137
ccs 38
cts 42
cp 0.9048
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A setValue() 9 20 2
A setExpr() 9 18 2
A assign() 0 14 3
A getSQL() 0 12 2
A getPlaceholder() 0 12 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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