{"action":"closed","issue":{"url":"https://api.github.com/repos/fruux/sabre-dav/issues/672","labels_url":"https://api.github.com/repos/fruux/sabre-dav/issues/672/labels{/name}","comments_url":"https://api.github.com/repos/fruux/sabre-dav/issues/672/comments","events_url":"https://api.github.com/repos/fruux/sabre-dav/issues/672/events","html_url":"https://github.com/fruux/sabre-dav/issues/672","id":84476964,"number":672,"title":"Support pagination and sorting","user":{"login":"kewisch","id":607198,"avatar_url":"https://avatars.githubusercontent.com/u/607198?v=3","gravatar_id":"","url":"https://api.github.com/users/kewisch","html_url":"https://github.com/kewisch","followers_url":"https://api.github.com/users/kewisch/followers","following_url":"https://api.github.com/users/kewisch/following{/other_user}","gists_url":"https://api.github.com/users/kewisch/gists{/gist_id}","starred_url":"https://api.github.com/users/kewisch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kewisch/subscriptions","organizations_url":"https://api.github.com/users/kewisch/orgs","repos_url":"https://api.github.com/users/kewisch/repos","events_url":"https://api.github.com/users/kewisch/events{/privacy}","received_events_url":"https://api.github.com/users/kewisch/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/fruux/sabre-dav/labels/question","name":"question","color":"e102d8"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-06-03T10:11:09Z","updated_at":"2015-07-02T21:19:17Z","closed_at":"2015-07-02T21:19:17Z","body":"We have a JSON plugin that allows retrieving events and contacts without the caldav queries. For scalability we'd like to paginate the results, at least for contacts. While I've managed to do this without modifying sabre-dav, I think it would be nice if it were possible to get members of a collection sorted and paginated.\r\n\r\nI'm proposing to add a new interface `\\Sabre\\DAV\\ISortableCollection` that a collection can optionally implement. It could look a bit like this:\r\n\r\n```php\r\ninterface ISortableCollection extends ICollection {\r\n\r\n    /**\r\n     * Returns an array with all the child nodes, allowing for pagination and sorting\r\n     *\r\n     * @param int $offset Number of entries to skip\r\n     * @param int $limit Maximum results, or 0 for unlimited\r\n     * @param string $sort Sort field, or null for unsorted\r\n     * @return DAV\\INode[]\r\n     */\r\n    function getChildren($offset = 0, $limit = 0, $sort = null);\r\n\r\n    /**\r\n     * Retrieves the number of items in the collection\r\n     *\r\n     * @return int\r\n     */\r\n    function getChildCount();\r\n}\r\n```\r\n\r\nOn the next level, `\\Sabre\\CardDAV\\AddressBook` and `\\Sabre\\CalDAV\\Calendar` implement this interface, having their `getChildren` methods extended with the parameters and passing them on to the backend.\r\n\r\nIn the backend, the `getCards` and `getCalendarObjects` methods would be extended with the same parameters and finally do the database lookup.\r\n\r\nWhat I am undecided on is how exactly the sort parameter would look like. For pagination it makes sense to sort the events in some way so the ordering is stable with different limit/offset parameters. What I have done now is to retrieve the FN from the contact and also save this in the database. I then passed the database field name as the `sort` parameter, which is obviously not ideal, and used this in the query.\r\n\r\nOn the other side, a flaw with this approach is that a contact may be missed when querying and another client adds or removes a contact in between. To solve this we would have to give each query an identifier and cache all calendar/contact paths on the first query until its done or encode this information in the next page link. In that case we could use `getMultipleChildren` and friends to retrieve the next batch of objects, but we would need a way to quickly get a list of all paths, or at least calendar ids. Bonus points for providing a builtin way to start such safe batched queries.\r\n\r\nI'd love to hear your input on this, and I'm happy to spin up a patch if you are interested. If you would like to see what I've done, check out the [patch for our project](https://ci.open-paas.org/stash/users/pkewisch/repos/esn-sabre/commits/2b7c9e22e545aa11c4439b12b322498f1a5d1079).\r\n\r\n"}}