summaryrefslogtreecommitdiff
path: root/libopie2
authoreilers <eilers>2004-12-20 14:14:07 (UTC)
committer eilers <eilers>2004-12-20 14:14:07 (UTC)
commit18e47153532d016d878f47e0ce11cb1a9716218e (patch) (unidiff)
tree52eb6c25258fda0b2f295a29809c4603f5e17b0b /libopie2
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 (limited to 'libopie2') (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
@@ -12,59 +12,252 @@
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() )
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
@@ -59,50 +59,53 @@ class 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
@@ -106,71 +106,71 @@ namespace {
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) );";
@@ -273,84 +273,84 @@ namespace {
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 )
@@ -401,49 +401,49 @@ bool OPimContactAccessBackend_SQL::load ()
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;
@@ -464,92 +464,93 @@ bool OPimContactAccessBackend_SQL::remove ( int uid )
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
@@ -618,89 +619,89 @@ QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &qu
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
@@ -717,154 +718,249 @@ bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
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 );
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
@@ -49,66 +49,67 @@ class OSQLResultItem;
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
@@ -136,70 +136,60 @@ bool OPimContactAccessBackend_VCard::add ( const OPimContact& newcontact )
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
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
@@ -37,52 +37,50 @@
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
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
@@ -162,295 +162,102 @@ bool OPimContactAccessBackend_XML::load ()
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
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
@@ -37,58 +37,53 @@
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;
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
@@ -45,55 +45,76 @@ class OPimAccessBackendPrivate;
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 /**
@@ -129,65 +150,66 @@ OPimAccessBackend<T>::~OPimAccessBackend() {
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 )
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
@@ -39,95 +39,116 @@
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.
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
@@ -69,88 +69,124 @@ public:
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
@@ -237,53 +273,48 @@ QArray<int> OPimAccessTemplate<T>::records()const {
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 */
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
@@ -59,89 +59,108 @@ struct OPimBase {
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
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}