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

akonadi

  • 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  "prefix nco:<http://www.semanticdesktop.org/ontologies/2007/03/22/nco#>"
53  "SELECT ?r WHERE { ?r a nco:Contact }"
54 #endif
55  ) );
56 }
57 
58 ContactSearchJob::~ContactSearchJob()
59 {
60  delete d;
61 }
62 
63 void ContactSearchJob::setQuery( Criterion criterion, const QString &value )
64 {
65  setQuery( criterion, value, ExactMatch );
66 }
67 
68 // helper method, returns the SPARQL sub-expression to be used for finding
69 // string either as a whole word, the start of a word, or anywhere in a word
70 static QString containsQueryString( bool doWholeWordSearch, bool matchWordBoundary )
71 {
72  if ( doWholeWordSearch )
73  return QString::fromLatin1( "?v bif:contains \"'%1'\" . " );
74  else
75  return QString::fromLatin1("FILTER regex(str(?v), \"%1\", \"i\")" )
76  .arg( matchWordBoundary? QLatin1String("\\\\b%1") : QLatin1String("%1") );
77 }
78 
79 void ContactSearchJob::setQuery( Criterion criterion, const QString &value, Match match )
80 {
81  if ( match == StartsWithMatch && value.size() < 4 )
82  match = ExactMatch;
83 
84  const bool doWholeWordSearch = value.size() < 3;
85  const bool matchWordBoundary = match == ContainsWordBoundaryMatch;
86 
87  QString query;
88 
89 #ifndef AKONADI_USE_STRIGI_SEARCH
90  query = QString::fromLatin1( "prefix nco:<http://www.semanticdesktop.org/ontologies/2007/03/22/nco#>" );
91 #endif
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 a nco:Contact . "
117  " ?r nco:fullname \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. "
118  " "
119  "} "
120 #endif
121  );
122  } else if ( criterion == Email ) {
123  query += QString::fromLatin1(
124 #ifdef AKONADI_USE_STRIGI_SEARCH
125  "<request>"
126  " <query>"
127  " <and>"
128  " <equals>"
129  " <field name=\"type\"/>"
130  " <string>PersonContact</string>"
131  " </equals>"
132  " <equals>"
133  " <field name=\"emailAddress\"/>"
134  " <string>%1</string>"
135  " </equals>"
136  " </and>"
137  " </query>"
138  "</request>"
139 #else
140  "SELECT DISTINCT ?person ?reqProp1 "
141  "WHERE { "
142  " "
143  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
144  " ?person a nco:Contact ; "
145  " nco:hasEmailAddress ?email . "
146  " ?email nco:emailAddress \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> . "
147  " "
148  "}"
149 #endif
150  );
151  } else if ( criterion == NickName ) {
152  query += QString::fromLatin1(
153 #ifdef AKONADI_USE_STRIGI_SEARCH
154  "<request>"
155  " <query>"
156  " <and>"
157  " <equals>"
158  " <field name=\"type\"/>"
159  " <string>PersonContact</string>"
160  " </equals>"
161  " <equals>"
162  " <field name=\"nickname\"/>"
163  " <string>%1</string>"
164  " </equals>"
165  " </and>"
166  " </query>"
167  "</request>"
168 #else
169  "SELECT DISTINCT ?r ?reqProp1 "
170  "WHERE { "
171  " "
172  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
173  " ?r a nco:Contact . "
174  " ?r nco:nickname \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> ."
175  " "
176  "}"
177 #endif
178  );
179  } else if ( criterion == NameOrEmail ) {
180  query += QString::fromLatin1(
181 #ifdef AKONADI_USE_STRIGI_SEARCH
182  "<request>"
183  " <query>"
184  " <and>"
185  " <equals>"
186  " <field name=\"type\"/>"
187  " <string>PersonContact</string>"
188  " </equals>"
189  " <or>"
190  " <equals>"
191  " <field name=\"fullname\"/>"
192  " <string>%1</string>"
193  " </equals>"
194  " <equals>"
195  " <field name=\"nameGiven\"/>"
196  " <string>%1</string>"
197  " </equals>"
198  " <equals>"
199  " <field name=\"nameFamily\"/>"
200  " <string>%1</string>"
201  " </equals>"
202  " <equals>"
203  " <field name=\"emailAddress\"/>"
204  " <string>%1</string>"
205  " </equals>"
206  " </or>"
207  " </and>"
208  " </query>"
209  "</request>"
210 #else
211  "SELECT DISTINCT ?r ?reqProp1 "
212  "WHERE { "
213  " "
214  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
215  " ?r a nco:Contact . "
216  " { ?r nco:fullname \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. } "
217  " UNION "
218  " { ?r nco:nameGiven \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. } "
219  " UNION "
220  " { ?r nco:nameFamily \"%1\"^^<http://www.w3.org/2001/XMLSchema#string>. } "
221  " UNION "
222  " { ?r nco:hasEmailAddress ?email . "
223  " ?email nco:emailAddress \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> . } "
224  " "
225  "}"
226 #endif
227  );
228  } else if ( criterion == ContactUid ) {
229  query += QString::fromLatin1(
230 #ifdef AKONADI_USE_STRIGI_SEARCH
231  "<request>"
232  " <query>"
233  " <and>"
234  " <equals>"
235  " <field name=\"type\"/>"
236  " <string>PersonContact</string>"
237  " </equals>"
238  " <equals>"
239  " <field name=\"contactUID\"/>"
240  " <string>%1</string>"
241  " </equals>"
242  " </and>"
243  " </query>"
244  "</request>"
245 #else
246  "SELECT DISTINCT ?r ?reqProp1 "
247  "WHERE { "
248  " "
249  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
250  " ?r a nco:Contact . "
251  " ?r nco:contactUID \"%1\"^^<http://www.w3.org/2001/XMLSchema#string> ."
252  " "
253  "}"
254 #endif
255  );
256  }
257  } else if ( match == StartsWithMatch ) {
258  if ( criterion == Name ) {
259  query += QString::fromLatin1(
260 #ifdef AKONADI_USE_STRIGI_SEARCH
261  "<request>"
262  " <query>"
263  " <and>"
264  " <equals>"
265  " <field name=\"type\"/>"
266  " <string>PersonContact</string>"
267  " </equals>"
268  " <startsWith>"
269  " <field name=\"fullname\"/>"
270  " <string>%1</string>"
271  " </startsWith>"
272  " </and>"
273  " </query>"
274  "</request>"
275 #else
276  "SELECT DISTINCT ?r ?reqProp1 "
277  "WHERE { "
278  " "
279  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
280  " ?r a nco:Contact . "
281  " ?r nco:fullname ?v . "
282  " ?v bif:contains \"'%1*'\" . "
283  " "
284  "} "
285 #endif
286  );
287  } else if ( criterion == Email ) {
288  query += QString::fromLatin1(
289 #ifdef AKONADI_USE_STRIGI_SEARCH
290  "<request>"
291  " <query>"
292  " <and>"
293  " <equals>"
294  " <field name=\"type\"/>"
295  " <string>PersonContact</string>"
296  " </equals>"
297  " <startsWith>"
298  " <field name=\"emailAddress\"/>"
299  " <string>%1</string>"
300  " </startsWith>"
301  " </and>"
302  " </query>"
303  "</request>"
304 #else
305  "SELECT DISTINCT ?person ?reqProp1 "
306  "WHERE { "
307  " "
308  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
309  " ?person a nco:Contact ; "
310  " nco:hasEmailAddress ?email . "
311  " ?email nco:emailAddress ?v . "
312  " FILTER regex(str(?v), \"^%1\", \"i\") "
313  " "
314  "}"
315 #endif
316  );
317  } else if ( criterion == NickName ) {
318  query += QString::fromLatin1(
319 #ifdef AKONADI_USE_STRIGI_SEARCH
320  "<request>"
321  " <query>"
322  " <and>"
323  " <equals>"
324  " <field name=\"type\"/>"
325  " <string>PersonContact</string>"
326  " </equals>"
327  " <startsWith>"
328  " <field name=\"nickname\"/>"
329  " <string>%1</string>"
330  " </startsWith>"
331  " </and>"
332  " </query>"
333  "</request>"
334 #else
335  "SELECT DISTINCT ?r ?reqProp1 "
336  "WHERE { "
337  " "
338  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
339  " ?r a nco:Contact . "
340  " ?r nco:nickname ?v . "
341  " FILTER regex(str(?v), \"^%1\", \"i\") "
342  " "
343  "}"
344 #endif
345  );
346  } else if ( criterion == NameOrEmail ) {
347  query += QString::fromLatin1(
348 #ifdef AKONADI_USE_STRIGI_SEARCH
349  "<request>"
350  " <query>"
351  " <and>"
352  " <equals>"
353  " <field name=\"type\"/>"
354  " <string>PersonContact</string>"
355  " </equals>"
356  " <or>"
357  " <startsWith>"
358  " <field name=\"fullname\"/>"
359  " <string>%1</string>"
360  " </startsWith>"
361  " <startsWith>"
362  " <field name=\"nameGiven\"/>"
363  " <string>%1</string>"
364  " </startsWith>"
365  " <startsWith>"
366  " <field name=\"nameFamily\"/>"
367  " <string>%1</string>"
368  " </startsWith>"
369  " <startsWith>"
370  " <field name=\"emailAddress\"/>"
371  " <string>%1</string>"
372  " </startsWith>"
373  " </or>"
374  " </and>"
375  " </query>"
376  "</request>"
377 #else
378  "SELECT DISTINCT ?r ?reqProp1 "
379  "WHERE { "
380  " "
381  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
382  " ?r a nco:Contact . "
383  " { ?r nco:fullname ?v . "
384  " FILTER regex(str(?v), \"^%1\", \"i\") } "
385  " UNION "
386  " { ?r nco:nameGiven ?v . "
387  " FILTER regex(str(?v), \"^%1\", \"i\") } "
388  " UNION "
389  " { ?r nco:nameFamily ?v . "
390  " FILTER regex(str(?v), \"^%1\", \"i\") } "
391  " UNION "
392  " { ?r nco:hasEmailAddress ?email . "
393  " ?email nco:emailAddress ?v . "
394  " FILTER regex(str(?v), \"^%1\", \"i\") } "
395  " "
396  "}"
397 #endif
398  );
399  } else if ( criterion == ContactUid ) {
400  query += QString::fromLatin1(
401 #ifdef AKONADI_USE_STRIGI_SEARCH
402  "<request>"
403  " <query>"
404  " <and>"
405  " <equals>"
406  " <field name=\"type\"/>"
407  " <string>PersonContact</string>"
408  " </equals>"
409  " <startsWith>"
410  " <field name=\"contactUID\"/>"
411  " <string>%1</string>"
412  " </startsWith>"
413  " </and>"
414  " </query>"
415  "</request>"
416 #else
417  "SELECT DISTINCT ?r ?reqProp1 "
418  "WHERE { "
419  " "
420  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
421  " ?r a nco:Contact . "
422  " ?r nco:contactUID ?v . "
423  " ?v bif:contains \"'%1*'\" . "
424  " "
425  "}"
426 #endif
427  );
428  }
429  } else if ( match == ContainsMatch || match == ContainsWordBoundaryMatch ) {
430  if ( criterion == Name ) {
431  query += QString::fromLatin1(
432 #ifdef AKONADI_USE_STRIGI_SEARCH
433  "<request>"
434  " <query>"
435  " <and>"
436  " <equals>"
437  " <field name=\"type\"/>"
438  " <string>PersonContact</string>"
439  " </equals>"
440  " <contains>"
441  " <field name=\"fullname\"/>"
442  " <string>%1</string>"
443  " </contains>"
444  " </and>"
445  " </query>"
446  "</request>"
447 #else
448  "SELECT DISTINCT ?r ?reqProp1 "
449  "WHERE { "
450  " "
451  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
452  " ?r a nco:Contact . "
453  " ?r nco:fullname ?v . "
454  "%1"
455  " "
456  "} "
457 #endif
458  );
459  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
460  } else if ( criterion == Email ) {
461  query += QString::fromLatin1(
462 #ifdef AKONADI_USE_STRIGI_SEARCH
463  "<request>"
464  " <query>"
465  " <and>"
466  " <equals>"
467  " <field name=\"type\"/>"
468  " <string>PersonContact</string>"
469  " </equals>"
470  " <contains>"
471  " <field name=\"emailAddress\"/>"
472  " <string>%1</string>"
473  " </contains>"
474  " </and>"
475  " </query>"
476  "</request>"
477 #else
478  "SELECT DISTINCT ?person ?reqProp1 "
479  "WHERE { "
480  " "
481  " ?person <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
482  " ?person a nco:Contact ; "
483  " nco:hasEmailAddress ?email . "
484  " ?email nco:emailAddress ?v . "
485  "%1"
486  " "
487  "}"
488 #endif
489  );
490  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
491  } else if ( criterion == NickName ) {
492  query += QString::fromLatin1(
493 #ifdef AKONADI_USE_STRIGI_SEARCH
494  "<request>"
495  " <query>"
496  " <and>"
497  " <equals>"
498  " <field name=\"type\"/>"
499  " <string>PersonContact</string>"
500  " </equals>"
501  " <contains>"
502  " <field name=\"nickname\"/>"
503  " <string>%1</string>"
504  " </contains>"
505  " </and>"
506  " </query>"
507  "</request>"
508 #else
509  "SELECT DISTINCT ?r ?reqProp1 "
510  "WHERE { "
511  " "
512  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
513  " ?r a nco:Contact . "
514  " ?r nco:nickname ?v . "
515  "%1"
516  " "
517  "}"
518 #endif
519  );
520  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
521  } else if ( criterion == NameOrEmail ) {
522  query += QString::fromLatin1(
523 #ifdef AKONADI_USE_STRIGI_SEARCH
524  "<request>"
525  " <query>"
526  " <and>"
527  " <equals>"
528  " <field name=\"type\"/>"
529  " <string>PersonContact</string>"
530  " </equals>"
531  " <or>"
532  " <contains>"
533  " <field name=\"fullname\"/>"
534  " <string>%1</string>"
535  " </contains>"
536  " <contains>"
537  " <field name=\"nameGiven\"/>"
538  " <string>%1</string>"
539  " </contains>"
540  " <contains>"
541  " <field name=\"nameFamily\"/>"
542  " <string>%1</string>"
543  " </contains>"
544  " <contains>"
545  " <field name=\"emailAddress\"/>"
546  " <string>%1</string>"
547  " </contains>"
548  " </or>"
549  " </and>"
550  " </query>"
551  "</request>"
552 #else
553  "SELECT DISTINCT ?r ?reqProp1 "
554  "WHERE { "
555  " "
556  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
557  " ?r a nco:Contact . "
558  " { ?r nco:fullname ?v . "
559  "%1 }"
560  " UNION "
561  " { ?r nco:nameGiven ?v . "
562  "%1 }"
563  " UNION "
564  " { ?r nco:nameFamily ?v . "
565  "%1 }"
566  " UNION "
567  " { ?r nco:hasEmailAddress ?email . "
568  " ?email nco:emailAddress ?v . "
569  "%1 }"
570  " "
571  "}"
572 #endif
573  );
574  query = query.arg( containsQueryString( doWholeWordSearch, matchWordBoundary ) );
575  } else if ( criterion == ContactUid ) {
576  query += QString::fromLatin1(
577 #ifdef AKONADI_USE_STRIGI_SEARCH
578  "<request>"
579  " <query>"
580  " <and>"
581  " <equals>"
582  " <field name=\"type\"/>"
583  " <string>Contact</string>"
584  " </equals>"
585  " <contains>"
586  " <field name=\"contactUID\"/>"
587  " <string>%1</string>"
588  " </contains>"
589  " </and>"
590  " </query>"
591  "</request>"
592 #else
593  "SELECT DISTINCT ?r ?reqProp1 "
594  "WHERE { "
595  " "
596  " ?r <" + akonadiItemIdUri().toEncoded() + "> ?reqProp1 . "
597  " ?r a nco:Contact . "
598  " ?r nco:contactUID ?v . "
599  " ?v bif:contains \"'%1'\" . "
600  " "
601  "}"
602 #endif
603  );
604  }
605  }
606 
607  if ( d->mLimit != -1 ) {
608 #ifndef AKONADI_USE_STRIGI_SEARCH
609  query += QString::fromLatin1( " LIMIT %1" ).arg( d->mLimit );
610 #endif
611  }
612  query = query.arg( value );
613 
614  ItemSearchJob::setQuery( query );
615 }
616 
617 void ContactSearchJob::setLimit( int limit )
618 {
619  d->mLimit = limit;
620 }
621 
622 KABC::Addressee::List ContactSearchJob::contacts() const
623 {
624  KABC::Addressee::List contacts;
625 
626  foreach ( const Item &item, items() ) {
627  if ( item.hasPayload<KABC::Addressee>() )
628  contacts.append( item.payload<KABC::Addressee>() );
629  }
630 
631  return contacts;
632 }
633 
634 #include "contactsearchjob.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Dec 10 2012 13:48:08 by doxygen 1.8.1.2 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-4.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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