Update::clearValues()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 27
rs 8.8333
c 0
b 0
f 0
cc 7
nc 5
nop 1
1
<?php
2
3
namespace Kir\MySQL\Builder;
4
5
use Kir\MySQL\Builder\Internal\DefaultValue;
6
use Kir\MySQL\Builder\Internal\Types;
7
use Kir\MySQL\Builder\Traits\JoinBuilder;
8
use Kir\MySQL\Builder\Traits\LimitBuilder;
9
use Kir\MySQL\Builder\Traits\OffsetBuilder;
10
use Kir\MySQL\Builder\Traits\OrderByBuilder;
11
use Kir\MySQL\Builder\Traits\TableBuilder;
12
use Kir\MySQL\Builder\Traits\TableNameBuilder;
13
use Kir\MySQL\Builder\Traits\WhereBuilder;
14
use RuntimeException;
15
16
/**
17
 * @phpstan-import-type DBTableNameType from Types
18
 */
19
abstract class Update extends InsertUpdateStatement {
20
	use TableNameBuilder;
21
	use TableBuilder;
22
	use JoinBuilder;
23
	use WhereBuilder;
24
	use OrderByBuilder;
25
	use LimitBuilder;
26
	use OffsetBuilder;
27
28
	/** @var mixed[] */
29
	private array $fields = [];
30
31
	/**
32
	 * @param ($table is null ? DBTableNameType : string) $alias
0 ignored issues
show
Bug introduced by
The type Kir\MySQL\Builder\is was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
	 * @param null|DBTableNameType $table
0 ignored issues
show
Bug introduced by
The type Kir\MySQL\Builder\DBTableNameType was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
	 * @return $this
35
	 */
36
	public function table($alias, $table = null): self {
37
		if($table === null) {
38
			[$alias, $table] = [$table, $alias];
39
		}
40
		$this->addTable($alias, $table);
41
42
		return $this;
43
	}
44
45
	/**
46
	 * @param string $fieldName
47
	 * @param mixed $value
48
	 * @return $this
49
	 */
50
	public function set(string $fieldName, $value): self {
51
		$sqlField = $fieldName;
52
		$sqlValue = $this->db()->quote($value);
53
		$this->fields[$sqlField] = $sqlValue;
54
55
		return $this;
56
	}
57
58
	/**
59
	 * @param string $fieldName
60
	 * @return $this
61
	 */
62
	public function setDefault(string $fieldName): self {
63
		$sqlField = $fieldName;
64
		$this->fields[$sqlField] = new DefaultValue();
65
66
		return $this;
67
	}
68
69
	/**
70
	 * @param string $expr
71
	 * @param mixed ...$args
72
	 * @return $this
73
	 */
74
	public function setExpr(string $expr, ...$args): self {
75
		if(count($args) > 0) {
76
			$this->fields[] = func_get_args();
77
		} else {
78
			$this->fields[] = $expr;
79
		}
80
81
		return $this;
82
	}
83
84
	/**
85
	 * @param array<string, mixed> $data
86
	 * @param array<int, string>|null $allowedFields
87
	 * @return $this
88
	 */
89
	public function setAll(array $data, ?array $allowedFields = null): self {
90
		if($allowedFields !== null) {
91
			foreach($data as $fieldName => $value) {
92
				if(in_array($fieldName, $allowedFields)) {
93
					$this->set($fieldName, $value);
94
				}
95
			}
96
		} else {
97
			$values = $this->clearValues($data);
98
			foreach($values as $fieldName => $value) {
99
				$this->set($fieldName, $value);
100
			}
101
		}
102
103
		return $this;
104
	}
105
106
	/**
107
	 * @param array<string, mixed> $params
108
	 * @return int
109
	 */
110
	abstract public function run(array $params = []): int;
111
112
	/**
113
	 * @return string
114
	 */
115
	public function __toString(): string {
116
		$query = "UPDATE\n";
117
		$query = $this->buildTables($query);
118
		$query = $this->buildJoins($query);
119
		$query .= "SET\n";
120
		$query = $this->buildAssignments($query);
121
		$query = $this->buildWhereConditions($query);
122
		$query = $this->buildOrder($query);
123
		$query = $this->buildLimit($query);
124
		$query = $this->buildOffset($query);
125
126
		return $query;
127
	}
128
129
	/**
130
	 * @param string $query
131
	 * @return string
132
	 */
133
	private function buildAssignments(string $query): string {
134
		$sqlFields = $this->buildFieldList($this->fields);
135
		if(!count($sqlFields)) {
136
			throw new RuntimeException('No field-data found');
137
		}
138
139
		return sprintf("%s%s\n", $query, implode(",\n", $sqlFields));
140
	}
141
142
	/**
143
	 * @param array<string, mixed> $values
144
	 * @return array<string, mixed>
145
	 */
146
	private function clearValues(array $values): array {
147
		if(!count($values)) {
148
			return [];
149
		}
150
		$tables = $this->getTables();
151
		if(!count($tables)) {
152
			throw new RuntimeException('Table name is missing');
153
		}
154
		if(count($tables) > 1) {
155
			throw new RuntimeException('Batch values only work with max. one table');
156
		}
157
158
		$table = $tables[0];
159
		$tableName = $table['name'];
160
161
		$result = [];
162
		if(is_string($tableName)) {
163
			$fields = $this->db()->getTableFields($tableName);
164
165
			foreach($values as $fieldName => $fieldValue) {
166
				if(in_array($fieldName, $fields, true)) {
167
					$result[$fieldName] = $fieldValue;
168
				}
169
			}
170
		}
171
172
		return $result;
173
	}
174
}
175