Update::setExpr()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
c 0
b 0
f 0
rs 10
cc 2
nc 2
nop 2
1
<?php
2
namespace Kir\MySQL\Builder;
3
4
use Kir\MySQL\Builder\Internal\DefaultValue;
5
use Kir\MySQL\Builder\Internal\Types;
6
use Kir\MySQL\Builder\Traits\JoinBuilder;
7
use Kir\MySQL\Builder\Traits\LimitBuilder;
8
use Kir\MySQL\Builder\Traits\OffsetBuilder;
9
use Kir\MySQL\Builder\Traits\OrderByBuilder;
10
use Kir\MySQL\Builder\Traits\TableBuilder;
11
use Kir\MySQL\Builder\Traits\TableNameBuilder;
12
use Kir\MySQL\Builder\Traits\WhereBuilder;
13
use RuntimeException;
14
15
/**
16
 * @phpstan-import-type DBTableNameType from Types
17
 */
18
abstract class Update extends InsertUpdateStatement {
19
	use TableNameBuilder;
20
	use TableBuilder;
21
	use JoinBuilder;
22
	use WhereBuilder;
23
	use OrderByBuilder;
24
	use LimitBuilder;
25
	use OffsetBuilder;
26
27
	/** @var mixed[] */
28
	private array $fields = [];
29
30
	/**
31
	 * @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...
32
	 * @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...
33
	 * @return $this
34
	 */
35
	public function table($alias, $table = null): self {
36
		if($table === null) {
37
			[$alias, $table] = [$table, $alias];
38
		}
39
		$this->addTable($alias, $table);
40
		return $this;
41
	}
42
43
	/**
44
	 * @param string $fieldName
45
	 * @param mixed $value
46
	 * @return $this
47
	 */
48
	public function set(string $fieldName, $value): self {
49
		$sqlField = $fieldName;
50
		$sqlValue = $this->db()->quote($value);
51
		$this->fields[$sqlField] = $sqlValue;
52
		return $this;
53
	}
54
55
	/**
56
	 * @param string $fieldName
57
	 * @return $this
58
	 */
59
	public function setDefault(string $fieldName): self {
60
		$sqlField = $fieldName;
61
		$this->fields[$sqlField] = new DefaultValue();
62
		return $this;
63
	}
64
65
	/**
66
	 * @param string $expr
67
	 * @param mixed ...$args
68
	 * @return $this
69
	 */
70
	public function setExpr(string $expr, ...$args): self {
71
		if(count($args) > 0) {
72
			$this->fields[] = func_get_args();
73
		} else {
74
			$this->fields[] = $expr;
75
		}
76
		return $this;
77
	}
78
79
	/**
80
	 * @param array<string, mixed> $data
81
	 * @param array<int, string>|null $allowedFields
82
	 * @return $this
83
	 */
84
	public function setAll(array $data, ?array $allowedFields = null): self {
85
		if($allowedFields !== null) {
86
			foreach($data as $fieldName => $value) {
87
				if(in_array($fieldName, $allowedFields)) {
88
					$this->set($fieldName, $value);
89
				}
90
			}
91
		} else {
92
			$values = $this->clearValues($data);
93
			foreach($values as $fieldName => $value) {
94
				$this->set($fieldName, $value);
95
			}
96
		}
97
		return $this;
98
	}
99
100
	/**
101
	 * @param array<string, mixed> $params
102
	 * @return int
103
	 */
104
	abstract public function run(array $params = []): int;
105
106
	/**
107
	 * @return string
108
	 */
109
	public function __toString(): string {
110
		$query = "UPDATE\n";
111
		$query = $this->buildTables($query);
112
		$query = $this->buildJoins($query);
113
		$query .= "SET\n";
114
		$query = $this->buildAssignments($query);
115
		$query = $this->buildWhereConditions($query);
116
		$query = $this->buildOrder($query);
117
		$query = $this->buildLimit($query);
118
		$query = $this->buildOffset($query);
119
		return $query;
120
	}
121
122
	/**
123
	 * @param string $query
124
	 * @return string
125
	 */
126
	private function buildAssignments(string $query): string {
127
		$sqlFields = $this->buildFieldList($this->fields);
128
		if(!count($sqlFields)) {
129
			throw new RuntimeException('No field-data found');
130
		}
131
		return sprintf("%s%s\n", $query, implode(",\n", $sqlFields));
132
	}
133
134
	/**
135
	 * @param array<string, mixed> $values
136
	 * @return array<string, mixed>
137
	 */
138
	private function clearValues(array $values): array {
139
		if(!count($values)) {
140
			return [];
141
		}
142
		$tables = $this->getTables();
143
		if(!count($tables)) {
144
			throw new RuntimeException('Table name is missing');
145
		}
146
		if(count($tables) > 1) {
147
			throw new RuntimeException('Batch values only work with max. one table');
148
		}
149
150
		$table = $tables[0];
151
		$tableName = $table['name'];
152
153
		$result = [];
154
		if(is_string($tableName)) {
0 ignored issues
show
introduced by
The condition is_string($tableName) is always false.
Loading history...
155
			$fields = $this->db()->getTableFields($tableName);
156
157
			foreach($values as $fieldName => $fieldValue) {
158
				if(in_array($fieldName, $fields, true)) {
159
					$result[$fieldName] = $fieldValue;
160
				}
161
			}
162
		}
163
		return $result;
164
	}
165
}
166