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

BulkUpdates   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 8
Bugs 0 Features 3
Metric Value
wmc 19
eloc 68
c 8
b 0
f 3
dl 0
loc 102
ccs 0
cts 61
cp 0
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A mysqlCreate() 0 17 3
A pgCreate() 0 26 4
A addInstance() 0 4 1
A __construct() 0 3 1
A createSQL() 0 8 3
A getUpdateFields() 0 7 2
A updateGroup() 0 22 5
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