Test Failed
Push — master ( c36a4e...c6936f )
by Jean-Christophe
03:13
created

BulkUpdates::updateGroup()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 3
Bugs 0 Features 2
Metric Value
eloc 17
c 3
b 0
f 2
dl 0
loc 22
ccs 0
cts 0
cp 0
rs 9.3888
cc 5
nc 12
nop 0
crap 30
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.2
13
 *
14
 */
15
class BulkUpdates extends AbstractBulks {
16
17
	public function __construct($className) {
18
		parent::__construct ( $className );
19
		$this->insertFields = \implode ( ',', $this->getQuotedKeys ( $this->fields, $this->db->quote ) );
20
	}
21
22
	public function addInstance($instance, $id = null) {
23
		$id = $id ?? OrmUtils::getFirstKeyValue ( $instance );
24
		$this->updateInstanceRest ( $instance );
25
		$this->instances [$id] = $instance;
26
	}
27
28
	public function createSQL() {
29
		switch ($this->dbType) {
30
			case 'mysql' :
31
				return $this->mysqlCreate ();
32
			case 'pgsql' :
33
				return $this->pgCreate ();
34
			default :
35
				throw new \RuntimeException ( $this->dbType . ' does not support bulk updates!' );
36
		}
37
	}
38
39
	private function pgCreate() {
40
		$quote = $this->db->quote;
41
		$tableName = OrmUtils::getTableName ( $this->class );
42
43
		$count = \count ( $this->instances );
44
		$modelField = \implode ( '', \array_fill ( 0, $count, ' WHEN ? THEN ? ' ) );
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 = \array_merge ( $parameters, $keys );
63
		$this->parameters = $parameters;
64
		return "UPDATE {$quote}{$tableName}{$quote} SET " . \implode ( ',', $caseFields ) . " WHERE {$quote}{$pk}{$quote} IN (" . \implode ( ',', \array_fill ( 0, $count, '?' ) ) . ')';
65
	}
66
67
	private function mysqlCreate() {
68
		$quote = $this->db->quote;
69
		$tableName = OrmUtils::getTableName ( $this->class );
70
		$fieldCount = \count ( $this->fields );
71
		$parameters = [ ];
72
		$values = [ ];
73
		$modelFields = '(' . \implode ( ',', \array_fill ( 0, $fieldCount, '?' ) ) . ')';
74
		foreach ( $this->instances as $instance ) {
75
			$parameters = \array_merge ( $parameters, \array_values ( $instance->_rest ) );
76
			$values [] = $modelFields;
77
		}
78
		$duplicateKey = [ ];
79
		foreach ( $this->fields as $field ) {
80
			$duplicateKey [] = "{$quote}{$field}{$quote} = VALUES({$quote}{$field}{$quote})";
81
		}
82
		$this->parameters = $parameters;
83
		return "INSERT INTO {$quote}{$tableName}{$quote} (" . $this->insertFields . ') VALUES ' . \implode ( ',', $values ) . ' ON DUPLICATE KEY UPDATE ' . \implode ( ',', $duplicateKey );
84
	}
85
86
	private function getUpdateFields() {
1 ignored issue
show
Unused Code introduced by
The method getUpdateFields() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
87
		$ret = array ();
88
		$quote = $this->db->quote;
89
		foreach ( $this->insertFields as $field ) {
90
			$ret [] = $quote . $field . $quote . '= :' . $field;
91
		}
92
		return \implode ( ',', $ret );
93
	}
94
95
	public function updateGroup() {
96
		$quote = $this->db->quote;
97
		$tableName = OrmUtils::getTableName ( $this->class );
98
		$sql = '';
99
		foreach ( $this->instances as $instance ) {
100
			$kv = OrmUtils::getKeyFieldsAndValues ( $instance );
101
			$sql .= "UPDATE {$quote}{$tableName}{$quote} SET " . $this->db->getUpdateFieldsKeyAndValues ( $instance->_rest ) . ' WHERE ' . $this->db->getCondition ( $kv ) . ';';
102
		}
103
		while ( true ) {
104
			try {
105
				$result = false;
106
				$this->db->beginTransaction ();
107
				$this->db->execute ( $sql );
108
				$result = $this->db->commit ();
109
				if ($result !== false) {
110
					return true;
111
				}
112
			} catch ( \Exception $e ) {
113
				$this->db->rollBack ();
114
			}
115
		}
116
		return false;
117
	}
118
}
119
120