Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 69 additions & 9 deletions apps/files_sharing/lib/cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/

namespace OC\Files\Cache;
use OCP\Share_Backend_Collection;

/**
* Metadata cache for shared files
Expand Down Expand Up @@ -226,7 +227,36 @@ public function getStatus($file) {
* @return array of file data
*/
public function search($pattern) {
// TODO

// normalize pattern
$pattern = $this->normalize($pattern);

$ids = $this->getAll();

$files = array();

// divide into 1k chunks
$chunks = array_chunk($ids, 1000);

foreach ($chunks as $chunk) {
$placeholders = join(',', array_fill(0, count($chunk), '?'));

$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
`encrypted`, `unencrypted_size`, `etag`
FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `fileid` IN (' . $placeholders . ')';

$result = \OC_DB::executeAudited($sql, array_merge(array($pattern), $chunk));

while ($row = $result->fetchRow()) {
if (substr($row['path'], 0, 6)==='files/') {
$row['path'] = substr($row['path'],6); // remove 'files/' from path as it's relative to '/Shared'
}
$row['mimetype'] = $this->getMimetype($row['mimetype']);
$row['mimepart'] = $this->getMimetype($row['mimepart']);
$files[] = $row;
}
}
return $files;
}

/**
Expand All @@ -244,13 +274,30 @@ public function searchByMime($mimetype) {
}
$mimetype = $this->getMimetypeId($mimetype);
$ids = $this->getAll();
$placeholders = join(',', array_fill(0, count($ids), '?'));
$query = \OC_DB::prepare('
SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN (' . $placeholders . ')'
);
$result = $query->execute(array_merge(array($mimetype), $ids));
return $result->fetchAll();

$files = array();

// divide into 1k chunks
$chunks = array_chunk($ids, 1000);

foreach ($chunks as $chunk) {
$placeholders = join(',', array_fill(0, count($ids), '?'));
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
`encrypted`, `unencrypted_size`, `etag`
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN (' . $placeholders . ')';

$result = \OC_DB::executeAudited($sql, array_merge(array($mimetype), $chunk));

while ($row = $result->fetchRow()) {
if (substr($row['path'], 0, 6)==='files/') {
$row['path'] = substr($row['path'],6); // remove 'files/' from path as it's relative to '/Shared'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's wrong. I'll just fix these methods in #4382.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the status of this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@icewind1991 To me it seems correct for #4516

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it seems to only work from search results that originates from the main store of the user, I think any result originating from an external storage will still have an incorrect path

For a proper fix, the mountpoint of for the storage which holds the search result should be compared with the user home folder

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict files and files_external use / as the root for their mountpoints. only the files_sharing cache returns results prefixed with 'Shared'. feel free to give a code example or highjack this PR. what would a test for this look like?

}
$row['mimetype'] = $this->getMimetype($row['mimetype']);
$row['mimepart'] = $this->getMimetype($row['mimepart']);
$files[] = $row;
}
}
return $files;
}

/**
Expand All @@ -272,7 +319,20 @@ public function calculateFolderSize($path) {
* @return int[]
*/
public function getAll() {
return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL);
$ids = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL);
$folderBackend = \OCP\Share::getBackend('folder');
if ($folderBackend instanceof Share_Backend_Collection) {
foreach ($ids as $file) {
/** @var $folderBackend Share_Backend_Collection */
$children = $folderBackend->getChildren($file);
foreach ($children as $child) {
$ids[] = (int)$child['source'];
}

}
}

return $ids;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions lib/public/share.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,10 @@ public static function setExpirationDate($itemType, $itemSource, $date) {

/**
* @brief Get the backend class for the specified item type
* @param string Item type
* @return Sharing backend object
* @param string $itemType
* @return Share_Backend
*/
private static function getBackend($itemType) {
public static function getBackend($itemType) {
if (isset(self::$backends[$itemType])) {
return self::$backends[$itemType];
} else if (isset(self::$backendTypes[$itemType]['class'])) {
Expand Down