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

BulkUpdates::getUpdateFields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 5
c 1
b 0
f 1
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 10
cc 2
nc 2
nop 0
crap 6
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