Completed
Push — master ( e37d11...f223f9 )
by Ron
02:36
created

TableGateway::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 8
nc 1
nop 4
1
<?php
2
namespace Kir\MySQL;
3
4
use Exception;
5
use Kir\MySQL\Builder\DBExpr;
6
use Kir\MySQL\TableGateway\SelectResult;
7
8
/**
9
 * @internal
10
 */
11
class TableGateway {
12
	/** @var Database */
13
	private $db;
14
	/** @var array */
15
	private $primaryKeys;
16
	/** @var array */
17
	private $options;
18
	/** @var string */
19
	private $tableName;
20
21
	/**
22
	 * @param Database $db
23
	 * @param string $tableName
24
	 * @param array $primaryKeys
25
	 * @param array $options
26
	 */
27
	public function __construct(Database $db, $tableName, array $primaryKeys, array $options = []) {
28
		$this->db = $db;
29
		$this->primaryKeys = array_values($primaryKeys);
30
		$options = array_merge(['allow-delete-all' => false], $options);
31
		$options = array_merge(['calc-found-rows' => false], $options);
32
		$options = array_merge(['preserve-types' => true], $options);
33
		$this->options = $options;
34
		$this->tableName = (string) $tableName;
35
	}
36
37
	/**
38
	 * @param array $data
39
	 * @param array $options
40
	 * @return SelectResult
41
	 */
42
	public function select(array $data = [], array $options = []) {
43
		$select = $this->db->select()
44
		->from('t', $this->tableName);
45
		if(array_key_exists('select-fields', $options) && is_array($options['select-fields'])) {
46
			$select->fields($options['select-fields']);
47
		}
48
		if(array_key_exists('calc-found-rows', $options)) {
49
			$select->setCalcFoundRows($options['calc-found-rows']);
50
		}
51
		if(array_key_exists('preserve-types', $options)) {
52
			$select->setPreserveTypes($options['preserve-types']);
53
		}
54
		if(array_key_exists('select-distinct', $options)) {
55
			$select->distinct($options['select-distinct']);
56
		}
57
		foreach($data as $fieldName => $value) {
58
			if($value instanceof DBExpr) {
59
				$select->where($value);
60
			} else {
61
				$select->where(sprintf("%s=?", $this->db->quoteField($fieldName)), $value);
62
			}
63
		}
64
		if(array_key_exists('debug', $options)) {
65
			$select->debug($options['debug']);
66
		}
67
		return new SelectResult($select, $options);
68
	}
69
70
	/**
71
	 * @param array $data
72
	 * @param array $options
73
	 * @return int
74
	 */
75
	public function insert(array $data, array $options = []) {
76
		$options = array_merge($this->options, $options);
77
		$insert = $this->db->insert()
78
		->into($this->tableName);
79 View Code Duplication
		if(array_key_exists('mask', $options) && is_array($options['mask'])) {
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...
80
			$insert->setMask(array_values($options['mask']));
81
		}
82
		if(count($this->primaryKeys) === 1) {
83
			$insert->setKey($this->primaryKeys[0]);
84
		}
85
		if(array_key_exists('defaults', $options)) {
86
			$data = array_merge($options['defaults'], $data);
87
		}
88
		if(array_key_exists('insert-defaults', $options)) {
89
			$data = array_merge($options['insert-defaults'], $data);
90
		}
91
		if(array_key_exists('insert-ignore', $options)) {
92
			$insert->setIgnore($options['insert-ignore']);
93
		}
94
		$insert->addAll($data);
95
		if(array_key_exists('debug', $options)) {
96
			$insert->debug($options['debug']);
97
		}
98
		return $insert->run();
99
	}
100
101
	/**
102
	 * @param array $data
103
	 * @param array $options
104
	 * @return int
105
	 */
106
	public function upsert(array $data, array $options = []) {
107
		$options = array_merge($this->options, $options);
108
		$insert = $this->db->insert()
109
		->into($this->tableName);
110 View Code Duplication
		if(array_key_exists('mask', $options) && is_array($options['mask'])) {
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...
111
			$insert->setMask(array_values($options['mask']));
112
		}
113
		if(count($this->primaryKeys) === 1) {
114
			$insert->setKey($this->primaryKeys[0]);
115
		}
116
		if(array_key_exists('defaults', $options)) {
117
			$data = array_merge($options['defaults'], $data);
118
		}
119
		if(array_key_exists('insert-defaults', $options)) {
120
			$data = array_merge($options['insert-defaults'], $data);
121
		}
122
		$keyData = array_intersect_key($data, array_combine($this->primaryKeys, $this->primaryKeys));
123
		$insert->addAll($keyData);
124
		$valueData = array_diff_key($data, array_combine($this->primaryKeys, $this->primaryKeys));
125
		$insert->addOrUpdateAll($valueData);
126
		if(array_key_exists('debug', $options)) {
127
			$insert->debug($options['debug']);
128
		}
129
		return $insert->run();
130
	}
131
132
	/**
133
	 * @param array $data
134
	 * @param array $options
135
	 * @return int
136
	 */
137
	public function update(array $data, array $options = []) {
138
		$options = array_merge($this->options, $options);
139
		$update = $this->db->update()
140
		->table($this->tableName);
141 View Code Duplication
		if(array_key_exists('mask', $options) && is_array($options['mask'])) {
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...
142
			$update->setMask(array_values($options['mask']));
143
		}
144
		if(array_key_exists('defaults', $options)) {
145
			$data = array_merge($options['defaults'], $data);
146
		}
147
		if(array_key_exists('update-defaults', $options)) {
148
			$data = array_merge($options['update-defaults'], $data);
149
		}
150
		$keyData = array_intersect_key($data, array_combine($this->primaryKeys, $this->primaryKeys));
151
		foreach($keyData as $fieldName => $value) {
152
			$update->where(sprintf("%s=?", $this->db->quoteField($fieldName)), $value);
153
		}
154
		$valueData = array_diff_key($data, array_combine($this->primaryKeys, $this->primaryKeys));
155
		$update->setAll($valueData);
156
		if(array_key_exists($options, 'debug')) {
157
			$update->debug($options['debug']);
158
		}
159
		return $update->run();
160
	}
161
162
	/**
163
	 * @param array $data
164
	 * @param array $options
165
	 * @return int
166
	 * @throws Exception
167
	 */
168
	public function delete(array $data = null, array $options = []) {
169
		if(!is_array($data)) {
170
			throw new Exception('Missing data parameter');
171
		}
172
		$options = array_merge($this->options, $options);
173
		$delete = $this->db->delete()
174
		->from($this->tableName);
175
		if(array_key_exists('delete-defaults', $options)) {
176
			$data = array_merge($options['delete-defaults'], $data);
177
		}
178
		$keyData = array_intersect_key($data, array_combine($this->primaryKeys, $this->primaryKeys));
179
		if(count($keyData) !== count($this->primaryKeys) && !$options['allow-delete-all']) {
180
			throw new Exception("You try to delete all data from {$this->tableName} which is not allowed by configuration");
181
		}
182
		foreach($keyData as $fieldName => $value) {
183
			$delete->where(sprintf("%s=?", $this->db->quoteField($fieldName)), $value);
184
		}
185
		if(array_key_exists($options, 'debug')) {
186
			$delete->debug($options['debug']);
187
		}
188
		return $delete->run();
189
	}
190
}
191