summaryrefslogtreecommitdiffstats
path: root/apps/dav/lib
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2020-06-04 10:05:28 +0200
committerJoas Schilling <coding@schilljs.com>2020-06-10 09:38:59 +0200
commitfdd8c86c60bcfcaa5e4018e3c637be5273967d17 (patch)
tree96091e3b88683455a44bd33d00a2e7d305eb4655 /apps/dav/lib
parent9806dec9b3f985ce8a05c9852064e38fa7b199a5 (diff)
downloadnextcloud-server-fdd8c86c60bcfcaa5e4018e3c637be5273967d17.tar.gz
nextcloud-server-fdd8c86c60bcfcaa5e4018e3c637be5273967d17.zip
Fix pagination of contacts search
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'apps/dav/lib')
-rw-r--r--apps/dav/lib/CardDAV/CardDavBackend.php44
1 files changed, 27 insertions, 17 deletions
diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php
index a5d50762922..40b48f69ae0 100644
--- a/apps/dav/lib/CardDAV/CardDavBackend.php
+++ b/apps/dav/lib/CardDAV/CardDavBackend.php
@@ -944,39 +944,49 @@ class CardDavBackend implements BackendInterface, SyncSupport {
* @param array $searchProperties defines the properties within the query pattern should match
* @param array $options = array() to define the search behavior
* - 'escape_like_param' - If set to false wildcards _ and % are not escaped, otherwise they are
+ * - 'limit' - Set a numeric limit for the search results
+ * - 'offset' - Set the offset for the limited search results
* @return array an array of contacts which are arrays of key-value-pairs
*/
public function search($addressBookId, $pattern, $searchProperties, $options = []) {
- $query = $this->db->getQueryBuilder();
$query2 = $this->db->getQueryBuilder();
- $query2->selectDistinct('cp.cardid')->from($this->dbCardsPropertiesTable, 'cp');
- $query2->andWhere($query2->expr()->eq('cp.addressbookid', $query->createNamedParameter($addressBookId)));
+ $query2->selectDistinct('cp.cardid')
+ ->from($this->dbCardsPropertiesTable, 'cp')
+ ->andWhere($query2->expr()->eq('cp.addressbookid', $query2->createNamedParameter($addressBookId)));
$or = $query2->expr()->orX();
foreach ($searchProperties as $property) {
- $or->add($query2->expr()->eq('cp.name', $query->createNamedParameter($property)));
+ $or->add($query2->expr()->eq('cp.name', $query2->createNamedParameter($property)));
}
$query2->andWhere($or);
// No need for like when the pattern is empty
if ('' !== $pattern) {
if (\array_key_exists('escape_like_param', $options) && $options['escape_like_param'] === false) {
- $query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter($pattern)));
+ $query2->andWhere($query2->expr()->ilike('cp.value', $query2->createNamedParameter($pattern)));
} else {
- $query2->andWhere($query2->expr()->ilike('cp.value', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
+ $query2->andWhere($query2->expr()->ilike('cp.value', $query2->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%')));
}
}
-// // FIXME Broken on MySQL: SQLSTATE[42000]: Syntax error or access violation: 1235 This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
-// // FIXME Should use 2 queries instead
-// if (isset($options['limit'])) {
-// $query2->setMaxResults($options['limit']);
-// }
-// if (isset($options['offset'])) {
-// $query2->setFirstResult($options['offset']);
-// }
-
- $query->select('c.carddata', 'c.uri')->from($this->dbCardsTable, 'c')
- ->where($query->expr()->in('c.id', $query->createFunction($query2->getSQL())));
+
+ if (isset($options['limit'])) {
+ $query2->setMaxResults($options['limit']);
+ }
+ if (isset($options['offset'])) {
+ $query2->setFirstResult($options['offset']);
+ }
+
+ $result = $query2->execute();
+ $matches = $result->fetchAll();
+ $result->closeCursor();
+ $matches = array_map(function ($match) {
+ return (int) $match['cardid'];
+ }, $matches);
+
+ $query = $this->db->getQueryBuilder();
+ $query->select('c.carddata', 'c.uri')
+ ->from($this->dbCardsTable, 'c')
+ ->where($query->expr()->in('c.id', $query->createNamedParameter($matches, IQueryBuilder::PARAM_INT_ARRAY)));
$result = $query->execute();
$cards = $result->fetchAll();