• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • contact
contactsearchjob.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "contactsearchjob.h"
23 
24 #include <akonadi/itemfetchscope.h>
25 
26 using namespace Akonadi;
27 
28 class ContactSearchJob::Private
29 {
30  public:
31  int mLimit;
32 };
33 
34 ContactSearchJob::ContactSearchJob( QObject * parent )
35  : ItemSearchJob( QString(), parent ), d( new Private() )
36 {
37  fetchScope().fetchFullPayload();
38  d->mLimit = -1;
39 
40  // by default search for all contacts
41  ItemSearchJob::setQuery( QLatin1String( ""
42 #ifdef AKONADI_USE_STRIGI_SEARCH
43  "<request>"
44  " <query>"
45  " <equals>"
46  " <field name=\"type\"/>"
47  " <string>PersonContact</string>"
48  " </equals>"
49  " </query>"
50  "</request>"
51 #else
52  "SELECT ?r WHERE { ?r a nco:Contact }"
53 #endif
54  ) );
55 }
56 
57 ContactSearchJob::~ContactSearchJob()
58 {
59  delete d;
60 }
61 
62 void ContactSearchJob::setQuery( Criterion criterion, const QString &value )
63 {
64  setQuery( criterion, value, ExactMatch );
65 }
66 
67 // helper method, returns the SPARQL sub-expression to be used for finding
68 // string either as a whole word, the start of a word, or anywhere in a word
69 static QString containsQueryString( bool doWholeWordSearch, bool matchWordBoundary )
70 {
71  if ( doWholeWordSearch ) {
72  return QString::fromLatin1( "?v bif:contains \"'%1'\" . " );
73  } else {
74  if ( matchWordBoundary ) {
75  return QString::fromLatin1( "?v bif:contains \"'%1*'\" . " );
76  } else {
77  return QString::fromLatin1( "FILTER regex(str(?v), \"%1\", \"i\")" );
78  }
79  }
80 }
81 
82 void ContactSearchJob::setQuery( Criterion criterion, const QString &value, Match match )
83 {
84  if ( match == StartsWithMatch && value.size() < 4 ) {
85  match = ExactMatch;
86  }
87 
88  const bool doWholeWordSearch = value.size() < 3;
89  const bool matchWordBoundary = match == ContainsWordBoundaryMatch;
90 
91  QString query;
92 
93  if ( match == ExactMatch ) {
94  if ( criterion == Name ) {
95  query += QString::fromLatin1(
96 #ifdef AKONADI_USE_STRIGI_SEARCH
97  "<request>"
98  " <query>"
99  " <and>"
100  " <equals>"
101  " <field name=\"type\"/>"
102  " <string>PersonContact</string>"
103  " </equals>"
104  " <equals>"
105  " <field name=\"fullname\"/>"
106  " <string>%1</string>"
107  " </equals>"
108  " </and>"
109  " </query>"
110  "</request>"
111 #else
112  "SELECT DISTINCT ?r ?reqProp1 "
113  "WHERE { "
114  " "
115  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
116  " ?r nco:fullname \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. "
117  " "
118  "} "
119 #endif
120  );
121  } else if ( criterion == Email ) {
122  query += QString::fromLatin1(
123 #ifdef AKONADI_USE_STRIGI_SEARCH
124  "<request>"
125  " <query>"
126  " <and>"
127  " <equals>"
128  " <field name=\"type\"/>"
129  " <string>PersonContact</string>"
130  " </equals>"
131  " <equals>"
132  " <field name=\"emailAddress\"/>"
133  " <string>%1</string>"
134  " </equals>"
135  " </and>"
136  " </query>"
137  "</request>"
138 #else
139  "SELECT DISTINCT ?person ?reqProp1 "
140  "WHERE { "
141  " "
142  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
143  " ?person nco:hasEmailAddress ?email . "
144  " ?email nco:emailAddress \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> . "
145  " "
146  "}"
147 #endif
148  );
149  } else if ( criterion == NickName ) {
150  query += QString::fromLatin1(
151 #ifdef AKONADI_USE_STRIGI_SEARCH
152  "<request>"
153  " <query>"
154  " <and>"
155  " <equals>"
156  " <field name=\"type\"/>"
157  " <string>PersonContact</string>"
158  " </equals>"
159  " <equals>"
160  " <field name=\"nickname\"/>"
161  " <string>%1</string>"
162  " </equals>"
163  " </and>"
164  " </query>"
165  "</request>"
166 #else
167  "SELECT DISTINCT ?r ?reqProp1 "
168  "WHERE { "
169  " "
170  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
171  " ?r nco:nickname \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> ."
172  " "
173  "}"
174 #endif
175  );
176  } else if ( criterion == NameOrEmail ) {
177  query += QString::fromLatin1(
178 #ifdef AKONADI_USE_STRIGI_SEARCH
179  "<request>"
180  " <query>"
181  " <and>"
182  " <equals>"
183  " <field name=\"type\"/>"
184  " <string>PersonContact</string>"
185  " </equals>"
186  " <or>"
187  " <equals>"
188  " <field name=\"fullname\"/>"
189  " <string>%1</string>"
190  " </equals>"
191  " <equals>"
192  " <field name=\"nameGiven\"/>"
193  " <string>%1</string>"
194  " </equals>"
195  " <equals>"
196  " <field name=\"nameFamily\"/>"
197  " <string>%1</string>"
198  " </equals>"
199  " <equals>"
200  " <field name=\"emailAddress\"/>"
201  " <string>%1</string>"
202  " </equals>"
203  " </or>"
204  " </and>"
205  " </query>"
206  "</request>"
207 #else
208  "SELECT DISTINCT ?r ?reqProp1 "
209  "WHERE { "
210  " "
211  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
212  " { ?r ?p \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. "
213  " FILTER(?p in (nco:fullname, nco:nameGiven, nco:nameFamily, nco:nameAdditional)) . }"
214  " UNION "
215  " { ?r nco:hasEmailAddress ?email . "
216  " ?email nco:emailAddress \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> . } "
217  " "
218  "}"
219 #endif
220  );
221  } else if ( criterion == ContactUid ) {
222  query += QString::fromLatin1(
223 #ifdef AKONADI_USE_STRIGI_SEARCH
224  "<request>"
225  " <query>"
226  " <and>"
227  " <equals>"
228  " <field name=\"type\"/>"
229  " <string>PersonContact</string>"
230  " </equals>"
231  " <equals>"
232  " <field name=\"contactUID\"/>"
233  " <string>%1</string>"
234  " </equals>"
235  " </and>"
236  " </query>"
237  "</request>"
238 #else
239  "SELECT DISTINCT ?r ?reqProp1 "
240  "WHERE { "
241  " "
242  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
243  " ?r nco:contactUID \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> ."
244  " "
245  "}"
246 #endif
247  );
248  }
249  } else if ( match == StartsWithMatch ) {
250  if ( criterion == Name ) {
251  query += QString::fromLatin1(
252 #ifdef AKONADI_USE_STRIGI_SEARCH
253  "<request>"
254  " <query>"
255  " <and>"
256  " <equals>"
257  " <field name=\"type\"/>"
258  " <string>PersonContact</string>"
259  " </equals>"
260  " <startsWith>"
261  " <field name=\"fullname\"/>"
262  " <string>%1</string>"
263  " </startsWith>"
264  " </and>"
265  " </query>"
266  "</request>"
267 #else
268  "SELECT DISTINCT ?r ?reqProp1 "
269  "WHERE { "
270  " "
271  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
272  " ?r nco:fullname ?v . "
273  " ?v bif:contains \"'%1*'\" . "
274  " "
275  "} "
276 #endif
277  );
278  } else if ( criterion == Email ) {
279  query += QString::fromLatin1(
280 #ifdef AKONADI_USE_STRIGI_SEARCH
281  "<request>"
282  " <query>"
283  " <and>"
284  " <equals>"
285  " <field name=\"type\"/>"
286  " <string>PersonContact</string>"
287  " </equals>"
288  " <startsWith>"
289  " <field name=\"emailAddress\"/>"
290  " <string>%1</string>"
291  " </startsWith>"
292  " </and>"
293  " </query>"
294  "</request>"
295 #else
296  "SELECT DISTINCT ?person ?reqProp1 "
297  "WHERE { "
298  " "
299  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
300  " ?person nco:hasEmailAddress ?email . "
301  " ?email nco:emailAddress ?v . "
302  " ?v bif:contains \"'%1\'\" . "
303  " "
304  "}"
305 #endif
306  );
307  } else if ( criterion == NickName ) {
308  query += QString::fromLatin1(
309 #ifdef AKONADI_USE_STRIGI_SEARCH
310  "<request>"
311  " <query>"
312  " <and>"
313  " <equals>"
314  " <field name=\"type\"/>"
315  " <string>PersonContact</string>"
316  " </equals>"
317  " <startsWith>"
318  " <field name=\"nickname\"/>"
319  " <string>%1</string>"
320  " </startsWith>"
321  " </and>"
322  " </query>"
323  "</request>"
324 #else
325  "SELECT DISTINCT ?r ?reqProp1 "
326  "WHERE { "
327  " "
328  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
329  " ?r nco:nickname ?v . "
330  " ?v bif:contains \"'%1\'\" . "
331  " "
332  "}"
333 #endif
334  );
335  } else if ( criterion == NameOrEmail ) {
336  query += QString::fromLatin1(
337 #ifdef AKONADI_USE_STRIGI_SEARCH
338  "<request>"
339  " <query>"
340  " <and>"
341  " <equals>"
342  " <field name=\"type\"/>"
343  " <string>PersonContact</string>"
344  " </equals>"
345  " <or>"
346  " <startsWith>"
347  " <field name=\"fullname\"/>"
348  " <string>%1</string>"
349  " </startsWith>"
350  " <startsWith>"
351  " <field name=\"nameGiven\"/>"
352  " <string>%1</string>"
353  " </startsWith>"
354  " <startsWith>"
355  " <field name=\"nameFamily\"/>"
356  " <string>%1</string>"
357  " </startsWith>"
358  " <startsWith>"
359  " <field name=\"emailAddress\"/>"
360  " <string>%1</string>"
361  " </startsWith>"
362  " </or>"
363  " </and>"
364  " </query>"
365  "</request>"
366 #else
367  "SELECT DISTINCT ?r ?reqProp1 "
368  "WHERE { "
369  " "
370  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
371  " { ?r ?p ?v . "
372  " FILTER(?p in (nco:fullname, nco:nameGiven, nco:nameFamily, nco:nameAdditional)). "
373  " ?v bif:contains \"'%1'\" . }"
374  " UNION "
375  " { ?r nco:hasEmailAddress ?email . "
376  " ?email nco:emailAddress ?v . "
377  " ?v bif:contains \"'%1'\" . }"
378  " "
379  "}"
380 #endif
381  );
382  } else if ( criterion == ContactUid ) {
383  query += QString::fromLatin1(
384 #ifdef AKONADI_USE_STRIGI_SEARCH
385  "<request>"
386  " <query>"
387  " <and>"
388  " <equals>"
389  " <field name=\"type\"/>"
390  " <string>PersonContact</string>"
391  " </equals>"
392  " <startsWith>"
393  " <field name=\"contactUID\"/>"
394  " <string>%1</string>"
395  " </startsWith>"
396  " </and>"
397  " </query>"
398  "</request>"
399 #else
400  "SELECT DISTINCT ?r ?reqProp1 "
401  "WHERE { "
402  " "
403  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
404  " ?r nco:contactUID ?v . "
405  " ?v bif:contains \"'%1*'\" . "
406  " "
407  "}"
408 #endif
409  );
410  }
411  } else if ( match == ContainsMatch || match == ContainsWordBoundaryMatch ) {
412  if ( criterion == Name ) {
413  query += QString::fromLatin1(
414 #ifdef AKONADI_USE_STRIGI_SEARCH
415  "<request>"
416  " <query>"
417  " <and>"
418  " <equals>"
419  " <field name=\"type\"/>"
420  " <string>PersonContact</string>"
421  " </equals>"
422  " <contains>"
423  " <field name=\"fullname\"/>"
424  " <string>%1</string>"
425  " </contains>"
426  " </and>"
427  " </query>"
428  "</request>"
429 #else
430  "SELECT DISTINCT ?r ?reqProp1 "
431  "WHERE { "
432  " "
433  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
434  " ?r nco:fullname ?v . "
435  "%1"
436  " "
437  "} "
438 #endif
439  );
440  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
441  } else if ( criterion == Email ) {
442  query += QString::fromLatin1(
443 #ifdef AKONADI_USE_STRIGI_SEARCH
444  "<request>"
445  " <query>"
446  " <and>"
447  " <equals>"
448  " <field name=\"type\"/>"
449  " <string>PersonContact</string>"
450  " </equals>"
451  " <contains>"
452  " <field name=\"emailAddress\"/>"
453  " <string>%1</string>"
454  " </contains>"
455  " </and>"
456  " </query>"
457  "</request>"
458 #else
459  "SELECT DISTINCT ?person ?reqProp1 "
460  "WHERE { "
461  " "
462  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
463  " ?person nco:hasEmailAddress ?email . "
464  " ?email nco:emailAddress ?v . "
465  "%1"
466  " "
467  "}"
468 #endif
469  );
470  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
471  } else if ( criterion == NickName ) {
472  query += QString::fromLatin1(
473 #ifdef AKONADI_USE_STRIGI_SEARCH
474  "<request>"
475  " <query>"
476  " <and>"
477  " <equals>"
478  " <field name=\"type\"/>"
479  " <string>PersonContact</string>"
480  " </equals>"
481  " <contains>"
482  " <field name=\"nickname\"/>"
483  " <string>%1</string>"
484  " </contains>"
485  " </and>"
486  " </query>"
487  "</request>"
488 #else
489  "SELECT DISTINCT ?r ?reqProp1 "
490  "WHERE { "
491  " "
492  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
493  " ?r nco:nickname ?v . "
494  "%1"
495  " "
496  "}"
497 #endif
498  );
499  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
500  } else if ( criterion == NameOrEmail ) {
501  query += QString::fromLatin1(
502 #ifdef AKONADI_USE_STRIGI_SEARCH
503  "<request>"
504  " <query>"
505  " <and>"
506  " <equals>"
507  " <field name=\"type\"/>"
508  " <string>PersonContact</string>"
509  " </equals>"
510  " <or>"
511  " <contains>"
512  " <field name=\"fullname\"/>"
513  " <string>%1</string>"
514  " </contains>"
515  " <contains>"
516  " <field name=\"nameGiven\"/>"
517  " <string>%1</string>"
518  " </contains>"
519  " <contains>"
520  " <field name=\"nameFamily\"/>"
521  " <string>%1</string>"
522  " </contains>"
523  " <contains>"
524  " <field name=\"emailAddress\"/>"
525  " <string>%1</string>"
526  " </contains>"
527  " </or>"
528  " </and>"
529  " </query>"
530  "</request>"
531 #else
532  "SELECT DISTINCT ?r ?reqProp1 "
533  "WHERE { "
534  " "
535  " ?r<" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
536  " { ?r ?p ?v ."
537  " FILTER(?p in (nco:fullname, nco:nameGiven, nco:nameFamily, nco:nameAdditional) ) ."
538  "%1 } UNION"
539  " { ?r nco:hasEmailAddress ?email . "
540  " ?email nco:emailAddress ?v . "
541  "%1 }"
542  " "
543  "}"
544 #endif
545  );
546  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
547  } else if ( criterion == ContactUid ) {
548  query += QString::fromLatin1(
549 #ifdef AKONADI_USE_STRIGI_SEARCH
550  "<request>"
551  " <query>"
552  " <and>"
553  " <equals>"
554  " <field name=\"type\"/>"
555  " <string>Contact</string>"
556  " </equals>"
557  " <contains>"
558  " <field name=\"contactUID\"/>"
559  " <string>%1</string>"
560  " </contains>"
561  " </and>"
562  " </query>"
563  "</request>"
564 #else
565  "SELECT DISTINCT ?r ?reqProp1 "
566  "WHERE { "
567  " "
568  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
569  " ?r nco:contactUID ?v . "
570  " ?v bif:contains \"'%1'\" . "
571  " "
572  "}"
573 #endif
574  );
575  }
576  }
577 
578  if ( d->mLimit != -1 ) {
579 #ifndef AKONADI_USE_STRIGI_SEARCH
580  query += QString::fromLatin1( " LIMIT %1" ).arg( d->mLimit );
581 #endif
582  }
583  query = query.arg( value );
584 
585  ItemSearchJob::setQuery( query );
586 }
587 
588 void ContactSearchJob::setLimit( int limit )
589 {
590  d->mLimit = limit;
591 }
592 
593 KABC::Addressee::List ContactSearchJob::contacts() const
594 {
595  KABC::Addressee::List contacts;
596 
597  foreach ( const Item &item, items() ) {
598  if ( item.hasPayload<KABC::Addressee>() ) {
599  contacts.append( item.payload<KABC::Addressee>() );
600  }
601  }
602 
603  return contacts;
604 }
605 
Akonadi::ContactSearchJob::Match
Match
Describes the type of pattern matching that shall be used.
Definition: contactsearchjob.h:112
Akonadi::ContactSearchJob::ContainsMatch
The result must contain the pattern (case insensitive).
Definition: contactsearchjob.h:115
Akonadi::ItemSearchJob::items
Item::List items() const
Returns the items that matched the search query.
Definition: itemsearchjob.cpp:154
Akonadi::ContactSearchJob::setLimit
void setLimit(int limit)
Sets a limit on how many results will be returned by this search job.
Definition: contactsearchjob.cpp:588
Akonadi::ItemFetchScope::fetchFullPayload
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
Definition: itemfetchscope.cpp:68
Akonadi::ContactSearchJob::NickName
The nickname of the contact.
Definition: contactsearchjob.h:102
Akonadi::ContactSearchJob::NameOrEmail
The name or email address of the contact.
Definition: contactsearchjob.h:103
Akonadi::ContactSearchJob::ContactSearchJob
ContactSearchJob(QObject *parent=0)
Creates a new contact search job.
Definition: contactsearchjob.cpp:34
Akonadi::ContactSearchJob::StartsWithMatch
The result must start with the pattern (case insensitive).
Definition: contactsearchjob.h:114
Akonadi::ContactSearchJob::~ContactSearchJob
~ContactSearchJob()
Destroys the contact search job.
Definition: contactsearchjob.cpp:57
Akonadi::ItemSearchJob::fetchScope
ItemFetchScope & fetchScope()
Returns the item fetch scope.
Definition: itemsearchjob.cpp:109
Akonadi::ContactSearchJob::contacts
KABC::Addressee::List contacts() const
Returns the contacts that matched the search criteria.
Definition: contactsearchjob.cpp:593
Akonadi::ItemSearchJob::akonadiItemIdUri
static QUrl akonadiItemIdUri()
Returns an URI that represents a predicate that is always added to the Nepomuk resource by the Akonad...
Definition: itemsearchjob.cpp:161
Akonadi::ContactSearchJob::Email
The email address of the contact.
Definition: contactsearchjob.h:101
Akonadi::ContactSearchJob::setQuery
void setQuery(Criterion criterion, const QString &value)
Sets the criterion and value for the search.
Definition: contactsearchjob.cpp:62
Akonadi::ItemSearchJob::setQuery
void setQuery(const QString &query)
Sets the search query in SPARQL format.
Definition: itemsearchjob.cpp:95
Akonadi::ContactSearchJob::ContactUid
The global unique identifier of the contact.
Definition: contactsearchjob.h:104
Akonadi::ItemSearchJob
Job that searches for items in the Akonadi storage.
Definition: itemsearchjob.h:70
Akonadi::ContactSearchJob::Criterion
Criterion
Describes the criteria that can be searched for.
Definition: contactsearchjob.h:99
Akonadi::ContactSearchJob::Name
The name of the contact.
Definition: contactsearchjob.h:100
Akonadi::ContactSearchJob::ContainsWordBoundaryMatch
The result must contain a word starting with the pattern (case insensitive).
Definition: contactsearchjob.h:116
Akonadi::ContactSearchJob::ExactMatch
The result must match exactly the pattern (case sensitive).
Definition: contactsearchjob.h:113
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal