Test Failed
Push — master ( ccf43a...ee4cc3 )
by Jean-Christophe
17:42
created

BulkUpdates   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 28
Bugs 0 Features 5
Metric Value
wmc 18
eloc 61
c 28
b 0
f 5
dl 0
loc 94
ccs 0
cts 81
cp 0
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A addInstance() 0 4 1
A __construct() 0 3 1
A createSQL() 0 8 4
A mysqlCreate() 0 16 3
A pgCreate() 0 25 4
A getUpdateFields() 0 7 2
A groupOp() 0 15 3
1
<?php
2
3
namespace Ubiquity\orm\bulk;
4
5
use Ubiquity\orm\OrmUtils;
6
7
/**
8
 * Ubiquity\orm\bulk$BulkUpdates
9
 * This class is part of Ubiquity
10
 *
11
 * @author jcheron <[email protected]>
12
 * @version 1.0.3
13
 *
14
 */
15
class BulkUpdates extends AbstractBulks {
16
	private $sqlUpdate = [ ];
17
18
	public function __construct($className) {
19
		parent::__construct ( $className );
20
		$this->insertFields = \implode ( ',', $this->getQuotedKeys ( $this->fields, $this->db->quote ) );
21
	}
22
23
	public function addInstance($instance, $id = null) {
24
		$id = $id ?? OrmUtils::getFirstKeyValue ( $instance );
25
		$this->updateInstanceRest ( $instance );
26
		$this->instances [$id] = $instance;
27
	}
28
29
	public function createSQL() {
30
		switch ($this->dbType) {
31
			case 'mysql' :
32
			case 'pgsql' :
33
			case 'tarantool' :
34
				return $this->pgCreate ();
35
			default :
36
				throw new \RuntimeException ( $this->dbType . ' does not support bulk updates!' );
37
		}
38
	}
39
40
	private function pgCreate() {
41
		$quote = $this->db->quote;
42
43
		$count = \count ( $this->instances );
44
		$modelField = \str_repeat ( ' WHEN ? THEN ? ', $count );
45
46
		$keys = \array_keys ( $this->instances );
47
		$parameters = [ ];
48
		$_rest = [ ];
49
		foreach ( $this->instances as $k => $instance ) {
50
			$_rest [$k] = $instance->_rest;
51
		}
52
53
		$caseFields = [ ];
54
		$pk = $this->pkName;
55
		foreach ( $this->fields as $field ) {
56
			$caseFields [] = "{$quote}{$field}{$quote} = (CASE {$quote}{$pk}{$quote} {$modelField} ELSE {$quote}{$field}{$quote} END)";
57
			foreach ( $_rest as $pkv => $_restInstance ) {
58
				$parameters [] = $pkv;
59
				$parameters [] = $_restInstance [$field];
60
			}
61
		}
62
		$parameters = [ ...$parameters,...$keys ];
63
		$this->parameters = $parameters;
64
		return "UPDATE {$quote}{$this->tableName}{$quote} SET " . \implode ( ',', $caseFields ) . " WHERE {$quote}{$pk}{$quote} IN (" . \str_repeat ( '?,', $count - 1 ) . '?)';
65
	}
66
67
	private function mysqlCreate() {
68
		$quote = $this->db->quote;
69
		$fieldCount = \count ( $this->fields );
70
		$parameters = [ ];
71
		$values = [ ];
72
		$modelFields = '(' . \implode ( ',', \array_fill ( 0, $fieldCount, '?' ) ) . ')';
73
		foreach ( $this->instances as $instance ) {
74
			$parameters = \array_merge ( $parameters, \array_values ( $instance->_rest ) );
75
			$values [] = $modelFields;
76
		}
77
		$duplicateKey = [ ];
78
		foreach ( $this->fields as $field ) {
79
			$duplicateKey [] = "{$quote}{$field}{$quote} = VALUES({$quote}{$field}{$quote})";
80
		}
81
		$this->parameters = $parameters;
82
		return "INSERT INTO {$quote}{$this->tableName}{$quote} (" . $this->insertFields . ') VALUES ' . \implode ( ',', $values ) . ' ON DUPLICATE KEY UPDATE ' . \implode ( ',', $duplicateKey );
83
	}
84
85
	private function getUpdateFields() {
86
		$ret = array ();
87
		$quote = $this->db->quote;
88
		foreach ( $this->insertFields as $field ) {
89
			$ret [] = $quote . $field . $quote . '= :' . $field;
90
		}
91
		return \implode ( ',', $ret );
92
	}
93
94
	public function groupOp($count = 5) {
95
		$quote = $this->db->quote;
96
		$groups = \array_chunk ( $this->instances, $count );
97
98
		$updateTable = "UPDATE {$quote}{$this->tableName}{$quote} SET ";
99
		foreach ( $groups as $group ) {
100
			$sql = '';
101
			foreach ( $group as $instance ) {
102
				$kv = OrmUtils::getKeyFieldsAndValues ( $instance );
103
				$sql .= $updateTable . $this->db->getUpdateFieldsKeyAndValues ( $instance->_rest, $this->fields ) . ' WHERE ' . $this->db->getCondition ( $kv ) . ';';
104
			}
105
			$this->execGroupTrans ( $sql );
106
		}
107
		$this->instances = [ ];
108
		$this->parameters = [ ];
109
	}
110
}
111
112