-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce pagination in files-filter report #26507
Conversation
@DeepDiver1975, thanks for your PR! By analyzing the history of the files in this pull request, we identified @PVince81 and @nickvergessen to be potential reviewers. |
d67ffa0
to
980d966
Compare
for #13915 |
980d966
to
a108477
Compare
memcache ? 😦 |
$requestedProps[] = $propVal['name']; | ||
} | ||
$requestedProps = $report->properties; | ||
$filterRules = $report->filters; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really ? did the format change ?
use Sabre\Xml\Reader; | ||
use Sabre\Xml\XmlDeserializable; | ||
|
||
class FilterRequest implements XmlDeserializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oohhhh, clever
Code looks good so far |
throw new PreconditionFailed('Cannot filter by non-existing tag', 0, $e); | ||
if (!is_null($report->limit)) { | ||
$length = $report->limit['size']; | ||
$offset = $report->limit['page'] * $length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first page should be 1, not 0.
How about using limit and offset instead ? Might be easier to grasp...
Test report report.xml: <?xml version="1.0" encoding="utf-8" ?>
<oc:filter-files xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns" >
<a:prop>
<a:getetag/>
</a:prop>
<oc:limit page="0" size="10" />
</oc:filter-files> % curl -u admin:admin -X REPORT -H "Content-Type: text/xml" --data-binary "@report.xml" 'http://localhost/owncloud/remote.php/dav/files/admin/' |
Some concerns: the regular filter report returns a flat list of files from all folders. This flat list can be paginated in this report, this is fine. However we will also need a paginated call for folder-specific contents, without recursing. Should we make a separate report time for this maybe ? Or add a property |
a108477
to
f4aa5d2
Compare
@DeepDiver1975 I've rebased this. Also I discovered today that Sabre has a shorter way of compiling results from multiple nodes using There will still be a performance issue here because we need to resolve every node individually. Side note: if we ever implement Webdav sync it also uses |
|
Arghh, no, not good. I suspect that the old implementation also suffered from this. Since we have the files API node already, we should already be able to wrap it (it's a I'll revert my commit because it will degrade the performance. From what I see we already had created the matching Sabre File and Directory in More about this in a minute after the revert... |
So, I've reverted the commit instead of deleting it, in case we still want it. (Squashing will kill it later). Now looking at However if we want REPORT to be used for pagination on simple folders, then we need a different approach there. Usually calling So to solve the above question we really need to discuss "recursive / flattened / arbitrary results" vs "only show results from the current folder". One idea would be to provide one generic REPORT type that only does a PROPFIND on the files endpoints (or even any part of the tree!) and paginates whatever the PROPFIND / Then we provide another REPORT, which is the one from this PR, to really do search-like queries. In such queries the results are not limited to the current folder, so we have to use Or a hybrid variant is to have a single REPORT type but with a @DeepDiver1975 thoughts ? |
I wrote down some ideas about implementing a generic pagination report that would work for every PROPFIND-enabled endpoint: #26840 |
Regarding recursive vs children, I think we could even call them differently:
|
So for "recursive" vs "flat" the answer from @DeepDiver1975 was using the "Depth" header. |
1d87fb6
to
c355695
Compare
Rebased. Also I found a way to simplify the response code to use a more Sabr-y way to do it: c355695 All discovered while working on the customgroups REPORT: owncloud/customgroups#27. Note: in the customgroups pagination I used a different format for the search pattern + pagination: <?xml version="1.0" encoding="utf-8" ?>
<oc:search-query xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns">
<a:prop>
<oc:role></oc:role>
<oc:display-name></oc:display-name>
</a:prop>
<oc:search>
<oc:pattern>us</oc:pattern>
<oc:limit>5</oc:limit>
<oc:offset>0</oc:offset>
</oc:search>
</oc:search-query> |
How about we finish this without the cache ? It will be crude but at least it will make it possible for clients to at least request the first page with limit. |
This will also properly return 404 properties
c355695
to
a7ed90f
Compare
Rebased and pushed some changes:
Next up: integration tests for pagination when filtering. |
|
Fixed integration tests and also added a new integration test for pagination. @DeepDiver1975 @jvillafanez please review |
$requestedProps = $report->properties; | ||
$filterRules = $report->filters; | ||
|
||
if (empty($filterRules['systemtag']) && is_null($filterRules['favorite'])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should refine the condition... empty
is always scary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure... "systemtag" here is an array so empty fits but "favorite" is only a single string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if "systemtag" will be always an array no matter what, then it's fine. Something similar for "favorite" (wondering if ''
or '0' would behave as we expect).
Anyway a comment would be useful to clarify any doubt, mainly to say that this is on purpose.
} | ||
// TODO: if depth one, could use a different search algo based on getChildren() ... | ||
// TODO: Depth header filtering? | ||
$results = $folder->search($report->search['pattern']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove dead code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boohoo, ok I'll move it to another WIP PR
} | ||
} | ||
|
||
$obj = new self(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to use self
instead of explicitly calling the current class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Written by @DeepDiver1975 and likely copied from other Sabre deserializer classes where self
was used. More convenient than rewriting the current class name I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was copied from Sabre, i guess it's fine. Don't like it, but ok.
' . $filterRules . ' | ||
</oc:filter-rules> | ||
</oc:filter-files>'; | ||
<oc:filter-files xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns" > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to find a better way to generate this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I'll let @owncloud/qa go wild to improve this separately.
return new File($this->fileView, $filesNode); | ||
} else if ($filesNode instanceof \OCP\Files\Folder) { | ||
return new Directory($this->fileView, $filesNode); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should log something here unless this null
is properly detected and reported. I wouldn't like to miss this case if something goes horribly wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll throw a "WTF this can't be" style exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance that this exception is catched in the middle and doesn't show up? just making sure this will be visible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's wrapped in a SabreException later upstream:
<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
<s:exception>Exception</s:exception>
<s:message>Unrecognized Files API node returned, aborting</s:message>
</d:error>
I haven't checked deeply the FilesReportPlugin.php file, in case someone wants to recheck that file |
There aren't many changes there so I think it's ok. Basically the response stays the same except that the array we pass there is sliced. @jvillafanez adjusted, see last two commits |
Final review ? @jvillafanez @DeepDiver1975 |
#26507 (comment) and #26507 (comment) . Other than that 👍 |
- disable REPORT without filter Because we need to use Node::search($pattern) to find all matching nodes in all the subfolder recursively, but the result nodes contain incomplete information like owner. - remove unneeded trailing slash when buildling response href This got obsoleted when switching to generateMultiStatus() - add integration pagination test for favorites REPORT - throw exception for unknown node types in FilesReportPlugin
9a23cd4
to
fad6a05
Compare
Added comment, squashed my commits into a smaller set. Since there are no actual code changes -> instamerge |
Raised doc ticket with some instructions: https://github.com/owncloud/documentation/issues/2950 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Description
Allow pagination when listing files
ToDos
Motivation and Context
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: