summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp180
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp1
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp70
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.h2
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp173
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.h5
-rw-r--r--libopie2/opiepim/core/opimcontact.h2
7 files changed, 339 insertions, 94 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 1ea35a8..3142f75 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -1,760 +1,826 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers <eilers.stefan@epost.de> 3 Copyright (C) Stefan Eilers <eilers.stefan@epost.de>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Contact Database. 30 * SQL Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#include "ocontactaccessbackend_sql.h" 33#include "ocontactaccessbackend_sql.h"
34 34
35#include <qarray.h> 35#include <qarray.h>
36#include <qdatetime.h> 36#include <qdatetime.h>
37#include <qstringlist.h> 37#include <qstringlist.h>
38 38
39#include <qpe/global.h> 39#include <qpe/global.h>
40#include <qpe/recordfields.h> 40#include <qpe/recordfields.h>
41 41
42#include <opie2/opimcontact.h>
42#include <opie2/opimcontactfields.h> 43#include <opie2/opimcontactfields.h>
43#include <opie2/opimdateconversion.h> 44#include <opie2/opimdateconversion.h>
44#include <opie2/osqldriver.h> 45#include <opie2/osqldriver.h>
45#include <opie2/osqlresult.h> 46#include <opie2/osqlresult.h>
46#include <opie2/osqlmanager.h> 47#include <opie2/osqlmanager.h>
47#include <opie2/osqlquery.h> 48#include <opie2/osqlquery.h>
48 49
50using namespace Opie;
49using namespace Opie::DB; 51using namespace Opie::DB;
50 52
51 53
52/* 54/*
53 * Implementation of used query types 55 * Implementation of used query types * CREATE query
54 * CREATE query
55 * LOAD query 56 * LOAD query
56 * INSERT 57 * INSERT
57 * REMOVE 58 * REMOVE
58 * CLEAR 59 * CLEAR
59 */ 60 */
60namespace Opie { 61namespace {
61 /** 62 /**
62 * CreateQuery for the Todolist Table 63 * CreateQuery for the Todolist Table
63 */ 64 */
64 class CreateQuery : public OSQLQuery { 65 class CreateQuery : public OSQLQuery {
65 public: 66 public:
66 CreateQuery(); 67 CreateQuery();
67 ~CreateQuery(); 68 ~CreateQuery();
68 QString query()const; 69 QString query()const;
69 }; 70 };
70 71
71 /** 72 /**
72 * Clears (delete) a Table 73 * Clears (delete) a Table
73 */ 74 */
74 class ClearQuery : public OSQLQuery { 75 class ClearQuery : public OSQLQuery {
75 public: 76 public:
76 ClearQuery(); 77 ClearQuery();
77 ~ClearQuery(); 78 ~ClearQuery();
78 QString query()const; 79 QString query()const;
79 80
80 }; 81 };
81 82
82 83
83 /** 84 /**
84 * LoadQuery 85 * LoadQuery
85 * this one queries for all uids 86 * this one queries for all uids
86 */ 87 */
87 class LoadQuery : public OSQLQuery { 88 class LoadQuery : public OSQLQuery {
88 public: 89 public:
89 LoadQuery(); 90 LoadQuery();
90 ~LoadQuery(); 91 ~LoadQuery();
91 QString query()const; 92 QString query()const;
92 }; 93 };
93 94
94 /** 95 /**
95 * inserts/adds a OPimContact to the table 96 * inserts/adds a OPimContact to the table
96 */ 97 */
97 class InsertQuery : public OSQLQuery { 98 class InsertQuery : public OSQLQuery {
98 public: 99 public:
99 InsertQuery(const OPimContact& ); 100 InsertQuery(const OPimContact& );
100 ~InsertQuery(); 101 ~InsertQuery();
101 QString query()const; 102 QString query()const;
102 private: 103 private:
103 OPimContact m_contact; 104 OPimContact m_contact;
104 }; 105 };
105 106
106 107
107 /** 108 /**
108 * removes one from the table 109 * removes one from the table
109 */ 110 */
110 class RemoveQuery : public OSQLQuery { 111 class RemoveQuery : public OSQLQuery {
111 public: 112 public:
112 RemoveQuery(int uid ); 113 RemoveQuery(int uid );
113 ~RemoveQuery(); 114 ~RemoveQuery();
114 QString query()const; 115 QString query()const;
115 private: 116 private:
116 int m_uid; 117 int m_uid;
117 }; 118 };
118 119
119 /** 120 /**
120 * a find query for noncustom elements 121 * a find query for noncustom elements
121 */ 122 */
122 class FindQuery : public OSQLQuery { 123 class FindQuery : public OSQLQuery {
123 public: 124 public:
124 FindQuery(int uid); 125 FindQuery(int uid);
125 FindQuery(const QArray<int>& ); 126 FindQuery(const QArray<int>& );
126 ~FindQuery(); 127 ~FindQuery();
127 QString query()const; 128 QString query()const;
128 private: 129 private:
129 QString single()const; 130 QString single()const;
130 QString multi()const; 131 QString multi()const;
131 QArray<int> m_uids; 132 QArray<int> m_uids;
132 int m_uid; 133 int m_uid;
133 }; 134 };
134 135
135 /** 136 /**
136 * a find query for custom elements 137 * a find query for custom elements
137 */ 138 */
138 class FindCustomQuery : public OSQLQuery { 139 class FindCustomQuery : public OSQLQuery {
139 public: 140 public:
140 FindCustomQuery(int uid); 141 FindCustomQuery(int uid);
141 FindCustomQuery(const QArray<int>& ); 142 FindCustomQuery(const QArray<int>& );
142 ~FindCustomQuery(); 143 ~FindCustomQuery();
143 QString query()const; 144 QString query()const;
144 private: 145 private:
145 QString single()const; 146 QString single()const;
146 QString multi()const; 147 QString multi()const;
147 QArray<int> m_uids; 148 QArray<int> m_uids;
148 int m_uid; 149 int m_uid;
149 }; 150 };
150 151
151 152
152 153
153 // We using three tables to store the information: 154 // We using two tables to store the information:
154 // 1. addressbook : It contains General information about the contact (non custom) 155 // 1. addressbook : It contains General information about the contact (non custom)
155 // 2. custom_data : Not official supported entries 156 // 2. custom_data : Not official supported entries
156 // All tables are connected by the uid of the contact. 157 // All tables are connected by the uid of the contact.
157 // Maybe I should add a table for meta-information ? 158 // Maybe I should add a table for meta-information ?
158 CreateQuery::CreateQuery() : OSQLQuery() {} 159 CreateQuery::CreateQuery() : OSQLQuery() {}
159 CreateQuery::~CreateQuery() {} 160 CreateQuery::~CreateQuery() {}
160 QString CreateQuery::query()const { 161 QString CreateQuery::query()const {
161 QString qu; 162 QString qu;
162 163
163 qu += "create table addressbook( uid PRIMARY KEY "; 164 qu += "create table addressbook( uid PRIMARY KEY ";
164 165
165 QStringList fieldList = OPimContactFields::untrfields( false ); 166 QStringList fieldList = OPimContactFields::untrfields( false );
166 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 167 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
167 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); 168 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
168 } 169 }
169 qu += " );"; 170 qu += " );";
170 171
171 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 172 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
172 173
173 return qu; 174 return qu;
174 } 175 }
175 176
176 ClearQuery::ClearQuery() 177 ClearQuery::ClearQuery()
177 : OSQLQuery() {} 178 : OSQLQuery() {}
178 ClearQuery::~ClearQuery() {} 179 ClearQuery::~ClearQuery() {}
179 QString ClearQuery::query()const { 180 QString ClearQuery::query()const {
180 QString qu = "drop table addressbook;"; 181 QString qu = "drop table addressbook;";
181 qu += "drop table custom_data;"; 182 qu += "drop table custom_data;";
182 // qu += "drop table dates;"; 183 // qu += "drop table dates;";
183 return qu; 184 return qu;
184 } 185 }
185 186
186 187
187 LoadQuery::LoadQuery() : OSQLQuery() {} 188 LoadQuery::LoadQuery() : OSQLQuery() {}
188 LoadQuery::~LoadQuery() {} 189 LoadQuery::~LoadQuery() {}
189 QString LoadQuery::query()const { 190 QString LoadQuery::query()const {
190 QString qu; 191 QString qu;
191 qu += "select uid from addressbook"; 192 qu += "select uid from addressbook";
192 193
193 return qu; 194 return qu;
194 } 195 }
195 196
196 197
197 InsertQuery::InsertQuery( const OPimContact& contact ) 198 InsertQuery::InsertQuery( const OPimContact& contact )
198 : OSQLQuery(), m_contact( contact ) { 199 : OSQLQuery(), m_contact( contact ) {
199 } 200 }
200 201
201 InsertQuery::~InsertQuery() { 202 InsertQuery::~InsertQuery() {
202 } 203 }
203 204
204 /* 205 /*
205 * converts from a OPimContact to a query 206 * converts from a OPimContact to a query
206 */ 207 */
207 QString InsertQuery::query()const{ 208 QString InsertQuery::query()const{
208 209
209 QString qu; 210 QString qu;
210 qu += "insert into addressbook VALUES( " + 211 qu += "insert into addressbook VALUES( " +
211 QString::number( m_contact.uid() ); 212 QString::number( m_contact.uid() );
212 213
213 // Get all information out of the contact-class 214 // Get all information out of the contact-class
214 // Remember: The category is stored in contactMap, too ! 215 // Remember: The category is stored in contactMap, too !
215 QMap<int, QString> contactMap = m_contact.toMap(); 216 QMap<int, QString> contactMap = m_contact.toMap();
216 217
217 QStringList fieldList = OPimContactFields::untrfields( false ); 218 QStringList fieldList = OPimContactFields::untrfields( false );
218 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 219 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
219 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 220 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
220 // Convert Column-String to Id and get value for this id.. 221 // Convert Column-String to Id and get value for this id..
221 // Hmmm.. Maybe not very cute solution.. 222 // Hmmm.. Maybe not very cute solution..
222 int id = translate[*it]; 223 int id = translate[*it];
223 switch ( id ){ 224 switch ( id ){
224 case Qtopia::Birthday:{ 225 case Qtopia::Birthday:
225 // These entries should stored in a special format 226 case Qtopia::Anniversary:{
226 // year-month-day 227 QDate day;
227 QDate day = m_contact.birthday(); 228 if ( id == Qtopia::Birthday ){
228 if ( day.isValid() ){ 229 day = m_contact.birthday();
229 qu += QString(",\"%1-%2-%3\"")
230 .arg( day.year() )
231 .arg( day.month() )
232 .arg( day.day() );
233 } else { 230 } else {
234 qu += ",\"\""; 231 day = m_contact.anniversary();
235 } 232 }
236 }
237 break;
238 case Qtopia::Anniversary:{
239 // These entries should stored in a special format 233 // These entries should stored in a special format
240 // year-month-day 234 // year-month-day
241 QDate day = m_contact.anniversary();
242 if ( day.isValid() ){ 235 if ( day.isValid() ){
243 qu += QString(",\"%1-%2-%3\"") 236 qu += QString(",\"%1-%2-%3\"")
244 .arg( day.year() ) 237 .arg( QString::number( day.year() ).rightJustify( 4, '0' ) )
245 .arg( day.month() ) 238 .arg( QString::number( day.month() ).rightJustify( 2, '0' ) )
246 .arg( day.day() ); 239 .arg( QString::number( day.day() ).rightJustify( 2, '0' ) );
247 } else { 240 } else {
248 qu += ",\"\""; 241 qu += ",\"\"";
249 } 242 }
250 } 243 }
251 break; 244 break;
252
253 default: 245 default:
254 qu += QString( ",\"%1\"" ).arg( contactMap[id] ); 246 qu += QString( ",\"%1\"" ).arg( contactMap[id] );
255 } 247 }
256 } 248 }
257 qu += " );"; 249 qu += " );";
258 250
259 251
260 // Now add custom data.. 252 // Now add custom data..
261 int id = 0; 253 int id = 0;
262 id = 0; 254 id = 0;
263 QMap<QString, QString> customMap = m_contact.toExtraMap(); 255 QMap<QString, QString> customMap = m_contact.toExtraMap();
264 for( QMap<QString, QString>::Iterator it = customMap.begin(); 256 for( QMap<QString, QString>::Iterator it = customMap.begin();
265 it != customMap.end(); ++it ){ 257 it != customMap.end(); ++it ){
266 qu += "insert into custom_data VALUES(" 258 qu += "insert into custom_data VALUES("
267 + QString::number( m_contact.uid() ) 259 + QString::number( m_contact.uid() )
268 + "," 260 + ","
269 + QString::number( id++ ) 261 + QString::number( id++ )
270 + ",'" 262 + ",'"
271 + it.key() //.latin1() 263 + it.key()
272 + "'," 264 + "',"
273 + "0" // Priority for future enhancements 265 + "0" // Priority for future enhancements
274 + ",'" 266 + ",'"
275 + it.data() //.latin1() 267 + it.data()
276 + "');"; 268 + "');";
277 } 269 }
278 // qu += "commit;"; 270 // qu += "commit;";
279 qWarning("add %s", qu.latin1() ); 271 qDebug("add %s", qu.latin1() );
280 return qu; 272 return qu;
281 } 273 }
282 274
283 275
284 RemoveQuery::RemoveQuery(int uid ) 276 RemoveQuery::RemoveQuery(int uid )
285 : OSQLQuery(), m_uid( uid ) {} 277 : OSQLQuery(), m_uid( uid ) {}
286 RemoveQuery::~RemoveQuery() {} 278 RemoveQuery::~RemoveQuery() {}
287 QString RemoveQuery::query()const { 279 QString RemoveQuery::query()const {
288 QString qu = "DELETE from addressbook where uid = " 280 QString qu = "DELETE from addressbook where uid = "
289 + QString::number(m_uid) + ";"; 281 + QString::number(m_uid) + ";";
290 qu += "DELETE from custom_data where uid = " 282 qu += "DELETE from custom_data where uid = "
291 + QString::number(m_uid) + ";"; 283 + QString::number(m_uid) + ";";
292 return qu; 284 return qu;
293 } 285 }
294 286
295 287
296 288
297 289
298 FindQuery::FindQuery(int uid) 290 FindQuery::FindQuery(int uid)
299 : OSQLQuery(), m_uid( uid ) { 291 : OSQLQuery(), m_uid( uid ) {
300 } 292 }
301 FindQuery::FindQuery(const QArray<int>& ints) 293 FindQuery::FindQuery(const QArray<int>& ints)
302 : OSQLQuery(), m_uids( ints ){ 294 : OSQLQuery(), m_uids( ints ){
303 } 295 }
304 FindQuery::~FindQuery() { 296 FindQuery::~FindQuery() {
305 } 297 }
306 QString FindQuery::query()const{ 298 QString FindQuery::query()const{
307 // if ( m_uids.count() == 0 ) 299 // if ( m_uids.count() == 0 )
308 return single(); 300 return single();
309 } 301 }
310 /* 302 /*
311 else 303 else
312 return multi(); 304 return multi();
313 } 305 }
314 QString FindQuery::multi()const { 306 QString FindQuery::multi()const {
315 QString qu = "select uid, type, value from addressbook where"; 307 QString qu = "select uid, type, value from addressbook where";
316 for (uint i = 0; i < m_uids.count(); i++ ) { 308 for (uint i = 0; i < m_uids.count(); i++ ) {
317 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 309 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
318 } 310 }
319 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 311 qu.remove( qu.length()-2, 2 ); // Hmmmm..
320 return qu; 312 return qu;
321 } 313 }
322 */ 314 */
323 QString FindQuery::single()const{ 315 QString FindQuery::single()const{
324 QString qu = "select *"; 316 QString qu = "select *";
325 qu += " from addressbook where uid = " + QString::number(m_uid); 317 qu += " from addressbook where uid = " + QString::number(m_uid);
326 318
327 // qWarning("find query: %s", qu.latin1() ); 319 // qWarning("find query: %s", qu.latin1() );
328 return qu; 320 return qu;
329 } 321 }
330 322
331 323
332 FindCustomQuery::FindCustomQuery(int uid) 324 FindCustomQuery::FindCustomQuery(int uid)
333 : OSQLQuery(), m_uid( uid ) { 325 : OSQLQuery(), m_uid( uid ) {
334 } 326 }
335 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 327 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
336 : OSQLQuery(), m_uids( ints ){ 328 : OSQLQuery(), m_uids( ints ){
337 } 329 }
338 FindCustomQuery::~FindCustomQuery() { 330 FindCustomQuery::~FindCustomQuery() {
339 } 331 }
340 QString FindCustomQuery::query()const{ 332 QString FindCustomQuery::query()const{
341 // if ( m_uids.count() == 0 ) 333 // if ( m_uids.count() == 0 )
342 return single(); 334 return single();
343 } 335 }
344 QString FindCustomQuery::single()const{ 336 QString FindCustomQuery::single()const{
345 QString qu = "select uid, type, value from custom_data where uid = "; 337 QString qu = "select uid, type, value from custom_data where uid = ";
346 qu += QString::number(m_uid); 338 qu += QString::number(m_uid);
347 return qu; 339 return qu;
348 } 340 }
349 341
350}; 342};
351 343
352 344
353/* --------------------------------------------------------------------------- */ 345/* --------------------------------------------------------------------------- */
354 346
355namespace Opie { 347namespace Opie {
356 348
357OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, 349OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */,
358 const QString& filename ): 350 const QString& filename ):
359 OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) 351 OPimContactAccessBackend(), m_changed(false), m_driver( NULL )
360{ 352{
361 qWarning("C'tor OPimContactAccessBackend_SQL starts"); 353 qDebug("C'tor OPimContactAccessBackend_SQL starts");
362 QTime t; 354 QTime t;
363 t.start(); 355 t.start();
364 356
365 /* Expecting to access the default filename if nothing else is set */ 357 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){ 358 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 359 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else 360 } else
369 m_fileName = filename; 361 m_fileName = filename;
370 362
371 // Get the standart sql-driver from the OSQLManager.. 363 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man; 364 OSQLManager man;
373 m_driver = man.standard(); 365 m_driver = man.standard();
374 m_driver->setUrl( m_fileName ); 366 m_driver->setUrl( m_fileName );
375 367
376 load(); 368 load();
377 369
378 qWarning("C'tor OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() ); 370 qDebug("C'tor OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() );
379} 371}
380 372
381OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () 373OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL ()
382{ 374{
383 if( m_driver ) 375 if( m_driver )
384 delete m_driver; 376 delete m_driver;
385} 377}
386 378
387bool OPimContactAccessBackend_SQL::load () 379bool OPimContactAccessBackend_SQL::load ()
388{ 380{
389 if (!m_driver->open() ) 381 if (!m_driver->open() )
390 return false; 382 return false;
391 383
392 // Don't expect that the database exists. 384 // Don't expect that the database exists.
393 // It is save here to create the table, even if it 385 // It is save here to create the table, even if it
394 // do exist. ( Is that correct for all databases ?? ) 386 // do exist. ( Is that correct for all databases ?? )
395 CreateQuery creat; 387 CreateQuery creat;
396 OSQLResult res = m_driver->query( &creat ); 388 OSQLResult res = m_driver->query( &creat );
397 389
398 update(); 390 update();
399 391
400 return true; 392 return true;
401 393
402} 394}
403 395
404bool OPimContactAccessBackend_SQL::reload() 396bool OPimContactAccessBackend_SQL::reload()
405{ 397{
406 return load(); 398 return load();
407} 399}
408 400
409bool OPimContactAccessBackend_SQL::save() 401bool OPimContactAccessBackend_SQL::save()
410{ 402{
411 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 403 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
412} 404}
413 405
414 406
415void OPimContactAccessBackend_SQL::clear () 407void OPimContactAccessBackend_SQL::clear ()
416{ 408{
417 ClearQuery cle; 409 ClearQuery cle;
418 OSQLResult res = m_driver->query( &cle ); 410 OSQLResult res = m_driver->query( &cle );
419 411
420 reload(); 412 reload();
421} 413}
422 414
423bool OPimContactAccessBackend_SQL::wasChangedExternally() 415bool OPimContactAccessBackend_SQL::wasChangedExternally()
424{ 416{
425 return false; 417 return false;
426} 418}
427 419
428QArray<int> OPimContactAccessBackend_SQL::allRecords() const 420QArray<int> OPimContactAccessBackend_SQL::allRecords() const
429{ 421{
430 422
431 // FIXME: Think about cute handling of changed tables.. 423 // FIXME: Think about cute handling of changed tables..
432 // Thus, we don't have to call update here... 424 // Thus, we don't have to call update here...
433 if ( m_changed ) 425 if ( m_changed )
434 ((OPimContactAccessBackend_SQL*)this)->update(); 426 ((OPimContactAccessBackend_SQL*)this)->update();
435 427
436 return m_uids; 428 return m_uids;
437} 429}
438 430
439bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) 431bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact )
440{ 432{
441 InsertQuery ins( newcontact ); 433 InsertQuery ins( newcontact );
442 OSQLResult res = m_driver->query( &ins ); 434 OSQLResult res = m_driver->query( &ins );
443 435
444 if ( res.state() == OSQLResult::Failure ) 436 if ( res.state() == OSQLResult::Failure )
445 return false; 437 return false;
446 438
447 int c = m_uids.count(); 439 int c = m_uids.count();
448 m_uids.resize( c+1 ); 440 m_uids.resize( c+1 );
449 m_uids[c] = newcontact.uid(); 441 m_uids[c] = newcontact.uid();
450 442
451 return true; 443 return true;
452} 444}
453 445
454 446
455bool OPimContactAccessBackend_SQL::remove ( int uid ) 447bool OPimContactAccessBackend_SQL::remove ( int uid )
456{ 448{
457 RemoveQuery rem( uid ); 449 RemoveQuery rem( uid );
458 OSQLResult res = m_driver->query(&rem ); 450 OSQLResult res = m_driver->query(&rem );
459 451
460 if ( res.state() == OSQLResult::Failure ) 452 if ( res.state() == OSQLResult::Failure )
461 return false; 453 return false;
462 454
463 m_changed = true; 455 m_changed = true;
464 456
465 return true; 457 return true;
466} 458}
467 459
468bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) 460bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
469{ 461{
470 if ( !remove( contact.uid() ) ) 462 if ( !remove( contact.uid() ) )
471 return false; 463 return false;
472 464
473 return add( contact ); 465 return add( contact );
474} 466}
475 467
476 468
477OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const 469OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
478{ 470{
479 qWarning("OPimContactAccessBackend_SQL::find()"); 471 qDebug("OPimContactAccessBackend_SQL::find()");
480 QTime t; 472 QTime t;
481 t.start(); 473 t.start();
482 474
483 OPimContact retContact( requestNonCustom( uid ) ); 475 OPimContact retContact( requestNonCustom( uid ) );
484 retContact.setExtraMap( requestCustom( uid ) ); 476 retContact.setExtraMap( requestCustom( uid ) );
485 477
486 qWarning("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); 478 qDebug("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
487 return retContact; 479 return retContact;
488} 480}
489 481
490 482
491 483
492QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ) 484QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd )
493{ 485{
494 QString qu = "SELECT uid FROM addressbook WHERE"; 486 QString qu = "SELECT uid FROM addressbook WHERE";
487 QString searchQuery ="";
488
489 QDate startDate;
490
491 if ( qd.isValid() )
492 startDate = qd.date();
493 else
494 startDate = QDate::currentDate();
495
495 496
496 QMap<int, QString> queryFields = query.toMap(); 497 QMap<int, QString> queryFields = query.toMap();
497 QStringList fieldList = OPimContactFields::untrfields( false ); 498 QStringList fieldList = OPimContactFields::untrfields( false );
498 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 499 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
499 500
500 // Convert every filled field to a SQL-Query 501 // Convert every filled field to a SQL-Query
501 bool isAnyFieldSelected = false; 502 // bool isAnyFieldSelected = false;
502 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 503 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
504
503 int id = translate[*it]; 505 int id = translate[*it];
504 QString queryStr = queryFields[id]; 506 QString queryStr = queryFields[id];
507 QDate* endDate = 0l;
508
505 if ( !queryStr.isEmpty() ){ 509 if ( !queryStr.isEmpty() ){
506 isAnyFieldSelected = true; 510 // If something is alredy stored in the query, add an "AND"
511 // to the end of the string to prepare for the next ..
512 if ( !searchQuery.isEmpty() )
513 searchQuery += " AND";
514
515 // isAnyFieldSelected = true;
507 switch( id ){ 516 switch( id ){
517 case Qtopia::Birthday:
518 endDate = new QDate( query.birthday() );
519 // Fall through !
520 case Qtopia::Anniversary:
521 if ( endDate == 0l )
522 endDate = new QDate( query.anniversary() );
523
524 if ( settings & OPimContactAccess::DateDiff ) {
525 searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" )
526 .arg( *it )
527 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) )
528 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) )
529 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) )
530 .arg( *it )
531 .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) )
532 .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) )
533 .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ;
534 }
535
536 if ( settings & OPimContactAccess::DateYear ){
537 if ( settings & OPimContactAccess::DateDiff )
538 searchQuery += " AND";
539
540 searchQuery += QString( " (\"%1\" LIKE '%2-%')" )
541 .arg( *it )
542 .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) );
543 }
544
545 if ( settings & OPimContactAccess::DateMonth ){
546 if ( ( settings & OPimContactAccess::DateDiff )
547 || ( settings & OPimContactAccess::DateYear ) )
548 searchQuery += " AND";
549
550 searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" )
551 .arg( *it )
552 .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) );
553 }
554
555 if ( settings & OPimContactAccess::DateDay ){
556 if ( ( settings & OPimContactAccess::DateDiff )
557 || ( settings & OPimContactAccess::DateYear )
558 || ( settings & OPimContactAccess::DateMonth ) )
559 searchQuery += " AND";
560
561 searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" )
562 .arg( *it )
563 .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) );
564 }
565
566 break;
508 default: 567 default:
509 // Switching between case sensitive and insensitive... 568 // Switching between case sensitive and insensitive...
510 // LIKE is not case sensitive, GLOB is case sensitive 569 // LIKE is not case sensitive, GLOB is case sensitive
511 // Do exist a better solution to switch this ? 570 // Do exist a better solution to switch this ?
512 if ( settings & OPimContactAccess::IgnoreCase ) 571 if ( settings & OPimContactAccess::IgnoreCase )
513 qu += "(\"" + *it + "\"" + " LIKE " + "'" 572 searchQuery += "(\"" + *it + "\"" + " LIKE " + "'"
514 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; 573 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")";
515 else 574 else
516 qu += "(\"" + *it + "\"" + " GLOB " + "'" 575 searchQuery += "(\"" + *it + "\"" + " GLOB " + "'"
517 + queryStr + "'" + ") AND "; 576 + queryStr + "'" + ")";
518 577
519 } 578 }
520 } 579 }
521 } 580 }
522 // Skip trailing "AND" 581 // Skip trailing "AND"
523 if ( isAnyFieldSelected ) 582 // if ( isAnyFieldSelected )
524 qu = qu.left( qu.length() - 4 ); 583 // qu = qu.left( qu.length() - 4 );
584
585 qu += searchQuery;
525 586
526 qWarning( "queryByExample query: %s", qu.latin1() ); 587 qDebug( "queryByExample query: %s", qu.latin1() );
527 588
528 // Execute query and return the received uid's 589 // Execute query and return the received uid's
529 OSQLRawQuery raw( qu ); 590 OSQLRawQuery raw( qu );
530 OSQLResult res = m_driver->query( &raw ); 591 OSQLResult res = m_driver->query( &raw );
531 if ( res.state() != OSQLResult::Success ){ 592 if ( res.state() != OSQLResult::Success ){
532 QArray<int> empty; 593 QArray<int> empty;
533 return empty; 594 return empty;
534 } 595 }
535 596
536 QArray<int> list = extractUids( res ); 597 QArray<int> list = extractUids( res );
537 598
538 return list; 599 return list;
539} 600}
540 601
541QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 602QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
542{ 603{
543 QArray<int> nix(0); 604 QArray<int> nix(0);
544 return nix; 605 return nix;
545} 606}
546 607
547const uint OPimContactAccessBackend_SQL::querySettings() 608const uint OPimContactAccessBackend_SQL::querySettings()
548{ 609{
549 return OPimContactAccess::IgnoreCase 610 return OPimContactAccess::IgnoreCase
550 || OPimContactAccess::WildCards; 611 || OPimContactAccess::WildCards
612 || OPimContactAccess::DateDiff
613 || OPimContactAccess::DateYear
614 || OPimContactAccess::DateMonth
615 || OPimContactAccess::DateDay
616 ;
551} 617}
552 618
553bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 619bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
554{ 620{
555 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 621 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
556 * may be added with any of the other settings. IgnoreCase should never used alone. 622 * may be added with any of the other settings. IgnoreCase should never used alone.
557 * Wildcards, RegExp, ExactMatch should never used at the same time... 623 * Wildcards, RegExp, ExactMatch should never used at the same time...
558 */ 624 */
559 625
560 // Step 1: Check whether the given settings are supported by this backend 626 // Step 1: Check whether the given settings are supported by this backend
561 if ( ( querySettings & ( 627 if ( ( querySettings & (
562 OPimContactAccess::IgnoreCase 628 OPimContactAccess::IgnoreCase
563 | OPimContactAccess::WildCards 629 | OPimContactAccess::WildCards
564 // | OPimContactAccess::DateDiff 630 | OPimContactAccess::DateDiff
565 // | OPimContactAccess::DateYear 631 | OPimContactAccess::DateYear
566 // | OPimContactAccess::DateMonth 632 | OPimContactAccess::DateMonth
567 // | OPimContactAccess::DateDay 633 | OPimContactAccess::DateDay
568 // | OPimContactAccess::RegExp 634 // | OPimContactAccess::RegExp
569 // | OPimContactAccess::ExactMatch 635 // | OPimContactAccess::ExactMatch
570 ) ) != querySettings ) 636 ) ) != querySettings )
571 return false; 637 return false;
572 638
573 // Step 2: Check whether the given combinations are ok.. 639 // Step 2: Check whether the given combinations are ok..
574 640
575 // IngoreCase alone is invalid 641 // IngoreCase alone is invalid
576 if ( querySettings == OPimContactAccess::IgnoreCase ) 642 if ( querySettings == OPimContactAccess::IgnoreCase )
577 return false; 643 return false;
578 644
579 // WildCards, RegExp and ExactMatch should never used at the same time 645 // WildCards, RegExp and ExactMatch should never used at the same time
580 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 646 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
581 | OPimContactAccess::DateDiff 647 | OPimContactAccess::DateDiff
582 | OPimContactAccess::DateYear 648 | OPimContactAccess::DateYear
583 | OPimContactAccess::DateMonth 649 | OPimContactAccess::DateMonth
584 | OPimContactAccess::DateDay 650 | OPimContactAccess::DateDay
585 ) 651 )
586 ){ 652 ){
587 case OPimContactAccess::RegExp: 653 case OPimContactAccess::RegExp:
588 return ( true ); 654 return ( true );
589 case OPimContactAccess::WildCards: 655 case OPimContactAccess::WildCards:
590 return ( true ); 656 return ( true );
591 case OPimContactAccess::ExactMatch: 657 case OPimContactAccess::ExactMatch:
592 return ( true ); 658 return ( true );
593 case 0: // one of the upper removed bits were set.. 659 case 0: // one of the upper removed bits were set..
594 return ( true ); 660 return ( true );
595 default: 661 default:
596 return ( false ); 662 return ( false );
597 } 663 }
598 664
599} 665}
600 666
601QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 667QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int )
602{ 668{
603 QTime t; 669 QTime t;
604 t.start(); 670 t.start();
605 671
606 QString query = "SELECT uid FROM addressbook "; 672 QString query = "SELECT uid FROM addressbook ";
607 query += "ORDER BY \"Last Name\" "; 673 query += "ORDER BY \"Last Name\" ";
608 674
609 if ( !asc ) 675 if ( !asc )
610 query += "DESC"; 676 query += "DESC";
611 677
612 // qWarning("sorted query is: %s", query.latin1() ); 678 // qDebug("sorted query is: %s", query.latin1() );
613 679
614 OSQLRawQuery raw( query ); 680 OSQLRawQuery raw( query );
615 OSQLResult res = m_driver->query( &raw ); 681 OSQLResult res = m_driver->query( &raw );
616 if ( res.state() != OSQLResult::Success ){ 682 if ( res.state() != OSQLResult::Success ){
617 QArray<int> empty; 683 QArray<int> empty;
618 return empty; 684 return empty;
619 } 685 }
620 686
621 QArray<int> list = extractUids( res ); 687 QArray<int> list = extractUids( res );
622 688
623 qWarning("sorted needed %d ms!", t.elapsed() ); 689 qDebug("sorted needed %d ms!", t.elapsed() );
624 return list; 690 return list;
625} 691}
626 692
627 693
628void OPimContactAccessBackend_SQL::update() 694void OPimContactAccessBackend_SQL::update()
629{ 695{
630 qWarning("Update starts"); 696 qDebug("Update starts");
631 QTime t; 697 QTime t;
632 t.start(); 698 t.start();
633 699
634 // Now load the database set and extract the uid's 700 // Now load the database set and extract the uid's
635 // which will be held locally 701 // which will be held locally
636 702
637 LoadQuery lo; 703 LoadQuery lo;
638 OSQLResult res = m_driver->query(&lo); 704 OSQLResult res = m_driver->query(&lo);
639 if ( res.state() != OSQLResult::Success ) 705 if ( res.state() != OSQLResult::Success )
640 return; 706 return;
641 707
642 m_uids = extractUids( res ); 708 m_uids = extractUids( res );
643 709
644 m_changed = false; 710 m_changed = false;
645 711
646 qWarning("Update ends %d ms", t.elapsed() ); 712 qDebug("Update ends %d ms", t.elapsed() );
647} 713}
648 714
649QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const 715QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
650{ 716{
651 qWarning("extractUids"); 717 qDebug("extractUids");
652 QTime t; 718 QTime t;
653 t.start(); 719 t.start();
654 OSQLResultItem::ValueList list = res.results(); 720 OSQLResultItem::ValueList list = res.results();
655 OSQLResultItem::ValueList::Iterator it; 721 OSQLResultItem::ValueList::Iterator it;
656 QArray<int> ints(list.count() ); 722 QArray<int> ints(list.count() );
657 qWarning(" count = %d", list.count() ); 723 qDebug(" count = %d", list.count() );
658 724
659 int i = 0; 725 int i = 0;
660 for (it = list.begin(); it != list.end(); ++it ) { 726 for (it = list.begin(); it != list.end(); ++it ) {
661 ints[i] = (*it).data("uid").toInt(); 727 ints[i] = (*it).data("uid").toInt();
662 i++; 728 i++;
663 } 729 }
664 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 730 qDebug("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
665 731
666 return ints; 732 return ints;
667 733
668} 734}
669 735
670QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const 736QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const
671{ 737{
672 QTime t; 738 QTime t;
673 t.start(); 739 t.start();
674 740
675 QMap<int, QString> nonCustomMap; 741 QMap<int, QString> nonCustomMap;
676 742
677 int t2needed = 0; 743 int t2needed = 0;
678 int t3needed = 0; 744 int t3needed = 0;
679 QTime t2; 745 QTime t2;
680 t2.start(); 746 t2.start();
681 FindQuery query( uid ); 747 FindQuery query( uid );
682 OSQLResult res_noncustom = m_driver->query( &query ); 748 OSQLResult res_noncustom = m_driver->query( &query );
683 t2needed = t2.elapsed(); 749 t2needed = t2.elapsed();
684 750
685 OSQLResultItem resItem = res_noncustom.first(); 751 OSQLResultItem resItem = res_noncustom.first();
686 752
687 QTime t3; 753 QTime t3;
688 t3.start(); 754 t3.start();
689 // Now loop through all columns 755 // Now loop through all columns
690 QStringList fieldList = OPimContactFields::untrfields( false ); 756 QStringList fieldList = OPimContactFields::untrfields( false );
691 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 757 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
692 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 758 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
693 // Get data for the selected column and store it with the 759 // Get data for the selected column and store it with the
694 // corresponding id into the map.. 760 // corresponding id into the map..
695 761
696 int id = translate[*it]; 762 int id = translate[*it];
697 QString value = resItem.data( (*it) ); 763 QString value = resItem.data( (*it) );
698 764
699 // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() ); 765 // qDebug("Reading %s... found: %s", (*it).latin1(), value.latin1() );
700 766
701 switch( id ){ 767 switch( id ){
702 case Qtopia::Birthday: 768 case Qtopia::Birthday:
703 case Qtopia::Anniversary:{ 769 case Qtopia::Anniversary:{
704 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 770 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
705 QStringList list = QStringList::split( '-', value ); 771 QStringList list = QStringList::split( '-', value );
706 QStringList::Iterator lit = list.begin(); 772 QStringList::Iterator lit = list.begin();
707 int year = (*lit).toInt(); 773 int year = (*lit).toInt();
708 int month = (*(++lit)).toInt(); 774 int month = (*(++lit)).toInt();
709 int day = (*(++lit)).toInt(); 775 int day = (*(++lit)).toInt();
710 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ 776 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){
711 QDate date( year, month, day ); 777 QDate date( year, month, day );
712 nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); 778 nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) );
713 } 779 }
714 } 780 }
715 break; 781 break;
716 case Qtopia::AddressCategory: 782 case Qtopia::AddressCategory:
717 qWarning("Category is: %s", value.latin1() ); 783 qDebug("Category is: %s", value.latin1() );
718 default: 784 default:
719 nonCustomMap.insert( id, value ); 785 nonCustomMap.insert( id, value );
720 } 786 }
721 } 787 }
722 788
723 // First insert uid 789 // First insert uid
724 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) ); 790 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
725 t3needed = t3.elapsed(); 791 t3needed = t3.elapsed();
726 792
727 // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() ); 793 // qDebug("Adding UID: %s", resItem.data( "uid" ).latin1() );
728 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", 794 qDebug("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms",
729 t.elapsed(), t2needed, t3needed ); 795 t.elapsed(), t2needed, t3needed );
730 796
731 return nonCustomMap; 797 return nonCustomMap;
732} 798}
733 799
734QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const 800QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const
735{ 801{
736 QTime t; 802 QTime t;
737 t.start(); 803 t.start();
738 804
739 QMap<QString, QString> customMap; 805 QMap<QString, QString> customMap;
740 806
741 FindCustomQuery query( uid ); 807 FindCustomQuery query( uid );
742 OSQLResult res_custom = m_driver->query( &query ); 808 OSQLResult res_custom = m_driver->query( &query );
743 809
744 if ( res_custom.state() == OSQLResult::Failure ) { 810 if ( res_custom.state() == OSQLResult::Failure ) {
745 qWarning("OSQLResult::Failure in find query !!"); 811 qWarning("OSQLResult::Failure in find query !!");
746 QMap<QString, QString> empty; 812 QMap<QString, QString> empty;
747 return empty; 813 return empty;
748 } 814 }
749 815
750 OSQLResultItem::ValueList list = res_custom.results(); 816 OSQLResultItem::ValueList list = res_custom.results();
751 OSQLResultItem::ValueList::Iterator it = list.begin(); 817 OSQLResultItem::ValueList::Iterator it = list.begin();
752 for ( ; it != list.end(); ++it ) { 818 for ( ; it != list.end(); ++it ) {
753 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 819 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
754 } 820 }
755 821
756 qWarning("RequestCustom needed: %d ms", t.elapsed() ); 822 qDebug("RequestCustom needed: %d ms", t.elapsed() );
757 return customMap; 823 return customMap;
758} 824}
759 825
760} 826}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 2b467c3..7b4d81f 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,616 +1,617 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * XML Backend for the OPIE-Contact Database. 30 * XML Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#include <opie2/ocontactaccessbackend_xml.h> 33#include <opie2/ocontactaccessbackend_xml.h>
34 34
35#include <qasciidict.h> 35#include <qasciidict.h>
36#include <qfile.h> 36#include <qfile.h>
37#include <qfileinfo.h> 37#include <qfileinfo.h>
38#include <qregexp.h> 38#include <qregexp.h>
39#include <qarray.h> 39#include <qarray.h>
40#include <qmap.h> 40#include <qmap.h>
41 41
42#include <qpe/global.h> 42#include <qpe/global.h>
43 43
44#include <opie2/xmltree.h> 44#include <opie2/xmltree.h>
45#include <opie2/ocontactaccessbackend.h> 45#include <opie2/ocontactaccessbackend.h>
46#include <opie2/ocontactaccess.h> 46#include <opie2/ocontactaccess.h>
47 47
48#include <stdlib.h> 48#include <stdlib.h>
49#include <errno.h> 49#include <errno.h>
50 50
51using namespace Opie::Core; 51using namespace Opie::Core;
52 52
53 53
54namespace Opie { 54namespace Opie {
55OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): 55OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ):
56 m_changed( false ) 56 m_changed( false )
57{ 57{
58 // Just m_contactlist should call delete if an entry 58 // Just m_contactlist should call delete if an entry
59 // is removed. 59 // is removed.
60 m_contactList.setAutoDelete( true ); 60 m_contactList.setAutoDelete( true );
61 m_uidToContact.setAutoDelete( false ); 61 m_uidToContact.setAutoDelete( false );
62 62
63 m_appName = appname; 63 m_appName = appname;
64 64
65 /* Set journalfile name ... */ 65 /* Set journalfile name ... */
66 m_journalName = getenv("HOME"); 66 m_journalName = getenv("HOME");
67 m_journalName +="/.abjournal" + appname; 67 m_journalName +="/.abjournal" + appname;
68 68
69 /* Expecting to access the default filename if nothing else is set */ 69 /* Expecting to access the default filename if nothing else is set */
70 if ( filename.isEmpty() ){ 70 if ( filename.isEmpty() ){
71 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 71 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
72 } else 72 } else
73 m_fileName = filename; 73 m_fileName = filename;
74 74
75 /* Load Database now */ 75 /* Load Database now */
76 load (); 76 load ();
77} 77}
78 78
79bool OPimContactAccessBackend_XML::save() 79bool OPimContactAccessBackend_XML::save()
80{ 80{
81 81
82 if ( !m_changed ) 82 if ( !m_changed )
83 return true; 83 return true;
84 84
85 QString strNewFile = m_fileName + ".new"; 85 QString strNewFile = m_fileName + ".new";
86 QFile f( strNewFile ); 86 QFile f( strNewFile );
87 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 87 if ( !f.open( IO_WriteOnly|IO_Raw ) )
88 return false; 88 return false;
89 89
90 int total_written; 90 int total_written;
91 int idx_offset = 0; 91 int idx_offset = 0;
92 QString out; 92 QString out;
93 93
94 // Write Header 94 // Write Header
95 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 95 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
96 " <Groups>\n" 96 " <Groups>\n"
97 " </Groups>\n" 97 " </Groups>\n"
98 " <Contacts>\n"; 98 " <Contacts>\n";
99 QCString cstr = out.utf8(); 99 QCString cstr = out.utf8();
100 f.writeBlock( cstr.data(), cstr.length() ); 100 f.writeBlock( cstr.data(), cstr.length() );
101 idx_offset += cstr.length(); 101 idx_offset += cstr.length();
102 out = ""; 102 out = "";
103 103
104 // Write all contacts 104 // Write all contacts
105 QListIterator<OPimContact> it( m_contactList ); 105 QListIterator<OPimContact> it( m_contactList );
106 for ( ; it.current(); ++it ) { 106 for ( ; it.current(); ++it ) {
107 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 107 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
108 out += "<Contact "; 108 out += "<Contact ";
109 (*it)->save( out ); 109 (*it)->save( out );
110 out += "/>\n"; 110 out += "/>\n";
111 cstr = out.utf8(); 111 cstr = out.utf8();
112 total_written = f.writeBlock( cstr.data(), cstr.length() ); 112 total_written = f.writeBlock( cstr.data(), cstr.length() );
113 idx_offset += cstr.length(); 113 idx_offset += cstr.length();
114 if ( total_written != int(cstr.length()) ) { 114 if ( total_written != int(cstr.length()) ) {
115 f.close(); 115 f.close();
116 QFile::remove( strNewFile ); 116 QFile::remove( strNewFile );
117 return false; 117 return false;
118 } 118 }
119 out = ""; 119 out = "";
120 } 120 }
121 out += " </Contacts>\n</AddressBook>\n"; 121 out += " </Contacts>\n</AddressBook>\n";
122 122
123 // Write Footer 123 // Write Footer
124 cstr = out.utf8(); 124 cstr = out.utf8();
125 total_written = f.writeBlock( cstr.data(), cstr.length() ); 125 total_written = f.writeBlock( cstr.data(), cstr.length() );
126 if ( total_written != int( cstr.length() ) ) { 126 if ( total_written != int( cstr.length() ) ) {
127 f.close(); 127 f.close();
128 QFile::remove( strNewFile ); 128 QFile::remove( strNewFile );
129 return false; 129 return false;
130 } 130 }
131 f.close(); 131 f.close();
132 132
133 // move the file over, I'm just going to use the system call 133 // move the file over, I'm just going to use the system call
134 // because, I don't feel like using QDir. 134 // because, I don't feel like using QDir.
135 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 135 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
136 qWarning( "problem renaming file %s to %s, errno: %d", 136 qWarning( "problem renaming file %s to %s, errno: %d",
137 strNewFile.latin1(), m_journalName.latin1(), errno ); 137 strNewFile.latin1(), m_journalName.latin1(), errno );
138 // remove the tmp file... 138 // remove the tmp file...
139 QFile::remove( strNewFile ); 139 QFile::remove( strNewFile );
140 } 140 }
141 141
142 /* The journalfile should be removed now... */ 142 /* The journalfile should be removed now... */
143 removeJournal(); 143 removeJournal();
144 144
145 m_changed = false; 145 m_changed = false;
146 return true; 146 return true;
147} 147}
148 148
149bool OPimContactAccessBackend_XML::load () 149bool OPimContactAccessBackend_XML::load ()
150{ 150{
151 m_contactList.clear(); 151 m_contactList.clear();
152 m_uidToContact.clear(); 152 m_uidToContact.clear();
153 153
154 /* Load XML-File and journal if it exists */ 154 /* Load XML-File and journal if it exists */
155 if ( !load ( m_fileName, false ) ) 155 if ( !load ( m_fileName, false ) )
156 return false; 156 return false;
157 /* The returncode of the journalfile is ignored due to the 157 /* The returncode of the journalfile is ignored due to the
158 * fact that it does not exist when this class is instantiated ! 158 * fact that it does not exist when this class is instantiated !
159 * But there may such a file exist, if the application crashed. 159 * But there may such a file exist, if the application crashed.
160 * Therefore we try to load it to get the changes before the # 160 * Therefore we try to load it to get the changes before the #
161 * crash happened... 161 * crash happened...
162 */ 162 */
163 load (m_journalName, true); 163 load (m_journalName, true);
164 164
165 return true; 165 return true;
166} 166}
167 167
168void OPimContactAccessBackend_XML::clear () 168void OPimContactAccessBackend_XML::clear ()
169{ 169{
170 m_contactList.clear(); 170 m_contactList.clear();
171 m_uidToContact.clear(); 171 m_uidToContact.clear();
172 172
173 m_changed = false; 173 m_changed = false;
174} 174}
175 175
176bool OPimContactAccessBackend_XML::wasChangedExternally() 176bool OPimContactAccessBackend_XML::wasChangedExternally()
177{ 177{
178 QFileInfo fi( m_fileName ); 178 QFileInfo fi( m_fileName );
179 179
180 QDateTime lastmod = fi.lastModified (); 180 QDateTime lastmod = fi.lastModified ();
181 181
182 return (lastmod != m_readtime); 182 return (lastmod != m_readtime);
183} 183}
184 184
185QArray<int> OPimContactAccessBackend_XML::allRecords() const 185QArray<int> OPimContactAccessBackend_XML::allRecords() const
186{ 186{
187 QArray<int> uid_list( m_contactList.count() ); 187 QArray<int> uid_list( m_contactList.count() );
188 188
189 uint counter = 0; 189 uint counter = 0;
190 QListIterator<OPimContact> it( m_contactList ); 190 QListIterator<OPimContact> it( m_contactList );
191 for( ; it.current(); ++it ){ 191 for( ; it.current(); ++it ){
192 uid_list[counter++] = (*it)->uid(); 192 uid_list[counter++] = (*it)->uid();
193 } 193 }
194 194
195 return ( uid_list ); 195 return ( uid_list );
196} 196}
197 197
198OPimContact OPimContactAccessBackend_XML::find ( int uid ) const 198OPimContact OPimContactAccessBackend_XML::find ( int uid ) const
199{ 199{
200 OPimContact foundContact; //Create empty contact 200 OPimContact foundContact; //Create empty contact
201 201
202 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); 202 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) );
203 203
204 if ( found ){ 204 if ( found ){
205 foundContact = *found; 205 foundContact = *found;
206 } 206 }
207 207
208 return ( foundContact ); 208 return ( foundContact );
209} 209}
210 210
211QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, 211QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings,
212 const QDateTime& d ) 212 const QDateTime& d )
213{ 213{
214 214
215 QArray<int> m_currentQuery( m_contactList.count() ); 215 QArray<int> m_currentQuery( m_contactList.count() );
216 QListIterator<OPimContact> it( m_contactList ); 216 QListIterator<OPimContact> it( m_contactList );
217 uint arraycounter = 0; 217 uint arraycounter = 0;
218 218
219 for( ; it.current(); ++it ){ 219 for( ; it.current(); ++it ){
220 /* Search all fields and compare them with query object. Store them into list 220 /* Search all fields and compare them with query object. Store them into list
221 * if all fields matches. 221 * if all fields matches.
222 */ 222 */
223 QDate* queryDate = 0l; 223 QDate* queryDate = 0l;
224 QDate* checkDate = 0l; 224 QDate* checkDate = 0l;
225 bool allcorrect = true; 225 bool allcorrect = true;
226 for ( int i = 0; i < Qtopia::Groups; i++ ) { 226 for ( int i = 0; i < Qtopia::Groups; i++ ) {
227 // Birthday and anniversary are special nonstring fields and should 227 // Birthday and anniversary are special nonstring fields and should
228 // be handled specially 228 // be handled specially
229 switch ( i ){ 229 switch ( i ){
230 case Qtopia::Birthday: 230 case Qtopia::Birthday:
231 queryDate = new QDate( query.birthday() ); 231 queryDate = new QDate( query.birthday() );
232 checkDate = new QDate( (*it)->birthday() ); 232 checkDate = new QDate( (*it)->birthday() );
233 // fall through
233 case Qtopia::Anniversary: 234 case Qtopia::Anniversary:
234 if ( queryDate == 0l ){ 235 if ( queryDate == 0l ){
235 queryDate = new QDate( query.anniversary() ); 236 queryDate = new QDate( query.anniversary() );
236 checkDate = new QDate( (*it)->anniversary() ); 237 checkDate = new QDate( (*it)->anniversary() );
237 } 238 }
238 239
239 if ( queryDate->isValid() ){ 240 if ( queryDate->isValid() ){
240 if( checkDate->isValid() ){ 241 if( checkDate->isValid() ){
241 if ( settings & OPimContactAccess::DateYear ){ 242 if ( settings & OPimContactAccess::DateYear ){
242 if ( queryDate->year() != checkDate->year() ) 243 if ( queryDate->year() != checkDate->year() )
243 allcorrect = false; 244 allcorrect = false;
244 } 245 }
245 if ( settings & OPimContactAccess::DateMonth ){ 246 if ( settings & OPimContactAccess::DateMonth ){
246 if ( queryDate->month() != checkDate->month() ) 247 if ( queryDate->month() != checkDate->month() )
247 allcorrect = false; 248 allcorrect = false;
248 } 249 }
249 if ( settings & OPimContactAccess::DateDay ){ 250 if ( settings & OPimContactAccess::DateDay ){
250 if ( queryDate->day() != checkDate->day() ) 251 if ( queryDate->day() != checkDate->day() )
251 allcorrect = false; 252 allcorrect = false;
252 } 253 }
253 if ( settings & OPimContactAccess::DateDiff ) { 254 if ( settings & OPimContactAccess::DateDiff ) {
254 QDate current; 255 QDate current;
255 // If we get an additional date, we 256 // If we get an additional date, we
256 // will take this date instead of 257 // will take this date instead of
257 // the current one.. 258 // the current one..
258 if ( !d.date().isValid() ) 259 if ( !d.date().isValid() )
259 current = QDate::currentDate(); 260 current = QDate::currentDate();
260 else 261 else
261 current = d.date(); 262 current = d.date();
262 263
263 // We have to equalize the year, otherwise 264 // We have to equalize the year, otherwise
264 // the search will fail.. 265 // the search will fail..
265 checkDate->setYMD( current.year(), 266 checkDate->setYMD( current.year(),
266 checkDate->month(), 267 checkDate->month(),
267 checkDate->day() ); 268 checkDate->day() );
268 if ( *checkDate < current ) 269 if ( *checkDate < current )
269 checkDate->setYMD( current.year()+1, 270 checkDate->setYMD( current.year()+1,
270 checkDate->month(), 271 checkDate->month(),
271 checkDate->day() ); 272 checkDate->day() );
272 273
273 // Check whether the birthday/anniversary date is between 274 // Check whether the birthday/anniversary date is between
274 // the current/given date and the maximum date 275 // the current/given date and the maximum date
275 // ( maximum time range ) ! 276 // ( maximum time range ) !
276 qWarning("Checking if %s is between %s and %s ! ", 277 qWarning("Checking if %s is between %s and %s ! ",
277 checkDate->toString().latin1(), 278 checkDate->toString().latin1(),
278 current.toString().latin1(), 279 current.toString().latin1(),
279 queryDate->toString().latin1() ); 280 queryDate->toString().latin1() );
280 if ( current.daysTo( *queryDate ) >= 0 ){ 281 if ( current.daysTo( *queryDate ) >= 0 ){
281 if ( !( ( *checkDate >= current ) && 282 if ( !( ( *checkDate >= current ) &&
282 ( *checkDate <= *queryDate ) ) ){ 283 ( *checkDate <= *queryDate ) ) ){
283 allcorrect = false; 284 allcorrect = false;
284 qWarning (" Nope!.."); 285 qWarning (" Nope!..");
285 } 286 }
286 } 287 }
287 } 288 }
288 } else{ 289 } else{
289 // checkDate is invalid. Therefore this entry is always rejected 290 // checkDate is invalid. Therefore this entry is always rejected
290 allcorrect = false; 291 allcorrect = false;
291 } 292 }
292 } 293 }
293 294
294 delete queryDate; 295 delete queryDate;
295 queryDate = 0l; 296 queryDate = 0l;
296 delete checkDate; 297 delete checkDate;
297 checkDate = 0l; 298 checkDate = 0l;
298 break; 299 break;
299 default: 300 default:
300 /* Just compare fields which are not empty in the query object */ 301 /* Just compare fields which are not empty in the query object */
301 if ( !query.field(i).isEmpty() ){ 302 if ( !query.field(i).isEmpty() ){
302 switch ( settings & ~( OPimContactAccess::IgnoreCase 303 switch ( settings & ~( OPimContactAccess::IgnoreCase
303 | OPimContactAccess::DateDiff 304 | OPimContactAccess::DateDiff
304 | OPimContactAccess::DateYear 305 | OPimContactAccess::DateYear
305 | OPimContactAccess::DateMonth 306 | OPimContactAccess::DateMonth
306 | OPimContactAccess::DateDay 307 | OPimContactAccess::DateDay
307 | OPimContactAccess::MatchOne 308 | OPimContactAccess::MatchOne
308 ) ){ 309 ) ){
309 310
310 case OPimContactAccess::RegExp:{ 311 case OPimContactAccess::RegExp:{
311 QRegExp expr ( query.field(i), 312 QRegExp expr ( query.field(i),
312 !(settings & OPimContactAccess::IgnoreCase), 313 !(settings & OPimContactAccess::IgnoreCase),
313 false ); 314 false );
314 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 315 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
315 allcorrect = false; 316 allcorrect = false;
316 } 317 }
317 break; 318 break;
318 case OPimContactAccess::WildCards:{ 319 case OPimContactAccess::WildCards:{
319 QRegExp expr ( query.field(i), 320 QRegExp expr ( query.field(i),
320 !(settings & OPimContactAccess::IgnoreCase), 321 !(settings & OPimContactAccess::IgnoreCase),
321 true ); 322 true );
322 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 323 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
323 allcorrect = false; 324 allcorrect = false;
324 } 325 }
325 break; 326 break;
326 case OPimContactAccess::ExactMatch:{ 327 case OPimContactAccess::ExactMatch:{
327 if (settings & OPimContactAccess::IgnoreCase){ 328 if (settings & OPimContactAccess::IgnoreCase){
328 if ( query.field(i).upper() != 329 if ( query.field(i).upper() !=
329 (*it)->field(i).upper() ) 330 (*it)->field(i).upper() )
330 allcorrect = false; 331 allcorrect = false;
331 }else{ 332 }else{
332 if ( query.field(i) != (*it)->field(i) ) 333 if ( query.field(i) != (*it)->field(i) )
333 allcorrect = false; 334 allcorrect = false;
334 } 335 }
335 } 336 }
336 break; 337 break;
337 } 338 }
338 } 339 }
339 } 340 }
340 } 341 }
341 if ( allcorrect ){ 342 if ( allcorrect ){
342 m_currentQuery[arraycounter++] = (*it)->uid(); 343 m_currentQuery[arraycounter++] = (*it)->uid();
343 } 344 }
344 } 345 }
345 346
346 // Shrink to fit.. 347 // Shrink to fit..
347 m_currentQuery.resize(arraycounter); 348 m_currentQuery.resize(arraycounter);
348 349
349 return m_currentQuery; 350 return m_currentQuery;
350} 351}
351 352
352QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 353QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
353{ 354{
354 QArray<int> m_currentQuery( m_contactList.count() ); 355 QArray<int> m_currentQuery( m_contactList.count() );
355 QListIterator<OPimContact> it( m_contactList ); 356 QListIterator<OPimContact> it( m_contactList );
356 uint arraycounter = 0; 357 uint arraycounter = 0;
357 358
358 for( ; it.current(); ++it ){ 359 for( ; it.current(); ++it ){
359 if ( (*it)->match( r ) ){ 360 if ( (*it)->match( r ) ){
360 m_currentQuery[arraycounter++] = (*it)->uid(); 361 m_currentQuery[arraycounter++] = (*it)->uid();
361 } 362 }
362 363
363 } 364 }
364 // Shrink to fit.. 365 // Shrink to fit..
365 m_currentQuery.resize(arraycounter); 366 m_currentQuery.resize(arraycounter);
366 367
367 return m_currentQuery; 368 return m_currentQuery;
368} 369}
369 370
370const uint OPimContactAccessBackend_XML::querySettings() 371const uint OPimContactAccessBackend_XML::querySettings()
371{ 372{
372 return ( OPimContactAccess::WildCards 373 return ( OPimContactAccess::WildCards
373 | OPimContactAccess::IgnoreCase 374 | OPimContactAccess::IgnoreCase
374 | OPimContactAccess::RegExp 375 | OPimContactAccess::RegExp
375 | OPimContactAccess::ExactMatch 376 | OPimContactAccess::ExactMatch
376 | OPimContactAccess::DateDiff 377 | OPimContactAccess::DateDiff
377 | OPimContactAccess::DateYear 378 | OPimContactAccess::DateYear
378 | OPimContactAccess::DateMonth 379 | OPimContactAccess::DateMonth
379 | OPimContactAccess::DateDay 380 | OPimContactAccess::DateDay
380 ); 381 );
381} 382}
382 383
383bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 384bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
384{ 385{
385 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 386 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
386 * may be added with any of the other settings. IgnoreCase should never used alone. 387 * may be added with any of the other settings. IgnoreCase should never used alone.
387 * Wildcards, RegExp, ExactMatch should never used at the same time... 388 * Wildcards, RegExp, ExactMatch should never used at the same time...
388 */ 389 */
389 390
390 // Step 1: Check whether the given settings are supported by this backend 391 // Step 1: Check whether the given settings are supported by this backend
391 if ( ( querySettings & ( 392 if ( ( querySettings & (
392 OPimContactAccess::IgnoreCase 393 OPimContactAccess::IgnoreCase
393 | OPimContactAccess::WildCards 394 | OPimContactAccess::WildCards
394 | OPimContactAccess::DateDiff 395 | OPimContactAccess::DateDiff
395 | OPimContactAccess::DateYear 396 | OPimContactAccess::DateYear
396 | OPimContactAccess::DateMonth 397 | OPimContactAccess::DateMonth
397 | OPimContactAccess::DateDay 398 | OPimContactAccess::DateDay
398 | OPimContactAccess::RegExp 399 | OPimContactAccess::RegExp
399 | OPimContactAccess::ExactMatch 400 | OPimContactAccess::ExactMatch
400 ) ) != querySettings ) 401 ) ) != querySettings )
401 return false; 402 return false;
402 403
403 // Step 2: Check whether the given combinations are ok.. 404 // Step 2: Check whether the given combinations are ok..
404 405
405 // IngoreCase alone is invalid 406 // IngoreCase alone is invalid
406 if ( querySettings == OPimContactAccess::IgnoreCase ) 407 if ( querySettings == OPimContactAccess::IgnoreCase )
407 return false; 408 return false;
408 409
409 // WildCards, RegExp and ExactMatch should never used at the same time 410 // WildCards, RegExp and ExactMatch should never used at the same time
410 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 411 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
411 | OPimContactAccess::DateDiff 412 | OPimContactAccess::DateDiff
412 | OPimContactAccess::DateYear 413 | OPimContactAccess::DateYear
413 | OPimContactAccess::DateMonth 414 | OPimContactAccess::DateMonth
414 | OPimContactAccess::DateDay 415 | OPimContactAccess::DateDay
415 ) 416 )
416 ){ 417 ){
417 case OPimContactAccess::RegExp: 418 case OPimContactAccess::RegExp:
418 return ( true ); 419 return ( true );
419 case OPimContactAccess::WildCards: 420 case OPimContactAccess::WildCards:
420 return ( true ); 421 return ( true );
421 case OPimContactAccess::ExactMatch: 422 case OPimContactAccess::ExactMatch:
422 return ( true ); 423 return ( true );
423 case 0: // one of the upper removed bits were set.. 424 case 0: // one of the upper removed bits were set..
424 return ( true ); 425 return ( true );
425 default: 426 default:
426 return ( false ); 427 return ( false );
427 } 428 }
428} 429}
429 430
430// Currently only asc implemented.. 431// Currently only asc implemented..
431QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) 432QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int )
432{ 433{
433 QMap<QString, int> nameToUid; 434 QMap<QString, int> nameToUid;
434 QStringList names; 435 QStringList names;
435 QArray<int> m_currentQuery( m_contactList.count() ); 436 QArray<int> m_currentQuery( m_contactList.count() );
436 437
437 // First fill map and StringList with all Names 438 // First fill map and StringList with all Names
438 // Afterwards sort namelist and use map to fill array to return.. 439 // Afterwards sort namelist and use map to fill array to return..
439 QListIterator<OPimContact> it( m_contactList ); 440 QListIterator<OPimContact> it( m_contactList );
440 for( ; it.current(); ++it ){ 441 for( ; it.current(); ++it ){
441 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 442 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
442 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 443 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
443 } 444 }
444 names.sort(); 445 names.sort();
445 446
446 int i = 0; 447 int i = 0;
447 if ( asc ){ 448 if ( asc ){
448 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 449 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
449 m_currentQuery[i++] = nameToUid[ (*it) ]; 450 m_currentQuery[i++] = nameToUid[ (*it) ];
450 }else{ 451 }else{
451 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 452 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
452 m_currentQuery[i++] = nameToUid[ (*it) ]; 453 m_currentQuery[i++] = nameToUid[ (*it) ];
453 } 454 }
454 455
455 return m_currentQuery; 456 return m_currentQuery;
456 457
457} 458}
458 459
459bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) 460bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact )
460{ 461{
461 //qWarning("odefaultbackend: ACTION::ADD"); 462 //qWarning("odefaultbackend: ACTION::ADD");
462 updateJournal (newcontact, ACTION_ADD); 463 updateJournal (newcontact, ACTION_ADD);
463 addContact_p( newcontact ); 464 addContact_p( newcontact );
464 465
465 m_changed = true; 466 m_changed = true;
466 467
467 return true; 468 return true;
468} 469}
469 470
470bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) 471bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact )
471{ 472{
472 m_changed = true; 473 m_changed = true;
473 474
474 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 475 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
475 476
476 if ( found ) { 477 if ( found ) {
477 OPimContact* newCont = new OPimContact( contact ); 478 OPimContact* newCont = new OPimContact( contact );
478 479
479 updateJournal ( *newCont, ACTION_REPLACE); 480 updateJournal ( *newCont, ACTION_REPLACE);
480 m_contactList.removeRef ( found ); 481 m_contactList.removeRef ( found );
481 m_contactList.append ( newCont ); 482 m_contactList.append ( newCont );
482 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 483 m_uidToContact.remove( QString().setNum( contact.uid() ) );
483 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 484 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
484 485
485 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 486 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
486 487
487 return true; 488 return true;
488 } else 489 } else
489 return false; 490 return false;
490} 491}
491 492
492bool OPimContactAccessBackend_XML::remove ( int uid ) 493bool OPimContactAccessBackend_XML::remove ( int uid )
493{ 494{
494 m_changed = true; 495 m_changed = true;
495 496
496 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 497 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) );
497 498
498 if ( found ) { 499 if ( found ) {
499 updateJournal ( *found, ACTION_REMOVE); 500 updateJournal ( *found, ACTION_REMOVE);
500 m_contactList.removeRef ( found ); 501 m_contactList.removeRef ( found );
501 m_uidToContact.remove( QString().setNum( uid ) ); 502 m_uidToContact.remove( QString().setNum( uid ) );
502 503
503 return true; 504 return true;
504 } else 505 } else
505 return false; 506 return false;
506} 507}
507 508
508bool OPimContactAccessBackend_XML::reload(){ 509bool OPimContactAccessBackend_XML::reload(){
509 /* Reload is the same as load in this implementation */ 510 /* Reload is the same as load in this implementation */
510 return ( load() ); 511 return ( load() );
511} 512}
512 513
513void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) 514void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact )
514{ 515{
515 OPimContact* contRef = new OPimContact( newcontact ); 516 OPimContact* contRef = new OPimContact( newcontact );
516 517
517 m_contactList.append ( contRef ); 518 m_contactList.append ( contRef );
518 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 519 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
519} 520}
520 521
521/* This function loads the xml-database and the journalfile */ 522/* This function loads the xml-database and the journalfile */
522bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) 523bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal )
523{ 524{
524 525
525 /* We use the time of the last read to check if the file was 526 /* We use the time of the last read to check if the file was
526 * changed externally. 527 * changed externally.
527 */ 528 */
528 if ( !isJournal ){ 529 if ( !isJournal ){
529 QFileInfo fi( filename ); 530 QFileInfo fi( filename );
530 m_readtime = fi.lastModified (); 531 m_readtime = fi.lastModified ();
531 } 532 }
532 533
533 const int JOURNALACTION = Qtopia::Notes + 1; 534 const int JOURNALACTION = Qtopia::Notes + 1;
534 const int JOURNALROW = JOURNALACTION + 1; 535 const int JOURNALROW = JOURNALACTION + 1;
535 536
536 bool foundAction = false; 537 bool foundAction = false;
537 journal_action action = ACTION_ADD; 538 journal_action action = ACTION_ADD;
538 int journalKey = 0; 539 int journalKey = 0;
539 QMap<int, QString> contactMap; 540 QMap<int, QString> contactMap;
540 QMap<QString, QString> customMap; 541 QMap<QString, QString> customMap;
541 QMap<QString, QString>::Iterator customIt; 542 QMap<QString, QString>::Iterator customIt;
542 QAsciiDict<int> dict( 47 ); 543 QAsciiDict<int> dict( 47 );
543 544
544 dict.setAutoDelete( TRUE ); 545 dict.setAutoDelete( TRUE );
545 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 546 dict.insert( "Uid", new int(Qtopia::AddressUid) );
546 dict.insert( "Title", new int(Qtopia::Title) ); 547 dict.insert( "Title", new int(Qtopia::Title) );
547 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 548 dict.insert( "FirstName", new int(Qtopia::FirstName) );
548 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 549 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
549 dict.insert( "LastName", new int(Qtopia::LastName) ); 550 dict.insert( "LastName", new int(Qtopia::LastName) );
550 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 551 dict.insert( "Suffix", new int(Qtopia::Suffix) );
551 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 552 dict.insert( "FileAs", new int(Qtopia::FileAs) );
552 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 553 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
553 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 554 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
554 dict.insert( "Emails", new int(Qtopia::Emails) ); 555 dict.insert( "Emails", new int(Qtopia::Emails) );
555 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 556 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
556 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 557 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
557 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 558 dict.insert( "HomeState", new int(Qtopia::HomeState) );
558 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 559 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
559 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 560 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
560 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 561 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
561 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 562 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
562 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 563 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
563 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 564 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
564 dict.insert( "Company", new int(Qtopia::Company) ); 565 dict.insert( "Company", new int(Qtopia::Company) );
565 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 566 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
566 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 567 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
567 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 568 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
568 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 569 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
569 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 570 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
570 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 571 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
571 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 572 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
572 dict.insert( "Department", new int(Qtopia::Department) ); 573 dict.insert( "Department", new int(Qtopia::Department) );
573 dict.insert( "Office", new int(Qtopia::Office) ); 574 dict.insert( "Office", new int(Qtopia::Office) );
574 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 575 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
575 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 576 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
576 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 577 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
577 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 578 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
578 dict.insert( "Profession", new int(Qtopia::Profession) ); 579 dict.insert( "Profession", new int(Qtopia::Profession) );
579 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 580 dict.insert( "Assistant", new int(Qtopia::Assistant) );
580 dict.insert( "Manager", new int(Qtopia::Manager) ); 581 dict.insert( "Manager", new int(Qtopia::Manager) );
581 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 582 dict.insert( "Spouse", new int(Qtopia::Spouse) );
582 dict.insert( "Children", new int(Qtopia::Children) ); 583 dict.insert( "Children", new int(Qtopia::Children) );
583 dict.insert( "Gender", new int(Qtopia::Gender) ); 584 dict.insert( "Gender", new int(Qtopia::Gender) );
584 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 585 dict.insert( "Birthday", new int(Qtopia::Birthday) );
585 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 586 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
586 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 587 dict.insert( "Nickname", new int(Qtopia::Nickname) );
587 dict.insert( "Notes", new int(Qtopia::Notes) ); 588 dict.insert( "Notes", new int(Qtopia::Notes) );
588 dict.insert( "action", new int(JOURNALACTION) ); 589 dict.insert( "action", new int(JOURNALACTION) );
589 dict.insert( "actionrow", new int(JOURNALROW) ); 590 dict.insert( "actionrow", new int(JOURNALROW) );
590 591
591 //qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() ); 592 //qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() );
592 593
593 XMLElement *root = XMLElement::load( filename ); 594 XMLElement *root = XMLElement::load( filename );
594 if(root != 0l ){ // start parsing 595 if(root != 0l ){ // start parsing
595 /* Parse all XML-Elements and put the data into the 596 /* Parse all XML-Elements and put the data into the
596 * Contact-Class 597 * Contact-Class
597 */ 598 */
598 XMLElement *element = root->firstChild(); 599 XMLElement *element = root->firstChild();
599 //qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() ); 600 //qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() );
600 element = element->firstChild(); 601 element = element->firstChild();
601 602
602 /* Search Tag "Contacts" which is the parent of all Contacts */ 603 /* Search Tag "Contacts" which is the parent of all Contacts */
603 while( element && !isJournal ){ 604 while( element && !isJournal ){
604 if( element->tagName() != QString::fromLatin1("Contacts") ){ 605 if( element->tagName() != QString::fromLatin1("Contacts") ){
605 //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 606 //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
606 // element->tagName().latin1()); 607 // element->tagName().latin1());
607 element = element->nextChild(); 608 element = element->nextChild();
608 } else { 609 } else {
609 element = element->firstChild(); 610 element = element->firstChild();
610 break; 611 break;
611 } 612 }
612 } 613 }
613 /* Parse all Contacts and ignore unknown tags */ 614 /* Parse all Contacts and ignore unknown tags */
614 while( element ){ 615 while( element ){
615 if( element->tagName() != QString::fromLatin1("Contact") ){ 616 if( element->tagName() != QString::fromLatin1("Contact") ){
616 //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s", 617 //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s",
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
index a779dc1..8a8cb0b 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
@@ -1,368 +1,432 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Calender Database. 30 * SQL Backend for the OPIE-Calender Database.
31 * 31 *
32 */ 32 */
33 33
34#include <stdio.h> 34#include <stdio.h>
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37#include <qarray.h> 37#include <qarray.h>
38#include <qstringlist.h> 38#include <qstringlist.h>
39 39
40#include <qpe/global.h> 40#include <qpe/global.h>
41 41
42#include <opie2/osqldriver.h> 42#include <opie2/osqldriver.h>
43#include <opie2/osqlmanager.h> 43#include <opie2/osqlmanager.h>
44#include <opie2/osqlquery.h> 44#include <opie2/osqlquery.h>
45 45
46#include <opie2/opimrecurrence.h> 46#include <opie2/opimrecurrence.h>
47#include <opie2/odatebookaccessbackend_sql.h> 47#include <opie2/odatebookaccessbackend_sql.h>
48 48
49using namespace Opie::DB; 49using namespace Opie::DB;
50 50
51namespace {
52 /**
53 * a find query for custom elements
54 */
55 class FindCustomQuery : public OSQLQuery {
56 public:
57 FindCustomQuery(int uid);
58 FindCustomQuery(const QArray<int>& );
59 ~FindCustomQuery();
60 QString query()const;
61 private:
62 QString single()const;
63 QString multi()const;
64 QArray<int> m_uids;
65 int m_uid;
66 };
67
68 FindCustomQuery::FindCustomQuery(int uid)
69 : OSQLQuery(), m_uid( uid ) {
70 }
71 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
72 : OSQLQuery(), m_uids( ints ){
73 }
74 FindCustomQuery::~FindCustomQuery() {
75 }
76 QString FindCustomQuery::query()const{
77 // if ( m_uids.count() == 0 )
78 return single();
79 }
80 QString FindCustomQuery::single()const{
81 QString qu = "select uid, type, value from custom_data where uid = ";
82 qu += QString::number(m_uid);
83 return qu;
84 }
85}
86
87
51namespace Opie { 88namespace Opie {
52 89
53 90
54ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , 91ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
55 const QString& fileName ) 92 const QString& fileName )
56 : ODateBookAccessBackend(), m_driver( NULL ) 93 : ODateBookAccessBackend(), m_driver( NULL )
57{ 94{
58 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; 95 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
59 96
60 // Get the standart sql-driver from the OSQLManager.. 97 // Get the standart sql-driver from the OSQLManager..
61 OSQLManager man; 98 OSQLManager man;
62 m_driver = man.standard(); 99 m_driver = man.standard();
63 m_driver->setUrl( m_fileName ); 100 m_driver->setUrl( m_fileName );
64 101
65 initFields(); 102 initFields();
66 103
67 load(); 104 load();
68} 105}
69 106
70ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { 107ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
71 if( m_driver ) 108 if( m_driver )
72 delete m_driver; 109 delete m_driver;
73} 110}
74 111
75void ODateBookAccessBackend_SQL::initFields() 112void ODateBookAccessBackend_SQL::initFields()
76{ 113{
77 114
78 // This map contains the translation of the fieldtype id's to 115 // This map contains the translation of the fieldtype id's to
79 // the names of the table columns 116 // the names of the table columns
80 m_fieldMap.insert( OPimEvent::FUid, "uid" ); 117 m_fieldMap.insert( OPimEvent::FUid, "uid" );
81 m_fieldMap.insert( OPimEvent::FCategories, "Categories" ); 118 m_fieldMap.insert( OPimEvent::FCategories, "Categories" );
82 m_fieldMap.insert( OPimEvent::FDescription, "Description" ); 119 m_fieldMap.insert( OPimEvent::FDescription, "Description" );
83 m_fieldMap.insert( OPimEvent::FLocation, "Location" ); 120 m_fieldMap.insert( OPimEvent::FLocation, "Location" );
84 m_fieldMap.insert( OPimEvent::FType, "Type" ); 121 m_fieldMap.insert( OPimEvent::FType, "Type" );
85 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" ); 122 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" );
86 m_fieldMap.insert( OPimEvent::FSound, "Sound" ); 123 m_fieldMap.insert( OPimEvent::FSound, "Sound" );
87 m_fieldMap.insert( OPimEvent::FRType, "RType" ); 124 m_fieldMap.insert( OPimEvent::FRType, "RType" );
88 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" ); 125 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" );
89 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" ); 126 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" );
90 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" ); 127 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" );
91 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" ); 128 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" );
92 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" ); 129 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" );
93 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" ); 130 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" );
94 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" ); 131 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" );
95 m_fieldMap.insert( OPimEvent::FStart, "Start" ); 132 m_fieldMap.insert( OPimEvent::FStart, "Start" );
96 m_fieldMap.insert( OPimEvent::FEnd, "End" ); 133 m_fieldMap.insert( OPimEvent::FEnd, "End" );
97 m_fieldMap.insert( OPimEvent::FNote, "Note" ); 134 m_fieldMap.insert( OPimEvent::FNote, "Note" );
98 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" ); 135 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" );
99 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" ); 136 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" );
100 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" ); 137 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" );
101 138
102 // Create a map that maps the column name to the id 139 // Create a map that maps the column name to the id
103 QMapConstIterator<int, QString> it; 140 QMapConstIterator<int, QString> it;
104 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 141 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
105 m_reverseFieldMap.insert( it.data(), it.key() ); 142 m_reverseFieldMap.insert( it.data(), it.key() );
106 } 143 }
107 144
108} 145}
109 146
110bool ODateBookAccessBackend_SQL::load() 147bool ODateBookAccessBackend_SQL::load()
111{ 148{
112 if (!m_driver->open() ) 149 if (!m_driver->open() )
113 return false; 150 return false;
114 151
115 // Don't expect that the database exists. 152 // Don't expect that the database exists.
116 // It is save here to create the table, even if it 153 // It is save here to create the table, even if it
117 // do exist. ( Is that correct for all databases ?? ) 154 // do exist. ( Is that correct for all databases ?? )
118 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; 155 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY ";
119 156
120 QMap<int, QString>::Iterator it; 157 QMap<int, QString>::Iterator it;
121 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 158 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
122 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); 159 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() );
123 } 160 }
124 qu += " );"; 161 qu += " );";
125 162
126 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 163 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
127 164
128 qWarning( "command: %s", qu.latin1() ); 165 qWarning( "command: %s", qu.latin1() );
129 166
130 OSQLRawQuery raw( qu ); 167 OSQLRawQuery raw( qu );
131 OSQLResult res = m_driver->query( &raw ); 168 OSQLResult res = m_driver->query( &raw );
132 if ( res.state() != OSQLResult::Success ) 169 if ( res.state() != OSQLResult::Success )
133 return false; 170 return false;
134 171
135 update(); 172 update();
136 173
137 return true; 174 return true;
138} 175}
139 176
140void ODateBookAccessBackend_SQL::update() 177void ODateBookAccessBackend_SQL::update()
141{ 178{
142 179
143 QString qu = "select uid from datebook"; 180 QString qu = "select uid from datebook";
144 OSQLRawQuery raw( qu ); 181 OSQLRawQuery raw( qu );
145 OSQLResult res = m_driver->query( &raw ); 182 OSQLResult res = m_driver->query( &raw );
146 if ( res.state() != OSQLResult::Success ){ 183 if ( res.state() != OSQLResult::Success ){
147 // m_uids.clear(); 184 // m_uids.clear();
148 return; 185 return;
149 } 186 }
150 187
151 m_uids = extractUids( res ); 188 m_uids = extractUids( res );
152 189
153} 190}
154 191
155bool ODateBookAccessBackend_SQL::reload() 192bool ODateBookAccessBackend_SQL::reload()
156{ 193{
157 return load(); 194 return load();
158} 195}
159 196
160bool ODateBookAccessBackend_SQL::save() 197bool ODateBookAccessBackend_SQL::save()
161{ 198{
162 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 199 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
163} 200}
164 201
165QArray<int> ODateBookAccessBackend_SQL::allRecords()const 202QArray<int> ODateBookAccessBackend_SQL::allRecords()const
166{ 203{
167 return m_uids; 204 return m_uids;
168} 205}
169 206
170QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) { 207QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) {
171 return QArray<int>(); 208 return QArray<int>();
172} 209}
173 210
174void ODateBookAccessBackend_SQL::clear() 211void ODateBookAccessBackend_SQL::clear()
175{ 212{
176 QString qu = "drop table datebook;"; 213 QString qu = "drop table datebook;";
177 qu += "drop table custom_data;"; 214 qu += "drop table custom_data;";
178 215
179 OSQLRawQuery raw( qu ); 216 OSQLRawQuery raw( qu );
180 OSQLResult res = m_driver->query( &raw ); 217 OSQLResult res = m_driver->query( &raw );
181 218
182 reload(); 219 reload();
183} 220}
184 221
185 222
186OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ 223OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{
187 QString qu = "select *"; 224 QString qu = "select *";
188 qu += "from datebook where uid = " + QString::number(uid); 225 qu += "from datebook where uid = " + QString::number(uid);
189 226
190 OSQLRawQuery raw( qu ); 227 OSQLRawQuery raw( qu );
191 OSQLResult res = m_driver->query( &raw ); 228 OSQLResult res = m_driver->query( &raw );
192 229
193 OSQLResultItem resItem = res.first(); 230 OSQLResultItem resItem = res.first();
194 231
195 // Create Map for date event and insert UID 232 // Create Map for date event and insert UID
196 QMap<int,QString> dateEventMap; 233 QMap<int,QString> dateEventMap;
197 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) ); 234 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) );
198 235
199 // Now insert the data out of the columns into the map. 236 // Now insert the data out of the columns into the map.
200 QMapConstIterator<int, QString> it; 237 QMapConstIterator<int, QString> it;
201 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 238 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
202 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); 239 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) );
203 } 240 }
204 241
205 // Last step: Put map into date event and return it 242 // Last step: Put map into date event, add custom map and return it
206 OPimEvent retDate( dateEventMap ); 243 OPimEvent retDate( dateEventMap );
207 244 retDate.setExtraMap( requestCustom( uid ) );
208 return retDate; 245 return retDate;
209} 246}
210 247
211// FIXME: Speed up update of uid's.. 248// FIXME: Speed up update of uid's..
212bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) 249bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev )
213{ 250{
214 QMap<int,QString> eventMap = ev.toMap(); 251 QMap<int,QString> eventMap = ev.toMap();
215 252
216 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); 253 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() );
217 QMap<int, QString>::Iterator it; 254 QMap<int, QString>::Iterator it;
218 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 255 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
219 if ( !eventMap[it.key()].isEmpty() ) 256 if ( !eventMap[it.key()].isEmpty() )
220 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); 257 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] );
221 else 258 else
222 qu += QString( ",\"\"" ); 259 qu += QString( ",\"\"" );
223 } 260 }
224 qu += " );"; 261 qu += " );";
225 262
226 // Add custom entries 263 // Add custom entries
227 int id = 0; 264 int id = 0;
228 QMap<QString, QString> customMap = ev.toExtraMap(); 265 QMap<QString, QString> customMap = ev.toExtraMap();
229 for( QMap<QString, QString>::Iterator it = customMap.begin(); 266 for( QMap<QString, QString>::Iterator it = customMap.begin();
230 it != customMap.end(); ++it ){ 267 it != customMap.end(); ++it ){
231 qu += "insert into custom_data VALUES(" 268 qu += "insert into custom_data VALUES("
232 + QString::number( ev.uid() ) 269 + QString::number( ev.uid() )
233 + "," 270 + ","
234 + QString::number( id++ ) 271 + QString::number( id++ )
235 + ",'" 272 + ",'"
236 + it.key() //.latin1() 273 + it.key() //.latin1()
237 + "'," 274 + "',"
238 + "0" // Priority for future enhancements 275 + "0" // Priority for future enhancements
239 + ",'" 276 + ",'"
240 + it.data() //.latin1() 277 + it.data() //.latin1()
241 + "');"; 278 + "');";
242 } 279 }
243 qWarning("add %s", qu.latin1() ); 280 qWarning("add %s", qu.latin1() );
244 281
245 OSQLRawQuery raw( qu ); 282 OSQLRawQuery raw( qu );
246 OSQLResult res = m_driver->query( &raw ); 283 OSQLResult res = m_driver->query( &raw );
247 if ( res.state() != OSQLResult::Success ){ 284 if ( res.state() != OSQLResult::Success ){
248 return false; 285 return false;
249 } 286 }
250 287
251 // Update list of uid's 288 // Update list of uid's
252 update(); 289 update();
253 290
254 return true; 291 return true;
255} 292}
256 293
257// FIXME: Speed up update of uid's.. 294// FIXME: Speed up update of uid's..
258bool ODateBookAccessBackend_SQL::remove( int uid ) 295bool ODateBookAccessBackend_SQL::remove( int uid )
259{ 296{
260 QString qu = "DELETE from datebook where uid = " 297 QString qu = "DELETE from datebook where uid = "
261 + QString::number( uid ) + ";"; 298 + QString::number( uid ) + ";";
262 qu += "DELETE from custom_data where uid = " 299 qu += "DELETE from custom_data where uid = "
263 + QString::number( uid ) + ";"; 300 + QString::number( uid ) + ";";
264 301
265 OSQLRawQuery raw( qu ); 302 OSQLRawQuery raw( qu );
266 OSQLResult res = m_driver->query( &raw ); 303 OSQLResult res = m_driver->query( &raw );
267 if ( res.state() != OSQLResult::Success ){ 304 if ( res.state() != OSQLResult::Success ){
268 return false; 305 return false;
269 } 306 }
270 307
271 // Update list of uid's 308 // Update list of uid's
272 update(); 309 update();
273 310
274 return true; 311 return true;
275} 312}
276 313
277bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev ) 314bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev )
278{ 315{
279 remove( ev.uid() ); 316 remove( ev.uid() );
280 return add( ev ); 317 return add( ev );
281} 318}
282 319
283QArray<int> ODateBookAccessBackend_SQL::rawEvents()const 320QArray<int> ODateBookAccessBackend_SQL::rawEvents()const
284{ 321{
285 return allRecords(); 322 return allRecords();
286} 323}
287 324
288QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const 325QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const
289{ 326{
290 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; 327 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\"";
291 OSQLRawQuery raw( qu ); 328 OSQLRawQuery raw( qu );
292 OSQLResult res = m_driver->query( &raw ); 329 OSQLResult res = m_driver->query( &raw );
293 if ( res.state() != OSQLResult::Success ){ 330 if ( res.state() != OSQLResult::Success ){
294 QArray<int> nix; 331 QArray<int> nix;
295 return nix; 332 return nix;
296 } 333 }
297 334
298 return extractUids( res ); 335 return extractUids( res );
299} 336}
300 337
301QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const 338QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const
302{ 339{
303 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; 340 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\"";
304 OSQLRawQuery raw( qu ); 341 OSQLRawQuery raw( qu );
305 OSQLResult res = m_driver->query( &raw ); 342 OSQLResult res = m_driver->query( &raw );
306 if ( res.state() != OSQLResult::Success ){ 343 if ( res.state() != OSQLResult::Success ){
307 QArray<int> nix; 344 QArray<int> nix;
308 return nix; 345 return nix;
309 } 346 }
310 347
311 return extractUids( res ); 348 return extractUids( res );
312} 349}
313 350
314OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() 351OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats()
315{ 352{
316 QArray<int> nonRepUids = nonRepeats(); 353 QArray<int> nonRepUids = nonRepeats();
317 OPimEvent::ValueList list; 354 OPimEvent::ValueList list;
318 355
319 for (uint i = 0; i < nonRepUids.count(); ++i ){ 356 for (uint i = 0; i < nonRepUids.count(); ++i ){
320 list.append( find( nonRepUids[i] ) ); 357 list.append( find( nonRepUids[i] ) );
321 } 358 }
322 359
323 return list; 360 return list;
324 361
325} 362}
326OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() 363OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()
327{ 364{
328 QArray<int> rawRepUids = rawRepeats(); 365 QArray<int> rawRepUids = rawRepeats();
329 OPimEvent::ValueList list; 366 OPimEvent::ValueList list;
330 367
331 for (uint i = 0; i < rawRepUids.count(); ++i ){ 368 for (uint i = 0; i < rawRepUids.count(); ++i ){
332 list.append( find( rawRepUids[i] ) ); 369 list.append( find( rawRepUids[i] ) );
333 } 370 }
334 371
335 return list; 372 return list;
336} 373}
337 374
338 375
339QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 376QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
340{ 377{
341 QArray<int> null; 378 QArray<int> null;
342 return null; 379 return null;
343} 380}
344 381
345/* ===== Private Functions ========================================== */ 382/* ===== Private Functions ========================================== */
346 383
347QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const 384QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const
348{ 385{
349 qWarning("extractUids"); 386 qWarning("extractUids");
350 QTime t; 387 QTime t;
351 t.start(); 388 t.start();
352 OSQLResultItem::ValueList list = res.results(); 389 OSQLResultItem::ValueList list = res.results();
353 OSQLResultItem::ValueList::Iterator it; 390 OSQLResultItem::ValueList::Iterator it;
354 QArray<int> ints(list.count() ); 391 QArray<int> ints(list.count() );
355 qWarning(" count = %d", list.count() ); 392 qWarning(" count = %d", list.count() );
356 393
357 int i = 0; 394 int i = 0;
358 for (it = list.begin(); it != list.end(); ++it ) { 395 for (it = list.begin(); it != list.end(); ++it ) {
359 ints[i] = (*it).data("uid").toInt(); 396 ints[i] = (*it).data("uid").toInt();
360 i++; 397 i++;
361 } 398 }
362 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 399 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
363 400
364 return ints; 401 return ints;
365 402
366} 403}
367 404
405QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const
406{
407 QTime t;
408 t.start();
409
410 QMap<QString, QString> customMap;
411
412 FindCustomQuery query( uid );
413 OSQLResult res_custom = m_driver->query( &query );
414
415 if ( res_custom.state() == OSQLResult::Failure ) {
416 qWarning("OSQLResult::Failure in find query !!");
417 QMap<QString, QString> empty;
418 return empty;
419 }
420
421 OSQLResultItem::ValueList list = res_custom.results();
422 OSQLResultItem::ValueList::Iterator it = list.begin();
423 for ( ; it != list.end(); ++it ) {
424 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
425 }
426
427 qDebug("RequestCustom needed: %d ms", t.elapsed() );
428 return customMap;
429}
430
431
368} 432}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
index 60d7f21..b624159 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
@@ -1,97 +1,99 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
31 31
32#include <qmap.h> 32#include <qmap.h>
33#include <opie2/osqlresult.h> 33#include <opie2/osqlresult.h>
34 34
35#include <opie2/odatebookaccessbackend.h> 35#include <opie2/odatebookaccessbackend.h>
36 36
37namespace Opie { 37namespace Opie {
38namespace DB { 38namespace DB {
39class OSQLDriver; 39class OSQLDriver;
40} 40}
41} 41}
42 42
43namespace Opie { 43namespace Opie {
44/** 44/**
45 * This is the default SQL implementation for DateBoook SQL storage 45 * This is the default SQL implementation for DateBoook SQL storage
46 * It fully implements the interface 46 * It fully implements the interface
47 * @see ODateBookAccessBackend 47 * @see ODateBookAccessBackend
48 * @see OPimAccessBackend 48 * @see OPimAccessBackend
49 */ 49 */
50class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { 50class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
51public: 51public:
52 ODateBookAccessBackend_SQL( const QString& appName, 52 ODateBookAccessBackend_SQL( const QString& appName,
53 const QString& fileName = QString::null); 53 const QString& fileName = QString::null);
54 ~ODateBookAccessBackend_SQL(); 54 ~ODateBookAccessBackend_SQL();
55 55
56 bool load(); 56 bool load();
57 bool reload(); 57 bool reload();
58 bool save(); 58 bool save();
59 59
60 QArray<int> allRecords()const; 60 QArray<int> allRecords()const;
61 QArray<int> matchRegexp(const QRegExp &r) const; 61 QArray<int> matchRegexp(const QRegExp &r) const;
62 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); 62 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() );
63 OPimEvent find( int uid )const; 63 OPimEvent find( int uid )const;
64 void clear(); 64 void clear();
65 bool add( const OPimEvent& ev ); 65 bool add( const OPimEvent& ev );
66 bool remove( int uid ); 66 bool remove( int uid );
67 bool replace( const OPimEvent& ev ); 67 bool replace( const OPimEvent& ev );
68 68
69 QArray<UID> rawEvents()const; 69 QArray<UID> rawEvents()const;
70 QArray<UID> rawRepeats()const; 70 QArray<UID> rawRepeats()const;
71 QArray<UID> nonRepeats()const; 71 QArray<UID> nonRepeats()const;
72 72
73 OPimEvent::ValueList directNonRepeats(); 73 OPimEvent::ValueList directNonRepeats();
74 OPimEvent::ValueList directRawRepeats(); 74 OPimEvent::ValueList directRawRepeats();
75 75
76private: 76private:
77 bool loadFile(); 77 bool loadFile();
78 QString m_fileName; 78 QString m_fileName;
79 QArray<int> m_uids; 79 QArray<int> m_uids;
80 80
81 QMap<int, QString> m_fieldMap; 81 QMap<int, QString> m_fieldMap;
82 QMap<QString, int> m_reverseFieldMap; 82 QMap<QString, int> m_reverseFieldMap;
83 83
84 Opie::DB::OSQLDriver* m_driver; 84 Opie::DB::OSQLDriver* m_driver;
85 85
86 class Private; 86 class Private;
87 Private *d; 87 Private *d;
88 88
89 void initFields(); 89 void initFields();
90 void update(); 90 void update();
91
91 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; 92 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const;
93 QMap<QString, QString> requestCustom( int uid ) const;
92 94
93}; 95};
94 96
95} 97}
96 98
97#endif 99#endif
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index d218090..b4170fc 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -1,728 +1,839 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 Copyright (C) Holger Freyther (zecke@handhelds.org)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 5 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 6 .=l.
6 .>+-= 7 .>+-=
7 _;:, .> :=|. This program is free software; you can 8 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 9.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 10:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 11.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 12 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 13 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 14 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 15 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 16 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 17 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 18 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 19 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 20..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 21++= -. .` .: details.
21 : = ...= . :.=- 22 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 23 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 24 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 25 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 26 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 27 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 28 Boston, MA 02111-1307, USA.
28*/ 29*/
29 30
30#include <qdatetime.h> 31#include <qdatetime.h>
32#include <qmap.h>
33#include <qstring.h>
31 34
32#include <qpe/global.h> 35#include <qpe/global.h>
33 36
34#include <opie2/osqldriver.h> 37#include <opie2/osqldriver.h>
35#include <opie2/osqlresult.h> 38#include <opie2/osqlresult.h>
36#include <opie2/osqlmanager.h> 39#include <opie2/osqlmanager.h>
37#include <opie2/osqlquery.h> 40#include <opie2/osqlquery.h>
38 41
39#include <opie2/otodoaccesssql.h> 42#include <opie2/otodoaccesssql.h>
40#include <opie2/opimstate.h> 43#include <opie2/opimstate.h>
41#include <opie2/opimnotifymanager.h> 44#include <opie2/opimnotifymanager.h>
42#include <opie2/opimrecurrence.h> 45#include <opie2/opimrecurrence.h>
43 46
44using namespace Opie::DB; 47using namespace Opie::DB;
45 48
46using namespace Opie; 49using namespace Opie;
47/* 50/*
48 * first some query 51 * first some query
49 * CREATE query 52 * CREATE query
50 * LOAD query 53 * LOAD query
51 * INSERT 54 * INSERT
52 * REMOVE 55 * REMOVE
53 * CLEAR 56 * CLEAR
54 */ 57 */
55namespace { 58namespace {
56 /** 59 /**
57 * CreateQuery for the Todolist Table 60 * CreateQuery for the Todolist Table
58 */ 61 */
59 class CreateQuery : public OSQLQuery { 62 class CreateQuery : public OSQLQuery {
60 public: 63 public:
61 CreateQuery(); 64 CreateQuery();
62 ~CreateQuery(); 65 ~CreateQuery();
63 QString query()const; 66 QString query()const;
64 }; 67 };
65 68
66 /** 69 /**
67 * LoadQuery 70 * LoadQuery
68 * this one queries for all uids 71 * this one queries for all uids
69 */ 72 */
70 class LoadQuery : public OSQLQuery { 73 class LoadQuery : public OSQLQuery {
71 public: 74 public:
72 LoadQuery(); 75 LoadQuery();
73 ~LoadQuery(); 76 ~LoadQuery();
74 QString query()const; 77 QString query()const;
75 }; 78 };
76 79
77 /** 80 /**
78 * inserts/adds a OPimTodo to the table 81 * inserts/adds a OPimTodo to the table
79 */ 82 */
80 class InsertQuery : public OSQLQuery { 83 class InsertQuery : public OSQLQuery {
81 public: 84 public:
82 InsertQuery(const OPimTodo& ); 85 InsertQuery(const OPimTodo& );
83 ~InsertQuery(); 86 ~InsertQuery();
84 QString query()const; 87 QString query()const;
85 private: 88 private:
86 OPimTodo m_todo; 89 OPimTodo m_todo;
87 }; 90 };
88 91
89 /** 92 /**
90 * removes one from the table 93 * removes one from the table
91 */ 94 */
92 class RemoveQuery : public OSQLQuery { 95 class RemoveQuery : public OSQLQuery {
93 public: 96 public:
94 RemoveQuery(int uid ); 97 RemoveQuery(int uid );
95 ~RemoveQuery(); 98 ~RemoveQuery();
96 QString query()const; 99 QString query()const;
97 private: 100 private:
98 int m_uid; 101 int m_uid;
99 }; 102 };
100 103
101 /** 104 /**
102 * Clears (delete) a Table 105 * Clears (delete) a Table
103 */ 106 */
104 class ClearQuery : public OSQLQuery { 107 class ClearQuery : public OSQLQuery {
105 public: 108 public:
106 ClearQuery(); 109 ClearQuery();
107 ~ClearQuery(); 110 ~ClearQuery();
108 QString query()const; 111 QString query()const;
109 112
110 }; 113 };
111 114
112 /** 115 /**
113 * a find query 116 * a find query
114 */ 117 */
115 class FindQuery : public OSQLQuery { 118 class FindQuery : public OSQLQuery {
116 public: 119 public:
117 FindQuery(int uid); 120 FindQuery(int uid);
118 FindQuery(const QArray<int>& ); 121 FindQuery(const QArray<int>& );
119 ~FindQuery(); 122 ~FindQuery();
120 QString query()const; 123 QString query()const;
121 private: 124 private:
122 QString single()const; 125 QString single()const;
123 QString multi()const; 126 QString multi()const;
124 QArray<int> m_uids; 127 QArray<int> m_uids;
125 int m_uid; 128 int m_uid;
126 }; 129 };
127 130
128 /** 131 /**
129 * overdue query 132 * overdue query
130 */ 133 */
131 class OverDueQuery : public OSQLQuery { 134 class OverDueQuery : public OSQLQuery {
132 public: 135 public:
133 OverDueQuery(); 136 OverDueQuery();
134 ~OverDueQuery(); 137 ~OverDueQuery();
135 QString query()const; 138 QString query()const;
136 }; 139 };
137 class EffQuery : public OSQLQuery { 140 class EffQuery : public OSQLQuery {
138 public: 141 public:
139 EffQuery( const QDate&, const QDate&, bool inc ); 142 EffQuery( const QDate&, const QDate&, bool inc );
140 ~EffQuery(); 143 ~EffQuery();
141 QString query()const; 144 QString query()const;
142 private: 145 private:
143 QString with()const; 146 QString with()const;
144 QString out()const; 147 QString out()const;
145 QDate m_start; 148 QDate m_start;
146 QDate m_end; 149 QDate m_end;
147 bool m_inc :1; 150 bool m_inc :1;
148 }; 151 };
149 152
150 153
154 /**
155 * a find query for custom elements
156 */
157 class FindCustomQuery : public OSQLQuery {
158 public:
159 FindCustomQuery(int uid);
160 FindCustomQuery(const QArray<int>& );
161 ~FindCustomQuery();
162 QString query()const;
163 private:
164 QString single()const;
165 QString multi()const;
166 QArray<int> m_uids;
167 int m_uid;
168 };
169
170
171
151 CreateQuery::CreateQuery() : OSQLQuery() {} 172 CreateQuery::CreateQuery() : OSQLQuery() {}
152 CreateQuery::~CreateQuery() {} 173 CreateQuery::~CreateQuery() {}
153 QString CreateQuery::query()const { 174 QString CreateQuery::query()const {
154 QString qu; 175 QString qu;
155 qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; 176 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
156 qu += "description, summary, priority, DueDate, progress , state, "; 177 qu += "description, summary, priority, DueDate, progress , state, ";
157 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) 178 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers)
158 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; 179 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, ";
159 qu += "reminders, alarms, maintainer, startdate, completeddate);"; 180 qu += "reminders, alarms, maintainer, startdate, completeddate);";
160 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 181 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
161 return qu; 182 return qu;
162 } 183 }
163 184
164 LoadQuery::LoadQuery() : OSQLQuery() {} 185 LoadQuery::LoadQuery() : OSQLQuery() {}
165 LoadQuery::~LoadQuery() {} 186 LoadQuery::~LoadQuery() {}
166 QString LoadQuery::query()const { 187 QString LoadQuery::query()const {
167 QString qu; 188 QString qu;
168 // We do not need "distinct" here. The primary key is always unique.. 189 // We do not need "distinct" here. The primary key is always unique..
169 //qu += "select distinct uid from todolist"; 190 //qu += "select distinct uid from todolist";
170 qu += "select uid from todolist"; 191 qu += "select uid from todolist";
171 192
172 return qu; 193 return qu;
173 } 194 }
174 195
175 InsertQuery::InsertQuery( const OPimTodo& todo ) 196 InsertQuery::InsertQuery( const OPimTodo& todo )
176 : OSQLQuery(), m_todo( todo ) { 197 : OSQLQuery(), m_todo( todo ) {
177 } 198 }
178 InsertQuery::~InsertQuery() { 199 InsertQuery::~InsertQuery() {
179 } 200 }
180 /* 201 /*
181 * converts from a OPimTodo to a query 202 * converts from a OPimTodo to a query
182 * we leave out X-Ref + Alarms 203 * we leave out X-Ref + Maintainer
204 * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding
205 * decoding stuff there.. (eilers)
183 */ 206 */
184 QString InsertQuery::query()const{ 207 QString InsertQuery::query()const{
185 208
186 int year, month, day; 209 int year, month, day;
187 year = month = day = 0; 210 year = month = day = 0;
188 if (m_todo.hasDueDate() ) { 211 if (m_todo.hasDueDate() ) {
189 QDate date = m_todo.dueDate(); 212 QDate date = m_todo.dueDate();
190 year = date.year(); 213 year = date.year();
191 month = date.month(); 214 month = date.month();
192 day = date.day(); 215 day = date.day();
193 } 216 }
194 int sYear = 0, sMonth = 0, sDay = 0; 217 int sYear = 0, sMonth = 0, sDay = 0;
195 if( m_todo.hasStartDate() ){ 218 if( m_todo.hasStartDate() ){
196 QDate sDate = m_todo.startDate(); 219 QDate sDate = m_todo.startDate();
197 sYear = sDate.year(); 220 sYear = sDate.year();
198 sMonth= sDate.month(); 221 sMonth= sDate.month();
199 sDay = sDate.day(); 222 sDay = sDate.day();
200 } 223 }
201 224
202 int eYear = 0, eMonth = 0, eDay = 0; 225 int eYear = 0, eMonth = 0, eDay = 0;
203 if( m_todo.hasCompletedDate() ){ 226 if( m_todo.hasCompletedDate() ){
204 QDate eDate = m_todo.completedDate(); 227 QDate eDate = m_todo.completedDate();
205 eYear = eDate.year(); 228 eYear = eDate.year();
206 eMonth= eDate.month(); 229 eMonth= eDate.month();
207 eDay = eDate.day(); 230 eDay = eDate.day();
208 } 231 }
209 QString qu; 232 QString qu;
210 QMap<int, QString> recMap = m_todo.recurrence().toMap(); 233 QMap<int, QString> recMap = m_todo.recurrence().toMap();
211 qu = "insert into todolist VALUES(" 234 qu = "insert into todolist VALUES("
212 + QString::number( m_todo.uid() ) + "," 235 + QString::number( m_todo.uid() ) + ","
213 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," 236 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
214 + QString::number( m_todo.isCompleted() ) + "," 237 + QString::number( m_todo.isCompleted() ) + ","
215 + "'" + m_todo.description() + "'" + "," 238 + "'" + m_todo.description() + "'" + ","
216 + "'" + m_todo.summary() + "'" + "," 239 + "'" + m_todo.summary() + "'" + ","
217 + QString::number(m_todo.priority() ) + "," 240 + QString::number(m_todo.priority() ) + ","
218 + "'" + QString::number(year) + "-" 241 + "'" + QString::number(year).rightJustify( 4, '0' ) + "-"
219 + QString::number(month) 242 + QString::number(month).rightJustify( 2, '0' )
220 + "-" + QString::number( day ) + "'" + "," 243 + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + ","
221 + QString::number( m_todo.progress() ) + "," 244 + QString::number( m_todo.progress() ) + ","
222 + QString::number( m_todo.state().state() ) + "," 245 + QString::number( m_todo.state().state() ) + ","
223 + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," 246 + "'" + recMap[ OPimRecurrence::RType ] + "'" + ","
224 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," 247 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + ","
225 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," 248 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + ","
226 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," 249 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + ","
227 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," 250 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + ","
228 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," 251 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + ","
229 + "'" + recMap[ OPimRecurrence::Created ] + "'" + "," 252 + "'" + recMap[ OPimRecurrence::Created ] + "'" + ","
230 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ","; 253 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ",";
231 254
232 if ( m_todo.hasNotifiers() ) { 255 if ( m_todo.hasNotifiers() ) {
233 OPimNotifyManager manager = m_todo.notifiers(); 256 OPimNotifyManager manager = m_todo.notifiers();
234 qu += "'" + manager.remindersToString() + "'" + "," 257 qu += "'" + manager.remindersToString() + "'" + ","
235 + "'" + manager.alarmsToString() + "'" + ","; 258 + "'" + manager.alarmsToString() + "'" + ",";
236 } 259 }
237 else{ 260 else{
238 qu += QString( "''" ) + "," 261 qu += QString( "''" ) + ","
239 + "''" + ","; 262 + "''" + ",";
240 } 263 }
241 264
242 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) 265 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !)
243 + "'" + QString::number(sYear) + "-" 266 + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-"
244 + QString::number(sMonth) 267 + QString::number(sMonth).rightJustify( 2, '0' )
245 + "-" + QString::number(sDay) + "'" + "," 268 + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + ","
246 + "'" + QString::number(eYear) + "-" 269 + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-"
247 + QString::number(eMonth) 270 + QString::number(eMonth).rightJustify( 2, '0' )
248 + "-"+QString::number(eDay) + "'" 271 + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'"
249 + ")"; 272 + ")";
250 273
251 qWarning("add %s", qu.latin1() ); 274 // Save custom Entries:
275 int id = 0;
276 id = 0;
277 QMap<QString, QString> customMap = m_todo.toExtraMap();
278 for( QMap<QString, QString>::Iterator it = customMap.begin();
279 it != customMap.end(); ++it ){
280 qu += "insert into custom_data VALUES("
281 + QString::number( m_todo.uid() )
282 + ","
283 + QString::number( id++ )
284 + ",'"
285 + it.key()
286 + "',"
287 + "0" // Priority for future enhancements
288 + ",'"
289 + it.data()
290 + "');";
291 }
292
293
294 qDebug("add %s", qu.latin1() );
252 return qu; 295 return qu;
253 } 296 }
254 297
255 RemoveQuery::RemoveQuery(int uid ) 298 RemoveQuery::RemoveQuery(int uid )
256 : OSQLQuery(), m_uid( uid ) {} 299 : OSQLQuery(), m_uid( uid ) {}
257 RemoveQuery::~RemoveQuery() {} 300 RemoveQuery::~RemoveQuery() {}
258 QString RemoveQuery::query()const { 301 QString RemoveQuery::query()const {
259 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 302 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
260 return qu; 303 return qu;
261 } 304 }
262 305
263 306
264 ClearQuery::ClearQuery() 307 ClearQuery::ClearQuery()
265 : OSQLQuery() {} 308 : OSQLQuery() {}
266 ClearQuery::~ClearQuery() {} 309 ClearQuery::~ClearQuery() {}
267 QString ClearQuery::query()const { 310 QString ClearQuery::query()const {
268 QString qu = "drop table todolist"; 311 QString qu = "drop table todolist";
269 return qu; 312 return qu;
270 } 313 }
271 FindQuery::FindQuery(int uid) 314 FindQuery::FindQuery(int uid)
272 : OSQLQuery(), m_uid(uid ) { 315 : OSQLQuery(), m_uid(uid ) {
273 } 316 }
274 FindQuery::FindQuery(const QArray<int>& ints) 317 FindQuery::FindQuery(const QArray<int>& ints)
275 : OSQLQuery(), m_uids(ints){ 318 : OSQLQuery(), m_uids(ints){
276 } 319 }
277 FindQuery::~FindQuery() { 320 FindQuery::~FindQuery() {
278 } 321 }
279 QString FindQuery::query()const{ 322 QString FindQuery::query()const{
280 if (m_uids.count() == 0 ) 323 if (m_uids.count() == 0 )
281 return single(); 324 return single();
282 else 325 else
283 return multi(); 326 return multi();
284 } 327 }
285 QString FindQuery::single()const{ 328 QString FindQuery::single()const{
286 QString qu = "select * from todolist where uid = " + QString::number(m_uid); 329 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
287 return qu; 330 return qu;
288 } 331 }
289 QString FindQuery::multi()const { 332 QString FindQuery::multi()const {
290 QString qu = "select * from todolist where "; 333 QString qu = "select * from todolist where ";
291 for (uint i = 0; i < m_uids.count(); i++ ) { 334 for (uint i = 0; i < m_uids.count(); i++ ) {
292 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 335 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
293 } 336 }
294 qu.remove( qu.length()-2, 2 ); 337 qu.remove( qu.length()-2, 2 );
295 return qu; 338 return qu;
296 } 339 }
297 340
298 OverDueQuery::OverDueQuery(): OSQLQuery() {} 341 OverDueQuery::OverDueQuery(): OSQLQuery() {}
299 OverDueQuery::~OverDueQuery() {} 342 OverDueQuery::~OverDueQuery() {}
300 QString OverDueQuery::query()const { 343 QString OverDueQuery::query()const {
301 QDate date = QDate::currentDate(); 344 QDate date = QDate::currentDate();
302 QString str; 345 QString str;
303 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 346 str = QString("select uid from todolist where DueDate ='%1-%2-%3'")
347 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) )
348 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) )
349 .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) );
304 350
305 return str; 351 return str;
306 } 352 }
307 353
308 354
309 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 355 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
310 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 356 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
311 EffQuery::~EffQuery() {} 357 EffQuery::~EffQuery() {}
312 QString EffQuery::query()const { 358 QString EffQuery::query()const {
313 return m_inc ? with() : out(); 359 return m_inc ? with() : out();
314 } 360 }
315 QString EffQuery::with()const { 361 QString EffQuery::with()const {
316 QString str; 362 QString str;
317 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 363 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
318 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 364 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) )
319 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 365 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) )
366 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) )
367 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) )
368 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) )
369 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) );
320 return str; 370 return str;
321 } 371 }
322 QString EffQuery::out()const { 372 QString EffQuery::out()const {
323 QString str; 373 QString str;
324 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 374 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
325 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 375 .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) )
326 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 376 .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) )
377 .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) )
378 .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) )
379 .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) )
380 .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) );
327 381
328 return str; 382 return str;
329 } 383 }
384
385 FindCustomQuery::FindCustomQuery(int uid)
386 : OSQLQuery(), m_uid( uid ) {
387 }
388 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
389 : OSQLQuery(), m_uids( ints ){
390 }
391 FindCustomQuery::~FindCustomQuery() {
392 }
393 QString FindCustomQuery::query()const{
394 return single(); // Multiple requests not supported !
395 }
396 QString FindCustomQuery::single()const{
397 QString qu = "select uid, type, value from custom_data where uid = ";
398 qu += QString::number(m_uid);
399 return qu;
400 }
401
330}; 402};
331 403
332 404
333namespace Opie { 405namespace Opie {
334OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) 406OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file )
335 : OPimTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) 407 : OPimTodoAccessBackend(),/* m_dict(15),*/ m_driver(NULL), m_dirty(true)
336{ 408{
337 QString fi = file; 409 QString fi = file;
338 if ( fi.isEmpty() ) 410 if ( fi.isEmpty() )
339 fi = Global::applicationFileName( "todolist", "todolist.db" ); 411 fi = Global::applicationFileName( "todolist", "todolist.db" );
340 OSQLManager man; 412 OSQLManager man;
341 m_driver = man.standard(); 413 m_driver = man.standard();
342 m_driver->setUrl(fi); 414 m_driver->setUrl(fi);
343 // fillDict(); 415 // fillDict();
344} 416}
345 417
346OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){ 418OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){
347 if( m_driver ) 419 if( m_driver )
348 delete m_driver; 420 delete m_driver;
349} 421}
350 422
351bool OPimTodoAccessBackendSQL::load(){ 423bool OPimTodoAccessBackendSQL::load(){
352 if (!m_driver->open() ) 424 if (!m_driver->open() )
353 return false; 425 return false;
354 426
355 CreateQuery creat; 427 CreateQuery creat;
356 OSQLResult res = m_driver->query(&creat ); 428 OSQLResult res = m_driver->query(&creat );
357 429
358 m_dirty = true; 430 m_dirty = true;
359 return true; 431 return true;
360} 432}
361bool OPimTodoAccessBackendSQL::reload(){ 433bool OPimTodoAccessBackendSQL::reload(){
362 return load(); 434 return load();
363} 435}
364 436
365bool OPimTodoAccessBackendSQL::save(){ 437bool OPimTodoAccessBackendSQL::save(){
366 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 438 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
367} 439}
368QArray<int> OPimTodoAccessBackendSQL::allRecords()const { 440QArray<int> OPimTodoAccessBackendSQL::allRecords()const {
369 if (m_dirty ) 441 if (m_dirty )
370 update(); 442 update();
371 443
372 return m_uids; 444 return m_uids;
373} 445}
374QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){ 446QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){
375 QArray<int> ints(0); 447 QArray<int> ints(0);
376 return ints; 448 return ints;
377} 449}
378OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ 450OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{
379 FindQuery query( uid ); 451 FindQuery query( uid );
380 return todo( m_driver->query(&query) ); 452 return todo( m_driver->query(&query) );
381 453
382} 454}
383OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 455OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
384 uint cur, Frontend::CacheDirection dir ) const{ 456 uint cur, Frontend::CacheDirection dir ) const{
385 uint CACHE = readAhead(); 457 uint CACHE = readAhead();
386 qWarning("searching for %d", uid ); 458 qDebug("searching for %d", uid );
387 QArray<int> search( CACHE ); 459 QArray<int> search( CACHE );
388 uint size =0; 460 uint size =0;
389 OPimTodo to; 461 OPimTodo to;
390 462
391 // we try to cache CACHE items 463 // we try to cache CACHE items
392 switch( dir ) { 464 switch( dir ) {
393 /* forward */ 465 /* forward */
394 case 0: // FIXME: Not a good style to use magic numbers here (eilers) 466 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
395 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 467 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
396 qWarning("size %d %d", size, ints[i] ); 468 qDebug("size %d %d", size, ints[i] );
397 search[size] = ints[i]; 469 search[size] = ints[i];
398 size++; 470 size++;
399 } 471 }
400 break; 472 break;
401 /* reverse */ 473 /* reverse */
402 case 1: // FIXME: Not a good style to use magic numbers here (eilers) 474 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
403 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 475 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
404 search[size] = ints[i]; 476 search[size] = ints[i];
405 size++; 477 size++;
406 } 478 }
407 break; 479 break;
408 } 480 }
409 search.resize( size ); 481 search.resize( size );
410 FindQuery query( search ); 482 FindQuery query( search );
411 OSQLResult res = m_driver->query( &query ); 483 OSQLResult res = m_driver->query( &query );
412 if ( res.state() != OSQLResult::Success ) 484 if ( res.state() != OSQLResult::Success )
413 return to; 485 return to;
414 486
415 return todo( res ); 487 return todo( res );
416} 488}
417void OPimTodoAccessBackendSQL::clear() { 489void OPimTodoAccessBackendSQL::clear() {
418 ClearQuery cle; 490 ClearQuery cle;
419 OSQLResult res = m_driver->query( &cle ); 491 OSQLResult res = m_driver->query( &cle );
420 CreateQuery qu; 492 CreateQuery qu;
421 res = m_driver->query(&qu); 493 res = m_driver->query(&qu);
422} 494}
423bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) { 495bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) {
424 InsertQuery ins( t ); 496 InsertQuery ins( t );
425 OSQLResult res = m_driver->query( &ins ); 497 OSQLResult res = m_driver->query( &ins );
426 498
427 if ( res.state() == OSQLResult::Failure ) 499 if ( res.state() == OSQLResult::Failure )
428 return false; 500 return false;
429 int c = m_uids.count(); 501 int c = m_uids.count();
430 m_uids.resize( c+1 ); 502 m_uids.resize( c+1 );
431 m_uids[c] = t.uid(); 503 m_uids[c] = t.uid();
432 504
433 return true; 505 return true;
434} 506}
435bool OPimTodoAccessBackendSQL::remove( int uid ) { 507bool OPimTodoAccessBackendSQL::remove( int uid ) {
436 RemoveQuery rem( uid ); 508 RemoveQuery rem( uid );
437 OSQLResult res = m_driver->query(&rem ); 509 OSQLResult res = m_driver->query(&rem );
438 510
439 if ( res.state() == OSQLResult::Failure ) 511 if ( res.state() == OSQLResult::Failure )
440 return false; 512 return false;
441 513
442 m_dirty = true; 514 m_dirty = true;
443 return true; 515 return true;
444} 516}
445/* 517/*
446 * FIXME better set query 518 * FIXME better set query
447 * but we need the cache for that 519 * but we need the cache for that
448 * now we remove 520 * now we remove
449 */ 521 */
450bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) { 522bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) {
451 remove( t.uid() ); 523 remove( t.uid() );
452 bool b= add(t); 524 bool b= add(t);
453 m_dirty = false; // we changed some stuff but the UID stayed the same 525 m_dirty = false; // we changed some stuff but the UID stayed the same
454 return b; 526 return b;
455} 527}
456QArray<int> OPimTodoAccessBackendSQL::overDue() { 528QArray<int> OPimTodoAccessBackendSQL::overDue() {
457 OverDueQuery qu; 529 OverDueQuery qu;
458 return uids( m_driver->query(&qu ) ); 530 return uids( m_driver->query(&qu ) );
459} 531}
460QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, 532QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s,
461 const QDate& t, 533 const QDate& t,
462 bool u) { 534 bool u) {
463 EffQuery ef(s, t, u ); 535 EffQuery ef(s, t, u );
464 return uids (m_driver->query(&ef) ); 536 return uids (m_driver->query(&ef) );
465} 537}
466/* 538/*
467 * 539 *
468 */ 540 */
469QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 541QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
470 int sortFilter, int cat ) { 542 int sortFilter, int cat ) {
471 qWarning("sorted %d, %d", asc, sortOrder ); 543 qDebug("sorted %d, %d", asc, sortOrder );
472 QString query; 544 QString query;
473 query = "select uid from todolist WHERE "; 545 query = "select uid from todolist WHERE ";
474 546
475 /* 547 /*
476 * Sort Filter stuff 548 * Sort Filter stuff
477 * not that straight forward 549 * not that straight forward
478 * FIXME: Replace magic numbers 550 * FIXME: Replace magic numbers
479 * 551 *
480 */ 552 */
481 /* Category */ 553 /* Category */
482 if ( sortFilter & 1 ) { 554 if ( sortFilter & 1 ) {
483 QString str; 555 QString str;
484 if (cat != 0 ) str = QString::number( cat ); 556 if (cat != 0 ) str = QString::number( cat );
485 query += " categories like '%" +str+"%' AND"; 557 query += " categories like '%" +str+"%' AND";
486 } 558 }
487 /* Show only overdue */ 559 /* Show only overdue */
488 if ( sortFilter & 2 ) { 560 if ( sortFilter & 2 ) {
489 QDate date = QDate::currentDate(); 561 QDate date = QDate::currentDate();
490 QString due; 562 QString due;
491 QString base; 563 QString base;
492 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 564 base = QString("DueDate <= '%1-%2-%3' AND completed = 0")
565 .arg( QString::number( date.year() ).rightJustify( 4, '0' ) )
566 .arg( QString::number( date.month() ).rightJustify( 2, '0' ) )
567 .arg( QString::number( date.day() ).rightJustify( 2, '0' ) );
493 query += " " + base + " AND"; 568 query += " " + base + " AND";
494 } 569 }
495 /* not show completed */ 570 /* not show completed */
496 if ( sortFilter & 4 ) { 571 if ( sortFilter & 4 ) {
497 query += " completed = 0 AND"; 572 query += " completed = 0 AND";
498 }else{ 573 }else{
499 query += " ( completed = 1 OR completed = 0) AND"; 574 query += " ( completed = 1 OR completed = 0) AND";
500 } 575 }
501 /* srtip the end */ 576 /* strip the end */
502 query = query.remove( query.length()-3, 3 ); 577 query = query.remove( query.length()-3, 3 );
503 578
504 579
505 /* 580 /*
506 * sort order stuff 581 * sort order stuff
507 * quite straight forward 582 * quite straight forward
508 */ 583 */
509 query += "ORDER BY "; 584 query += "ORDER BY ";
510 switch( sortOrder ) { 585 switch( sortOrder ) {
511 /* completed */ 586 /* completed */
512 case 0: 587 case 0:
513 query += "completed"; 588 query += "completed";
514 break; 589 break;
515 case 1: 590 case 1:
516 query += "priority"; 591 query += "priority";
517 break; 592 break;
518 case 2: 593 case 2:
519 query += "summary"; 594 query += "summary";
520 break; 595 break;
521 case 3: 596 case 3:
522 query += "DueDate"; 597 query += "DueDate";
523 break; 598 break;
524 } 599 }
525 600
526 if ( !asc ) { 601 if ( !asc ) {
527 qWarning("not ascending!"); 602 qDebug("not ascending!");
528 query += " DESC"; 603 query += " DESC";
529 } 604 }
530 605
531 qWarning( query ); 606 qDebug( query );
532 OSQLRawQuery raw(query ); 607 OSQLRawQuery raw(query );
533 return uids( m_driver->query(&raw) ); 608 return uids( m_driver->query(&raw) );
534} 609}
535bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 610bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
536 if ( str == "0-0-0" ) 611 if ( str == "0-0-0" )
537 return false; 612 return false;
538 else{ 613 else{
539 int day, year, month; 614 int day, year, month;
540 QStringList list = QStringList::split("-", str ); 615 QStringList list = QStringList::split("-", str );
541 year = list[0].toInt(); 616 year = list[0].toInt();
542 month = list[1].toInt(); 617 month = list[1].toInt();
543 day = list[2].toInt(); 618 day = list[2].toInt();
544 da.setYMD( year, month, day ); 619 da.setYMD( year, month, day );
545 return true; 620 return true;
546 } 621 }
547} 622}
548OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 623OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res ) const{
549 if ( res.state() == OSQLResult::Failure ) { 624 if ( res.state() == OSQLResult::Failure ) {
550 OPimTodo to; 625 OPimTodo to;
551 return to; 626 return to;
552 } 627 }
553 628
554 OSQLResultItem::ValueList list = res.results(); 629 OSQLResultItem::ValueList list = res.results();
555 OSQLResultItem::ValueList::Iterator it = list.begin(); 630 OSQLResultItem::ValueList::Iterator it = list.begin();
556 qWarning("todo1"); 631 qDebug("todo1");
557 OPimTodo to = todo( (*it) ); 632 OPimTodo to = todo( (*it) );
558 cache( to ); 633 cache( to );
559 ++it; 634 ++it;
560 635
561 for ( ; it != list.end(); ++it ) { 636 for ( ; it != list.end(); ++it ) {
562 qWarning("caching"); 637 qDebug("caching");
563 cache( todo( (*it) ) ); 638 cache( todo( (*it) ) );
564 } 639 }
565 return to; 640 return to;
566} 641}
567OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 642OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
568 qWarning("todo"); 643 qDebug("todo(ResultItem)");
644
645 // Request information from addressbook table and create the OPimTodo-object.
646
569 bool hasDueDate = false; QDate dueDate = QDate::currentDate(); 647 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
570 hasDueDate = date( dueDate, item.data("DueDate") ); 648 hasDueDate = date( dueDate, item.data("DueDate") );
571 QStringList cats = QStringList::split(";", item.data("categories") ); 649 QStringList cats = QStringList::split(";", item.data("categories") );
572 650
573 qWarning("Item is completed: %d", item.data("completed").toInt() ); 651 qDebug("Item is completed: %d", item.data("completed").toInt() );
574 652
575 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 653 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
576 cats, item.data("summary"), item.data("description"), 654 cats, item.data("summary"), item.data("description"),
577 item.data("progress").toUShort(), hasDueDate, dueDate, 655 item.data("progress").toUShort(), hasDueDate, dueDate,
578 item.data("uid").toInt() ); 656 item.data("uid").toInt() );
579 657
580 bool isOk; 658 bool isOk;
581 int prioInt = QString( item.data("priority") ).toInt( &isOk ); 659 int prioInt = QString( item.data("priority") ).toInt( &isOk );
582 if ( isOk ) 660 if ( isOk )
583 to.setPriority( prioInt ); 661 to.setPriority( prioInt );
584 662
585 bool hasStartDate = false; QDate startDate = QDate::currentDate(); 663 bool hasStartDate = false; QDate startDate = QDate::currentDate();
586 hasStartDate = date( startDate, item.data("startdate") ); 664 hasStartDate = date( startDate, item.data("startdate") );
587 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); 665 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
588 hasCompletedDate = date( completedDate, item.data("completeddate") ); 666 hasCompletedDate = date( completedDate, item.data("completeddate") );
589 667
590 if ( hasStartDate ) 668 if ( hasStartDate )
591 to.setStartDate( startDate ); 669 to.setStartDate( startDate );
592 if ( hasCompletedDate ) 670 if ( hasCompletedDate )
593 to.setCompletedDate( completedDate ); 671 to.setCompletedDate( completedDate );
594 672
595 OPimNotifyManager& manager = to.notifiers(); 673 OPimNotifyManager& manager = to.notifiers();
596 manager.alarmsFromString( item.data("alarms") ); 674 manager.alarmsFromString( item.data("alarms") );
597 manager.remindersFromString( item.data("reminders") ); 675 manager.remindersFromString( item.data("reminders") );
598 676
599 OPimState pimState; 677 OPimState pimState;
600 pimState.setState( QString( item.data("state") ).toInt() ); 678 pimState.setState( QString( item.data("state") ).toInt() );
601 to.setState( pimState ); 679 to.setState( pimState );
602 680
603 QMap<int, QString> recMap; 681 QMap<int, QString> recMap;
604 recMap.insert( OPimRecurrence::RType , item.data("RType") ); 682 recMap.insert( OPimRecurrence::RType , item.data("RType") );
605 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") ); 683 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") );
606 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") ); 684 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") );
607 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") ); 685 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") );
608 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") ); 686 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") );
609 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); 687 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") );
610 recMap.insert( OPimRecurrence::Created , item.data("Created") ); 688 recMap.insert( OPimRecurrence::Created , item.data("Created") );
611 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); 689 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") );
612 690
613 OPimRecurrence recur; 691 OPimRecurrence recur;
614 recur.fromMap( recMap ); 692 recur.fromMap( recMap );
615 to.setRecurrence( recur ); 693 to.setRecurrence( recur );
616 694
695 // Finally load the custom-entries for this UID and put it into the created object
696 to.setExtraMap( requestCustom( to.uid() ) );
697
617 return to; 698 return to;
618} 699}
619OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { 700OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const {
620 FindQuery find( uid ); 701 FindQuery find( uid );
621 return todo( m_driver->query(&find) ); 702 return todo( m_driver->query(&find) );
622} 703}
623/* 704/*
624 * update the dict 705 * update the dict
625 */ 706 */
626void OPimTodoAccessBackendSQL::fillDict() { 707void OPimTodoAccessBackendSQL::fillDict() {
708
709#if 0
627 /* initialize dict */ 710 /* initialize dict */
628 /* 711 /*
629 * UPDATE dict if you change anything!!! 712 * UPDATE dict if you change anything!!!
630 * FIXME: Isn't this dict obsolete ? (eilers) 713 * FIXME: Isn't this dict obsolete ? (eilers)
631 */ 714 */
632 m_dict.setAutoDelete( TRUE ); 715 m_dict.setAutoDelete( TRUE );
633 m_dict.insert("Categories" , new int(OPimTodo::Category) ); 716 m_dict.insert("Categories" , new int(OPimTodo::Category) );
634 m_dict.insert("Uid" , new int(OPimTodo::Uid) ); 717 m_dict.insert("Uid" , new int(OPimTodo::Uid) );
635 m_dict.insert("HasDate" , new int(OPimTodo::HasDate) ); 718 m_dict.insert("HasDate" , new int(OPimTodo::HasDate) );
636 m_dict.insert("Completed" , new int(OPimTodo::Completed) ); 719 m_dict.insert("Completed" , new int(OPimTodo::Completed) );
637 m_dict.insert("Description" , new int(OPimTodo::Description) ); 720 m_dict.insert("Description" , new int(OPimTodo::Description) );
638 m_dict.insert("Summary" , new int(OPimTodo::Summary) ); 721 m_dict.insert("Summary" , new int(OPimTodo::Summary) );
639 m_dict.insert("Priority" , new int(OPimTodo::Priority) ); 722 m_dict.insert("Priority" , new int(OPimTodo::Priority) );
640 m_dict.insert("DateDay" , new int(OPimTodo::DateDay) ); 723 m_dict.insert("DateDay" , new int(OPimTodo::DateDay) );
641 m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); 724 m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
642 m_dict.insert("DateYear" , new int(OPimTodo::DateYear) ); 725 m_dict.insert("DateYear" , new int(OPimTodo::DateYear) );
643 m_dict.insert("Progress" , new int(OPimTodo::Progress) ); 726 m_dict.insert("Progress" , new int(OPimTodo::Progress) );
644 m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers) 727 m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers)
645 m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); 728 m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
646// m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers) 729// m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers)
647// m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers) 730// m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers)
731
732#endif
648} 733}
649/* 734/*
650 * need to be const so let's fool the 735 * need to be const so let's fool the
651 * compiler :( 736 * compiler :(
652 */ 737 */
653void OPimTodoAccessBackendSQL::update()const { 738void OPimTodoAccessBackendSQL::update()const {
654 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; 739 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false;
655 LoadQuery lo; 740 LoadQuery lo;
656 OSQLResult res = m_driver->query(&lo); 741 OSQLResult res = m_driver->query(&lo);
657 if ( res.state() != OSQLResult::Success ) 742 if ( res.state() != OSQLResult::Success )
658 return; 743 return;
659 744
660 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); 745 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res );
661} 746}
662QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 747QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{
663 748
664 OSQLResultItem::ValueList list = res.results(); 749 OSQLResultItem::ValueList list = res.results();
665 OSQLResultItem::ValueList::Iterator it; 750 OSQLResultItem::ValueList::Iterator it;
666 QArray<int> ints(list.count() ); 751 QArray<int> ints(list.count() );
667 qWarning(" count = %d", list.count() ); 752 qDebug(" count = %d", list.count() );
668 753
669 int i = 0; 754 int i = 0;
670 for (it = list.begin(); it != list.end(); ++it ) { 755 for (it = list.begin(); it != list.end(); ++it ) {
671 ints[i] = (*it).data("uid").toInt(); 756 ints[i] = (*it).data("uid").toInt();
672 i++; 757 i++;
673 } 758 }
674 return ints; 759 return ints;
675} 760}
676 761
677QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 762QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
678{ 763{
679 764
680#warning OPimTodoAccessBackendSQL::matchRegexp() not implemented !! 765#warning OPimTodoAccessBackendSQL::matchRegexp() not implemented !!
681 766
682#if 0 767#if 0
683 768
684 Copied from xml-backend by not adapted to sql (eilers) 769 Copied from xml-backend by not adapted to sql (eilers)
685 770
686 QArray<int> m_currentQuery( m_events.count() ); 771 QArray<int> m_currentQuery( m_events.count() );
687 uint arraycounter = 0; 772 uint arraycounter = 0;
688 773
689 774
690 775
691 QMap<int, OPimTodo>::ConstIterator it; 776 QMap<int, OPimTodo>::ConstIterator it;
692 for (it = m_events.begin(); it != m_events.end(); ++it ) { 777 for (it = m_events.begin(); it != m_events.end(); ++it ) {
693 if ( it.data().match( r ) ) 778 if ( it.data().match( r ) )
694 m_currentQuery[arraycounter++] = it.data().uid(); 779 m_currentQuery[arraycounter++] = it.data().uid();
695 780
696 } 781 }
697 // Shrink to fit.. 782 // Shrink to fit..
698 m_currentQuery.resize(arraycounter); 783 m_currentQuery.resize(arraycounter);
699 784
700 return m_currentQuery; 785 return m_currentQuery;
701#endif 786#endif
702 QArray<int> empty; 787 QArray<int> empty;
703 return empty; 788 return empty;
704} 789}
705QBitArray OPimTodoAccessBackendSQL::supports()const { 790QBitArray OPimTodoAccessBackendSQL::supports()const {
706 791
707 return sup(); 792 return sup();
708} 793}
709 794
710QBitArray OPimTodoAccessBackendSQL::sup() const{ 795QBitArray OPimTodoAccessBackendSQL::sup() const{
711 796
712 QBitArray ar( OPimTodo::CompletedDate + 1 ); 797 QBitArray ar( OPimTodo::CompletedDate + 1 );
713 ar.fill( true ); 798 ar.fill( true );
714 ar[OPimTodo::CrossReference] = false; 799 ar[OPimTodo::CrossReference] = false;
715 ar[OPimTodo::State ] = false; 800 ar[OPimTodo::State ] = false;
716 ar[OPimTodo::Reminders] = false; 801 ar[OPimTodo::Reminders] = false;
717 ar[OPimTodo::Notifiers] = false; 802 ar[OPimTodo::Notifiers] = false;
718 ar[OPimTodo::Maintainer] = false; 803 ar[OPimTodo::Maintainer] = false;
719 804
720 return ar; 805 return ar;
721} 806}
722 807
723void OPimTodoAccessBackendSQL::removeAllCompleted(){ 808void OPimTodoAccessBackendSQL::removeAllCompleted(){
724#warning OPimTodoAccessBackendSQL::removeAllCompleted() not implemented !! 809#warning OPimTodoAccessBackendSQL::removeAllCompleted() not implemented !!
725 810
726} 811}
727 812
813
814QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const
815{
816 QMap<QString, QString> customMap;
817
818 FindCustomQuery query( uid );
819 OSQLResult res_custom = m_driver->query( &query );
820
821 if ( res_custom.state() == OSQLResult::Failure ) {
822 qWarning("OSQLResult::Failure in find query !!");
823 QMap<QString, QString> empty;
824 return empty;
825 }
826
827 OSQLResultItem::ValueList list = res_custom.results();
828 OSQLResultItem::ValueList::Iterator it = list.begin();
829 for ( ; it != list.end(); ++it ) {
830 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
831 }
832
833 return customMap;
834}
835
836
837
838
728} 839}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h
index 0ae2591..0cc7722 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.h
+++ b/libopie2/opiepim/backend/otodoaccesssql.h
@@ -1,92 +1,93 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_PIM_ACCESS_SQL_H 29#ifndef OPIE_PIM_ACCESS_SQL_H
30#define OPIE_PIM_ACCESS_SQL_H 30#define OPIE_PIM_ACCESS_SQL_H
31 31
32#include <qasciidict.h> 32/* #include <qasciidict.h> */
33 33
34#include <opie2/otodoaccessbackend.h> 34#include <opie2/otodoaccessbackend.h>
35 35
36namespace Opie { 36namespace Opie {
37namespace DB { 37namespace DB {
38class OSQLDriver; 38class OSQLDriver;
39class OSQLResult; 39class OSQLResult;
40class OSQLResultItem; 40class OSQLResultItem;
41} 41}
42} 42}
43 43
44namespace Opie { 44namespace Opie {
45 45
46class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend { 46class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend {
47public: 47public:
48 OPimTodoAccessBackendSQL( const QString& file ); 48 OPimTodoAccessBackendSQL( const QString& file );
49 ~OPimTodoAccessBackendSQL(); 49 ~OPimTodoAccessBackendSQL();
50 50
51 bool load(); 51 bool load();
52 bool reload(); 52 bool reload();
53 bool save(); 53 bool save();
54 QArray<int> allRecords()const; 54 QArray<int> allRecords()const;
55 55
56 QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() ); 56 QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() );
57 OPimTodo find(int uid)const; 57 OPimTodo find(int uid)const;
58 OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 58 OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
59 void clear(); 59 void clear();
60 bool add( const OPimTodo& t ); 60 bool add( const OPimTodo& t );
61 bool remove( int uid ); 61 bool remove( int uid );
62 bool replace( const OPimTodo& t ); 62 bool replace( const OPimTodo& t );
63 63
64 QArray<int> overDue(); 64 QArray<int> overDue();
65 QArray<int> effectiveToDos( const QDate& start, 65 QArray<int> effectiveToDos( const QDate& start,
66 const QDate& end, bool includeNoDates ); 66 const QDate& end, bool includeNoDates );
67 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 67 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
68 68
69 QBitArray supports()const; 69 QBitArray supports()const;
70 QArray<int> matchRegexp( const QRegExp &r ) const; 70 QArray<int> matchRegexp( const QRegExp &r ) const;
71 void removeAllCompleted(); 71 void removeAllCompleted();
72 72
73 73
74private: 74private:
75 void update()const; 75 void update()const;
76 void fillDict(); 76 void fillDict();
77 inline bool date( QDate& date, const QString& )const; 77 inline bool date( QDate& date, const QString& )const;
78 inline OPimTodo todo( const Opie::DB::OSQLResult& )const; 78 inline OPimTodo todo( const Opie::DB::OSQLResult& )const;
79 inline OPimTodo todo( Opie::DB::OSQLResultItem& )const; 79 inline OPimTodo todo( Opie::DB::OSQLResultItem& )const;
80 inline QArray<int> uids( const Opie::DB::OSQLResult& )const; 80 inline QArray<int> uids( const Opie::DB::OSQLResult& )const;
81 OPimTodo todo( int uid )const; 81 OPimTodo todo( int uid )const;
82 QBitArray sup() const; 82 QBitArray sup() const;
83 QMap<QString, QString> requestCustom( int uid ) const;
83 84
84 QAsciiDict<int> m_dict; 85 // QAsciiDict<int> m_dict;
85 Opie::DB::OSQLDriver* m_driver; 86 Opie::DB::OSQLDriver* m_driver;
86 QArray<int> m_uids; 87 QArray<int> m_uids;
87 bool m_dirty : 1; 88 bool m_dirty : 1;
88}; 89};
89 90
90} 91}
91 92
92#endif 93#endif
diff --git a/libopie2/opiepim/core/opimcontact.h b/libopie2/opiepim/core/opimcontact.h
index c08f7ed..9d3cacc 100644
--- a/libopie2/opiepim/core/opimcontact.h
+++ b/libopie2/opiepim/core/opimcontact.h
@@ -1,256 +1,256 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) Stefan Eilers <eilers.stefan@handhelds.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#ifndef OCONTACT_H 30#ifndef OCONTACT_H
31#define OCONTACT_H 31#define OCONTACT_H
32 32
33/* OPIE */ 33/* OPIE */
34#include <opie2/opimrecord.h> 34#include <opie2/opimrecord.h>
35#include <qpe/recordfields.h> 35#include <qpe/recordfields.h>
36 36
37/* QT */ 37/* QT */
38#include <qdatetime.h> 38#include <qdatetime.h>
39#include <qstringlist.h> 39#include <qstringlist.h>
40 40
41#if defined(QPC_TEMPLATEDLL) 41#if defined(QPC_TEMPLATEDLL)
42// MOC_SKIP_BEGIN 42// MOC_SKIP_BEGIN
43QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; 43QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
44// MOC_SKIP_END 44// MOC_SKIP_END
45#endif 45#endif
46 46
47namespace Opie 47namespace Opie
48{ 48{
49class OPimContactPrivate; 49class OPimContactPrivate;
50 50
51/** 51/**
52 * OPimContact class represents a specialised PIM Record for contacts. 52 * OPimContact class represents a specialised PIM Record for contacts.
53 * It does store all kind of persopn related information. 53 * It does store all kind of persopn related information.
54 * 54 *
55 * @short Contact Container 55 * @short Contact Container
56 * @author TT, Stefan Eiler, Holger Freyther 56 * @author TT, Stefan Eiler, Holger Freyther
57 */ 57 */
58class QPC_EXPORT OPimContact : public OPimRecord 58class QPC_EXPORT OPimContact : public OPimRecord
59{ 59{
60 friend class DataSet; 60 friend class DataSet;
61 61
62 public: 62 public:
63 OPimContact(); 63 OPimContact();
64 OPimContact( const QMap<int, QString> &fromMap ); 64 OPimContact( const QMap<int, QString> &fromMap );
65 virtual ~OPimContact(); 65 virtual ~OPimContact();
66 66
67 enum DateFormat{ 67 enum DateFormat{
68 Zip_City_State = 0, 68 Zip_City_State = 0,
69 City_State_Zip 69 City_State_Zip
70 }; 70 };
71 71
72 /* 72 /*
73 * do we need to inline them 73 * do we need to inline them
74 * if yes do we need to inline them this way? 74 * if yes do we need to inline them this way?
75 * -zecke 75 * -zecke
76 */ 76 */
77 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } 77 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
78 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } 78 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
79 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } 79 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
80 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } 80 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
81 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } 81 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
82 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } 82 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
83 void setFileAs(); 83 void setFileAs();
84 84
85 // default email address 85 // default email address
86 void setDefaultEmail( const QString &v ); 86 void setDefaultEmail( const QString &v );
87 // inserts email to list and ensure's doesn't already exist 87 // inserts email to list and ensure's doesn't already exist
88 void insertEmail( const QString &v ); 88 void insertEmail( const QString &v );
89 void removeEmail( const QString &v ); 89 void removeEmail( const QString &v );
90 void clearEmails(); 90 void clearEmails();
91 void insertEmails( const QStringList &v ); 91 void insertEmails( const QStringList &v );
92 92
93 // home 93 // home
94 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } 94 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
95 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } 95 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }
96 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } 96 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); }
97 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } 97 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); }
98 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } 98 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); }
99 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } 99 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); }
100 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } 100 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); }
101 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } 101 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); }
102 void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } 102 void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); }
103 103
104 // business 104 // business
105 void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } 105 void setCompany( const QString &v ) { replace( Qtopia::Company, v ); }
106 void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } 106 void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); }
107 void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } 107 void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); }
108 void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } 108 void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); }
109 void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } 109 void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); }
110 void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } 110 void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); }
111 void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } 111 void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); }
112 void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } 112 void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); }
113 void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } 113 void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); }
114 void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } 114 void setOffice( const QString &v ) { replace( Qtopia::Office, v ); }
115 void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } 115 void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); }
116 void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } 116 void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); }
117 void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } 117 void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); }
118 void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } 118 void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); }
119 void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } 119 void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); }
120 void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } 120 void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); }
121 void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } 121 void setManager( const QString &v ) { replace( Qtopia::Manager, v ); }
122 122
123 // personal 123 // personal
124 void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } 124 void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); }
125 void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } 125 void setGender( const QString &v ) { replace( Qtopia::Gender, v ); }
126 void setBirthday( const QDate &v ); 126 void setBirthday( const QDate &v );
127 void setAnniversary( const QDate &v ); 127 void setAnniversary( const QDate &v );
128 void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } 128 void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); }
129 void setChildren( const QString &v ); 129 void setChildren( const QString &v );
130 130
131 // other 131 // other
132 void setNotes( const QString &v ) { replace( Qtopia::Notes, v ); } 132 void setNotes( const QString &v ) { replace( Qtopia::Notes, v ); }
133 133
134 virtual bool match( const QRegExp &regexp ) const; 134 virtual bool match( const QRegExp &regexp ) const;
135 135
136 // // custom 136 // // custom
137 // void setCustomField( const QString &key, const QString &v ) 137 // void setCustomField( const QString &key, const QString &v )
138 // { replace(Custom- + key, v ); } 138 // { replace(Custom- + key, v ); }
139 139
140 // name 140 // name
141 QString fullName() const; 141 QString fullName() const;
142 QString title() const { return find( Qtopia::Title ); } 142 QString title() const { return find( Qtopia::Title ); }
143 QString firstName() const { return find( Qtopia::FirstName ); } 143 QString firstName() const { return find( Qtopia::FirstName ); }
144 QString middleName() const { return find( Qtopia::MiddleName ); } 144 QString middleName() const { return find( Qtopia::MiddleName ); }
145 QString lastName() const { return find( Qtopia::LastName ); } 145 QString lastName() const { return find( Qtopia::LastName ); }
146 QString suffix() const { return find( Qtopia::Suffix ); } 146 QString suffix() const { return find( Qtopia::Suffix ); }
147 QString fileAs() const { return find( Qtopia::FileAs ); } 147 QString fileAs() const { return find( Qtopia::FileAs ); }
148 148
149 // email 149 // email
150 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } 150 QString defaultEmail() const { return find( Qtopia::DefaultEmail ); }
151 QStringList emailList() const; 151 QStringList emailList() const;
152 152
153 // home 153 // home
154 /* 154 /*
155 * OPimAddress address(enum Location)const; 155 * OPimAddress address(enum Location)const;
156 * would be some how nicer... 156 * would be some how nicer...
157 * -zecke 157 * -zecke
158 */ 158 */
159 QString homeStreet() const { return find( Qtopia::HomeStreet ); } 159 QString homeStreet() const { return find( Qtopia::HomeStreet ); }
160 QString homeCity() const { return find( Qtopia::HomeCity ); } 160 QString homeCity() const { return find( Qtopia::HomeCity ); }
161 QString homeState() const { return find( Qtopia::HomeState ); } 161 QString homeState() const { return find( Qtopia::HomeState ); }
162 QString homeZip() const { return find( Qtopia::HomeZip ); } 162 QString homeZip() const { return find( Qtopia::HomeZip ); }
163 QString homeCountry() const { return find( Qtopia::HomeCountry ); } 163 QString homeCountry() const { return find( Qtopia::HomeCountry ); }
164 QString homePhone() const { return find( Qtopia::HomePhone ); } 164 QString homePhone() const { return find( Qtopia::HomePhone ); }
165 QString homeFax() const { return find( Qtopia::HomeFax ); } 165 QString homeFax() const { return find( Qtopia::HomeFax ); }
166 QString homeMobile() const { return find( Qtopia::HomeMobile ); } 166 QString homeMobile() const { return find( Qtopia::HomeMobile ); }
167 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } 167 QString homeWebpage() const { return find( Qtopia::HomeWebPage ); }
168 /** Multi line string containing all non-empty address info in the form 168 /** Multi line string containing all non-empty address info in the form
169 * Street 169 * Street
170 * City, State Zip 170 * City, State Zip
171 * Country 171 * Country
172 */ 172 */
173 QString displayHomeAddress() const; 173 QString displayHomeAddress() const;
174 174
175 // business 175 // business
176 QString company() const { return find( Qtopia::Company ); } 176 QString company() const { return find( Qtopia::Company ); }
177 QString businessStreet() const { return find( Qtopia::BusinessStreet ); } 177 QString businessStreet() const { return find( Qtopia::BusinessStreet ); }
178 QString businessCity() const { return find( Qtopia::BusinessCity ); } 178 QString businessCity() const { return find( Qtopia::BusinessCity ); }
179 QString businessState() const { return find( Qtopia::BusinessState ); } 179 QString businessState() const { return find( Qtopia::BusinessState ); }
180 QString businessZip() const { return find( Qtopia::BusinessZip ); } 180 QString businessZip() const { return find( Qtopia::BusinessZip ); }
181 QString businessCountry() const { return find( Qtopia::BusinessCountry ); } 181 QString businessCountry() const { return find( Qtopia::BusinessCountry ); }
182 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } 182 QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); }
183 QString jobTitle() const { return find( Qtopia::JobTitle ); } 183 QString jobTitle() const { return find( Qtopia::JobTitle ); }
184 QString department() const { return find( Qtopia::Department ); } 184 QString department() const { return find( Qtopia::Department ); }
185 QString office() const { return find( Qtopia::Office ); } 185 QString office() const { return find( Qtopia::Office ); }
186 QString businessPhone() const { return find( Qtopia::BusinessPhone ); } 186 QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
187 QString businessFax() const { return find( Qtopia::BusinessFax ); } 187 QString businessFax() const { return find( Qtopia::BusinessFax ); }
188 QString businessMobile() const { return find( Qtopia::BusinessMobile ); } 188 QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
189 QString businessPager() const { return find( Qtopia::BusinessPager ); } 189 QString businessPager() const { return find( Qtopia::BusinessPager ); }
190 QString profession() const { return find( Qtopia::Profession ); } 190 QString profession() const { return find( Qtopia::Profession ); }
191 QString assistant() const { return find( Qtopia::Assistant ); } 191 QString assistant() const { return find( Qtopia::Assistant ); }
192 QString manager() const { return find( Qtopia::Manager ); } 192 QString manager() const { return find( Qtopia::Manager ); }
193 /** Multi line string containing all non-empty address info in the form 193 /** Multi line string containing all non-empty address info in the form
194 * Street 194 * Street
195 * City, State Zip 195 * City, State Zip
196 * Country 196 * Country
197 */ 197 */
198 QString displayBusinessAddress() const; 198 QString displayBusinessAddress() const;
199 199
200 //personal 200 //personal
201 QString spouse() const { return find( Qtopia::Spouse ); } 201 QString spouse() const { return find( Qtopia::Spouse ); }
202 QString gender() const { return find( Qtopia::Gender ); } 202 QString gender() const { return find( Qtopia::Gender ); }
203 QDate birthday() const; 203 QDate birthday() const;
204 QDate anniversary() const; 204 QDate anniversary() const;
205 QString nickname() const { return find( Qtopia::Nickname ); } 205 QString nickname() const { return find( Qtopia::Nickname ); }
206 QString children() const { return find( Qtopia::Children ); } 206 QString children() const { return find( Qtopia::Children ); }
207 QStringList childrenList() const; 207 QStringList childrenList() const;
208 208
209 // other 209 // other
210 QString notes() const { return find( Qtopia::Notes ); } 210 QString notes() const { return find( Qtopia::Notes ); }
211 QString groups() const { return find( Qtopia::Groups ); } 211 QString groups() const { return find( Qtopia::Groups ); }
212 QStringList groupList() const; 212 QStringList groupList() const;
213 213
214 QString toRichText() const; 214 QString toRichText() const;
215 QMap<int, QString> toMap() const; 215 QMap<int, QString> toMap() const;
216 QString field( int key ) const { return find( key ); } 216 QString field( int key ) const { return find( key ); }
217 217
218 218
219 void setUid( int i ); 219 void setUid( int i );
220 220
221 QString toShortText() const; 221 QString toShortText() const;
222 QString type() const; 222 QString type() const;
223 class QString recordField( int ) const; 223 class QString recordField( int ) const;
224 224
225 // Why private ? (eilers,se) 225 // Why private ? (eilers,se)
226 QString emailSeparator() const { return " "; } 226 QString emailSeparator() const { return " "; }
227 227
228 // the emails should be seperated by a comma 228 // the emails should be seperated by a comma
229 void setEmails( const QString &v ); 229 void setEmails( const QString &v );
230 QString emails() const { return find( Qtopia::Emails ); } 230 QString emails() const { return find( Qtopia::Emails ); }
231 static int rtti(); 231 static int rtti();
232 232
233 private: 233 private:
234 // The XML Backend needs some access to the private functions 234 // The XML Backend needs some access to the private functions
235 friend class OPimContactAccessBackend_XML; 235 friend class OPimContactAccessBackend_XML;
236 236
237 void insert( int key, const QString &value ); 237 void insert( int key, const QString &value );
238 void replace( int key, const QString &value ); 238 void replace( int key, const QString &value );
239 QString find( int key ) const; 239 QString find( int key ) const;
240 static QStringList fields(); 240 static QStringList fields();
241 241
242 void save( QString &buf ) const; 242 void save( QString &buf ) const;
243 243
244 QString displayAddress( const QString &street, 244 QString displayAddress( const QString &street,
245 const QString &city, 245 const QString &city,
246 const QString &state, 246 const QString &state,
247 const QString &zip, 247 const QString &zip,
248 const QString &country ) const; 248 const QString &country ) const;
249 249
250 QMap<int, QString> mMap; 250 QMap<int, QString> mMap;
251 OPimContactPrivate *d; 251 OPimContactPrivate *d;
252}; 252};
253 253
254} 254}
255 255
256#endif 256#endif