summaryrefslogtreecommitdiff
authoreilers <eilers>2004-12-20 14:14:07 (UTC)
committer eilers <eilers>2004-12-20 14:14:07 (UTC)
commit18e47153532d016d878f47e0ce11cb1a9716218e (patch) (unidiff)
tree52eb6c25258fda0b2f295a29809c4603f5e17b0b
parent876e48baa20213d8265041cfac3034fe92cb0590 (diff)
downloadopie-18e47153532d016d878f47e0ce11cb1a9716218e.zip
opie-18e47153532d016d878f47e0ce11cb1a9716218e.tar.gz
opie-18e47153532d016d878f47e0ce11cb1a9716218e.tar.bz2
Recovery of the following Changes:
* Implement fast and full featured version of sorted() for addressbook * Implement generic queryByExample for all Addressboook backends. It allows incremental search. * Update of API Documentation
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/ChangeLog4
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend.cpp205
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend.h9
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp144
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h23
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp14
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_vcard.h4
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp205
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h9
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h40
-rw-r--r--libopie2/opiepim/core/ocontactaccess.h37
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h53
-rw-r--r--libopie2/opiepim/core/opimtemplatebase.h57
-rw-r--r--libopie2/opiepim/opiepim.pro2
14 files changed, 493 insertions, 313 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog
index 9c85e4b..dd57259 100644
--- a/libopie2/opiepim/ChangeLog
+++ b/libopie2/opiepim/ChangeLog
@@ -1,14 +1,18 @@
12004-11-23 Stefan Eilers <stefan@eilers-online.net>
2 * Implement fast and full featured version of sorted() for addressbook
3 * Implement generic queryByExample for all Addressboook backends. It allows incremental search.
4 * Update of API Documentation
12004-11-18 Holger Freyther <freyther@handhelds.org> 52004-11-18 Holger Freyther <freyther@handhelds.org>
2 * Every Access can give a set of Occurrences for a period or a datetime 6 * Every Access can give a set of Occurrences for a period or a datetime
3 * QueryByExample, Find, Sort can be generically accessed by OPimBase 7 * QueryByExample, Find, Sort can be generically accessed by OPimBase
4 pointer interface 8 pointer interface
5 * OPimBackendOccurrence gets split up to OPimOccurrences by 9 * OPimBackendOccurrence gets split up to OPimOccurrences by
6 OPimTemplateBase 10 OPimTemplateBase
7 * Add safeCast to various OPimRecords 11 * Add safeCast to various OPimRecords
8 * Kill memleak in OPimTodo 12 * Kill memleak in OPimTodo
9 * Add SortVector implementations for OPimTodo and OPimContact 13 * Add SortVector implementations for OPimTodo and OPimContact
10 14
11 2004-??-??The Opie Team <opie@handhelds.org> 15 2004-??-??The Opie Team <opie@handhelds.org>
12 * Implemented some important modifications to allow to use OPimRecords as it is, without 16 * Implemented some important modifications to allow to use OPimRecords as it is, without
13 have to cast them. This makes it possible to write applications which handling pim 17 have to cast them. This makes it possible to write applications which handling pim
14 data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file 18 data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.cpp b/libopie2/opiepim/backend/ocontactaccessbackend.cpp
index 6ef60eb..b4fdd46 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp
@@ -1,110 +1,303 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) 2004 Holger Freyther <freyther@handhelds.org> 3 Copyright (C) 2004 Holger Freyther <freyther@handhelds.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#include "ocontactaccessbackend.h" 30#include "ocontactaccessbackend.h"
31#include <opie2/private/opimcontactsortvector.h> 31#include <opie2/private/opimcontactsortvector.h>
32#include <opie2/ocontactaccess.h> 32#include <opie2/ocontactaccess.h>
33 33
34#include <opie2/odebug.h> 34#include <opie2/odebug.h>
35 35
36#include <qdatetime.h>
37
36namespace Opie { 38namespace Opie {
37OPimContactAccessBackend::OPimContactAccessBackend() {} 39OPimContactAccessBackend::OPimContactAccessBackend() {}
38 40
39UIDArray 41UIDArray OPimContactAccessBackend::queryByExample( const UIDArray& uid_array, const OPimContact& query, int settings,
40OPimContactAccessBackend::queryByExample( const OPimContact&, int, 42 const QDateTime& d )const {
41 const QDateTime& )const { 43 odebug << "Using Unaccelerated OPimContactAccessBackend implementation of queryByExample!" << oendl;
42 return UIDArray(); 44
45 UIDArray m_currentQuery( uid_array.count() );
46 uint arraycounter = 0;
47
48 for( uint it = 0; it < uid_array.count(); ++it ){
49 /* Search all fields and compare them with query object. Store them into list
50 * if all fields matches.
51 */
52 QDate* queryDate = 0l;
53 QDate* checkDate = 0l;
54 bool allcorrect = true;
55 for ( int i = 0; i < Qtopia::Groups; i++ ) {
56 // Birthday and anniversary are special nonstring fields and should
57 // be handled specially
58 switch ( i ){
59 case Qtopia::Birthday:
60 queryDate = new QDate( query.birthday() );
61 checkDate = new QDate( find( uid_array[it] ).birthday() );
62 // fall through
63 case Qtopia::Anniversary:
64 if ( queryDate == 0l ){
65 queryDate = new QDate( query.anniversary() );
66 checkDate = new QDate( find( uid_array[it] ).anniversary() );
67 }
68
69 if ( queryDate->isValid() ){
70 if( checkDate->isValid() ){
71 if ( settings & OPimContactAccess::DateYear ){
72 if ( queryDate->year() != checkDate->year() )
73 allcorrect = false;
74 }
75 if ( settings & OPimContactAccess::DateMonth ){
76 if ( queryDate->month() != checkDate->month() )
77 allcorrect = false;
78 }
79 if ( settings & OPimContactAccess::DateDay ){
80 if ( queryDate->day() != checkDate->day() )
81 allcorrect = false;
82 }
83 if ( settings & OPimContactAccess::DateDiff ) {
84 QDate current;
85 // If we get an additional date, we
86 // will take this date instead of
87 // the current one..
88 if ( !d.date().isValid() )
89 current = QDate::currentDate();
90 else
91 current = d.date();
92
93 // We have to equalize the year, otherwise
94 // the search will fail..
95 checkDate->setYMD( current.year(),
96 checkDate->month(),
97 checkDate->day() );
98 if ( *checkDate < current )
99 checkDate->setYMD( current.year()+1,
100 checkDate->month(),
101 checkDate->day() );
102
103 // Check whether the birthday/anniversary date is between
104 // the current/given date and the maximum date
105 // ( maximum time range ) !
106 if ( current.daysTo( *queryDate ) >= 0 ){
107 if ( !( ( *checkDate >= current ) &&
108 ( *checkDate <= *queryDate ) ) ){
109 allcorrect = false;
110 }
111 }
112 }
113 } else{
114 // checkDate is invalid. Therefore this entry is always rejected
115 allcorrect = false;
116 }
117 }
118
119 delete queryDate;
120 queryDate = 0l;
121 delete checkDate;
122 checkDate = 0l;
123 break;
124 default:
125 /* Just compare fields which are not empty in the query object */
126 if ( !query.field(i).isEmpty() ){
127 switch ( settings & ~( OPimContactAccess::IgnoreCase
128 | OPimContactAccess::DateDiff
129 | OPimContactAccess::DateYear
130 | OPimContactAccess::DateMonth
131 | OPimContactAccess::DateDay
132 | OPimContactAccess::MatchOne
133 ) ){
134
135 case OPimContactAccess::RegExp:{
136 QRegExp expr ( query.field(i),
137 !(settings & OPimContactAccess::IgnoreCase),
138 false );
139 if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 )
140 allcorrect = false;
141 }
142 break;
143 case OPimContactAccess::WildCards:{
144 QRegExp expr ( query.field(i),
145 !(settings & OPimContactAccess::IgnoreCase),
146 true );
147 if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 )
148 allcorrect = false;
149 }
150 break;
151 case OPimContactAccess::ExactMatch:{
152 if (settings & OPimContactAccess::IgnoreCase){
153 if ( query.field(i).upper() !=
154 find( uid_array[it] ).field(i).upper() )
155 allcorrect = false;
156 }else{
157 if ( query.field(i) != find( uid_array[it] ).field(i) )
158 allcorrect = false;
159 }
160 }
161 break;
162 }
163 }
164 }
165 }
166 if ( allcorrect ){
167 m_currentQuery[arraycounter++] = uid_array[it];
168 }
169 }
170
171 // Shrink to fit..
172 m_currentQuery.resize(arraycounter);
173
174 return m_currentQuery;
175
43} 176}
44 177
45UIDArray 178const uint OPimContactAccessBackend::querySettings() const
46OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, 179{
180 return ( OPimContactAccess::WildCards
181 | OPimContactAccess::IgnoreCase
182 | OPimContactAccess::RegExp
183 | OPimContactAccess::ExactMatch
184 | OPimContactAccess::DateDiff
185 | OPimContactAccess::DateYear
186 | OPimContactAccess::DateMonth
187 | OPimContactAccess::DateDay
188 );
189}
190
191bool OPimContactAccessBackend::hasQuerySettings (uint querySettings) const
192{
193 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
194 * may be added with any of the other settings. IgnoreCase should never used alone.
195 * Wildcards, RegExp, ExactMatch should never used at the same time...
196 */
197
198 // Step 1: Check whether the given settings are supported by this backend
199 if ( ( querySettings & (
200 OPimContactAccess::IgnoreCase
201 | OPimContactAccess::WildCards
202 | OPimContactAccess::DateDiff
203 | OPimContactAccess::DateYear
204 | OPimContactAccess::DateMonth
205 | OPimContactAccess::DateDay
206 | OPimContactAccess::RegExp
207 | OPimContactAccess::ExactMatch
208 ) ) != querySettings )
209 return false;
210
211 // Step 2: Check whether the given combinations are ok..
212
213 // IngoreCase alone is invalid
214 if ( querySettings == OPimContactAccess::IgnoreCase )
215 return false;
216
217 // WildCards, RegExp and ExactMatch should never used at the same time
218 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
219 | OPimContactAccess::DateDiff
220 | OPimContactAccess::DateYear
221 | OPimContactAccess::DateMonth
222 | OPimContactAccess::DateDay
223 )
224 ){
225 case OPimContactAccess::RegExp:
226 return ( true );
227 case OPimContactAccess::WildCards:
228 return ( true );
229 case OPimContactAccess::ExactMatch:
230 return ( true );
231 case 0: // one of the upper removed bits were set..
232 return ( true );
233 default:
234 return ( false );
235 }
236}
237
238
239UIDArray OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder,
47 int filter, const QArray<int>& categories)const { 240 int filter, const QArray<int>& categories)const {
48 odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl; 241 odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl;
49 242
50 Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder ); 243 Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder );
51 244
52 int item = 0; 245 int item = 0;
53 uint cat_count = categories.count(); 246 uint cat_count = categories.count();
54 uint eve_count = ar.count(); 247 uint eve_count = ar.count();
55 bool bCat = filter & OPimContactAccess::FilterCategory ? true : false; 248 bool bCat = filter & OPimContactAccess::FilterCategory ? true : false;
56 bool catPassed = false; 249 bool catPassed = false;
57 int cat; 250 int cat;
58 251
59 for ( uint i = 0; i < eve_count; ++i ) { 252 for ( uint i = 0; i < eve_count; ++i ) {
60 OPimContact contact = find( ar[i], ar, i, Frontend::Forward ); 253 OPimContact contact = find( ar[i], ar, i, Frontend::Forward );
61 if ( contact.isEmpty() ) 254 if ( contact.isEmpty() )
62 continue; 255 continue;
63 256
64 /* show category */ 257 /* show category */
65 /* -1 == unfiled */ 258 /* -1 == unfiled */
66 catPassed = false; 259 catPassed = false;
67 for ( uint cat_nu = 0; cat_nu < cat_count; ++cat_nu ) { 260 for ( uint cat_nu = 0; cat_nu < cat_count; ++cat_nu ) {
68 cat = categories[cat_nu]; 261 cat = categories[cat_nu];
69 if ( bCat && cat == -1 ) { 262 if ( bCat && cat == -1 ) {
70 if(!contact.categories().isEmpty() ) 263 if(!contact.categories().isEmpty() )
71 continue; 264 continue;
72 } else if ( bCat && cat != 0) 265 } else if ( bCat && cat != 0)
73 if (!contact.categories().contains( cat ) ) 266 if (!contact.categories().contains( cat ) )
74 continue; 267 continue;
75 catPassed = true; 268 catPassed = true;
76 break; 269 break;
77 } 270 }
78 271
79 /* 272 /*
80 * If none of the Categories matched 273 * If none of the Categories matched
81 * continue 274 * continue
82 */ 275 */
83 if ( !catPassed ) 276 if ( !catPassed )
84 continue; 277 continue;
85 278
86 vector.insert(item++, contact ); 279 vector.insert(item++, contact );
87 } 280 }
88 281
89 vector.resize( item ); 282 vector.resize( item );
90 /* sort it now */ 283 /* sort it now */
91 vector.sort(); 284 vector.sort();
92 /* now get the uids */ 285 /* now get the uids */
93 UIDArray array( vector.count() ); 286 UIDArray array( vector.count() );
94 for (uint i= 0; i < vector.count(); i++ ) 287 for (uint i= 0; i < vector.count(); i++ )
95 array[i] = vector.uidAt( i ); 288 array[i] = vector.uidAt( i );
96 289
97 return array; 290 return array;
98} 291}
99 292
100OPimBackendOccurrence::List OPimContactAccessBackend::occurrences( const QDate& start, 293OPimBackendOccurrence::List OPimContactAccessBackend::occurrences( const QDate& start,
101 const QDate& end)const { 294 const QDate& end)const {
102 OPimBackendOccurrence::List lst; 295 OPimBackendOccurrence::List lst;
103 296
104 UIDArray records = allRecords(); 297 UIDArray records = allRecords();
105 const uint count = records.count(); 298 const uint count = records.count();
106 int uid; 299 int uid;
107 300
108 for ( uint i = 0; i < count; ++i ) { 301 for ( uint i = 0; i < count; ++i ) {
109 uid = records[i]; 302 uid = records[i];
110 OPimContact contact = find(uid, records, i, Frontend::Forward ); 303 OPimContact contact = find(uid, records, i, Frontend::Forward );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h
index efb04c7..ee6dbc2 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend.h
@@ -19,90 +19,93 @@
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/** 29/**
30 * The class responsible for managing a backend. 30 * The class responsible for managing a backend.
31 * The implementation of this abstract class contains 31 * The implementation of this abstract class contains
32 * the complete database handling. 32 * the complete database handling.
33 * 33 *
34 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 34 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
35 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 35 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
36 * 36 *
37 */ 37 */
38 38
39#ifndef _OCONTACTACCESSBACKEND_H_ 39#ifndef _OCONTACTACCESSBACKEND_H_
40#define _OCONTACTACCESSBACKEND_H_ 40#define _OCONTACTACCESSBACKEND_H_
41 41
42#include <opie2/opimcontact.h> 42#include <opie2/opimcontact.h>
43#include <opie2/opimaccessbackend.h> 43#include <opie2/opimaccessbackend.h>
44 44
45#include <qregexp.h> 45#include <qregexp.h>
46 46
47namespace Opie { 47namespace Opie {
48/** 48/**
49 * This class represents the interface of all Contact Backends. 49 * This class represents the interface of all Contact Backends.
50 * Derivates of this class will be used to access the contacts. 50 * Derivates of this class will be used to access the contacts.
51 * As implementation currently XML and vCard exist. This class needs to be implemented 51 * As implementation currently XML and vCard exist. This class needs to be implemented
52 * if you want to provide your own storage. 52 * if you want to provide your own storage.
53 * In all queries a list of uids is passed on instead of loading the actual record! 53 * In all queries a list of uids is passed on instead of loading the actual record!
54 * 54 *
55 * @see OPimContactAccessBackend_VCard 55 * @see OPimContactAccessBackend_VCard
56 * @see OPimContactAccessBackend_XML 56 * @see OPimContactAccessBackend_XML
57 */ 57 */
58class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { 58class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> {
59 public: 59 public:
60 OPimContactAccessBackend(); 60 OPimContactAccessBackend();
61 61
62 62
63 /** 63 /**
64 * Return if database was changed externally. 64 * Return if database was changed externally.
65 * This may just make sense on file based databases like a XML-File. 65 * This may just make sense on file based databases like a XML-File.
66 * It is used to prevent to overwrite the current database content 66 * It is used to prevent to overwrite the current database content
67 * if the file was already changed by something else ! 67 * if the file was already changed by something else !
68 * If this happens, we have to reload before save our data. 68 * If this happens, we have to reload before save our data.
69 * If we use real databases, this should be handled by the database 69 * If we use real databases, this should be handled by the database
70 * management system themselve, therefore this function should always return false in 70 * management system themselve, therefore this function should always return false in
71 * this case. It is not our problem to handle this conflict ... 71 * this case. It is not our problem to handle this conflict ...
72 * @return <i>true</i> if the database was changed and if save without reload will 72 * @return <i>true</i> if the database was changed and if save without reload will
73 * be dangerous. <i>false</i> if the database was not changed or it is save to write 73 * be dangerous. <i>false</i> if the database was not changed or it is save to write
74 * in this situation. 74 * in this situation.
75 */ 75 */
76 virtual bool wasChangedExternally() = 0; 76 virtual bool wasChangedExternally() = 0;
77 77
78 /** 78 /**
79 * Return all possible settings. 79 * Return all possible settings.
80 * @return All settings provided by the current backend 80 * @return All settings provided by the current backend
81 * (i.e.: query_WildCards & query_IgnoreCase) 81 * (i.e.: query_WildCards & query_IgnoreCase)
82 */ 82 */
83 virtual const uint querySettings() = 0; 83 virtual const uint querySettings() const;
84 84
85 /** 85 /**
86 * Check whether settings are correct. 86 * Check whether settings are correct.
87 * @return <i>true</i> if the given settings are correct and possible. 87 * @return <i>true</i> if the given settings are correct and possible.
88 */ 88 */
89 virtual bool hasQuerySettings (uint querySettings) const = 0; 89 virtual bool hasQuerySettings (uint querySettings) const;
90 90
91 /**
92 * Advanced search mechanism.
93 */
94 UIDArray queryByExample( const UIDArray& uidlist, const OPimContact&, int settings, const QDateTime &d = QDateTime() ) const;
91 /** 95 /**
92 * Slow and inefficent default implementation 96 * Slow and inefficent default implementation
93 */ 97 */
94//@{ 98//@{
95 UIDArray queryByExample( const OPimContact&, int settings, const QDateTime& d = QDateTime() )const;
96 UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; 99 UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const;
97 OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const; 100 OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const;
98//@} 101//@}
99 102
100 103
101private: 104private:
102 class Private; 105 class Private;
103 Private *d; 106 Private *d;
104}; 107};
105 108
106} 109}
107 110
108#endif 111#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 3d284f7..9375f43 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -66,151 +66,151 @@ namespace {
66 /** 66 /**
67 * CreateQuery for the Todolist Table 67 * CreateQuery for the Todolist Table
68 */ 68 */
69 class CreateQuery : public OSQLQuery { 69 class CreateQuery : public OSQLQuery {
70 public: 70 public:
71 CreateQuery(); 71 CreateQuery();
72 ~CreateQuery(); 72 ~CreateQuery();
73 QString query()const; 73 QString query()const;
74 }; 74 };
75 75
76 /** 76 /**
77 * Clears (delete) a Table 77 * Clears (delete) a Table
78 */ 78 */
79 class ClearQuery : public OSQLQuery { 79 class ClearQuery : public OSQLQuery {
80 public: 80 public:
81 ClearQuery(); 81 ClearQuery();
82 ~ClearQuery(); 82 ~ClearQuery();
83 QString query()const; 83 QString query()const;
84 84
85 }; 85 };
86 86
87 87
88 /** 88 /**
89 * LoadQuery 89 * LoadQuery
90 * this one queries for all uids 90 * this one queries for all uids
91 */ 91 */
92 class LoadQuery : public OSQLQuery { 92 class LoadQuery : public OSQLQuery {
93 public: 93 public:
94 LoadQuery(); 94 LoadQuery();
95 ~LoadQuery(); 95 ~LoadQuery();
96 QString query()const; 96 QString query()const;
97 }; 97 };
98 98
99 /** 99 /**
100 * inserts/adds a OPimContact to the table 100 * inserts/adds a OPimContact to the table
101 */ 101 */
102 class InsertQuery : public OSQLQuery { 102 class InsertQuery : public OSQLQuery {
103 public: 103 public:
104 InsertQuery(const OPimContact& ); 104 InsertQuery(const OPimContact& );
105 ~InsertQuery(); 105 ~InsertQuery();
106 QString query()const; 106 QString query()const;
107 private: 107 private:
108 OPimContact m_contact; 108 OPimContact m_contact;
109 }; 109 };
110 110
111 111
112 /** 112 /**
113 * removes one from the table 113 * removes one from the table
114 */ 114 */
115 class RemoveQuery : public OSQLQuery { 115 class RemoveQuery : public OSQLQuery {
116 public: 116 public:
117 RemoveQuery(int uid ); 117 RemoveQuery(int uid );
118 ~RemoveQuery(); 118 ~RemoveQuery();
119 QString query()const; 119 QString query()const;
120 private: 120 private:
121 int m_uid; 121 int m_uid;
122 }; 122 };
123 123
124 /** 124 /**
125 * a find query for noncustom elements 125 * a find query for noncustom elements
126 */ 126 */
127 class FindQuery : public OSQLQuery { 127 class FindQuery : public OSQLQuery {
128 public: 128 public:
129 FindQuery(int uid); 129 FindQuery(int uid);
130 FindQuery(const QArray<int>& ); 130 FindQuery(const UIDArray& );
131 ~FindQuery(); 131 ~FindQuery();
132 QString query()const; 132 QString query()const;
133 private: 133 private:
134 QString single()const; 134 QString single()const;
135 QString multi()const; 135 QString multi()const;
136 QArray<int> m_uids; 136 UIDArray m_uids;
137 int m_uid; 137 int m_uid;
138 }; 138 };
139 139
140 /** 140 /**
141 * a find query for custom elements 141 * a find query for custom elements
142 */ 142 */
143 class FindCustomQuery : public OSQLQuery { 143 class FindCustomQuery : public OSQLQuery {
144 public: 144 public:
145 FindCustomQuery(int uid); 145 FindCustomQuery(int uid);
146 FindCustomQuery(const QArray<int>& ); 146 FindCustomQuery(const UIDArray& );
147 ~FindCustomQuery(); 147 ~FindCustomQuery();
148 QString query()const; 148 QString query()const;
149 private: 149 private:
150 QString single()const; 150 QString single()const;
151 QString multi()const; 151 QString multi()const;
152 QArray<int> m_uids; 152 UIDArray m_uids;
153 int m_uid; 153 int m_uid;
154 }; 154 };
155 155
156 156
157 157
158 // We using two tables to store the information: 158 // We using two tables to store the information:
159 // 1. addressbook : It contains General information about the contact (non custom) 159 // 1. addressbook : It contains General information about the contact (non custom)
160 // 2. custom_data : Not official supported entries 160 // 2. custom_data : Not official supported entries
161 // All tables are connected by the uid of the contact. 161 // All tables are connected by the uid of the contact.
162 // Maybe I should add a table for meta-information ? 162 // Maybe I should add a table for meta-information ?
163 CreateQuery::CreateQuery() : OSQLQuery() {} 163 CreateQuery::CreateQuery() : OSQLQuery() {}
164 CreateQuery::~CreateQuery() {} 164 CreateQuery::~CreateQuery() {}
165 QString CreateQuery::query()const { 165 QString CreateQuery::query()const {
166 QString qu; 166 QString qu;
167 167
168 qu += "create table addressbook( uid PRIMARY KEY "; 168 qu += "create table addressbook( uid PRIMARY KEY ";
169 169
170 QStringList fieldList = OPimContactFields::untrfields( false ); 170 QStringList fieldList = OPimContactFields::untrfields( false );
171 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 171 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
172 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); 172 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
173 } 173 }
174 qu += " );"; 174 qu += " );";
175 175
176 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 176 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
177 177
178 return qu; 178 return qu;
179 } 179 }
180 180
181 ClearQuery::ClearQuery() 181 ClearQuery::ClearQuery()
182 : OSQLQuery() {} 182 : OSQLQuery() {}
183 ClearQuery::~ClearQuery() {} 183 ClearQuery::~ClearQuery() {}
184 QString ClearQuery::query()const { 184 QString ClearQuery::query()const {
185 QString qu = "drop table addressbook;"; 185 QString qu = "drop table addressbook;";
186 qu += "drop table custom_data;"; 186 qu += "drop table custom_data;";
187// qu += "drop table dates;"; 187// qu += "drop table dates;";
188 return qu; 188 return qu;
189 } 189 }
190 190
191 191
192 LoadQuery::LoadQuery() : OSQLQuery() {} 192 LoadQuery::LoadQuery() : OSQLQuery() {}
193 LoadQuery::~LoadQuery() {} 193 LoadQuery::~LoadQuery() {}
194 QString LoadQuery::query()const { 194 QString LoadQuery::query()const {
195 QString qu; 195 QString qu;
196 qu += "select uid from addressbook"; 196 qu += "select uid from addressbook";
197 197
198 return qu; 198 return qu;
199 } 199 }
200 200
201 201
202 InsertQuery::InsertQuery( const OPimContact& contact ) 202 InsertQuery::InsertQuery( const OPimContact& contact )
203 : OSQLQuery(), m_contact( contact ) { 203 : OSQLQuery(), m_contact( contact ) {
204 } 204 }
205 205
206 InsertQuery::~InsertQuery() { 206 InsertQuery::~InsertQuery() {
207 } 207 }
208 208
209 /* 209 /*
210 * converts from a OPimContact to a query 210 * converts from a OPimContact to a query
211 */ 211 */
212 QString InsertQuery::query()const{ 212 QString InsertQuery::query()const{
213 213
214 QString qu; 214 QString qu;
215 qu += "insert into addressbook VALUES( " + 215 qu += "insert into addressbook VALUES( " +
216 QString::number( m_contact.uid() ); 216 QString::number( m_contact.uid() );
@@ -233,678 +233,774 @@ namespace {
233 day = m_contact.birthday(); 233 day = m_contact.birthday();
234 } else { 234 } else {
235 day = m_contact.anniversary(); 235 day = m_contact.anniversary();
236 } 236 }
237 // These entries should stored in a special format 237 // These entries should stored in a special format
238 // year-month-day 238 // year-month-day
239 if ( day.isValid() ){ 239 if ( day.isValid() ){
240 qu += QString(",\"%1-%2-%3\"") 240 qu += QString(",\"%1-%2-%3\"")
241 .arg( QString::number( day.year() ).rightJustify( 4, '0' ) ) 241 .arg( QString::number( day.year() ).rightJustify( 4, '0' ) )
242 .arg( QString::number( day.month() ).rightJustify( 2, '0' ) ) 242 .arg( QString::number( day.month() ).rightJustify( 2, '0' ) )
243 .arg( QString::number( day.day() ).rightJustify( 2, '0' ) ); 243 .arg( QString::number( day.day() ).rightJustify( 2, '0' ) );
244 } else { 244 } else {
245 qu += ",\"\""; 245 qu += ",\"\"";
246 } 246 }
247 } 247 }
248 break; 248 break;
249 default: 249 default:
250 qu += QString( ",\"%1\"" ).arg( contactMap[id] ); 250 qu += QString( ",\"%1\"" ).arg( contactMap[id] );
251 } 251 }
252 } 252 }
253 qu += " );"; 253 qu += " );";
254 254
255 255
256 // Now add custom data.. 256 // Now add custom data..
257 int id = 0; 257 int id = 0;
258 id = 0; 258 id = 0;
259 QMap<QString, QString> customMap = m_contact.toExtraMap(); 259 QMap<QString, QString> customMap = m_contact.toExtraMap();
260 for( QMap<QString, QString>::Iterator it = customMap.begin(); 260 for( QMap<QString, QString>::Iterator it = customMap.begin();
261 it != customMap.end(); ++it ){ 261 it != customMap.end(); ++it ){
262 qu += "insert into custom_data VALUES(" 262 qu += "insert into custom_data VALUES("
263 + QString::number( m_contact.uid() ) 263 + QString::number( m_contact.uid() )
264 + "," 264 + ","
265 + QString::number( id++ ) 265 + QString::number( id++ )
266 + ",'" 266 + ",'"
267 + it.key() 267 + it.key()
268 + "'," 268 + "',"
269 + "0" // Priority for future enhancements 269 + "0" // Priority for future enhancements
270 + ",'" 270 + ",'"
271 + it.data() 271 + it.data()
272 + "');"; 272 + "');";
273 } 273 }
274 // qu += "commit;"; 274 // qu += "commit;";
275 odebug << "add " << qu << "" << oendl; 275 odebug << "add " << qu << "" << oendl;
276 return qu; 276 return qu;
277 } 277 }
278 278
279 279
280 RemoveQuery::RemoveQuery(int uid ) 280 RemoveQuery::RemoveQuery(int uid )
281 : OSQLQuery(), m_uid( uid ) {} 281 : OSQLQuery(), m_uid( uid ) {}
282 RemoveQuery::~RemoveQuery() {} 282 RemoveQuery::~RemoveQuery() {}
283 QString RemoveQuery::query()const { 283 QString RemoveQuery::query()const {
284 QString qu = "DELETE from addressbook where uid = " 284 QString qu = "DELETE from addressbook where uid = "
285 + QString::number(m_uid) + ";"; 285 + QString::number(m_uid) + ";";
286 qu += "DELETE from custom_data where uid = " 286 qu += "DELETE from custom_data where uid = "
287 + QString::number(m_uid) + ";"; 287 + QString::number(m_uid) + ";";
288 return qu; 288 return qu;
289 } 289 }
290 290
291 291
292 292
293 293
294 FindQuery::FindQuery(int uid) 294 FindQuery::FindQuery(int uid)
295 : OSQLQuery(), m_uid( uid ) { 295 : OSQLQuery(), m_uid( uid ) {
296 } 296 }
297 FindQuery::FindQuery(const QArray<int>& ints) 297 FindQuery::FindQuery(const UIDArray& ints)
298 : OSQLQuery(), m_uids( ints ){ 298 : OSQLQuery(), m_uids( ints ){
299 } 299 }
300 FindQuery::~FindQuery() { 300 FindQuery::~FindQuery() {
301 } 301 }
302 QString FindQuery::query()const{ 302 QString FindQuery::query()const{
303 if ( m_uids.count() == 0 ) 303 if ( m_uids.count() == 0 )
304 return single(); 304 return single();
305 else 305 else
306 return multi(); 306 return multi();
307 } 307 }
308 308
309 QString FindQuery::multi()const { 309 QString FindQuery::multi()const {
310 QString qu = "select * from addressbook where"; 310 QString qu = "select * from addressbook where";
311 for (uint i = 0; i < m_uids.count(); i++ ) { 311 for (uint i = 0; i < m_uids.count(); i++ ) {
312 qu += " uid = " + QString::number( m_uids[i] ) + " OR"; 312 qu += " uid = " + QString::number( m_uids[i] ) + " OR";
313 } 313 }
314 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 314 qu.remove( qu.length()-2, 2 ); // Hmmmm..
315 315
316 odebug << "find query: " << qu << "" << oendl; 316 odebug << "find query: " << qu << "" << oendl;
317 return qu; 317 return qu;
318 } 318 }
319 319
320 QString FindQuery::single()const{ 320 QString FindQuery::single()const{
321 QString qu = "select *"; 321 QString qu = "select *";
322 qu += " from addressbook where uid = " + QString::number(m_uid); 322 qu += " from addressbook where uid = " + QString::number(m_uid);
323 323
324 // owarn << "find query: " << qu << "" << oendl; 324 // owarn << "find query: " << qu << "" << oendl;
325 return qu; 325 return qu;
326 } 326 }
327 327
328 328
329 FindCustomQuery::FindCustomQuery(int uid) 329 FindCustomQuery::FindCustomQuery(int uid)
330 : OSQLQuery(), m_uid( uid ) { 330 : OSQLQuery(), m_uid( uid ) {
331 } 331 }
332 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 332 FindCustomQuery::FindCustomQuery(const UIDArray& ints)
333 : OSQLQuery(), m_uids( ints ){ 333 : OSQLQuery(), m_uids( ints ){
334 } 334 }
335 FindCustomQuery::~FindCustomQuery() { 335 FindCustomQuery::~FindCustomQuery() {
336 } 336 }
337 QString FindCustomQuery::query()const{ 337 QString FindCustomQuery::query()const{
338// if ( m_uids.count() == 0 ) 338// if ( m_uids.count() == 0 )
339 return single(); 339 return single();
340 } 340 }
341 QString FindCustomQuery::single()const{ 341 QString FindCustomQuery::single()const{
342 QString qu = "select uid, type, value from custom_data where uid = "; 342 QString qu = "select uid, type, value from custom_data where uid = ";
343 qu += QString::number(m_uid); 343 qu += QString::number(m_uid);
344 return qu; 344 return qu;
345 } 345 }
346 346
347}; 347};
348 348
349 349
350/* --------------------------------------------------------------------------- */ 350/* --------------------------------------------------------------------------- */
351 351
352namespace Opie { 352namespace Opie {
353 353
354OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, 354OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */,
355 const QString& filename ): 355 const QString& filename ):
356 OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) 356 OPimContactAccessBackend(), m_changed(false), m_driver( NULL )
357{ 357{
358 odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; 358 odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl;
359 QTime t; 359 QTime t;
360 t.start(); 360 t.start();
361 361
362 /* Expecting to access the default filename if nothing else is set */ 362 /* Expecting to access the default filename if nothing else is set */
363 if ( filename.isEmpty() ){ 363 if ( filename.isEmpty() ){
364 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 364 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
365 } else 365 } else
366 m_fileName = filename; 366 m_fileName = filename;
367 367
368 // Get the standart sql-driver from the OSQLManager.. 368 // Get the standart sql-driver from the OSQLManager..
369 OSQLManager man; 369 OSQLManager man;
370 m_driver = man.standard(); 370 m_driver = man.standard();
371 m_driver->setUrl( m_fileName ); 371 m_driver->setUrl( m_fileName );
372 372
373 load(); 373 load();
374 374
375 odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; 375 odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl;
376} 376}
377 377
378OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () 378OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL ()
379{ 379{
380 if( m_driver ) 380 if( m_driver )
381 delete m_driver; 381 delete m_driver;
382} 382}
383 383
384bool OPimContactAccessBackend_SQL::load () 384bool OPimContactAccessBackend_SQL::load ()
385{ 385{
386 if (!m_driver->open() ) 386 if (!m_driver->open() )
387 return false; 387 return false;
388 388
389 // Don't expect that the database exists. 389 // Don't expect that the database exists.
390 // It is save here to create the table, even if it 390 // It is save here to create the table, even if it
391 // do exist. ( Is that correct for all databases ?? ) 391 // do exist. ( Is that correct for all databases ?? )
392 CreateQuery creat; 392 CreateQuery creat;
393 OSQLResult res = m_driver->query( &creat ); 393 OSQLResult res = m_driver->query( &creat );
394 394
395 update(); 395 update();
396 396
397 return true; 397 return true;
398 398
399} 399}
400 400
401bool OPimContactAccessBackend_SQL::reload() 401bool OPimContactAccessBackend_SQL::reload()
402{ 402{
403 return load(); 403 return load();
404} 404}
405 405
406bool OPimContactAccessBackend_SQL::save() 406bool OPimContactAccessBackend_SQL::save()
407{ 407{
408 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 408 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
409} 409}
410 410
411 411
412void OPimContactAccessBackend_SQL::clear () 412void OPimContactAccessBackend_SQL::clear ()
413{ 413{
414 ClearQuery cle; 414 ClearQuery cle;
415 OSQLResult res = m_driver->query( &cle ); 415 OSQLResult res = m_driver->query( &cle );
416 416
417 reload(); 417 reload();
418} 418}
419 419
420bool OPimContactAccessBackend_SQL::wasChangedExternally() 420bool OPimContactAccessBackend_SQL::wasChangedExternally()
421{ 421{
422 return false; 422 return false;
423} 423}
424 424
425QArray<int> OPimContactAccessBackend_SQL::allRecords() const 425UIDArray OPimContactAccessBackend_SQL::allRecords() const
426{ 426{
427 427
428 // FIXME: Think about cute handling of changed tables.. 428 // FIXME: Think about cute handling of changed tables..
429 // Thus, we don't have to call update here... 429 // Thus, we don't have to call update here...
430 if ( m_changed ) 430 if ( m_changed )
431 ((OPimContactAccessBackend_SQL*)this)->update(); 431 ((OPimContactAccessBackend_SQL*)this)->update();
432 432
433 return m_uids; 433 return m_uids;
434} 434}
435 435
436bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) 436bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact )
437{ 437{
438 odebug << "add in contact SQL-Backend" << oendl; 438 odebug << "add in contact SQL-Backend" << oendl;
439 InsertQuery ins( newcontact ); 439 InsertQuery ins( newcontact );
440 OSQLResult res = m_driver->query( &ins ); 440 OSQLResult res = m_driver->query( &ins );
441 441
442 if ( res.state() == OSQLResult::Failure ) 442 if ( res.state() == OSQLResult::Failure )
443 return false; 443 return false;
444 444
445 int c = m_uids.count(); 445 int c = m_uids.count();
446 m_uids.resize( c+1 ); 446 m_uids.resize( c+1 );
447 m_uids[c] = newcontact.uid(); 447 m_uids[c] = newcontact.uid();
448 448
449 return true; 449 return true;
450} 450}
451 451
452 452
453bool OPimContactAccessBackend_SQL::remove ( int uid ) 453bool OPimContactAccessBackend_SQL::remove ( int uid )
454{ 454{
455 RemoveQuery rem( uid ); 455 RemoveQuery rem( uid );
456 OSQLResult res = m_driver->query(&rem ); 456 OSQLResult res = m_driver->query(&rem );
457 457
458 if ( res.state() == OSQLResult::Failure ) 458 if ( res.state() == OSQLResult::Failure )
459 return false; 459 return false;
460 460
461 m_changed = true; 461 m_changed = true;
462 462
463 return true; 463 return true;
464} 464}
465 465
466bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) 466bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
467{ 467{
468 if ( !remove( contact.uid() ) ) 468 if ( !remove( contact.uid() ) )
469 return false; 469 return false;
470 470
471 return add( contact ); 471 return add( contact );
472} 472}
473 473
474 474
475OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const 475OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
476{ 476{
477 odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; 477 odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl;
478 QTime t; 478 QTime t;
479 t.start(); 479 t.start();
480 480
481 OPimContact retContact( requestNonCustom( uid ) ); 481 OPimContact retContact( requestNonCustom( uid ) );
482 retContact.setExtraMap( requestCustom( uid ) ); 482 retContact.setExtraMap( requestCustom( uid ) );
483 483
484 odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; 484 odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl;
485 return retContact; 485 return retContact;
486} 486}
487 487
488OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const 488OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const
489{ 489{
490 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; 490 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl;
491 odebug << "searching for " << uid << "" << oendl; 491 odebug << "searching for " << uid << "" << oendl;
492 492
493 QTime t; 493 QTime t;
494 t.start(); 494 t.start();
495 495
496 uint numReadAhead = readAhead(); 496 uint numReadAhead = readAhead();
497 QArray<int> searchList( numReadAhead ); 497 QArray<int> searchList( numReadAhead );
498 498
499 uint size =0; 499 uint size =0;
500 500
501 // Build an array with all elements which should be requested and cached 501 // Build an array with all elements which should be requested and cached
502 // We will just request "numReadAhead" elements, starting from "current" position in 502 // We will just request "numReadAhead" elements, starting from "current" position in
503 // the list of many uids ! 503 // the list of many uids !
504 switch( direction ) { 504 switch( direction ) {
505 /* forward */ 505 /* forward */
506 case Frontend::Forward: 506 case Frontend::Forward:
507 for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { 507 for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) {
508 searchList[size] = queryUids[i]; 508 searchList[size] = queryUids[i];
509 size++; 509 size++;
510 } 510 }
511 break; 511 break;
512 /* reverse */ 512 /* reverse */
513 case Frontend::Reverse: 513 case Frontend::Reverse:
514 for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { 514 for ( uint i = current; i != 0 && size < numReadAhead; i-- ) {
515 searchList[size] = queryUids[i]; 515 searchList[size] = queryUids[i];
516 size++; 516 size++;
517 } 517 }
518 break; 518 break;
519 } 519 }
520 520
521 //Shrink to real size.. 521 //Shrink to real size..
522 searchList.resize( size ); 522 searchList.resize( size );
523 523
524 OPimContact retContact( requestContactsAndCache( uid, searchList ) ); 524 OPimContact retContact( requestContactsAndCache( uid, searchList ) );
525 525
526 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; 526 odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl;
527 return retContact; 527 return retContact;
528} 528}
529 529
530 530
531QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) 531UIDArray OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings,
532 const QDateTime& qd ) const
532{ 533{
533 QString qu = "SELECT uid FROM addressbook WHERE"; 534 QString qu = "SELECT uid FROM addressbook WHERE";
534 QString searchQuery =""; 535 QString searchQuery ="";
535 536
536 QDate startDate; 537 QDate startDate;
537 538
538 if ( qd.isValid() ) 539 if ( qd.isValid() )
539 startDate = qd.date(); 540 startDate = qd.date();
540 else 541 else
541 startDate = QDate::currentDate(); 542 startDate = QDate::currentDate();
542 543
543 544
544 QMap<int, QString> queryFields = query.toMap(); 545 QMap<int, QString> queryFields = query.toMap();
545 QStringList fieldList = OPimContactFields::untrfields( false ); 546 QStringList fieldList = OPimContactFields::untrfields( false );
546 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 547 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
547 548
548 // Convert every filled field to a SQL-Query 549 // Convert every filled field to a SQL-Query
549// bool isAnyFieldSelected = false; 550// bool isAnyFieldSelected = false;
550 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 551 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
551 552
552 int id = translate[*it]; 553 int id = translate[*it];
553 QString queryStr = queryFields[id]; 554 QString queryStr = queryFields[id];
554 QDate* endDate = 0l; 555 QDate* endDate = 0l;
555 556
556 if ( !queryStr.isEmpty() ){ 557 if ( !queryStr.isEmpty() ){
557 // If something is alredy stored in the query, add an "AND" 558 // If something is alredy stored in the query, add an "AND"
558 // to the end of the string to prepare for the next .. 559 // to the end of the string to prepare for the next ..
559 if ( !searchQuery.isEmpty() ) 560 if ( !searchQuery.isEmpty() )
560 searchQuery += " AND"; 561 searchQuery += " AND";
561 562
562// isAnyFieldSelected = true; 563// isAnyFieldSelected = true;
563 switch( id ){ 564 switch( id ){
564 case Qtopia::Birthday: 565 case Qtopia::Birthday:
565 endDate = new QDate( query.birthday() ); 566 endDate = new QDate( query.birthday() );
566 // Fall through ! 567 // Fall through !
567 case Qtopia::Anniversary: 568 case Qtopia::Anniversary:
568 if ( endDate == 0l ) 569 if ( endDate == 0l )
569 endDate = new QDate( query.anniversary() ); 570 endDate = new QDate( query.anniversary() );
570 571
571 if ( settings & OPimContactAccess::DateDiff ) { 572 if ( settings & OPimContactAccess::DateDiff ) {
572 searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) 573 searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" )
573 .arg( *it ) 574 .arg( *it )
574 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) 575 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) )
575 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) 576 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) )
576 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) 577 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) )
577 .arg( *it ) 578 .arg( *it )
578 .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) 579 .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) )
579 .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) 580 .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) )
580 .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; 581 .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ;
581 } 582 }
582 583
583 if ( settings & OPimContactAccess::DateYear ){ 584 if ( settings & OPimContactAccess::DateYear ){
584 if ( settings & OPimContactAccess::DateDiff ) 585 if ( settings & OPimContactAccess::DateDiff )
585 searchQuery += " AND"; 586 searchQuery += " AND";
586 587
587 searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) 588 searchQuery += QString( " (\"%1\" LIKE '%2-%')" )
588 .arg( *it ) 589 .arg( *it )
589 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); 590 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) );
590 } 591 }
591 592
592 if ( settings & OPimContactAccess::DateMonth ){ 593 if ( settings & OPimContactAccess::DateMonth ){
593 if ( ( settings & OPimContactAccess::DateDiff ) 594 if ( ( settings & OPimContactAccess::DateDiff )
594 || ( settings & OPimContactAccess::DateYear ) ) 595 || ( settings & OPimContactAccess::DateYear ) )
595 searchQuery += " AND"; 596 searchQuery += " AND";
596 597
597 searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) 598 searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" )
598 .arg( *it ) 599 .arg( *it )
599 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); 600 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) );
600 } 601 }
601 602
602 if ( settings & OPimContactAccess::DateDay ){ 603 if ( settings & OPimContactAccess::DateDay ){
603 if ( ( settings & OPimContactAccess::DateDiff ) 604 if ( ( settings & OPimContactAccess::DateDiff )
604 || ( settings & OPimContactAccess::DateYear ) 605 || ( settings & OPimContactAccess::DateYear )
605 || ( settings & OPimContactAccess::DateMonth ) ) 606 || ( settings & OPimContactAccess::DateMonth ) )
606 searchQuery += " AND"; 607 searchQuery += " AND";
607 608
608 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) 609 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" )
609 .arg( *it ) 610 .arg( *it )
610 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); 611 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) );
611 } 612 }
612 613
613 break; 614 break;
614 default: 615 default:
615 // Switching between case sensitive and insensitive... 616 // Switching between case sensitive and insensitive...
616 // LIKE is not case sensitive, GLOB is case sensitive 617 // LIKE is not case sensitive, GLOB is case sensitive
617 // Do exist a better solution to switch this ? 618 // Do exist a better solution to switch this ?
618 if ( settings & OPimContactAccess::IgnoreCase ) 619 if ( settings & OPimContactAccess::IgnoreCase )
619 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" 620 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'"
620 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; 621 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")";
621 else 622 else
622 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" 623 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'"
623 + queryStr + "'" + ")"; 624 + queryStr + "'" + ")";
624 625
625 } 626 }
626 } 627 }
627 628
628 delete endDate; 629 delete endDate;
629 } 630 }
630 // Skip trailing "AND" 631 // Skip trailing "AND"
631// if ( isAnyFieldSelected ) 632// if ( isAnyFieldSelected )
632// qu = qu.left( qu.length() - 4 ); 633// qu = qu.left( qu.length() - 4 );
633 634
634 qu += searchQuery; 635 qu += searchQuery;
635 636
636 odebug << "queryByExample query: " << qu << "" << oendl; 637 odebug << "queryByExample query: " << qu << "" << oendl;
637 638
638 // Execute query and return the received uid's 639 // Execute query and return the received uid's
639 OSQLRawQuery raw( qu ); 640 OSQLRawQuery raw( qu );
640 OSQLResult res = m_driver->query( &raw ); 641 OSQLResult res = m_driver->query( &raw );
641 if ( res.state() != OSQLResult::Success ){ 642 if ( res.state() != OSQLResult::Success ){
642 QArray<int> empty; 643 UIDArray empty;
643 return empty; 644 return empty;
644 } 645 }
645 646
646 QArray<int> list = extractUids( res ); 647 UIDArray list = extractUids( res );
647 648
648 return list; 649 return list;
649} 650}
650 651
651QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 652UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
652{ 653{
653#if 0 654#if 0
654 QArray<int> nix(0); 655 QArray<int> nix(0);
655 return nix; 656 return nix;
656 657
657#else 658#else
658 QString qu = "SELECT uid FROM addressbook WHERE ("; 659 QString qu = "SELECT uid FROM addressbook WHERE (";
659 QString searchlist; 660 QString searchlist;
660 661
661 QStringList fieldList = OPimContactFields::untrfields( false ); 662 QStringList fieldList = OPimContactFields::untrfields( false );
662 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 663 // QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
663 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 664 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
664 if ( !searchlist.isEmpty() ) 665 if ( !searchlist.isEmpty() )
665 searchlist += " OR "; 666 searchlist += " OR ";
666 searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; 667 searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") ";
667 } 668 }
668 669
669 qu = qu + searchlist + ")"; 670 qu = qu + searchlist + ")";
670 671
671 odebug << "query: " << qu << "" << oendl; 672 odebug << "query: " << qu << "" << oendl;
672 673
673 OSQLRawQuery raw( qu ); 674 OSQLRawQuery raw( qu );
674 OSQLResult res = m_driver->query( &raw ); 675 OSQLResult res = m_driver->query( &raw );
675 676
676 return extractUids( res ); 677 return extractUids( res );
677 678
678 679
679#endif 680#endif
680} 681}
681 682
682const uint OPimContactAccessBackend_SQL::querySettings() 683const uint OPimContactAccessBackend_SQL::querySettings() const
683{ 684{
684 return OPimContactAccess::IgnoreCase 685 return OPimContactAccess::IgnoreCase
685 | OPimContactAccess::WildCards 686 | OPimContactAccess::WildCards
686 | OPimContactAccess::DateDiff 687 | OPimContactAccess::DateDiff
687 | OPimContactAccess::DateYear 688 | OPimContactAccess::DateYear
688 | OPimContactAccess::DateMonth 689 | OPimContactAccess::DateMonth
689 | OPimContactAccess::DateDay 690 | OPimContactAccess::DateDay
690 ; 691 ;
691} 692}
692 693
693bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 694bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
694{ 695{
695 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 696 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
696 * may be added with any of the other settings. IgnoreCase should never used alone. 697 * may be added with any of the other settings. IgnoreCase should never used alone.
697 * Wildcards, RegExp, ExactMatch should never used at the same time... 698 * Wildcards, RegExp, ExactMatch should never used at the same time...
698 */ 699 */
699 700
700 // Step 1: Check whether the given settings are supported by this backend 701 // Step 1: Check whether the given settings are supported by this backend
701 if ( ( querySettings & ( 702 if ( ( querySettings & (
702 OPimContactAccess::IgnoreCase 703 OPimContactAccess::IgnoreCase
703 | OPimContactAccess::WildCards 704 | OPimContactAccess::WildCards
704 | OPimContactAccess::DateDiff 705 | OPimContactAccess::DateDiff
705 | OPimContactAccess::DateYear 706 | OPimContactAccess::DateYear
706 | OPimContactAccess::DateMonth 707 | OPimContactAccess::DateMonth
707 | OPimContactAccess::DateDay 708 | OPimContactAccess::DateDay
708// | OPimContactAccess::RegExp 709// | OPimContactAccess::RegExp
709// | OPimContactAccess::ExactMatch 710// | OPimContactAccess::ExactMatch
710 ) ) != querySettings ) 711 ) ) != querySettings )
711 return false; 712 return false;
712 713
713 // Step 2: Check whether the given combinations are ok.. 714 // Step 2: Check whether the given combinations are ok..
714 715
715 // IngoreCase alone is invalid 716 // IngoreCase alone is invalid
716 if ( querySettings == OPimContactAccess::IgnoreCase ) 717 if ( querySettings == OPimContactAccess::IgnoreCase )
717 return false; 718 return false;
718 719
719 // WildCards, RegExp and ExactMatch should never used at the same time 720 // WildCards, RegExp and ExactMatch should never used at the same time
720 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 721 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
721 | OPimContactAccess::DateDiff 722 | OPimContactAccess::DateDiff
722 | OPimContactAccess::DateYear 723 | OPimContactAccess::DateYear
723 | OPimContactAccess::DateMonth 724 | OPimContactAccess::DateMonth
724 | OPimContactAccess::DateDay 725 | OPimContactAccess::DateDay
725 ) 726 )
726 ){ 727 ){
727 case OPimContactAccess::RegExp: 728 case OPimContactAccess::RegExp:
728 return ( true ); 729 return ( true );
729 case OPimContactAccess::WildCards: 730 case OPimContactAccess::WildCards:
730 return ( true ); 731 return ( true );
731 case OPimContactAccess::ExactMatch: 732 case OPimContactAccess::ExactMatch:
732 return ( true ); 733 return ( true );
733 case 0: // one of the upper removed bits were set.. 734 case 0: // one of the upper removed bits were set..
734 return ( true ); 735 return ( true );
735 default: 736 default:
736 return ( false ); 737 return ( false );
737 } 738 }
738 739
739} 740}
740 741
741QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 742UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder,
743 int filter, const QArray<int>& categories )const
742{ 744{
743 QTime t; 745 QTime t;
744 t.start(); 746 t.start();
745 747
746 QString query = "SELECT uid FROM addressbook "; 748 QString query = "SELECT uid FROM addressbook";
747 query += "ORDER BY \"Last Name\" "; 749
750 query += " WHERE (";
751 for ( uint i = 0; i < ar.count(); i++ ) {
752 query += " uid = " + QString::number( ar[i] ) + " OR";
753 }
754 query.remove( query.length()-2, 2 ); // Hmmmm..
755 query += ")";
756
757
758 if ( filter != OPimBase::FilterOff ){
759 if ( filter & OPimContactAccess::DoNotShowWithCategory ){
760 query += " AND ( \"Categories\" == '' )";
761 } else if ( filter & OPimBase::FilterCategory ){
762 query += " AND (";
763 for ( uint i = 0; i < categories.count(); i++ ){
764 query += "\"Categories\" LIKE";
765 query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR";
766 }
767 query.remove( query.length()-2, 2 ); // Hmmmm..
768 query += ")";
769 }
770
771 if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){
772 query += " AND ( \"Children\" != '' )";
773 }
774
775 if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){
776 query += " AND ( \"Anniversary\" != '' )";
777 }
778
779 if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){
780 query += " AND ( \"Birthday\" != '' )";
781 }
782
783 if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){
784 // Expect that no Street means no Address, too! (eilers)
785 query += " AND ( \"Home Street\" != '' )";
786 }
787
788 if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){
789 // Expect that no Street means no Address, too! (eilers)
790 query += " AND ( \"Business Street\" != '' )";
791 }
792
793 }
794
795 query += " ORDER BY";
796
797 switch ( sortOrder ) {
798 case OPimContactAccess::SortSummary:
799 query += " \"Notes\"";
800 break;
801 case OPimContactAccess::SortByCategory:
802 query += " \"Categories\"";
803 break;
804 case OPimContactAccess::SortByDate:
805 query += " \"\"";
806 break;
807 case OPimContactAccess::SortTitle:
808 query += " \"Name Title\"";
809 break;
810 case OPimContactAccess::SortFirstName:
811 query += " \"First Name\"";
812 break;
813 case OPimContactAccess::SortMiddleName:
814 query += " \"Middle Name\"";
815 break;
816 case OPimContactAccess::SortLastName:
817 query += " \"Last Name\"";
818 break;
819 case OPimContactAccess::SortFileAsName:
820 query += " \"File As\"";
821 break;
822 case OPimContactAccess::SortSuffix:
823 query += " \"Suffix\"";
824 break;
825 case OPimContactAccess::SortEmail:
826 query += " \"Default Email\"";
827 break;
828 case OPimContactAccess::SortNickname:
829 query += " \"Nickname\"";
830 break;
831 case OPimContactAccess::SortAnniversary:
832 query += " \"Anniversary\"";
833 break;
834 case OPimContactAccess::SortBirthday:
835 query += " \"Birthday\"";
836 break;
837 case OPimContactAccess::SortGender:
838 query += " \"Gender\"";
839 break;
840 default:
841 query += " \"Last Name\"";
842 }
748 843
749 if ( !asc ) 844 if ( !asc )
750 query += "DESC"; 845 query += " DESC";
846
751 847
752 // odebug << "sorted query is: " << query << "" << oendl; 848 odebug << "sorted query is: " << query << "" << oendl;
753 849
754 OSQLRawQuery raw( query ); 850 OSQLRawQuery raw( query );
755 OSQLResult res = m_driver->query( &raw ); 851 OSQLResult res = m_driver->query( &raw );
756 if ( res.state() != OSQLResult::Success ){ 852 if ( res.state() != OSQLResult::Success ){
757 QArray<int> empty; 853 UIDArray empty;
758 return empty; 854 return empty;
759 } 855 }
760 856
761 QArray<int> list = extractUids( res ); 857 UIDArray list = extractUids( res );
762 858
763 odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; 859 odebug << "sorted needed " << t.elapsed() << " ms!" << oendl;
764 return list; 860 return list;
765} 861}
766 862
767 863
768void OPimContactAccessBackend_SQL::update() 864void OPimContactAccessBackend_SQL::update()
769{ 865{
770 odebug << "Update starts" << oendl; 866 odebug << "Update starts" << oendl;
771 QTime t; 867 QTime t;
772 t.start(); 868 t.start();
773 869
774 // Now load the database set and extract the uid's 870 // Now load the database set and extract the uid's
775 // which will be held locally 871 // which will be held locally
776 872
777 LoadQuery lo; 873 LoadQuery lo;
778 OSQLResult res = m_driver->query(&lo); 874 OSQLResult res = m_driver->query(&lo);
779 if ( res.state() != OSQLResult::Success ) 875 if ( res.state() != OSQLResult::Success )
780 return; 876 return;
781 877
782 m_uids = extractUids( res ); 878 m_uids = extractUids( res );
783 879
784 m_changed = false; 880 m_changed = false;
785 881
786 odebug << "Update ends " << t.elapsed() << " ms" << oendl; 882 odebug << "Update ends " << t.elapsed() << " ms" << oendl;
787} 883}
788 884
789QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const 885UIDArray OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
790{ 886{
791 odebug << "extractUids" << oendl; 887 odebug << "extractUids" << oendl;
792 QTime t; 888 QTime t;
793 t.start(); 889 t.start();
794 OSQLResultItem::ValueList list = res.results(); 890 OSQLResultItem::ValueList list = res.results();
795 OSQLResultItem::ValueList::Iterator it; 891 OSQLResultItem::ValueList::Iterator it;
796 QArray<int> ints(list.count() ); 892 UIDArray ints(list.count() );
797 odebug << " count = " << list.count() << "" << oendl; 893 odebug << " count = " << list.count() << "" << oendl;
798 894
799 int i = 0; 895 int i = 0;
800 for (it = list.begin(); it != list.end(); ++it ) { 896 for (it = list.begin(); it != list.end(); ++it ) {
801 ints[i] = (*it).data("uid").toInt(); 897 ints[i] = (*it).data("uid").toInt();
802 i++; 898 i++;
803 } 899 }
804 odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; 900 odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl;
805 901
806 return ints; 902 return ints;
807 903
808} 904}
809 905
810QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const 906QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const
811{ 907{
812 QTime t; 908 QTime t;
813 t.start(); 909 t.start();
814 910
815 int t2needed = 0; 911 int t2needed = 0;
816 int t3needed = 0; 912 int t3needed = 0;
817 QTime t2; 913 QTime t2;
818 t2.start(); 914 t2.start();
819 FindQuery query( uid ); 915 FindQuery query( uid );
820 OSQLResult res_noncustom = m_driver->query( &query ); 916 OSQLResult res_noncustom = m_driver->query( &query );
821 t2needed = t2.elapsed(); 917 t2needed = t2.elapsed();
822 918
823 OSQLResultItem resItem = res_noncustom.first(); 919 OSQLResultItem resItem = res_noncustom.first();
824 920
825 QMap<int, QString> nonCustomMap; 921 QMap<int, QString> nonCustomMap;
826 QTime t3; 922 QTime t3;
827 t3.start(); 923 t3.start();
828 nonCustomMap = fillNonCustomMap( resItem ); 924 nonCustomMap = fillNonCustomMap( resItem );
829 t3needed = t3.elapsed(); 925 t3needed = t3.elapsed();
830 926
831 927
832 // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; 928 // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
833 odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed 929 odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
834 << " ms, mapping: " << t3needed << " ms" << oendl; 930 << " ms, mapping: " << t3needed << " ms" << oendl;
835 931
836 return nonCustomMap; 932 return nonCustomMap;
837} 933}
838 934
839/* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ 935/* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */
840OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const 936OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const UIDArray& uidlist )const
841{ 937{
842 // We want to get all contacts with one query. 938 // We want to get all contacts with one query.
843 // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). 939 // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h).
844 // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned 940 // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned
845 // by using the cache.. 941 // by using the cache..
846 QArray<int> cachelist = uidlist; 942 UIDArray cachelist = uidlist;
847 OPimContact retContact; 943 OPimContact retContact;
848 944
849 odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; 945 odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl;
850 946
851 QTime t; 947 QTime t;
852 t.start(); 948 t.start();
853 949
854 int t2needed = 0; 950 int t2needed = 0;
855 int t3needed = 0; 951 int t3needed = 0;
856 QTime t2; 952 QTime t2;
857 t2.start(); 953 t2.start();
858 FindQuery query( cachelist ); 954 FindQuery query( cachelist );
859 OSQLResult res_noncustom = m_driver->query( &query ); 955 OSQLResult res_noncustom = m_driver->query( &query );
860 t2needed = t2.elapsed(); 956 t2needed = t2.elapsed();
861 957
862 QMap<int, QString> nonCustomMap; 958 QMap<int, QString> nonCustomMap;
863 QTime t3; 959 QTime t3;
864 t3.start(); 960 t3.start();
865 OSQLResultItem resItem = res_noncustom.first(); 961 OSQLResultItem resItem = res_noncustom.first();
866 do { 962 do {
867 OPimContact contact( fillNonCustomMap( resItem ) ); 963 OPimContact contact( fillNonCustomMap( resItem ) );
868 contact.setExtraMap( requestCustom( contact.uid() ) ); 964 contact.setExtraMap( requestCustom( contact.uid() ) );
869 odebug << "Caching uid: " << contact.uid() << oendl; 965 odebug << "Caching uid: " << contact.uid() << oendl;
870 cache( contact ); 966 cache( contact );
871 if ( contact.uid() == uid ) 967 if ( contact.uid() == uid )
872 retContact = contact; 968 retContact = contact;
873 resItem = res_noncustom.next(); 969 resItem = res_noncustom.next();
874 } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! 970 } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !!
875 t3needed = t3.elapsed(); 971 t3needed = t3.elapsed();
876 972
877 973
878 // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; 974 // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
879 odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed 975 odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
880 << " ms, mapping: " << t3needed << " ms" << oendl; 976 << " ms, mapping: " << t3needed << " ms" << oendl;
881 977
882 return retContact; 978 return retContact;
883} 979}
884 980
885QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const 981QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const
886{ 982{
887 QMap<int, QString> nonCustomMap; 983 QMap<int, QString> nonCustomMap;
888 984
889 // Now loop through all columns 985 // Now loop through all columns
890 QStringList fieldList = OPimContactFields::untrfields( false ); 986 QStringList fieldList = OPimContactFields::untrfields( false );
891 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 987 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
892 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 988 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
893 // Get data for the selected column and store it with the 989 // Get data for the selected column and store it with the
894 // corresponding id into the map.. 990 // corresponding id into the map..
895 991
896 int id = translate[*it]; 992 int id = translate[*it];
897 QString value = resultItem.data( (*it) ); 993 QString value = resultItem.data( (*it) );
898 994
899 // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; 995 // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl;
900 996
901 switch( id ){ 997 switch( id ){
902 case Qtopia::Birthday: 998 case Qtopia::Birthday:
903 case Qtopia::Anniversary:{ 999 case Qtopia::Anniversary:{
904 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 1000 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
905 QStringList list = QStringList::split( '-', value ); 1001 QStringList list = QStringList::split( '-', value );
906 QStringList::Iterator lit = list.begin(); 1002 QStringList::Iterator lit = list.begin();
907 int year = (*lit).toInt(); 1003 int year = (*lit).toInt();
908 int month = (*(++lit)).toInt(); 1004 int month = (*(++lit)).toInt();
909 int day = (*(++lit)).toInt(); 1005 int day = (*(++lit)).toInt();
910 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ 1006 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
index 28d9746..299c175 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -9,106 +9,107 @@
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Contact Database. 30 * SQL Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#ifndef _OPimContactAccessBackend_SQL_ 33#ifndef _OPimContactAccessBackend_SQL_
34#define _OPimContactAccessBackend_SQL_ 34#define _OPimContactAccessBackend_SQL_
35 35
36#include <opie2/ocontactaccessbackend.h> 36#include <opie2/ocontactaccessbackend.h>
37#include <opie2/ocontactaccess.h> 37#include <opie2/ocontactaccess.h>
38 38
39#include <qlist.h> 39#include <qlist.h>
40#include <qdict.h> 40#include <qdict.h>
41 41
42/* aren't in namespace Opie yet - alwin */ 42/* aren't in namespace Opie yet - alwin */
43namespace Opie { 43namespace Opie {
44namespace DB { 44namespace DB {
45class OSQLDriver; 45class OSQLDriver;
46class OSQLResult; 46class OSQLResult;
47class OSQLResultItem; 47class OSQLResultItem;
48} 48}
49} 49}
50 50
51namespace Opie { 51namespace Opie {
52 52
53/* the default xml implementation */ 53/* the default xml implementation */
54/** 54/**
55 * This class is the SQL implementation of a Contact backend 55 * This class is the SQL implementation of a Contact backend
56 * it does implement everything available for OPimContact. 56 * it does implement everything available for OPimContact.
57 * @see OPimAccessBackend for more information of available methods 57 * @see OPimAccessBackend for more information of available methods
58 */ 58 */
59class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { 59class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
60 public: 60 public:
61 OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); 61 OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
62 62
63 ~OPimContactAccessBackend_SQL (); 63 ~OPimContactAccessBackend_SQL ();
64 64
65 bool save(); 65 bool save();
66 66
67 bool load (); 67 bool load ();
68 68
69 void clear (); 69 void clear ();
70 70
71 bool wasChangedExternally(); 71 bool wasChangedExternally();
72 72
73 QArray<int> allRecords() const; 73 UIDArray allRecords() const;
74 74
75 OPimContact find( int uid ) const; 75 OPimContact find( int uid ) const;
76 OPimContact find( int uid, const QArray<int>& items, uint cur, Frontend::CacheDirection ) const; 76 OPimContact find( int uid, const UIDArray& items, uint cur, Frontend::CacheDirection ) const;
77 77
78 QArray<int> queryByExample ( const OPimContact &query, int settings, 78 UIDArray queryByExample ( const OPimContact &query, int settings,
79 const QDateTime& d ); 79 const QDateTime& d ) const;
80 80
81 QArray<int> matchRegexp( const QRegExp &r ) const; 81 UIDArray matchRegexp( const QRegExp &r ) const;
82 82
83 const uint querySettings(); 83 const uint querySettings() const;
84 84
85 bool hasQuerySettings (uint querySettings) const; 85 bool hasQuerySettings (uint querySettings) const;
86 86
87 // Currently only asc implemented.. 87 UIDArray sorted( const UIDArray& ar, bool asc, int sortOrder,
88 QArray<int> sorted( bool asc, int , int , int ); 88 int filter, const QArray<int>& categories)const;
89 bool add ( const OPimContact &newcontact ); 89
90 bool add ( const OPimContact &newcontact );
90 91
91 bool replace ( const OPimContact &contact ); 92 bool replace ( const OPimContact &contact );
92 93
93 bool remove ( int uid ); 94 bool remove ( int uid );
94 bool reload(); 95 bool reload();
95 96
96 private: 97 private:
97 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; 98 UIDArray extractUids( Opie::DB::OSQLResult& res ) const;
98 QMap<int, QString> requestNonCustom( int uid ) const; 99 QMap<int, QString> requestNonCustom( int uid ) const;
99 QMap<QString, QString> requestCustom( int uid ) const; 100 QMap<QString, QString> requestCustom( int uid ) const;
100 QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const; 101 QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const;
101 OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const; 102 OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const;
102 void update(); 103 void update();
103 104
104 protected: 105 protected:
105 bool m_changed; 106 bool m_changed;
106 QString m_fileName; 107 QString m_fileName;
107 QArray<int> m_uids; 108 UIDArray m_uids;
108 109
109 Opie::DB::OSQLDriver* m_driver; 110 Opie::DB::OSQLDriver* m_driver;
110}; 111};
111 112
112} 113}
113 114
114#endif 115#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
index 5bb21c7..f3b6d56 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp
@@ -96,150 +96,140 @@ bool OPimContactAccessBackend_VCard::load ()
96} 96}
97bool OPimContactAccessBackend_VCard::reload() 97bool OPimContactAccessBackend_VCard::reload()
98{ 98{
99 return load(); 99 return load();
100} 100}
101bool OPimContactAccessBackend_VCard::save() 101bool OPimContactAccessBackend_VCard::save()
102{ 102{
103 if (!m_dirty ) 103 if (!m_dirty )
104 return true; 104 return true;
105 105
106 QFile file( m_file ); 106 QFile file( m_file );
107 if (!file.open(IO_WriteOnly ) ) 107 if (!file.open(IO_WriteOnly ) )
108 return false; 108 return false;
109 109
110 VObject *obj; 110 VObject *obj;
111 obj = newVObject( VCCalProp ); 111 obj = newVObject( VCCalProp );
112 addPropValue( obj, VCVersionProp, "1.0" ); 112 addPropValue( obj, VCVersionProp, "1.0" );
113 113
114 VObject *vo; 114 VObject *vo;
115 for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){ 115 for(QMap<int, OPimContact>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
116 vo = createVObject( *it ); 116 vo = createVObject( *it );
117 writeVObject( file.fh, vo ); //FIXME: HACK!!! 117 writeVObject( file.fh, vo ); //FIXME: HACK!!!
118 cleanVObject( vo ); 118 cleanVObject( vo );
119 } 119 }
120 cleanStrTbl(); 120 cleanStrTbl();
121 deleteVObject( obj ); 121 deleteVObject( obj );
122 122
123 m_dirty = false; 123 m_dirty = false;
124 return true; 124 return true;
125 125
126 126
127} 127}
128void OPimContactAccessBackend_VCard::clear () 128void OPimContactAccessBackend_VCard::clear ()
129{ 129{
130 m_map.clear(); 130 m_map.clear();
131 m_dirty = true; // ??? sure ? (se) 131 m_dirty = true; // ??? sure ? (se)
132} 132}
133 133
134bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact ) 134bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact )
135{ 135{
136 m_map.insert( newcontact.uid(), newcontact ); 136 m_map.insert( newcontact.uid(), newcontact );
137 m_dirty = true; 137 m_dirty = true;
138 return true; 138 return true;
139} 139}
140 140
141bool OPimContactAccessBackend_VCard::remove ( int uid ) 141bool OPimContactAccessBackend_VCard::remove ( int uid )
142{ 142{
143 m_map.remove( uid ); 143 m_map.remove( uid );
144 m_dirty = true; 144 m_dirty = true;
145 return true; 145 return true;
146} 146}
147 147
148bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) 148bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact )
149{ 149{
150 m_map.replace( contact.uid(), contact ); 150 m_map.replace( contact.uid(), contact );
151 m_dirty = true; 151 m_dirty = true;
152 return true; 152 return true;
153} 153}
154 154
155OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const 155OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const
156{ 156{
157 return m_map[uid]; 157 return m_map[uid];
158} 158}
159 159
160QArray<int> OPimContactAccessBackend_VCard::allRecords() const 160UIDArray OPimContactAccessBackend_VCard::allRecords() const
161{ 161{
162 QArray<int> ar( m_map.count() ); 162 UIDArray ar( m_map.count() );
163 QMap<int, OPimContact>::ConstIterator it; 163 QMap<int, OPimContact>::ConstIterator it;
164 int i = 0; 164 int i = 0;
165 for ( it = m_map.begin(); it != m_map.end(); ++it ) { 165 for ( it = m_map.begin(); it != m_map.end(); ++it ) {
166 ar[i] = it.key(); 166 ar[i] = it.key();
167 i++; 167 i++;
168 } 168 }
169 return ar; 169 return ar;
170} 170}
171 171
172const uint OPimContactAccessBackend_VCard::querySettings()
173{
174 return 0; // No search possible
175}
176
177bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const
178{
179 return false; // No search possible, therefore all settings invalid ;)
180}
181
182bool OPimContactAccessBackend_VCard::wasChangedExternally() 172bool OPimContactAccessBackend_VCard::wasChangedExternally()
183{ 173{
184 return false; // Don't expect concurrent access 174 return false; // Don't expect concurrent access
185} 175}
186 176
187// *** Private stuff *** 177// *** Private stuff ***
188OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) 178OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj )
189{ 179{
190 OPimContact c; 180 OPimContact c;
191 VObjectIterator it; 181 VObjectIterator it;
192 initPropIterator( &it, obj ); 182 initPropIterator( &it, obj );
193 while( moreIteration( &it ) ) { 183 while( moreIteration( &it ) ) {
194 VObject *o = nextVObject( &it ); 184 VObject *o = nextVObject( &it );
195 QCString name = vObjectName( o ); 185 QCString name = vObjectName( o );
196 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 186 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
197 odebug << "(1)Read: " << name << " " << QString( value ).latin1() << oendl; 187 odebug << "(1)Read: " << name << " " << QString( value ).latin1() << oendl;
198 if ( name == VCVersionProp ) { 188 if ( name == VCVersionProp ) {
199 189
200 odebug << "Version: " << value << oendl; 190 odebug << "Version: " << value << oendl;
201 QStringList version = QStringList::split( ".", value ); 191 QStringList version = QStringList::split( ".", value );
202 version_major = version[0].toUInt(); 192 version_major = version[0].toUInt();
203 version_minor = version[1].toUInt(); 193 version_minor = version[1].toUInt();
204 odebug << "Major: "<< version_major << " Minor: " << version_minor << oendl; 194 odebug << "Major: "<< version_major << " Minor: " << version_minor << oendl;
205 195
206 } 196 }
207 else if ( name == VCNameProp ) { 197 else if ( name == VCNameProp ) {
208 VObjectIterator nit; 198 VObjectIterator nit;
209 initPropIterator( &nit, o ); 199 initPropIterator( &nit, o );
210 while( moreIteration( &nit ) ) { 200 while( moreIteration( &nit ) ) {
211 VObject *o = nextVObject( &nit ); 201 VObject *o = nextVObject( &nit );
212 QCString name = vObjectTypeInfo( o ); 202 QCString name = vObjectTypeInfo( o );
213 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 203 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
214 odebug << "Nametype is: "<< name << " Value: " << value.latin1() << oendl; 204 odebug << "Nametype is: "<< name << " Value: " << value.latin1() << oendl;
215 if ( name == VCNamePrefixesProp ) 205 if ( name == VCNamePrefixesProp )
216 c.setTitle( value ); 206 c.setTitle( value );
217 else if ( name == VCNameSuffixesProp ) 207 else if ( name == VCNameSuffixesProp )
218 c.setSuffix( value ); 208 c.setSuffix( value );
219 else if ( name == VCFamilyNameProp ) 209 else if ( name == VCFamilyNameProp )
220 c.setLastName( value ); 210 c.setLastName( value );
221 else if ( name == VCGivenNameProp ) 211 else if ( name == VCGivenNameProp )
222 c.setFirstName( value ); 212 c.setFirstName( value );
223 else if ( name == VCAdditionalNamesProp ) 213 else if ( name == VCAdditionalNamesProp )
224 c.setMiddleName( value ); 214 c.setMiddleName( value );
225 } 215 }
226 } 216 }
227 else if ( name == VCAdrProp ) { 217 else if ( name == VCAdrProp ) {
228 bool work = TRUE; // default address is work address 218 bool work = TRUE; // default address is work address
229 QString street; 219 QString street;
230 QString city; 220 QString city;
231 QString region; 221 QString region;
232 QString postal; 222 QString postal;
233 QString country; 223 QString country;
234 224
235 VObjectIterator nit; 225 VObjectIterator nit;
236 initPropIterator( &nit, o ); 226 initPropIterator( &nit, o );
237 while( moreIteration( &nit ) ) { 227 while( moreIteration( &nit ) ) {
238 VObject *o = nextVObject( &nit ); 228 VObject *o = nextVObject( &nit );
239 QCString name = vObjectTypeInfo( o ); 229 QCString name = vObjectTypeInfo( o );
240 QString value = QString::fromUtf8( vObjectStringZValue( o ) ); 230 QString value = QString::fromUtf8( vObjectStringZValue( o ) );
241 odebug << "AddressType is: "<< name << " Value: " << value.latin1() << oendl; 231 odebug << "AddressType is: "<< name << " Value: " << value.latin1() << oendl;
242 if ( name == VCHomeProp ) 232 if ( name == VCHomeProp )
243 work = FALSE; 233 work = FALSE;
244 else if ( name == VCWorkProp ) 234 else if ( name == VCWorkProp )
245 work = TRUE; 235 work = TRUE;
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
index b734530..3591988 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h
@@ -1,89 +1,87 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * VCard Backend for the OPIE-Contact Database. 30 * VCard Backend for the OPIE-Contact Database.
31 */ 31 */
32#ifndef __OCONTACTACCESSBACKEND_VCARD_H_ 32#ifndef __OCONTACTACCESSBACKEND_VCARD_H_
33#define __OCONTACTACCESSBACKEND_VCARD_H_ 33#define __OCONTACTACCESSBACKEND_VCARD_H_
34 34
35#include <opie2/opimcontact.h> 35#include <opie2/opimcontact.h>
36 36
37#include <opie2/ocontactaccessbackend.h> 37#include <opie2/ocontactaccessbackend.h>
38 38
39class VObject; 39class VObject;
40 40
41namespace Opie { 41namespace Opie {
42/** 42/**
43 * This is the vCard 2.1 implementation of the Contact Storage 43 * This is the vCard 2.1 implementation of the Contact Storage
44 * @see OPimContactAccessBackend_XML 44 * @see OPimContactAccessBackend_XML
45 * @see OPimAccessBackend 45 * @see OPimAccessBackend
46 */ 46 */
47class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { 47class OPimContactAccessBackend_VCard : public OPimContactAccessBackend {
48 public: 48 public:
49 OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); 49 OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null );
50 50
51 bool load (); 51 bool load ();
52 bool reload(); 52 bool reload();
53 bool save(); 53 bool save();
54 void clear (); 54 void clear ();
55 55
56 bool add ( const OPimContact& newcontact ); 56 bool add ( const OPimContact& newcontact );
57 bool remove ( int uid ); 57 bool remove ( int uid );
58 bool replace ( const OPimContact& contact ); 58 bool replace ( const OPimContact& contact );
59 59
60 OPimContact find ( int uid ) const; 60 OPimContact find ( int uid ) const;
61 QArray<int> allRecords() const; 61 UIDArray allRecords() const;
62 62
63 const uint querySettings();
64 bool hasQuerySettings (uint querySettings) const;
65 bool wasChangedExternally(); 63 bool wasChangedExternally();
66 64
67private: 65private:
68 OPimContact parseVObject( VObject* obj ); 66 OPimContact parseVObject( VObject* obj );
69 VObject* createVObject( const OPimContact& c ); 67 VObject* createVObject( const OPimContact& c );
70 QString convDateToVCardDate( const QDate& c ) const; 68 QString convDateToVCardDate( const QDate& c ) const;
71 QDate convVCardDateToDate( const QString& datestr ); 69 QDate convVCardDateToDate( const QString& datestr );
72 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); 70 VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value );
73 VObject *safeAddProp( VObject* o, const char* prop); 71 VObject *safeAddProp( VObject* o, const char* prop);
74 72
75 bool m_dirty : 1; 73 bool m_dirty : 1;
76 QString m_file; 74 QString m_file;
77 QMap<int, OPimContact> m_map; 75 QMap<int, OPimContact> m_map;
78 76
79 /** 77 /**
80 * Version of parsed VCard 78 * Version of parsed VCard
81 */ 79 */
82 uint version_major; 80 uint version_major;
83 uint version_minor; 81 uint version_minor;
84 82
85}; 83};
86 84
87} 85}
88 86
89#endif 87#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 5df7253..f96f1bf 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -122,375 +122,182 @@ bool OPimContactAccessBackend_XML::save()
122 out = ""; 122 out = "";
123 } 123 }
124 out += " </Contacts>\n</AddressBook>\n"; 124 out += " </Contacts>\n</AddressBook>\n";
125 125
126 // Write Footer 126 // Write Footer
127 cstr = out.utf8(); 127 cstr = out.utf8();
128 total_written = f.writeBlock( cstr.data(), cstr.length() ); 128 total_written = f.writeBlock( cstr.data(), cstr.length() );
129 if ( total_written != int( cstr.length() ) ) { 129 if ( total_written != int( cstr.length() ) ) {
130 f.close(); 130 f.close();
131 QFile::remove( strNewFile ); 131 QFile::remove( strNewFile );
132 return false; 132 return false;
133 } 133 }
134 f.close(); 134 f.close();
135 135
136 // move the file over, I'm just going to use the system call 136 // move the file over, I'm just going to use the system call
137 // because, I don't feel like using QDir. 137 // because, I don't feel like using QDir.
138 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 138 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
139 // remove the tmp file... 139 // remove the tmp file...
140 QFile::remove( strNewFile ); 140 QFile::remove( strNewFile );
141 } 141 }
142 142
143 /* The journalfile should be removed now... */ 143 /* The journalfile should be removed now... */
144 removeJournal(); 144 removeJournal();
145 145
146 m_changed = false; 146 m_changed = false;
147 return true; 147 return true;
148} 148}
149 149
150bool OPimContactAccessBackend_XML::load () 150bool OPimContactAccessBackend_XML::load ()
151{ 151{
152 m_contactList.clear(); 152 m_contactList.clear();
153 m_uidToContact.clear(); 153 m_uidToContact.clear();
154 154
155 /* Load XML-File and journal if it exists */ 155 /* Load XML-File and journal if it exists */
156 if ( !load ( m_fileName, false ) ) 156 if ( !load ( m_fileName, false ) )
157 return false; 157 return false;
158 /* The returncode of the journalfile is ignored due to the 158 /* The returncode of the journalfile is ignored due to the
159 * fact that it does not exist when this class is instantiated ! 159 * fact that it does not exist when this class is instantiated !
160 * But there may such a file exist, if the application crashed. 160 * But there may such a file exist, if the application crashed.
161 * Therefore we try to load it to get the changes before the # 161 * Therefore we try to load it to get the changes before the #
162 * crash happened... 162 * crash happened...
163 */ 163 */
164 load (m_journalName, true); 164 load (m_journalName, true);
165 165
166 return true; 166 return true;
167} 167}
168 168
169void OPimContactAccessBackend_XML::clear () 169void OPimContactAccessBackend_XML::clear ()
170{ 170{
171 m_contactList.clear(); 171 m_contactList.clear();
172 m_uidToContact.clear(); 172 m_uidToContact.clear();
173 173
174 m_changed = false; 174 m_changed = false;
175} 175}
176 176
177bool OPimContactAccessBackend_XML::wasChangedExternally() 177bool OPimContactAccessBackend_XML::wasChangedExternally()
178{ 178{
179 QFileInfo fi( m_fileName ); 179 QFileInfo fi( m_fileName );
180 180
181 QDateTime lastmod = fi.lastModified (); 181 QDateTime lastmod = fi.lastModified ();
182 182
183 return (lastmod != m_readtime); 183 return (lastmod != m_readtime);
184} 184}
185 185
186QArray<int> OPimContactAccessBackend_XML::allRecords() const 186UIDArray OPimContactAccessBackend_XML::allRecords() const
187{ 187{
188 QArray<int> uid_list( m_contactList.count() ); 188 UIDArray uid_list( m_contactList.count() );
189 189
190 uint counter = 0; 190 uint counter = 0;
191 QListIterator<OPimContact> it( m_contactList ); 191 QListIterator<OPimContact> it( m_contactList );
192 for( ; it.current(); ++it ){ 192 for( ; it.current(); ++it ){
193 uid_list[counter++] = (*it)->uid(); 193 uid_list[counter++] = (*it)->uid();
194 } 194 }
195 195
196 return ( uid_list ); 196 return ( uid_list );
197} 197}
198 198
199OPimContact OPimContactAccessBackend_XML::find ( int uid ) const 199OPimContact OPimContactAccessBackend_XML::find ( int uid ) const
200{ 200{
201 OPimContact foundContact; //Create empty contact 201 OPimContact foundContact; //Create empty contact
202 202
203 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); 203 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) );
204 204
205 if ( found ){ 205 if ( found ){
206 foundContact = *found; 206 foundContact = *found;
207 } 207 }
208 208
209 return ( foundContact ); 209 return ( foundContact );
210} 210}
211 211
212QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings,
213 const QDateTime& d )const
214{
215 QArray<int> m_currentQuery( m_contactList.count() );
216 QListIterator<OPimContact> it( m_contactList );
217 uint arraycounter = 0;
218
219 for( ; it.current(); ++it ){
220 /* Search all fields and compare them with query object. Store them into list
221 * if all fields matches.
222 */
223 QDate* queryDate = 0l;
224 QDate* checkDate = 0l;
225 bool allcorrect = true;
226 for ( int i = 0; i < Qtopia::Groups; i++ ) {
227 // Birthday and anniversary are special nonstring fields and should
228 // be handled specially
229 switch ( i ){
230 case Qtopia::Birthday:
231 queryDate = new QDate( query.birthday() );
232 checkDate = new QDate( (*it)->birthday() );
233 // fall through
234 case Qtopia::Anniversary:
235 if ( queryDate == 0l ){
236 queryDate = new QDate( query.anniversary() );
237 checkDate = new QDate( (*it)->anniversary() );
238 }
239
240 if ( queryDate->isValid() ){
241 if( checkDate->isValid() ){
242 if ( settings & OPimContactAccess::DateYear ){
243 if ( queryDate->year() != checkDate->year() )
244 allcorrect = false;
245 }
246 if ( settings & OPimContactAccess::DateMonth ){
247 if ( queryDate->month() != checkDate->month() )
248 allcorrect = false;
249 }
250 if ( settings & OPimContactAccess::DateDay ){
251 if ( queryDate->day() != checkDate->day() )
252 allcorrect = false;
253 }
254 if ( settings & OPimContactAccess::DateDiff ) {
255 QDate current;
256 // If we get an additional date, we
257 // will take this date instead of
258 // the current one..
259 if ( !d.date().isValid() )
260 current = QDate::currentDate();
261 else
262 current = d.date();
263
264 // We have to equalize the year, otherwise
265 // the search will fail..
266 checkDate->setYMD( current.year(),
267 checkDate->month(),
268 checkDate->day() );
269 if ( *checkDate < current )
270 checkDate->setYMD( current.year()+1,
271 checkDate->month(),
272 checkDate->day() );
273
274 // Check whether the birthday/anniversary date is between
275 // the current/given date and the maximum date
276 // ( maximum time range ) !
277 if ( current.daysTo( *queryDate ) >= 0 ){
278 if ( !( ( *checkDate >= current ) &&
279 ( *checkDate <= *queryDate ) ) ){
280 allcorrect = false;
281 }
282 }
283 }
284 } else{
285 // checkDate is invalid. Therefore this entry is always rejected
286 allcorrect = false;
287 }
288 }
289 212
290 delete queryDate; 213UIDArray OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
291 queryDate = 0l;
292 delete checkDate;
293 checkDate = 0l;
294 break;
295 default:
296 /* Just compare fields which are not empty in the query object */
297 if ( !query.field(i).isEmpty() ){
298 switch ( settings & ~( OPimContactAccess::IgnoreCase
299 | OPimContactAccess::DateDiff
300 | OPimContactAccess::DateYear
301 | OPimContactAccess::DateMonth
302 | OPimContactAccess::DateDay
303 | OPimContactAccess::MatchOne
304 ) ){
305
306 case OPimContactAccess::RegExp:{
307 QRegExp expr ( query.field(i),
308 !(settings & OPimContactAccess::IgnoreCase),
309 false );
310 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
311 allcorrect = false;
312 }
313 break;
314 case OPimContactAccess::WildCards:{
315 QRegExp expr ( query.field(i),
316 !(settings & OPimContactAccess::IgnoreCase),
317 true );
318 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
319 allcorrect = false;
320 }
321 break;
322 case OPimContactAccess::ExactMatch:{
323 if (settings & OPimContactAccess::IgnoreCase){
324 if ( query.field(i).upper() !=
325 (*it)->field(i).upper() )
326 allcorrect = false;
327 }else{
328 if ( query.field(i) != (*it)->field(i) )
329 allcorrect = false;
330 }
331 }
332 break;
333 }
334 }
335 }
336 }
337 if ( allcorrect ){
338 m_currentQuery[arraycounter++] = (*it)->uid();
339 }
340 }
341
342 // Shrink to fit..
343 m_currentQuery.resize(arraycounter);
344
345 return m_currentQuery;
346}
347
348QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
349{ 214{
350 QArray<int> m_currentQuery( m_contactList.count() ); 215 UIDArray m_currentQuery( m_contactList.count() );
351 QListIterator<OPimContact> it( m_contactList ); 216 QListIterator<OPimContact> it( m_contactList );
352 uint arraycounter = 0; 217 uint arraycounter = 0;
353 218
354 for( ; it.current(); ++it ){ 219 for( ; it.current(); ++it ){
355 if ( (*it)->match( r ) ){ 220 if ( (*it)->match( r ) ){
356 m_currentQuery[arraycounter++] = (*it)->uid(); 221 m_currentQuery[arraycounter++] = (*it)->uid();
357 } 222 }
358 223
359 } 224 }
360 // Shrink to fit.. 225 // Shrink to fit..
361 m_currentQuery.resize(arraycounter); 226 m_currentQuery.resize(arraycounter);
362 227
363 return m_currentQuery; 228 return m_currentQuery;
364} 229}
365 230
366const uint OPimContactAccessBackend_XML::querySettings()
367{
368 return ( OPimContactAccess::WildCards
369 | OPimContactAccess::IgnoreCase
370 | OPimContactAccess::RegExp
371 | OPimContactAccess::ExactMatch
372 | OPimContactAccess::DateDiff
373 | OPimContactAccess::DateYear
374 | OPimContactAccess::DateMonth
375 | OPimContactAccess::DateDay
376 );
377}
378 231
379bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
380{
381 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
382 * may be added with any of the other settings. IgnoreCase should never used alone.
383 * Wildcards, RegExp, ExactMatch should never used at the same time...
384 */
385
386 // Step 1: Check whether the given settings are supported by this backend
387 if ( ( querySettings & (
388 OPimContactAccess::IgnoreCase
389 | OPimContactAccess::WildCards
390 | OPimContactAccess::DateDiff
391 | OPimContactAccess::DateYear
392 | OPimContactAccess::DateMonth
393 | OPimContactAccess::DateDay
394 | OPimContactAccess::RegExp
395 | OPimContactAccess::ExactMatch
396 ) ) != querySettings )
397 return false;
398
399 // Step 2: Check whether the given combinations are ok..
400
401 // IngoreCase alone is invalid
402 if ( querySettings == OPimContactAccess::IgnoreCase )
403 return false;
404
405 // WildCards, RegExp and ExactMatch should never used at the same time
406 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
407 | OPimContactAccess::DateDiff
408 | OPimContactAccess::DateYear
409 | OPimContactAccess::DateMonth
410 | OPimContactAccess::DateDay
411 )
412 ){
413 case OPimContactAccess::RegExp:
414 return ( true );
415 case OPimContactAccess::WildCards:
416 return ( true );
417 case OPimContactAccess::ExactMatch:
418 return ( true );
419 case 0: // one of the upper removed bits were set..
420 return ( true );
421 default:
422 return ( false );
423 }
424}
425 232
426#if 0 233#if 0
427// Currently only asc implemented.. 234// Currently only asc implemented..
428QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) 235UIDArray OPimContactAccessBackend_XML::sorted( bool asc, int , int , int )
429{ 236{
430 QMap<QString, int> nameToUid; 237 QMap<QString, int> nameToUid;
431 QStringList names; 238 QStringList names;
432 QArray<int> m_currentQuery( m_contactList.count() ); 239 UIDArray m_currentQuery( m_contactList.count() );
433 240
434 // First fill map and StringList with all Names 241 // First fill map and StringList with all Names
435 // Afterwards sort namelist and use map to fill array to return.. 242 // Afterwards sort namelist and use map to fill array to return..
436 QListIterator<OPimContact> it( m_contactList ); 243 QListIterator<OPimContact> it( m_contactList );
437 for( ; it.current(); ++it ){ 244 for( ; it.current(); ++it ){
438 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 245 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
439 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 246 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
440 } 247 }
441 names.sort(); 248 names.sort();
442 249
443 int i = 0; 250 int i = 0;
444 if ( asc ){ 251 if ( asc ){
445 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 252 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
446 m_currentQuery[i++] = nameToUid[ (*it) ]; 253 m_currentQuery[i++] = nameToUid[ (*it) ];
447 }else{ 254 }else{
448 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 255 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
449 m_currentQuery[i++] = nameToUid[ (*it) ]; 256 m_currentQuery[i++] = nameToUid[ (*it) ];
450 } 257 }
451 258
452 return m_currentQuery; 259 return m_currentQuery;
453 260
454} 261}
455#endif 262#endif
456 263
457 264
458bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) 265bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact )
459{ 266{
460 updateJournal (newcontact, ACTION_ADD); 267 updateJournal (newcontact, ACTION_ADD);
461 addContact_p( newcontact ); 268 addContact_p( newcontact );
462 269
463 m_changed = true; 270 m_changed = true;
464 271
465 return true; 272 return true;
466} 273}
467 274
468bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) 275bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact )
469{ 276{
470 m_changed = true; 277 m_changed = true;
471 278
472 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 279 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
473 280
474 if ( found ) { 281 if ( found ) {
475 OPimContact* newCont = new OPimContact( contact ); 282 OPimContact* newCont = new OPimContact( contact );
476 283
477 updateJournal ( *newCont, ACTION_REPLACE); 284 updateJournal ( *newCont, ACTION_REPLACE);
478 m_contactList.removeRef ( found ); 285 m_contactList.removeRef ( found );
479 m_contactList.append ( newCont ); 286 m_contactList.append ( newCont );
480 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 287 m_uidToContact.remove( QString().setNum( contact.uid() ) );
481 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 288 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
482 289
483 return true; 290 return true;
484 } else 291 } else
485 return false; 292 return false;
486} 293}
487 294
488bool OPimContactAccessBackend_XML::remove ( int uid ) 295bool OPimContactAccessBackend_XML::remove ( int uid )
489{ 296{
490 m_changed = true; 297 m_changed = true;
491 298
492 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 299 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) );
493 300
494 if ( found ) { 301 if ( found ) {
495 updateJournal ( *found, ACTION_REMOVE); 302 updateJournal ( *found, ACTION_REMOVE);
496 m_contactList.removeRef ( found ); 303 m_contactList.removeRef ( found );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index 3e4f1e1..39378ec 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,105 +1,100 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * XML Backend for the OPIE-Contact Database. 30 * XML Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#ifndef _OPimContactAccessBackend_XML_ 33#ifndef _OPimContactAccessBackend_XML_
34#define _OPimContactAccessBackend_XML_ 34#define _OPimContactAccessBackend_XML_
35 35
36#include <opie2/ocontactaccessbackend.h> 36#include <opie2/ocontactaccessbackend.h>
37#include <opie2/ocontactaccess.h> 37#include <opie2/ocontactaccess.h>
38 38
39#include <qlist.h> 39#include <qlist.h>
40#include <qdict.h> 40#include <qdict.h>
41 41
42namespace Opie { 42namespace Opie {
43/* the default xml implementation */ 43/* the default xml implementation */
44/** 44/**
45 * This class is the XML implementation of a Contact backend 45 * This class is the XML implementation of a Contact backend
46 * it does implement everything available for OPimContact. 46 * it does implement everything available for OPimContact.
47 * @see OPimAccessBackend for more information of available methods 47 * @see OPimAccessBackend for more information of available methods
48 */ 48 */
49class OPimContactAccessBackend_XML : public OPimContactAccessBackend { 49class OPimContactAccessBackend_XML : public OPimContactAccessBackend {
50 public: 50 public:
51 OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); 51 OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null );
52 52
53 bool save(); 53 bool save();
54 54
55 bool load (); 55 bool load ();
56 56
57 void clear (); 57 void clear ();
58 58
59 bool wasChangedExternally(); 59 bool wasChangedExternally();
60 60
61 QArray<int> allRecords() const; 61 UIDArray allRecords() const;
62 62
63 OPimContact find ( int uid ) const; 63 OPimContact find ( int uid ) const;
64 64
65 QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d )const; 65 UIDArray matchRegexp( const QRegExp &r ) const;
66 QArray<int> matchRegexp( const QRegExp &r ) const;
67
68 const uint querySettings();
69
70 bool hasQuerySettings (uint querySettings) const;
71 66
72 bool add ( const OPimContact &newcontact ); 67 bool add ( const OPimContact &newcontact );
73 68
74 bool replace ( const OPimContact &contact ); 69 bool replace ( const OPimContact &contact );
75 70
76 bool remove ( int uid ); 71 bool remove ( int uid );
77 bool reload(); 72 bool reload();
78 73
79 private: 74 private:
80 75
81 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 76 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
82 77
83 void addContact_p( const OPimContact &newcontact ); 78 void addContact_p( const OPimContact &newcontact );
84 79
85 /* This function loads the xml-database and the journalfile */ 80 /* This function loads the xml-database and the journalfile */
86 bool load( const QString filename, bool isJournal ); 81 bool load( const QString filename, bool isJournal );
87 82
88 83
89 void updateJournal( const OPimContact& cnt, journal_action action ); 84 void updateJournal( const OPimContact& cnt, journal_action action );
90 void removeJournal(); 85 void removeJournal();
91 86
92 protected: 87 protected:
93 bool m_changed; 88 bool m_changed;
94 QString m_journalName; 89 QString m_journalName;
95 QString m_fileName; 90 QString m_fileName;
96 QString m_appName; 91 QString m_appName;
97 QList<OPimContact> m_contactList; 92 QList<OPimContact> m_contactList;
98 QDateTime m_readtime; 93 QDateTime m_readtime;
99 94
100 QDict<OPimContact> m_uidToContact; 95 QDict<OPimContact> m_uidToContact;
101}; 96};
102 97
103} 98}
104 99
105#endif 100#endif
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
index 0d112c9..7321758 100644
--- a/libopie2/opiepim/backend/opimaccessbackend.h
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -5,229 +5,251 @@
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_PIM_ACCESS_BACKEND 29#ifndef OPIE_PIM_ACCESS_BACKEND
30#define OPIE_PIM_ACCESS_BACKEND 30#define OPIE_PIM_ACCESS_BACKEND
31 31
32#include <qarray.h> 32#include <qarray.h>
33#include <qdatetime.h> 33#include <qdatetime.h>
34 34
35#include <opie2/opimtemplatebase.h> 35#include <opie2/opimtemplatebase.h>
36#include <opie2/opimrecord.h> 36#include <opie2/opimrecord.h>
37#include <opie2/opimbackendoccurrence.h> 37#include <opie2/opimbackendoccurrence.h>
38 38
39namespace Opie { 39namespace Opie {
40class OPimAccessBackendPrivate; 40class OPimAccessBackendPrivate;
41 41
42/** 42/**
43 * OPimAccessBackend is the Backend Interface to be used 43 * OPimAccessBackend is the Backend Interface to be used
44 * by OTemplateBase based Frontends. 44 * by OTemplateBase based Frontends.
45 * For efficency reasons and to support delayed loading 45 * For efficency reasons and to support delayed loading
46 * most of the Frontend functions can be implemented 46 * most of the Frontend functions can be implemented
47 * by this backend. 47 * by this backend.
48 * This allows to utilise the best method on each backend. 48 * This allows to utilise the best method on each backend.
49 * For example we can use SQL queries instead of self made 49 * For example we can use SQL queries instead of self made
50 * query which is first more efficent and also uses less memory. 50 * query which is first more efficent and also uses less memory.
51 */ 51 */
52template <class T = OPimRecord> 52template <class T = OPimRecord>
53class OPimAccessBackend { 53class OPimAccessBackend {
54public: 54public:
55 typedef OTemplateBase<T> Frontend; 55 typedef OTemplateBase<T> Frontend;
56 56
57 //@{ 57 //@{
58 OPimAccessBackend(int access = 0); 58 OPimAccessBackend(int access = 0);
59 virtual ~OPimAccessBackend(); 59 virtual ~OPimAccessBackend();
60 //@} 60 //@}
61 61
62 //@{ 62 //@{
63 virtual bool load() = 0; 63 virtual bool load() = 0;
64 virtual bool reload() = 0; 64 virtual bool reload() = 0;
65 virtual bool save() = 0; 65 virtual bool save() = 0;
66 virtual void clear() = 0; 66 virtual void clear() = 0;
67 //@} 67 //@}
68 68
69 //@{
70 // FIXME: Uncommented some of the abstract functions below. This should be removed as they are implemented in
71 // all typespecifc backenends (eilers)
72 /**
73 * Return all possible settings for queryByExample()
74 * @return All settings provided by the current backend
75 * (i.e.: query_WildCards & query_IgnoreCase)
76 * See implementation in the specific backends for contacts, todo and dates.
77 */
78 virtual const uint querySettings() const { return 0; } /* FIXME: Make Abstrakt !! = 0; */
79
80 /**
81 * Check whether settings are correct for queryByExample()
82 * See implementation in the specific backends for OPimContactAccess, OPimTodoAccess and ODateBookAccess.
83 * @return <i>true</i> if the given settings are correct and possible.
84 */
85 virtual bool hasQuerySettings (uint querySettings) const { return false; } /* FIXME: Make Abstrakt !! = 0; */
86 //@}
87
69 88
70 //@{ 89 //@{
71 virtual UIDArray allRecords()const = 0; 90 virtual UIDArray allRecords()const = 0;
72 virtual UIDArray matchRegexp(const QRegExp &r) const; 91 virtual UIDArray matchRegexp(const QRegExp &r) const;
73 virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const = 0; 92 virtual UIDArray queryByExample( const UIDArray&, const T& t,
74 virtual UIDArray queryByExample( const OPimRecord* rec, int, const QDateTime& d = QDateTime() )const; 93 int settings, const QDateTime& d = QDateTime() )const { return UIDArray(); } /* FIXME: Make Abstrakt !! = 0; */
75 virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; 94 virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const;
95 virtual UIDArray queryByExample( const OPimRecord* rec, int settings, const QDateTime& d = QDateTime() )const;
96 virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const = 0;
76 virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; 97 virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const;
77 virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const; 98 virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const;
78 virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const; 99 virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const;
79 //@} 100 //@}
80 101
81 102
82 //@{ 103 //@{
83 virtual T find(UID uid )const = 0; 104 virtual T find(UID uid )const = 0;
84 virtual T find(UID uid, const QArray<UID>& items, 105 virtual T find(UID uid, const QArray<UID>& items,
85 uint current, typename Frontend::CacheDirection )const ; 106 uint current, typename Frontend::CacheDirection )const ;
86 //@} 107 //@}
87 108
88 109
89 //@{ 110 //@{
90 virtual bool add( const T& t ) = 0; 111 virtual bool add( const T& t ) = 0;
91 virtual bool remove( UID uid ) = 0; 112 virtual bool remove( UID uid ) = 0;
92 virtual bool replace( const T& t ) = 0; 113 virtual bool replace( const T& t ) = 0;
93 //@} 114 //@}
94 115
95 116
96 117
97 void setFrontend( Frontend* front ); 118 void setFrontend( Frontend* front );
98 119
99 /** 120 /**
100 * set the read ahead count 121 * set the read ahead count
101 */ 122 */
102 void setReadAhead( uint count ); 123 void setReadAhead( uint count );
103protected: 124protected:
104 //@{ 125 //@{
105 int access()const; 126 int access()const;
106 void cache( const T& t )const; 127 void cache( const T& t )const;
107 void setSaneCacheSize( int ); 128 void setSaneCacheSize( int );
108 uint readAhead()const; 129 uint readAhead()const;
109 //@} 130 //@}
110 131
111private: 132private:
112 OPimAccessBackendPrivate *d; 133 OPimAccessBackendPrivate *d;
113 Frontend* m_front; 134 Frontend* m_front;
114 uint m_read; 135 uint m_read;
115 int m_acc; 136 int m_acc;
116 137
117}; 138};
118 139
119template <class T> 140template <class T>
120OPimAccessBackend<T>::OPimAccessBackend(int acc) 141OPimAccessBackend<T>::OPimAccessBackend(int acc)
121 : m_acc( acc ) 142 : m_acc( acc )
122{ 143{
123 m_front = 0l; 144 m_front = 0l;
124} 145}
125template <class T> 146template <class T>
126OPimAccessBackend<T>::~OPimAccessBackend() { 147OPimAccessBackend<T>::~OPimAccessBackend() {
127 148
128} 149}
129 150
130/* 151/*
131 * Slow but default matchRegexp Implementation 152 * Slow but default matchRegexp Implementation
132 * Create a Big Enough QArray and then iterate 153 * Create a Big Enough QArray and then iterate
133 * over all Records and matchRegexp them. 154 * over all Records and matchRegexp them.
134 * At the end we will resize the array to the actual 155 * At the end we will resize the array to the actual
135 * number of items 156 * number of items
136 */ 157 */
137template <class T> 158template <class T>
138UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const { 159UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const {
139 UIDArray all_rec = allRecords(); 160 UIDArray all_rec = allRecords();
140 UIDArray result( all_rec.count() ); 161 UIDArray result( all_rec.count() );
141 uint used_records = 0, all_rec_count = all_rec.count(); 162 uint used_records = 0, all_rec_count = all_rec.count();
142 163
143 for ( uint i = 0; i < all_rec_count; ++i ) 164 for ( uint i = 0; i < all_rec_count; ++i )
144 if (find( all_rec[i], all_rec, i, Frontend::Forward ).match( reg ) ) 165 if (find( all_rec[i], all_rec, i, Frontend::Forward ).match( reg ) )
145 result[used_records++] = all_rec[i]; 166 result[used_records++] = all_rec[i];
146 167
147 /* shrink to fit */ 168 /* shrink to fit */
148 result.resize( used_records ); 169 result.resize( used_records );
149 return result; 170 return result;
150} 171}
151 172
152template <class T> 173template <class T>
174UIDArray OPimAccessBackend<T>::queryByExample( const T& rec, int settings,
175 const QDateTime& datetime )const {
176
177 return queryByExample( allRecords(), rec, settings, datetime );
178}
179
180template <class T>
153UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings, 181UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings,
154 const QDateTime& datetime )const { 182 const QDateTime& datetime )const {
155 T* tmp_rec = T::safeCast( rec ); 183 T* tmp_rec = T::safeCast( rec );
156 UIDArray ar; 184 UIDArray ar;
157 if ( tmp_rec ) 185 if ( tmp_rec )
158 ar = queryByExample( *tmp_rec, settings, datetime ); 186 ar = queryByExample( *tmp_rec, settings, datetime );
159 187
160 return ar; 188 return ar;
161} 189}
162 190
163template <class T> 191template <class T>
164UIDArray OPimAccessBackend<T>::sorted( const UIDArray& ids, bool,
165 int, int, const QArray<int>& ) const {
166 return ids;
167}
168
169template <class T>
170UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter, 192UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter,
171 const QArray<int>& cats )const { 193 const QArray<int>& cats )const {
172 return sorted( allRecords(), asc, order, filter, cats ); 194 return sorted( allRecords(), asc, order, filter, cats );
173} 195}
174 196
175template<class T> 197template<class T>
176OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&, 198OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&,
177 const QDate& )const { 199 const QDate& )const {
178 return OPimBackendOccurrence::List(); 200 return OPimBackendOccurrence::List();
179} 201}
180 202
181template<class T> 203template<class T>
182OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDateTime& dt )const { 204OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDateTime& dt )const {
183 QDate date = dt.date(); 205 QDate date = dt.date();
184 return occurrences( date, date ); 206 return occurrences( date, date );
185} 207}
186 208
187template <class T> 209template <class T>
188void OPimAccessBackend<T>::setFrontend( Frontend* fr ) { 210void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
189 m_front = fr; 211 m_front = fr;
190} 212}
191template <class T> 213template <class T>
192void OPimAccessBackend<T>::cache( const T& t )const { 214void OPimAccessBackend<T>::cache( const T& t )const {
193 if ( m_front ) 215 if ( m_front )
194 m_front->cache( t ); 216 m_front->cache( t );
195} 217}
196 218
197template <class T> 219template <class T>
198void OPimAccessBackend<T>::setSaneCacheSize( int size) { 220void OPimAccessBackend<T>::setSaneCacheSize( int size) {
199 if ( m_front ) 221 if ( m_front )
200 m_front->setSaneCacheSize( size ); 222 m_front->setSaneCacheSize( size );
201} 223}
202template <class T> 224template <class T>
203T OPimAccessBackend<T>::find( int uid, const QArray<int>&, 225T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
204 uint, typename Frontend::CacheDirection ) const{ 226 uint, typename Frontend::CacheDirection ) const{
205 qDebug( "*** Lookahead feature not supported. Fallback to default find!!" ); 227 qDebug( "*** Lookahead feature not supported. Fallback to default find!!" );
206 return find( uid ); 228 return find( uid );
207} 229}
208template <class T> 230template <class T>
209void OPimAccessBackend<T>::setReadAhead( uint count ) { 231void OPimAccessBackend<T>::setReadAhead( uint count ) {
210 m_read = count; 232 m_read = count;
211} 233}
212template <class T> 234template <class T>
213uint OPimAccessBackend<T>::readAhead()const { 235uint OPimAccessBackend<T>::readAhead()const {
214 return m_read; 236 return m_read;
215} 237}
216template <class T> 238template <class T>
217int OPimAccessBackend<T>::access()const { 239int OPimAccessBackend<T>::access()const {
218 return m_acc; 240 return m_acc;
219} 241}
220 242
221} 243}
222 244
223/** 245/**
224 * \fn template <class T> OPimAccessBackend<T>::OPimAccessBackend(int hint ) 246 * \fn template <class T> OPimAccessBackend<T>::OPimAccessBackend(int hint )
225 * @param hint The access hint from the frontend 247 * @param hint The access hint from the frontend
226 */ 248 */
227 249
228/** 250/**
229 * \fn template <class T> bool OPimAccessBackend<T>::load() 251 * \fn template <class T> bool OPimAccessBackend<T>::load()
230 * Opens the DataBase and does necessary 252 * Opens the DataBase and does necessary
231 * initialisation of internal structures. 253 * initialisation of internal structures.
232 * 254 *
233 * @return true If the DataBase could be opened and 255 * @return true If the DataBase could be opened and
diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h
index 691ece2..bd85b4e 100644
--- a/libopie2/opiepim/core/ocontactaccess.h
+++ b/libopie2/opiepim/core/ocontactaccess.h
@@ -1,156 +1,177 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * ===================================================================== 30 * =====================================================================
31 * ToDo: Define enum for query settings 31 * ToDo: Define enum for query settings
32 * ===================================================================== 32 * =====================================================================
33 */ 33 */
34#ifndef _OCONTACTACCESS_H 34#ifndef _OCONTACTACCESS_H
35#define _OCONTACTACCESS_H 35#define _OCONTACTACCESS_H
36 36
37#include <qobject.h> 37#include <qobject.h>
38 38
39#include <qpe/qcopenvelope_qws.h> 39#include <qpe/qcopenvelope_qws.h>
40 40
41#include <qvaluelist.h> 41#include <qvaluelist.h>
42#include <qfileinfo.h> 42#include <qfileinfo.h>
43 43
44#include <opie2/opimcontact.h> 44#include <opie2/opimcontact.h>
45#include <opie2/ocontactaccessbackend.h> 45#include <opie2/ocontactaccessbackend.h>
46#include <opie2/opimaccesstemplate.h> 46#include <opie2/opimaccesstemplate.h>
47 47
48namespace Opie { 48namespace Opie {
49/** 49/**
50 * Class to access the contacts database. 50 * Class to access the contacts database.
51 * This is just a frontend for the real database handling which is 51 * This is just a frontend for the real database handling which is
52 * done by the backend. 52 * done by the backend.
53 * This class is used to access the Contacts on a system. This class as any OPIE PIM 53 * This class is used to access the Contacts on a system. This class as any OPIE PIM
54 * class is backend independent. 54 * class is backend independent.
55 * @author Stefan Eilers, Holger Freyther 55 * @author Stefan Eilers, Holger Freyther
56 * @see OPimAccessTemplate 56 * @see OPimAccessTemplate
57 */ 57 */
58class OPimContactAccess: public QObject, public OPimAccessTemplate<OPimContact> 58class OPimContactAccess: public QObject, public OPimAccessTemplate<OPimContact>
59{ 59{
60 Q_OBJECT 60 Q_OBJECT
61 61
62 public: 62 public:
63 /**
64 * Filter for sorted()
65 * @see SortFilterBase in OPimBase
66 */
63 enum SortFilter { 67 enum SortFilter {
64 DoNotShowNoneChildren = FilterCustom<<1, 68 /** Don't return entries who don't have children */
65 DoNotShowNoneAnniversary = FilterCustom<<2, 69 DoNotShowWithoutChildren = FilterCustom<<1,
66 DoNotShowNoneBirthday = FilterCustom<<3, 70 /** Don't return entries who don't have an anniversary */
67 DoNotShowNoHomeAddress = FilterCustom<<4, 71 DoNotShowWithoutAnniversary = FilterCustom<<2,
68 DoNotShowNoBusinessAddress = FilterCustom<<5 72 /** Don't return entries who don't have a birthday */
73 DoNotShowWithoutBirthday = FilterCustom<<3,
74 /** Don't return entries who don't have a home address */
75 DoNotShowWithoutHomeAddress = FilterCustom<<4,
76 /** Don't return entries who don't have a business address */
77 DoNotShowWithoutBusinessAddress = FilterCustom<<5,
78 /** Don't return entries which hava any category */
79 DoNotShowWithCategory = FilterCustom << 6
69 }; 80 };
70 81
82 /**
83 * Sort order for sorted()
84 * @see SortOrderBase in OPimBase
85 */
71 enum SortOrder { 86 enum SortOrder {
72 SortTitle = SortCustom, 87 SortTitle = SortCustom,
73 SortFirstName, 88 SortFirstName,
74 SortMiddleName, 89 SortMiddleName,
90 SortLastName,
75 SortSuffix, 91 SortSuffix,
76 SortEmail, 92 SortEmail,
77 SortNickname, 93 SortNickname,
94 SortFileAsName,
78 SortAnniversary, 95 SortAnniversary,
79 SortBirthday, 96 SortBirthday,
80 SortGender 97 SortGender
81 }; 98 };
82 99
83 /** 100 /**
84 * Create Database with contacts (addressbook). 101 * Create Database with contacts (addressbook).
85 * @param appname Name of application which wants access to the database 102 * @param appname Name of application which wants access to the database
86 * (i.e. "todolist") 103 * (i.e. "todolist")
87 * @param filename The name of the database file. If not set, the default one 104 * @param filename The name of the database file. If not set, the default one
88 * is used. 105 * is used.
89 * @param backend Pointer to an alternative Backend. If not set, we will use 106 * @param backend Pointer to an alternative Backend. If not set, we will use
90 * the default backend. 107 * the default backend.
91 * @param handlesync If <b>true</b> the database stores the current state 108 * @param handlesync If <b>true</b> the database stores the current state
92 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> 109 * automatically if it receives the signals <i>flush()</i> and <i>reload()</i>
93 * which are used before and after synchronisation. If the application wants 110 * which are used before and after synchronisation. If the application wants
94 * to react itself, it should be disabled by setting it to <b>false</b> 111 * to react itself, it should be disabled by setting it to <b>false</b>
95 * @see OPimContactAccessBackend 112 * @see OPimContactAccessBackend
96 */ 113 */
97 OPimContactAccess (const QString appname, const QString filename = 0l, 114 OPimContactAccess (const QString appname, const QString filename = 0l,
98 OPimContactAccessBackend* backend = 0l, bool handlesync = true); 115 OPimContactAccessBackend* backend = 0l, bool handlesync = true);
99 ~OPimContactAccess (); 116 ~OPimContactAccess ();
100 117
101 118
102 /** Return all possible settings. 119 /**
120 * Return all possible settings for queryByExample().
103 * @return All settings provided by the current backend 121 * @return All settings provided by the current backend
104 * (i.e.: query_WildCards & query_IgnoreCase) 122 * (i.e.: WildCards & IgnoreCase)
123 * @see QuerySettings in OPimBase for details of the parameter
105 */ 124 */
106 const uint querySettings(); 125 const uint querySettings();
107 126
108 /** Check whether settings are correct. 127 /**
128 * Check whether settings are correct for queryByExample().
109 * @return <i>true</i> if the given settings are correct and possible. 129 * @return <i>true</i> if the given settings are correct and possible.
130 * @see QuerySettings in OPimBase for details of the parameter
110 */ 131 */
111 bool hasQuerySettings ( int querySettings ) const; 132 bool hasQuerySettings ( int querySettings ) const;
112 133
113 /** 134 /**
114 * if the resource was changed externally. 135 * if the resource was changed externally.
115 * You should use the signal instead of polling possible changes ! 136 * You should use the signal instead of polling possible changes !
116 */ 137 */
117 bool wasChangedExternally()const; 138 bool wasChangedExternally()const;
118 139
119 140
120 /** Save contacts database. 141 /** Save contacts database.
121 * Save is more a "commit". After calling this function, all changes are public available. 142 * Save is more a "commit". After calling this function, all changes are public available.
122 * @return true if successful 143 * @return true if successful
123 */ 144 */
124 bool save(); 145 bool save();
125 146
126 /** 147 /**
127 * Return identification of used records 148 * Return identification of used records
128 */ 149 */
129 int rtti() const; 150 int rtti() const;
130 151
131 signals: 152 signals:
132 /* Signal is emitted if the database was changed. Therefore 153 /* Signal is emitted if the database was changed. Therefore
133 * we may need to reload to stay consistent. 154 * we may need to reload to stay consistent.
134 * @param which Pointer to the database who created this event. This pointer 155 * @param which Pointer to the database who created this event. This pointer
135 * is useful if an application has to handle multiple databases at the same time. 156 * is useful if an application has to handle multiple databases at the same time.
136 * @see reload() 157 * @see reload()
137 */ 158 */
138 void signalChanged ( const OPimContactAccess *which ); 159 void signalChanged ( const OPimContactAccess *which );
139 160
140 161
141 private: 162 private:
142 OPimContactAccessBackend *m_backEnd; 163 OPimContactAccessBackend *m_backEnd;
143 bool m_loading:1; 164 bool m_loading:1;
144 165
145 private slots: 166 private slots:
146 void copMessage( const QCString &msg, const QByteArray &data ); 167 void copMessage( const QCString &msg, const QByteArray &data );
147 168
148 private: 169 private:
149 class Private; 170 class Private;
150 Private *d; 171 Private *d;
151 172
152}; 173};
153 174
154} 175}
155 176
156#endif 177#endif
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
index 2deb92a..073d5f9 100644
--- a/libopie2/opiepim/core/opimaccesstemplate.h
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -29,301 +29,332 @@
29*/ 29*/
30#ifndef OPIE_PIM_ACCESS_TEMPLATE_H 30#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
31#define OPIE_PIM_ACCESS_TEMPLATE_H 31#define OPIE_PIM_ACCESS_TEMPLATE_H
32 32
33/* OPIE */ 33/* OPIE */
34#include <opie2/opimrecord.h> 34#include <opie2/opimrecord.h>
35#include <opie2/opimaccessbackend.h> 35#include <opie2/opimaccessbackend.h>
36#include <opie2/opimrecordlist.h> 36#include <opie2/opimrecordlist.h>
37 37
38#include <opie2/opimtemplatebase.h> 38#include <opie2/opimtemplatebase.h>
39#include <opie2/odebug.h> 39#include <opie2/odebug.h>
40 40
41/* QT */ 41/* QT */
42#include <qarray.h> 42#include <qarray.h>
43#include <qdatetime.h> 43#include <qdatetime.h>
44 44
45namespace Opie { 45namespace Opie {
46 46
47class OPimAccessTemplatePrivate; 47class OPimAccessTemplatePrivate;
48/** 48/**
49 * Thats the frontend to our OPIE PIM 49 * Thats the frontend to our OPIE PIM
50 * Library. Either you want to use it's 50 * Library. Either you want to use it's
51 * interface or you want to implement 51 * interface or you want to implement
52 * your own Access lib 52 * your own Access lib
53 * Just create a OPimRecord and inherit from 53 * Just create a OPimRecord and inherit from
54 * the templates 54 * the templates
55 */ 55 */
56 56
57template <class T = OPimRecord > 57template <class T = OPimRecord >
58class OPimAccessTemplate : public OTemplateBase<T> { 58class OPimAccessTemplate : public OTemplateBase<T> {
59public: 59public:
60 /** 60 /**
61 * 61 *
62 */ 62 */
63 enum Access { 63 enum Access {
64 Random = 0, 64 Random = 0,
65 SortedAccess 65 SortedAccess
66 }; 66 };
67 typedef OPimRecordList<T> List; 67 typedef OPimRecordList<T> List;
68 typedef OPimAccessBackend<T> BackEnd; 68 typedef OPimAccessBackend<T> BackEnd;
69 typedef OPimCache<T> Cache; 69 typedef OPimCache<T> Cache;
70 70
71 //@{ 71 //@{
72 OPimAccessTemplate( BackEnd* end); 72 OPimAccessTemplate( BackEnd* end);
73 virtual ~OPimAccessTemplate(); 73 virtual ~OPimAccessTemplate();
74 //@} 74 //@}
75 75
76 //@{ 76 //@{
77 bool load(); 77 bool load();
78 virtual bool reload(); 78 virtual bool reload();
79 bool save(); 79 bool save();
80 void clear() ; 80 void clear() ;
81 //@} 81 //@}
82 82
83 83
84 bool wasChangedExternally()const; 84 bool wasChangedExternally()const;
85 85
86 //@{ 86 //@{
87 virtual List allRecords()const; 87 virtual List allRecords()const;
88 virtual List matchRegexp( const QRegExp &r ) const; 88 virtual List matchRegexp( const QRegExp &r ) const;
89 virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); 89 virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() );
90 virtual T find( UID uid )const; 90 virtual T find( UID uid )const;
91 virtual T find( UID uid, const QArray<int>&, 91 virtual T find( UID uid, const QArray<int>&,
92 uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; 92 uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const;
93 virtual List sorted( const List&, bool ascending, int sortOrder, 93 //@}
94
95 /**
96 * Get sorted lists..
97 * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params:
98 * @param list of UID's received by allRecords() or others...
99 * @param sortOrder Setting the sort order defined by enum SortOrder
100 * @param ascending Sort in ascending order if true, otherwise descending
101 * @param sortFilter Setting the sort filter defined by enum SortFilter
102 * @param cat number of category.
103 */
104 virtual List sorted( const List& list, bool ascending, int sortOrder,
94 int sortFilter, int cat )const; 105 int sortFilter, int cat )const;
95 virtual List sorted( const List&, bool ascending, int sortOrder, 106
107 /**
108 * Get sorted lists..
109 * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params:
110 * @param list of UID's received by allRecords() or others...
111 * @param sortOrder Setting the sort order defined by enum SortOrder
112 * @param ascending Sort in ascending order if true, otherwise descending
113 * @param sortFilter Setting the sort filter defined by enum SortFilter
114 * @param cats List of categories.
115 */
116 virtual List sorted( const List& list, bool ascending, int sortOrder,
96 int sortFilter, const QArray<UID>& cats )const; 117 int sortFilter, const QArray<UID>& cats )const;
118
119 /**
120 * Get sorted lists..
121 * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params:
122 * @param ascending Sort in ascending order if true, otherwise descending
123 * @param sortOrder Setting the sort order defined by enum SortOrder
124 * @param sortFilter Setting the sort filter defined by enum SortFilter
125 * @param cat number of category.
126 */
97 virtual List sorted( bool ascending, int sortOrder, int sortFilter, int cat )const; 127 virtual List sorted( bool ascending, int sortOrder, int sortFilter, int cat )const;
98 virtual List sorted( bool ascending, int sortOrder, int sortOrder,
99 const QArray<UID>& cats )const;
100 //@}
101 128
129 /**
130 * Get sorted lists..
131 * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params:
132 * @param ascending Sort in ascending order if true, otherwise descending
133 * @param sortOrder Setting the sort order defined by enum SortOrder
134 * @param sortFilter Setting the sort filter defined by enum SortFilter
135 * @param cats List of categories.
136 */
137 virtual List sorted( bool ascending, int sortOrder, int sortFilter,
138 const QArray<UID>& cats )const;
102 /** 139 /**
103 * (Re)Implementation 140 * (Re)Implementation
104 */ 141 */
105 //@{ 142 //@{
106 UIDArray matchRegexpSimple( const QRegExp& r )const; 143 UIDArray matchRegexpSimple( const QRegExp& r )const;
107 UIDArray queryByExampleSimple( const OPimRecord*, int, const QDateTime& )const; 144 UIDArray queryByExampleSimple( const OPimRecord*, int, const QDateTime& )const;
108 UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder, 145 UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder,
109 int sortFilter, int cat )const; 146 int sortFilter, int cat )const;
110 UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder, 147 UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder,
111 int sortFilter, const QArray<int>& )const; 148 int sortFilter, const QArray<int>& )const;
112 UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, 149 UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter,
113 int cat )const; 150 int cat )const;
114 UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, 151 UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter,
115 const QArray<int>& )const; 152 const QArray<int>& )const;
116 OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const; 153 OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const;
117 OPimOccurrence::List occurrences( const QDateTime& dt )const; 154 OPimOccurrence::List occurrences( const QDateTime& dt )const;
118 //@} 155 //@}
119 156
120 //@{ 157 //@{
121 virtual bool add( const T& t ) ; 158 virtual bool add( const T& t ) ;
122 bool add( const OPimRecord& ); 159 bool add( const OPimRecord& );
123 bool add( const OPimRecord* ); 160 bool add( const OPimRecord* );
124 virtual bool remove( const T& t ); 161 virtual bool remove( const T& t );
125 bool remove( UID uid ); 162 bool remove( UID uid );
126 bool remove( const OPimRecord& ); 163 bool remove( const OPimRecord& );
127 virtual bool replace( const T& t) ; 164 virtual bool replace( const T& t) ;
128 165
129 //@} 166 //@}
130 167
131 void setReadAhead( uint count ); 168 void setReadAhead( uint count );
132 virtual T cacheFind( int uid )const;
133 void cache( const T& )const; 169 void cache( const T& )const;
134 void setSaneCacheSize( int ); 170 void setSaneCacheSize( int );
135 171
136 QArray<UID> records()const; 172 QArray<UID> records()const;
137protected: 173protected:
138 /** 174 /**
139 * invalidate the cache 175 * invalidate the cache
140 */ 176 */
141 void invalidateCache(); 177 void invalidateCache();
142 178
143 void setBackEnd( BackEnd* end ); 179 void setBackEnd( BackEnd* end );
144 /** 180 /**
145 * returns the backend 181 * returns the backend
146 */ 182 */
147 BackEnd* backEnd(); 183 BackEnd* backEnd();
148 BackEnd* m_backEnd; 184 BackEnd* m_backEnd;
149 185
150 Cache m_cache; 186 Cache m_cache;
151 187
152private: 188private:
153 OPimAccessTemplatePrivate *d; 189 OPimAccessTemplatePrivate *d;
154 190
155}; 191};
156 192
157/** 193/**
158 * c'tor BackEnd 194 * c'tor BackEnd
159 * enum Access a small hint on how to handle the backend 195 * enum Access a small hint on how to handle the backend
160 */ 196 */
161template <class T> 197template <class T>
162OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) 198OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
163 : OTemplateBase<T>(), m_backEnd( end ) 199 : OTemplateBase<T>(), m_backEnd( end )
164{ 200{
165 if (end ) 201 if (end )
166 end->setFrontend( this ); 202 end->setFrontend( this );
167} 203}
168template <class T> 204template <class T>
169OPimAccessTemplate<T>::~OPimAccessTemplate() { 205OPimAccessTemplate<T>::~OPimAccessTemplate() {
170 delete m_backEnd; 206 delete m_backEnd;
171} 207}
172 208
173/** 209/**
174 * load from the backend 210 * load from the backend
175 */ 211 */
176template <class T> 212template <class T>
177bool OPimAccessTemplate<T>::load() { 213bool OPimAccessTemplate<T>::load() {
178 invalidateCache(); 214 invalidateCache();
179 return m_backEnd->load(); 215 return m_backEnd->load();
180} 216}
181 217
182/** Reload database. 218/** Reload database.
183 * You should execute this function if the external database 219 * You should execute this function if the external database
184 * was changed. 220 * was changed.
185 * This function will load the external database and afterwards 221 * This function will load the external database and afterwards
186 * rejoin the local changes. Therefore the local database will be set consistent. 222 * rejoin the local changes. Therefore the local database will be set consistent.
187 */ 223 */
188template <class T> 224template <class T>
189bool OPimAccessTemplate<T>::reload() { 225bool OPimAccessTemplate<T>::reload() {
190 invalidateCache(); 226 invalidateCache();
191 return m_backEnd->reload(); 227 return m_backEnd->reload();
192} 228}
193 229
194/** 230/**
195 * Save contacts database. 231 * Save contacts database.
196 * Save is more a "commit". After calling this function, all changes are public available. 232 * Save is more a "commit". After calling this function, all changes are public available.
197 * @return true if successful 233 * @return true if successful
198 */ 234 */
199template <class T> 235template <class T>
200bool OPimAccessTemplate<T>::save() { 236bool OPimAccessTemplate<T>::save() {
201 return m_backEnd->save(); 237 return m_backEnd->save();
202} 238}
203 239
204 240
205/** 241/**
206 * return a List of records 242 * return a List of records
207 * you can iterate over them 243 * you can iterate over them
208 */ 244 */
209template <class T> 245template <class T>
210typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { 246typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const {
211 QArray<int> ints = m_backEnd->allRecords(); 247 QArray<int> ints = m_backEnd->allRecords();
212 List lis(ints, this ); 248 List lis(ints, this );
213 return lis; 249 return lis;
214} 250}
215 251
216/** 252/**
217 * return a List of records 253 * return a List of records
218 * that match the regex 254 * that match the regex
219 */ 255 */
220template <class T> 256template <class T>
221typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { 257typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const {
222 QArray<int> ints = m_backEnd->matchRegexp( r ); 258 QArray<int> ints = m_backEnd->matchRegexp( r );
223 List lis(ints, this ); 259 List lis(ints, this );
224 return lis; 260 return lis;
225} 261}
226 262
227/** 263/**
228 * find the OPimRecord uid 264 * find the OPimRecord uid
229 */ 265 */
230template <class T> 266template <class T>
231QArray<int> OPimAccessTemplate<T>::records()const { 267QArray<int> OPimAccessTemplate<T>::records()const {
232 return m_backEnd->allRecords(); 268 return m_backEnd->allRecords();
233} 269}
234 270
235 271
236/** 272/**
237 * queryByExample. 273 * queryByExample.
238 * @see otodoaccess, ocontactaccess 274 * @see otodoaccess, ocontactaccess
239 */ 275 */
240template <class T> 276template <class T>
241typename OPimAccessTemplate<T>::List 277typename OPimAccessTemplate<T>::List
242OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { 278OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) {
243 QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); 279 QArray<int> ints = m_backEnd->queryByExample( t, settings, d );
244 280
245 List lis(ints, this ); 281 List lis(ints, this );
246 return lis; 282 return lis;
247} 283}
248 284
249template <class T> 285template <class T>
250T OPimAccessTemplate<T>::find( UID uid ) const{ 286T OPimAccessTemplate<T>::find( UID uid ) const{
251 // First search in cache.. 287 // First search in cache..
252 if ( m_cache.contains( uid ) ) 288 if ( m_cache.contains( uid ) )
253 return m_cache.find( uid ); 289 return m_cache.find( uid );
254 290
255 T t = m_backEnd->find( uid ); 291 T t = m_backEnd->find( uid );
256 cache( t ); 292 cache( t );
257 293
258 return t; 294 return t;
259} 295}
260 296
261template <class T>
262T OPimAccessTemplate<T>::cacheFind( int uid ) const
263{
264 return m_cache.find( uid );
265}
266 297
267/** 298/**
268 * read ahead cache find method ;) 299 * read ahead cache find method ;)
269 */ 300 */
270template <class T> 301template <class T>
271T OPimAccessTemplate<T>::find( UID uid, const QArray<int>& ar, 302T OPimAccessTemplate<T>::find( UID uid, const QArray<int>& ar,
272 uint current, typename OTemplateBase<T>::CacheDirection dir )const { 303 uint current, typename OTemplateBase<T>::CacheDirection dir )const {
273 /* 304 /*
274 * better do T.isEmpty() 305 * better do T.isEmpty()
275 * after a find this way we would 306 * after a find this way we would
276 * avoid two finds in QCache... 307 * avoid two finds in QCache...
277 */ 308 */
278 if (m_cache.contains( uid ) ) 309 if (m_cache.contains( uid ) )
279 return m_cache.find( uid ); 310 return m_cache.find( uid );
280 311
281 312
282 T t = m_backEnd->find( uid, ar, current, dir ); 313 T t = m_backEnd->find( uid, ar, current, dir );
283 cache( t ); 314 cache( t );
284 return t; 315 return t;
285} 316}
286 317
287/** 318/**
288 * clears the backend and invalidates the backend 319 * clears the backend and invalidates the backend
289 */ 320 */
290template <class T> 321template <class T>
291void OPimAccessTemplate<T>::clear() { 322void OPimAccessTemplate<T>::clear() {
292 invalidateCache(); 323 invalidateCache();
293 m_backEnd->clear(); 324 m_backEnd->clear();
294} 325}
295 326
296 327
297/** 328/**
298 * add T to the backend 329 * add T to the backend
299 * @param t The item to add. 330 * @param t The item to add.
300 * @return <i>true</i> if added successfully. 331 * @return <i>true</i> if added successfully.
301 */ 332 */
302template <class T> 333template <class T>
303bool OPimAccessTemplate<T>::add( const T& t ) { 334bool OPimAccessTemplate<T>::add( const T& t ) {
304 cache( t ); 335 cache( t );
305 return m_backEnd->add( t ); 336 return m_backEnd->add( t );
306} 337}
307 338
308template <class T> 339template <class T>
309bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) { 340bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) {
310 /* same type */ 341 /* same type */
311 T tempInstance; 342 T tempInstance;
312 if ( rec.rtti() == tempInstance.rtti() ) { 343 if ( rec.rtti() == tempInstance.rtti() ) {
313 const T& t = static_cast<const T&>(rec); 344 const T& t = static_cast<const T&>(rec);
314 return add(t); 345 return add(t);
315 } else { 346 } else {
316 owarn << "Adding not possible: Objecttype mismatch" << oendl; 347 owarn << "Adding not possible: Objecttype mismatch" << oendl;
317 } 348 }
318 return false; 349 return false;
319} 350}
320 351
321/** 352/**
322 * Add an Opie PimRecord. 353 * Add an Opie PimRecord.
323 * Info: Take this if you are working with OPimRecords and you need to add it into any database. 354 * Info: Take this if you are working with OPimRecords and you need to add it into any database.
324 * But take care that the accessing database is compatible to the real type of OPimRecord !! 355 * But take care that the accessing database is compatible to the real type of OPimRecord !!
325 * Otherwise this access will be rejected ! 356 * Otherwise this access will be rejected !
326 */ 357 */
327template <class T> 358template <class T>
328bool OPimAccessTemplate<T>::add( const OPimRecord* rec) { 359bool OPimAccessTemplate<T>::add( const OPimRecord* rec) {
329 /* same type, but pointer */ 360 /* same type, but pointer */
diff --git a/libopie2/opiepim/core/opimtemplatebase.h b/libopie2/opiepim/core/opimtemplatebase.h
index b238a68..c8abab4 100644
--- a/libopie2/opiepim/core/opimtemplatebase.h
+++ b/libopie2/opiepim/core/opimtemplatebase.h
@@ -19,169 +19,188 @@
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OTEMPLATEBASE_H 29#ifndef OTEMPLATEBASE_H
30#define OTEMPLATEBASE_H 30#define OTEMPLATEBASE_H
31 31
32/* OPIE */ 32/* OPIE */
33#include <opie2/opimrecord.h> 33#include <opie2/opimrecord.h>
34#include <opie2/opimcache.h> 34#include <opie2/opimcache.h>
35#include <opie2/opimoccurrence.h> 35#include <opie2/opimoccurrence.h>
36#include <opie2/opimbackendoccurrence.h> 36#include <opie2/opimbackendoccurrence.h>
37 37
38/* QT */ 38/* QT */
39#include <qarray.h> 39#include <qarray.h>
40#include <qdatetime.h> 40#include <qdatetime.h>
41 41
42namespace Opie { 42namespace Opie {
43 43
44class OPimBasePrivate; 44class OPimBasePrivate;
45 45
46/** 46/**
47 * This is the base class for all our Interfaces to the 47 * This is the base class for all our Interfaces to the
48 * PIM Records. It is pointer based and can be used 48 * PIM Records. It is pointer based and can be used
49 * generically for all types of Records. 49 * generically for all types of Records.
50 * 50 *
51 */ 51 */
52struct OPimBase { 52struct OPimBase {
53 //@{ 53 //@{
54 OPimBase(); 54 OPimBase();
55 virtual ~OPimBase(); 55 virtual ~OPimBase();
56 //@} 56 //@}
57 57
58 //@{ 58 //@{
59 /** 59 /**
60 * return the rtti 60 * return the rtti
61 */ 61 */
62 virtual int rtti() const = 0; 62 virtual int rtti() const = 0;
63 virtual OPimRecord* record()const = 0; 63 virtual OPimRecord* record()const = 0;
64 virtual OPimRecord* record(int uid)const = 0; 64 virtual OPimRecord* record(int uid)const = 0;
65 //@} 65 //@}
66 66
67 //@{ 67 //@{
68 virtual bool add( const OPimRecord& ) = 0; 68 virtual bool add( const OPimRecord& ) = 0;
69 virtual bool add( const OPimRecord* ) = 0; 69 virtual bool add( const OPimRecord* ) = 0;
70 70
71 virtual bool remove( int uid ) = 0; 71 virtual bool remove( int uid ) = 0;
72 virtual bool remove( const OPimRecord& ) = 0; 72 virtual bool remove( const OPimRecord& ) = 0;
73 //@} 73 //@}
74 74
75 //@{ 75 //@{
76 virtual void clear() = 0; 76 virtual void clear() = 0;
77 virtual bool load() = 0; 77 virtual bool load() = 0;
78 virtual bool save() = 0; 78 virtual bool save() = 0;
79 //@} 79 //@}
80 80
81 //@{ 81 //@{
82 virtual QArray<UID> records()const = 0; 82 virtual QArray<UID> records()const = 0;
83 //@}
83 84
84 /** Constants for query. 85 /** Constants for query.
85 * Use this constants to set the query parameters. 86 * Use this constants to set the query parameters.
86 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! 87 * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes !
87 * @see queryByExample() 88 * @see queryByExample()
88 */ 89 */
89 enum QuerySettings { 90 enum QuerySettings {
90 WildCards = 0x0001, /** Use Wildcards */ 91 /** Use Wildcards */
91 IgnoreCase = 0x0002, /** Ignore the Case */ 92 WildCards = 0x0001,
92 RegExp = 0x0004, /** Do a Regular Expression match */ 93 /** Ignore the Case */
93 ExactMatch = 0x0008, /** It needs to exactly match */ 94 IgnoreCase = 0x0002,
94 MatchOne = 0x0010, /** Only one Entry must match */ 95 /** Do a Regular Expression match */
95 DateDiff = 0x0020, /** Find all entries from today until given date */ 96 RegExp = 0x0004,
96 DateYear = 0x0040, /** The year matches */ 97 /** It needs to exactly match */
97 DateMonth = 0x0080, /** The month matches */ 98 ExactMatch = 0x0008,
98 DateDay = 0x0100, /** The day matches */ 99 /** Only one Entry must match */
99 LastItem = 0xffff /** the last possible name */ 100 MatchOne = 0x0010,
101 /** Find all entries from today until given date */
102 DateDiff = 0x0020,
103 /** The year matches */
104 DateYear = 0x0040,
105 /** The month matches */
106 DateMonth = 0x0080,
107 /** The day matches */
108 DateDay = 0x0100,
109 /** The last possible name matches */
110 LastItem = 0xffff
100 }; 111 };
101 112
102 /** 113 /**
103 * Common Attributes for the Sort Order 114 * Common Attributes for the Sort Order
104 */ 115 */
105 enum SortOrderBase { 116 enum SortOrderBase {
106 SortSummary = 0, /** Sort by a Summary of the records */ 117 /** Sort by a Summary of the records */
107 SortByCategory = 1, /** Sort by Category */ 118 SortSummary = 0,
108 SortByDate = 2, /** Sort by Date */ 119 /** Sort by Category */
109 SortCustom = 10, /** The First available sort number for the OPimAccessTemplates */ 120 SortByCategory = 1,
110 LastSortOrderBase = 0xffff /** make this enum 16bit large */ 121 /** Sort by Date */
122 SortByDate = 2,
123 /** The First available sort number for the OPimAccessTemplates */
124 SortCustom = 10,
125 /** make this enum 16bit large */
126 LastSortOrderBase = 0xffff
111 }; 127 };
112 128
113 /** 129 /**
114 * Sort with the help of the \sa sorted function 130 * Sort a list of Items with the help of the sorted() function.
115 * a list of Items.
116 * The Item you provide in SortOrder will be used 131 * The Item you provide in SortOrder will be used
117 * for sorting. 132 * for sorting.
118 * 133 *
119 * @see sorted 134 * @see OPimAccessTemplate<>::sorted()
120 */ 135 */
121 enum SortFilterBase { 136 enum SortFilterBase {
137 /** Do not filter anything. */
138 FilterOff = 0,
139 /** Use given Categories for filter */
122 FilterCategory = 1, 140 FilterCategory = 1,
123 FilterCustom = 1024, 141 /** The first available custom filter defined in the specialized frontends */
142 FilterCustom = 1024,
124 LastSortFilterBase = 0xffffffff 143 LastSortFilterBase = 0xffffffff
125 }; 144 };
126 145
127 virtual UIDArray matchRegexpSimple( const QRegExp& r )const = 0; 146 virtual UIDArray matchRegexpSimple( const QRegExp& r )const = 0;
128 virtual UIDArray queryByExampleSimple( const OPimRecord*, int settings, 147 virtual UIDArray queryByExampleSimple( const OPimRecord*, int settings,
129 const QDateTime& d = QDateTime() )const = 0; 148 const QDateTime& d = QDateTime() )const = 0;
130 virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending, 149 virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending,
131 int sortOrder, int sortFilter, int cat)const = 0; 150 int sortOrder, int sortFilter, int cat)const = 0;
132 virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending, 151 virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending,
133 int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0; 152 int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0;
134 virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, int cat)const = 0; 153 virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, int cat)const = 0;
135 virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0; 154 virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0;
136 virtual OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const = 0; 155 virtual OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const = 0;
137 virtual OPimOccurrence::List occurrences( const QDateTime& dt )const = 0; 156 virtual OPimOccurrence::List occurrences( const QDateTime& dt )const = 0;
138 //@} 157 //@}
139 158
140 159
141protected: 160protected:
142 OPimOccurrence::List convertOccurrenceFromBackend( const OPimBackendOccurrence::List& )const; 161 OPimOccurrence::List convertOccurrenceFromBackend( const OPimBackendOccurrence::List& )const;
143 162
144private: 163private:
145 OPimBasePrivate* d; 164 OPimBasePrivate* d;
146}; 165};
147 166
148 167
149/** 168/**
150 * internal template base 169 * internal template base
151 * Attention: T needs to implement the copy c'tor!!! 170 * Attention: T needs to implement the copy c'tor!!!
152 */ 171 */
153class OTemplateBasePrivate; 172class OTemplateBasePrivate;
154template <class T = OPimRecord> 173template <class T = OPimRecord>
155class OTemplateBase : public OPimBase { 174class OTemplateBase : public OPimBase {
156public: 175public:
157 /** 176 /**
158 * The Direction for ReadAhead/ReadBehind which will 177 * The Direction for ReadAhead/ReadBehind which will
159 * be used by the backends to Cache Items in 178 * be used by the backends to Cache Items in
160 * advance. 179 * advance.
161 * For example if you know that you will access the 180 * For example if you know that you will access the
162 * next ten items you can give the backend a hint 181 * next ten items you can give the backend a hint
163 * to read ahead or read before. 182 * to read ahead or read before.
164 */ 183 */
165 enum CacheDirection { 184 enum CacheDirection {
166 Forward=0, /** Go forward when caching (++ to the index) */ 185 Forward=0, /** Go forward when caching (++ to the index) */
167 Reverse /** Go backward when caching (-- to the index) */ 186 Reverse /** Go backward when caching (-- to the index) */
168 }; 187 };
169 188
170 189
171 //@{ 190 //@{
172 OTemplateBase() {}; 191 OTemplateBase() {};
173 virtual ~OTemplateBase() {} 192 virtual ~OTemplateBase() {}
174 //@} 193 //@}
175 194
176 195
177 //@{ 196 //@{
178 virtual T find( int uid )const = 0; 197 virtual T find( int uid )const = 0;
179 198
180 /** 199 /**
181 * read ahead find 200 * read ahead find
182 */ 201 */
183 virtual T find( int uid, const QArray<int>& items, 202 virtual T find( int uid, const QArray<int>& items,
184 uint current, CacheDirection dir = Forward )const = 0; 203 uint current, CacheDirection dir = Forward )const = 0;
185 //@} 204 //@}
186 205
187 //@{ 206 //@{
diff --git a/libopie2/opiepim/opiepim.pro b/libopie2/opiepim/opiepim.pro
index 47ec6da..992fb8b 100644
--- a/libopie2/opiepim/opiepim.pro
+++ b/libopie2/opiepim/opiepim.pro
@@ -1,26 +1,26 @@
1TEMPLATE = lib 1TEMPLATE = lib
2CONFIG += qt warn_on 2CONFIG += qt warn_on
3DESTDIR = $(OPIEDIR)/lib 3DESTDIR = $(OPIEDIR)/lib
4 4
5INTERFACES = 5INTERFACES =
6TARGET = opiepim2 6TARGET = opiepim2
7VERSION = 1.9.1 7VERSION = 1.8.6
8INCLUDEPATH += $(OPIEDIR)/include 8INCLUDEPATH += $(OPIEDIR)/include
9DEPENDPATH += $(OPIEDIR)/include 9DEPENDPATH += $(OPIEDIR)/include
10LIBS += -lopiecore2 10LIBS += -lopiecore2
11 11
12include ( $(OPIEDIR)/gen.pro ) 12include ( $(OPIEDIR)/gen.pro )
13include ( core/core.pro ) 13include ( core/core.pro )
14include ( backend/backends.pro ) 14include ( backend/backends.pro )
15include ( ui/ui.pro ) 15include ( ui/ui.pro )
16include ( private/private.pro ) 16include ( private/private.pro )
17 17
18PRECOMPILED_HEADER = stable_pch.h 18PRECOMPILED_HEADER = stable_pch.h
19 19
20!contains( platform, x11 ) { 20!contains( platform, x11 ) {
21 include ( $(OPIEDIR)/include.pro ) 21 include ( $(OPIEDIR)/include.pro )
22} 22}
23 23
24contains( platform, x11 ) { 24contains( platform, x11 ) {
25 LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib 25 LIBS = -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib
26} 26}