11<?php
22
3+ declare (strict_types=1 );
4+
35/**
46 * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
57 * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
68 * SPDX-License-Identifier: AGPL-3.0-only
79 */
810namespace OC \Files \Cache ;
911
12+ use OC \DB \Exceptions \DbalException ;
1013use OCP \DB \QueryBuilder \IQueryBuilder ;
1114use OCP \Files \Storage \IStorage ;
1215use OCP \IDBConnection ;
2528 * @package OC\Files\Cache
2629 */
2730class Storage {
28- /** @var StorageGlobal|null */
29- private static $ globalCache = null ;
30- private $ storageId ;
31- private $ numericId ;
31+ private static ?StorageGlobal $ globalCache = null ;
3232
33- /**
34- * @return StorageGlobal
35- */
36- public static function getGlobalCache () {
33+ private string $ storageId ;
34+
35+ private int $ numericId ;
36+
37+ public static function getGlobalCache (): StorageGlobal {
3738 if (is_null (self ::$ globalCache )) {
3839 self ::$ globalCache = new StorageGlobal (Server::get (IDBConnection::class));
3940 }
41+
4042 return self ::$ globalCache ;
4143 }
4244
4345 /**
44- * @param \OC\Files\Storage\Storage|string $storage
45- * @param bool $isAvailable
4646 * @throws \RuntimeException
4747 */
48- public function __construct ($ storage , $ isAvailable , IDBConnection $ connection ) {
49- if ($ storage instanceof IStorage) {
50- $ this ->storageId = $ storage ->getId ();
51- } else {
52- $ this ->storageId = $ storage ;
53- }
54- $ this ->storageId = self ::adjustStorageId ($ this ->storageId );
48+ public function __construct (
49+ IStorage |string $ storage ,
50+ bool $ isAvailable ,
51+ IDBConnection $ connection ,
52+ ) {
53+ $ this ->storageId = $ storage instanceof IStorage ? $ storage ->getId () : $ storage ;
54+
55+ $ this ->storageId = self ::adjustStorageId ($ this ->storageId );
5556
5657 if ($ row = self ::getStorageById ($ this ->storageId )) {
57- $ this ->numericId = ( int ) $ row ['numeric_id ' ];
58+ $ this ->numericId = $ row ['numeric_id ' ];
5859 } else {
5960 $ available = $ isAvailable ? 1 : 0 ;
60- if ($ connection ->insertIfNotExist ('*PREFIX*storages ' , ['id ' => $ this ->storageId , 'available ' => $ available ])) {
61- $ this ->numericId = $ connection ->lastInsertId ('*PREFIX*storages ' );
62- } else {
63- if ($ row = self ::getStorageById ($ this ->storageId )) {
64- $ this ->numericId = (int )$ row ['numeric_id ' ];
65- } else {
66- throw new \RuntimeException ('Storage could neither be inserted nor be selected from the database: ' . $ this ->storageId );
61+
62+ try {
63+ $ qb = $ connection ->getQueryBuilder ();
64+ $ qb ->insert ('storages ' )
65+ ->values ([
66+ 'id ' => $ qb ->createNamedParameter ($ this ->storageId ),
67+ 'available ' => $ qb ->createNamedParameter ($ available ),
68+ ])
69+ ->executeStatement ();
70+ $ this ->numericId = $ qb ->getLastInsertId ();
71+ } catch (DbalException $ e ) {
72+ if ($ e ->getReason () === DbalException::REASON_UNIQUE_CONSTRAINT_VIOLATION ) {
73+ $ qb = $ connection ->getQueryBuilder ();
74+ $ result = $ qb ->select ('numeric_id ' )
75+ ->from ('storage ' )
76+ ->where ($ qb ->expr ()->eq ('id ' , $ qb ->createNamedParameter ($ this ->storageId )))
77+ ->executeQuery ();
78+ /** @var false|string|int $row */
79+ $ row = $ result ->fetchOne ();
80+ if ($ row === false ) {
81+ throw new \RuntimeException ('Storage could neither be inserted nor be selected from the database: ' . $ this ->storageId , $ e ->getCode (), $ e );
82+ }
83+
84+ $ this ->numericId = (int )$ row ;
6785 }
86+
87+ throw $ e ;
6888 }
6989 }
7090 }
7191
7292 /**
73- * @param string $storageId
74- * @return array
75- */
76- public static function getStorageById ($ storageId ) {
93+ * @return array{id: string, numeric_id: int, available: bool, last_checked: int}|null
94+ */
95+ public static function getStorageById (string $ storageId ): ?array {
7796 return self ::getGlobalCache ()->getStorageInfo ($ storageId );
7897 }
7998
@@ -83,71 +102,52 @@ public static function getStorageById($storageId) {
83102 * @return string unchanged $storageId if its length is less than 64 characters,
84103 * else returns the md5 of $storageId
85104 */
86- public static function adjustStorageId ($ storageId ) {
105+ public static function adjustStorageId (string $ storageId ): string {
87106 if (strlen ($ storageId ) > 64 ) {
88107 return md5 ($ storageId );
89108 }
109+
90110 return $ storageId ;
91111 }
92112
93113 /**
94114 * Get the numeric id for the storage
95- *
96- * @return int
97115 */
98- public function getNumericId () {
116+ public function getNumericId (): int {
99117 return $ this ->numericId ;
100118 }
101119
102120 /**
103- * Get the string id for the storage
104- *
105- * @param int $numericId
106- * @return string|null either the storage id string or null if the numeric id is not known
107- */
108- public static function getStorageId (int $ numericId ): ?string {
121+ * Get the string id for the storage
122+ *
123+ * @return string|null either the storage id string or null if the numeric id is not known
124+ */
125+ public static function getStorageId (int $ numericId ): ?string {
109126 $ storage = self ::getGlobalCache ()->getStorageInfoByNumericId ($ numericId );
110127 return $ storage ['id ' ] ?? null ;
111128 }
112129
113- /**
114- * Get the numeric of the storage with the provided string id
115- *
116- * @param $storageId
117- * @return int|null either the numeric storage id or null if the storage id is not known
118- */
119- public static function getNumericStorageId ($ storageId ) {
120- $ storageId = self ::adjustStorageId ($ storageId );
121-
122- if ($ row = self ::getStorageById ($ storageId )) {
123- return (int )$ row ['numeric_id ' ];
124- } else {
125- return null ;
126- }
127- }
128-
129130 /**
130131 * @return array{available: bool, last_checked: int}
131132 */
132- public function getAvailability () {
133+ public function getAvailability (): array {
133134 if ($ row = self ::getStorageById ($ this ->storageId )) {
134135 return [
135136 'available ' => (int )$ row ['available ' ] === 1 ,
136137 'last_checked ' => $ row ['last_checked ' ]
137138 ];
138- } else {
139- return [
139+ }
140+
141+ return [
140142 'available ' => true ,
141143 'last_checked ' => time (),
142144 ];
143- }
144145 }
145146
146147 /**
147- * @param bool $isAvailable
148148 * @param int $delay amount of seconds to delay reconsidering that storage further
149149 */
150- public function setAvailability ($ isAvailable , int $ delay = 0 ) {
150+ public function setAvailability (bool $ isAvailable , int $ delay = 0 ): void {
151151 $ available = $ isAvailable ? 1 : 0 ;
152152 if (!$ isAvailable ) {
153153 Server::get (LoggerInterface::class)->info ('Storage with ' . $ this ->storageId . ' marked as unavailable ' , ['app ' => 'lib ' ]);
@@ -162,43 +162,9 @@ public function setAvailability($isAvailable, int $delay = 0) {
162162 }
163163
164164 /**
165- * Check if a string storage id is known
166- *
167- * @param string $storageId
168- * @return bool
169- */
170- public static function exists ($ storageId ) {
171- return !is_null (self ::getNumericStorageId ($ storageId ));
172- }
173-
174- /**
175- * remove the entry for the storage
176- *
177- * @param string $storageId
178- */
179- public static function remove ($ storageId ) {
180- $ storageId = self ::adjustStorageId ($ storageId );
181- $ numericId = self ::getNumericStorageId ($ storageId );
182-
183- $ query = Server::get (IDBConnection::class)->getQueryBuilder ();
184- $ query ->delete ('storages ' )
185- ->where ($ query ->expr ()->eq ('id ' , $ query ->createNamedParameter ($ storageId )));
186- $ query ->executeStatement ();
187-
188- if (!is_null ($ numericId )) {
189- $ query = Server::get (IDBConnection::class)->getQueryBuilder ();
190- $ query ->delete ('filecache ' )
191- ->where ($ query ->expr ()->eq ('storage ' , $ query ->createNamedParameter ($ numericId )));
192- $ query ->executeStatement ();
193- }
194- }
195-
196- /**
197- * remove the entry for the storage by the mount id
198- *
199- * @param int $mountId
165+ * Remove the entry for the storage by the mount id.
200166 */
201- public static function cleanByMountId (int $ mountId ) {
167+ public static function cleanByMountId (int $ mountId ): void {
202168 $ db = Server::get (IDBConnection::class);
203169
204170 try {
@@ -213,24 +179,24 @@ public static function cleanByMountId(int $mountId) {
213179
214180 $ query = $ db ->getQueryBuilder ();
215181 $ query ->delete ('filecache ' )
216- ->where ($ query ->expr ()->in ('storage ' , $ query ->createNamedParameter ($ storageIds , IQueryBuilder::PARAM_INT_ARRAY )));
217- $ query ->runAcrossAllShards ();
218- $ query ->executeStatement ();
182+ ->where ($ query ->expr ()->in ('storage ' , $ query ->createNamedParameter ($ storageIds , IQueryBuilder::PARAM_INT_ARRAY )))
183+ ->runAcrossAllShards ()
184+ ->executeStatement ();
219185
220186 $ query = $ db ->getQueryBuilder ();
221187 $ query ->delete ('storages ' )
222- ->where ($ query ->expr ()->in ('numeric_id ' , $ query ->createNamedParameter ($ storageIds , IQueryBuilder::PARAM_INT_ARRAY )));
223- $ query ->executeStatement ();
188+ ->where ($ query ->expr ()->in ('numeric_id ' , $ query ->createNamedParameter ($ storageIds , IQueryBuilder::PARAM_INT_ARRAY )))
189+ ->executeStatement ();
224190
225191 $ query = $ db ->getQueryBuilder ();
226192 $ query ->delete ('mounts ' )
227- ->where ($ query ->expr ()->eq ('mount_id ' , $ query ->createNamedParameter ($ mountId , IQueryBuilder::PARAM_INT )));
228- $ query ->executeStatement ();
193+ ->where ($ query ->expr ()->eq ('mount_id ' , $ query ->createNamedParameter ($ mountId , IQueryBuilder::PARAM_INT )))
194+ ->executeStatement ();
229195
230196 $ db ->commit ();
231- } catch (\Exception $ e ) {
197+ } catch (\Exception $ exception ) {
232198 $ db ->rollBack ();
233- throw $ e ;
199+ throw $ exception ;
234200 }
235201 }
236202}
0 commit comments