Completed
Push — master ( 829b1d...cd3d61 )
by Maxence
02:55
created

UsingShortenUniqueIdInsteadOfCircleId::run()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 13
rs 8.8571
cc 5
eloc 9
nc 2
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Circles\Migration;
28
29
use OC\Share\Share;
30
use OCA\Circles\Db\CoreRequestBuilder;
31
use OCA\Circles\Model\Circle;
32
use OCP\IConfig;
33
use OCP\IDBConnection;
34
use OCP\Migration\IOutput;
35
use OCP\Migration\IRepairStep;
36
37
/**
38
 * Class UsingShortenUniqueIdInsteadOfCircleId
39
 *
40
 * @package OCA\Circles\Migration
41
 */
42
class UsingShortenUniqueIdInsteadOfCircleId implements IRepairStep {
43
44
	/** @var IDBConnection */
45
	protected $connection;
46
47
	/** @var  IConfig */
48
	protected $config;
49
50
	public function __construct(IDBConnection $connection, IConfig $config) {
51
		$this->connection = $connection;
52
		$this->config = $config;
53
	}
54
55
	/**
56
	 * Returns the step's name
57
	 *
58
	 * @return string
59
	 * @since 9.1.0
60
	 */
61
	public function getName() {
62
		return 'Using shorten unique id instead of circle id';
63
	}
64
65
	/**
66
	 * @param IOutput $output
67
	 */
68
	public function run(IOutput $output) {
69
		$oldVersion = explode(
70
			'.', \OC::$server->getConfig()
71
							 ->getAppValue('circles', 'installed_version', '')
72
		);
73
74
		if ((int)$oldVersion[0] === 0
75
			&& ((int)$oldVersion[1] < 12
76
				|| ((int)$oldVersion[1] === 12
77
					&& (int)$oldVersion[2] <= 1))) {
78
			$this->swapToShortenUniqueId();
79
		}
80
	}
81
82
83
	private function swapToShortenUniqueId() {
84
85
		$qb = $this->connection->getQueryBuilder();
86
87
		/** @noinspection PhpMethodParametersCountMismatchInspection */
88
		$qb->select('id', 'unique_id')
89
		   ->from(CoreRequestBuilder::TABLE_CIRCLES);
90
91
		$cursor = $qb->execute();
92
		while ($data = $cursor->fetch()) {
93
			$circleId = $data['id'];
94
			$shortenUniqueId = substr($data['unique_id'], 0, Circle::UNIQUEID_SHORT_LENGTH);
95
96
			$this->swapToShortenUniqueIdInTable(
97
				$circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_GROUPS
98
			);
99
			$this->swapToShortenUniqueIdInTable(
100
				$circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS
101
			);
102
103
			$this->cleanBuggyDuplicateEntries(
104
				$circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS, 'user_id'
105
			);
106
			$this->swapToShortenUniqueIdInTable(
107
				$circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_MEMBERS
108
			);
109
110
			$this->swapToShortenUniqueIdInTable(
111
				$circleId, $shortenUniqueId, CoreRequestBuilder::TABLE_LINKS
112
			);
113
			$this->swapToShortenUniqueIdInShares($circleId, $shortenUniqueId);
114
		}
115
		$cursor->closeCursor();
116
	}
117
118
119
	private function swapToShortenUniqueIdInTable($circleId, $shortenUniqueId, $table) {
120
121
		$qb = $this->connection->getQueryBuilder();
122
		$qb->update($table)
123
		   ->where(
124
			   $qb->expr()
125
				  ->eq('circle_id', $qb->createNamedParameter($circleId))
126
		   );
127
128
		$qb->set('circle_id', $qb->createNamedParameter($shortenUniqueId));
129
		$qb->execute();
130
	}
131
132
133
	private function swapToShortenUniqueIdInShares($circleId, $shortenUniqueId) {
134
		$qb = $this->connection->getQueryBuilder();
135
		$expr = $qb->expr();
136
137
		/** @noinspection PhpMethodParametersCountMismatchInspection */
138
		$qb->update('share')
139
		   ->where(
140
			   $expr->andX(
141
				   $expr->eq(
142
					   'share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE)
143
				   ),
144
				   $expr->eq('share_with', $qb->createNamedParameter($circleId))
145
			   )
146
		   );
147
148
		$qb->set('share_with', $qb->createNamedParameter($shortenUniqueId));
149
		$qb->execute();
150
	}
151
152
153
	private function cleanBuggyDuplicateEntries($circleId, $shortenUniqueId, $table, $field) {
154
155
		$qb = $this->connection->getQueryBuilder();
156
		$expr = $qb->expr();
157
158
		$qb->select($field)
159
		   ->from($table)
160
		   ->where(
161
			   $expr->eq('circle_id', $qb->createNamedParameter($circleId))
162
		   );
163
164
		$cursor = $qb->execute();
165
		while ($data = $cursor->fetch()) {
166
			$val = $data[$field];
167
			if ($val !== '') {
168
				$qb2 = $this->connection->getQueryBuilder();
169
				$expr2 = $qb2->expr();
170
				/** @noinspection PhpMethodParametersCountMismatchInspection */
171
				$qb2->delete($table)
172
					->where(
173
						$expr2->andX(
174
							$expr2->eq('circle_id', $qb2->createNamedParameter($shortenUniqueId)),
175
							$expr2->eq($field, $qb2->createNamedParameter($val))
176
						)
177
					);
178
				$qb2->execute();
179
			}
180
		}
181
		$cursor->closeCursor();
182
	}
183
184
}
185
186
187