PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/files/cache/upgrade.php

https://github.com/sezuan/core
PHP | 227 lines | 114 code | 15 blank | 98 comment | 16 complexity | 973f95a9d21bb2eae687af5fa371de42 MD5 | raw file
Possible License(s): AGPL-3.0, AGPL-1.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\Files\Cache;
  9. class Upgrade {
  10. /**
  11. * @var Legacy $legacy
  12. */
  13. private $legacy;
  14. private $numericIds = array();
  15. private $mimeTypeIds = array();
  16. /**
  17. * @param Legacy $legacy
  18. */
  19. public function __construct($legacy) {
  20. $this->legacy = $legacy;
  21. }
  22. /**
  23. * Preform a upgrade a path and it's childs
  24. *
  25. * @param string $path
  26. * @param bool $mode
  27. */
  28. function upgradePath($path, $mode = Scanner::SCAN_RECURSIVE) {
  29. if (!$this->legacy->hasItems()) {
  30. return;
  31. }
  32. \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $path);
  33. if ($row = $this->legacy->get($path)) {
  34. $data = $this->getNewData($row);
  35. if ($data) {
  36. $this->insert($data);
  37. $this->upgradeChilds($data['id'], $mode);
  38. }
  39. }
  40. }
  41. /**
  42. * upgrade all child elements of an item
  43. *
  44. * @param int $id
  45. * @param bool $mode
  46. */
  47. function upgradeChilds($id, $mode = Scanner::SCAN_RECURSIVE) {
  48. $children = $this->legacy->getChildren($id);
  49. foreach ($children as $child) {
  50. $childData = $this->getNewData($child);
  51. \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']);
  52. if ($childData) {
  53. $this->insert($childData);
  54. if ($mode == Scanner::SCAN_RECURSIVE) {
  55. $this->upgradeChilds($child['id']);
  56. }
  57. }
  58. }
  59. }
  60. /**
  61. * insert data into the new cache
  62. *
  63. * @param array $data the data for the new cache
  64. */
  65. function insert($data) {
  66. static $insertQuery = null;
  67. if(is_null($insertQuery)) {
  68. $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`
  69. ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` )
  70. VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
  71. }
  72. if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) {
  73. \OC_DB::executeAudited($insertQuery, array($data['id'], $data['storage'],
  74. $data['path'], $data['path_hash'], $data['parent'], $data['name'],
  75. $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'], $data['etag']));
  76. }
  77. }
  78. /**
  79. * check if an item is already in the new cache
  80. *
  81. * @param string $storage
  82. * @param string $pathHash
  83. * @param string $id
  84. * @return bool
  85. */
  86. function inCache($storage, $pathHash, $id) {
  87. static $query = null;
  88. if(is_null($query)) {
  89. $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?');
  90. }
  91. $result = \OC_DB::executeAudited($query, array($storage, $pathHash, $id));
  92. return (bool)$result->fetchRow();
  93. }
  94. /**
  95. * get the new data array from the old one
  96. *
  97. * @param array $data the data from the old cache
  98. * Example data array
  99. * Array
  100. * (
  101. * [id] => 418
  102. * [path] => /tina/files/picture.jpg //relative to datadir
  103. * [path_hash] => 66d4547e372888deed80b24fec9b192b
  104. * [parent] => 234
  105. * [name] => picture.jpg
  106. * [user] => tina
  107. * [size] => 1265283
  108. * [ctime] => 1363909709
  109. * [mtime] => 1363909709
  110. * [mimetype] => image/jpeg
  111. * [mimepart] => image
  112. * [encrypted] => 0
  113. * [versioned] => 0
  114. * [writable] => 1
  115. * )
  116. *
  117. * @return array
  118. */
  119. function getNewData($data) {
  120. //Make sure there is a path, otherwise we can do nothing.
  121. if(!isset($data['path'])) {
  122. return false;
  123. }
  124. $newData = $data;
  125. /**
  126. * @var \OC\Files\Storage\Storage $storage
  127. * @var string $internalPath;
  128. */
  129. list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']);
  130. if ($storage) {
  131. $newData['etag'] = $data['etag'];
  132. $newData['path_hash'] = md5($internalPath);
  133. $newData['path'] = $internalPath;
  134. $newData['storage'] = $this->getNumericId($storage);
  135. $newData['parent'] = ($internalPath === '') ? -1 : $data['parent'];
  136. $newData['permissions'] = ($data['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ;
  137. $newData['storage_object'] = $storage;
  138. $newData['mimetype'] = $this->getMimetypeId($newData['mimetype'], $storage);
  139. $newData['mimepart'] = $this->getMimetypeId($newData['mimepart'], $storage);
  140. return $newData;
  141. } else {
  142. \OC_Log::write('core', 'Unable to migrate data from old cache for '.$data['path'].' because the storage was not found', \OC_Log::ERROR);
  143. return false;
  144. }
  145. }
  146. /**
  147. * get the numeric storage id
  148. *
  149. * @param \OC\Files\Storage\Storage $storage
  150. * @return int
  151. */
  152. function getNumericId($storage) {
  153. $storageId = $storage->getId();
  154. if (!isset($this->numericIds[$storageId])) {
  155. $cache = $storage->getCache();
  156. $this->numericIds[$storageId] = $cache->getNumericStorageId();
  157. }
  158. return $this->numericIds[$storageId];
  159. }
  160. /**
  161. * get the numeric id for a mimetype
  162. *
  163. * @param string $mimetype
  164. * @param \OC\Files\Storage\Storage $storage
  165. * @return int
  166. */
  167. function getMimetypeId($mimetype, $storage) {
  168. if (!isset($this->mimeTypeIds[$mimetype])) {
  169. $cache = new Cache($storage);
  170. $this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype);
  171. }
  172. return $this->mimeTypeIds[$mimetype];
  173. }
  174. /**
  175. * check if a cache upgrade is required for $user
  176. *
  177. * @param string $user
  178. * @return bool
  179. */
  180. static function needUpgrade($user) {
  181. $cacheVersion = (int)\OCP\Config::getUserValue($user, 'files', 'cache_version', 4);
  182. return $cacheVersion < 5;
  183. }
  184. /**
  185. * mark the filecache as upgrade
  186. *
  187. * @param string $user
  188. */
  189. static function upgradeDone($user) {
  190. \OCP\Config::setUserValue($user, 'files', 'cache_version', 5);
  191. }
  192. /**
  193. * Does a "silent" upgrade, i.e. without an Event-Source as triggered
  194. * on User-Login via Ajax. This method is called within the regular
  195. * ownCloud upgrade.
  196. *
  197. * @param string $user a User ID
  198. */
  199. public static function doSilentUpgrade($user) {
  200. if(!self::needUpgrade($user)) {
  201. return;
  202. }
  203. $legacy = new \OC\Files\Cache\Legacy($user);
  204. if ($legacy->hasItems()) {
  205. \OC_DB::beginTransaction();
  206. $upgrade = new \OC\Files\Cache\Upgrade($legacy);
  207. $upgrade->upgradePath('/' . $user . '/files');
  208. \OC_DB::commit();
  209. }
  210. \OC\Files\Cache\Upgrade::upgradeDone($user);
  211. }
  212. }