summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp313
-rw-r--r--libopie/pim/ocontactfields.cpp10
-rw-r--r--libopie/pim/otodoaccesssql.cpp92
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp313
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp92
-rw-r--r--libopie2/opiepim/ocontactfields.cpp10
6 files changed, 740 insertions, 90 deletions
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp
index 4afa5f3..132c9fc 100644
--- a/libopie/pim/ocontactaccessbackend_sql.cpp
+++ b/libopie/pim/ocontactaccessbackend_sql.cpp
@@ -1,63 +1,84 @@
1/* 1/*
2 * SQL Backend for the OPIE-Contact Database. 2 * SQL Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ===================================================================== 12 * =====================================================================
13 * Version: $Id$ 13 * Version: $Id$
14 * ===================================================================== 14 * =====================================================================
15 * History: 15 * History:
16 * $Log$ 16 * $Log$
17 * Revision 1.2 2003/09/29 07:44:26 eilers
18 * Improvement of PIM-SQL Databases, but search queries are still limited.
19 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space.
20 * Todo: Started to add new attributes. Some type conversions missing.
21 *
17 * Revision 1.1 2003/09/22 14:31:16 eilers 22 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook. 23 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend. 24 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow... 25 * A lot of changes fill follow...
21 * 26 *
22 */ 27 */
23 28
24#include "ocontactaccessbackend_sql.h" 29#include "ocontactaccessbackend_sql.h"
25 30
26#include <qarray.h> 31#include <qarray.h>
27#include <qdatetime.h> 32#include <qdatetime.h>
28#include <qstringlist.h> 33#include <qstringlist.h>
29 34
30#include <qpe/global.h> 35#include <qpe/global.h>
31#include <qpe/recordfields.h> 36#include <qpe/recordfields.h>
32 37
33#include <opie/ocontactfields.h> 38#include <opie/ocontactfields.h>
34#include <opie/oconversion.h> 39#include <opie/oconversion.h>
35#include <opie2/osqldriver.h> 40#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h> 41#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h> 42#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h> 43#include <opie2/osqlquery.h>
39 44
45
46
47
48// If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead
49// vertical like "uid, type, value".
50// DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !!
51#define __STORE_HORIZONTAL_
52
53// Distinct loading is not very fast. If I expect that every person has just
54// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
55// which is faster..
56// But this may not be true for all entries, like company contacts..
57// The current AddressBook application handles this problem, but other may not.. (eilers)
58#define __USE_SUPERFAST_LOADQUERY
59
60
40/* 61/*
41 * Implementation of used query types 62 * Implementation of used query types
42 * CREATE query 63 * CREATE query
43 * LOAD query 64 * LOAD query
44 * INSERT 65 * INSERT
45 * REMOVE 66 * REMOVE
46 * CLEAR 67 * CLEAR
47 */ 68 */
48namespace { 69namespace {
49 /** 70 /**
50 * CreateQuery for the Todolist Table 71 * CreateQuery for the Todolist Table
51 */ 72 */
52 class CreateQuery : public OSQLQuery { 73 class CreateQuery : public OSQLQuery {
53 public: 74 public:
54 CreateQuery(); 75 CreateQuery();
55 ~CreateQuery(); 76 ~CreateQuery();
56 QString query()const; 77 QString query()const;
57 }; 78 };
58 79
59 /** 80 /**
60 * Clears (delete) a Table 81 * Clears (delete) a Table
61 */ 82 */
62 class ClearQuery : public OSQLQuery { 83 class ClearQuery : public OSQLQuery {
63 public: 84 public:
@@ -119,109 +140,174 @@ namespace {
119 QArray<int> m_uids; 140 QArray<int> m_uids;
120 int m_uid; 141 int m_uid;
121 }; 142 };
122 143
123 /** 144 /**
124 * a find query for custom elements 145 * a find query for custom elements
125 */ 146 */
126 class FindCustomQuery : public OSQLQuery { 147 class FindCustomQuery : public OSQLQuery {
127 public: 148 public:
128 FindCustomQuery(int uid); 149 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& ); 150 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery(); 151 ~FindCustomQuery();
131 QString query()const; 152 QString query()const;
132 private: 153 private:
133 QString single()const; 154 QString single()const;
134 QString multi()const; 155 QString multi()const;
135 QArray<int> m_uids; 156 QArray<int> m_uids;
136 int m_uid; 157 int m_uid;
137 }; 158 };
138 159
139 160
140 161
141 // We using three tables to store the information: 162 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom) 163 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc. 164 // 2. custom_data : Not official supported entries
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact. 165 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ? 166 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {} 167 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {} 168 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const { 169 QString CreateQuery::query()const {
150 QString qu; 170 QString qu;
171#ifdef __STORE_HORIZONTAL_
172
173 qu += "create table addressbook( uid PRIMARY KEY ";
174
175 QStringList fieldList = OContactFields::untrfields( false );
176 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
177 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
178 }
179 qu += " );";
180
181 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
182
183#else
184
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; 185 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 186 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; 187 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
188
189#endif // __STORE_HORIZONTAL_
154 return qu; 190 return qu;
155 } 191 }
156 192
157 ClearQuery::ClearQuery() 193 ClearQuery::ClearQuery()
158 : OSQLQuery() {} 194 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {} 195 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const { 196 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;"; 197 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;"; 198 qu += "drop table custom_data;";
163 qu += "drop table dates;"; 199 // qu += "drop table dates;";
164 return qu; 200 return qu;
165 } 201 }
166 202
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173 203
174 LoadQuery::LoadQuery() : OSQLQuery() {} 204 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {} 205 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const { 206 QString LoadQuery::query()const {
177 QString qu; 207 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY 208#ifdef __STORE_HORIZONTAL_
179 qu += "select distinct uid from addressbook"; 209 qu += "select uid from addressbook";
180#else 210#else
211# ifndef __USE_SUPERFAST_LOADQUERY
212 qu += "select distinct uid from addressbook";
213# else
181 qu += "select uid from addressbook where type = 'Last Name'"; 214 qu += "select uid from addressbook where type = 'Last Name'";
182#endif 215# endif // __USE_SUPERFAST_LOADQUERY
216#endif // __STORE_HORIZONTAL_
183 217
184 return qu; 218 return qu;
185 } 219 }
186 220
187 221
188 InsertQuery::InsertQuery( const OContact& contact ) 222 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) { 223 : OSQLQuery(), m_contact( contact ) {
190 } 224 }
191 225
192 InsertQuery::~InsertQuery() { 226 InsertQuery::~InsertQuery() {
193 } 227 }
194 228
195 /* 229 /*
196 * converts from a OContact to a query 230 * converts from a OContact to a query
197 */ 231 */
198 QString InsertQuery::query()const{ 232 QString InsertQuery::query()const{
199 233
234#ifdef __STORE_HORIZONTAL_
235 QString qu;
236 qu += "insert into addressbook VALUES( " +
237 QString::number( m_contact.uid() );
238
239 // Get all information out of the contact-class
240 // Remember: The category is stored in contactMap, too !
241 QMap<int, QString> contactMap = m_contact.toMap();
242
243 QStringList fieldList = OContactFields::untrfields( false );
244 QMap<QString, int> translate = OContactFields::untrFieldsToId();
245 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
246 // Convert Column-String to Id and get value for this id..
247 // Hmmm.. Maybe not very cute solution..
248 int id = translate[*it];
249 switch ( id ){
250 case Qtopia::Birthday:{
251 // These entries should stored in a special format
252 // year-month-day
253 QDate day = m_contact.birthday();
254 if ( day.isValid() ){
255 qu += QString(",\"%1-%2-%3\"")
256 .arg( day.year() )
257 .arg( day.month() )
258 .arg( day.day() );
259 } else {
260 qu += ",\"\"";
261 }
262 }
263 break;
264 case Qtopia::Anniversary:{
265 // These entries should stored in a special format
266 // year-month-day
267 QDate day = m_contact.anniversary();
268 if ( day.isValid() ){
269 qu += QString(",\"%1-%2-%3\"")
270 .arg( day.year() )
271 .arg( day.month() )
272 .arg( day.day() );
273 } else {
274 qu += ",\"\"";
275 }
276 }
277 break;
278
279 default:
280 qu += QString( ",\"%1\"" ).arg( contactMap[id] );
281 }
282 }
283 qu += " );";
284
285
286#else
200 // Get all information out of the contact-class 287 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too ! 288 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap(); 289 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204 290
205 QMap<QString, QString> addressbook_db; 291 QMap<QString, QString> addressbook_db;
206 292
207 // Get the translation from the ID to the String 293 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields(); 294 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209 295
210 for( QMap<int, QString>::Iterator it = contactMap.begin(); 296 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){ 297 it != contactMap.end(); ++it ){
212 switch ( it.key() ){ 298 switch ( it.key() ){
213 case Qtopia::Birthday:{ 299 case Qtopia::Birthday:{
214 // These entries should stored in a special format 300 // These entries should stored in a special format
215 // year-month-day 301 // year-month-day
216 QDate day = m_contact.birthday(); 302 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()], 303 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3") 304 QString("%1-%2-%3")
219 .arg( day.year() ) 305 .arg( day.year() )
220 .arg( day.month() ) 306 .arg( day.month() )
221 .arg( day.day() ) ); 307 .arg( day.day() ) );
222 } 308 }
223 break; 309 break;
224 case Qtopia::Anniversary:{ 310 case Qtopia::Anniversary:{
225 // These entries should stored in a special format 311 // These entries should stored in a special format
226 // year-month-day 312 // year-month-day
227 QDate day = m_contact.anniversary(); 313 QDate day = m_contact.anniversary();
@@ -240,163 +326,175 @@ namespace {
240 } 326 }
241 327
242 } 328 }
243 329
244 // Now convert this whole stuff into a SQL String, beginning with 330 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table.. 331 // the addressbook table..
246 QString qu; 332 QString qu;
247 // qu += "begin transaction;"; 333 // qu += "begin transaction;";
248 int id = 0; 334 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); 335 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){ 336 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES(" 337 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() ) 338 + QString::number( m_contact.uid() )
253 + "," 339 + ","
254 + QString::number( id++ ) 340 + QString::number( id++ )
255 + ",'" 341 + ",'"
256 + it.key() //.latin1() 342 + it.key() //.latin1()
257 + "'," 343 + "',"
258 + "0" // Priority for future enhancements 344 + "0" // Priority for future enhancements
259 + ",'" 345 + ",'"
260 + it.data() //.latin1() 346 + it.data() //.latin1()
261 + "');"; 347 + "');";
262 } 348 }
263 349
350 #endif //__STORE_HORIZONTAL_
264 // Now add custom data.. 351 // Now add custom data..
352#ifdef __STORE_HORIZONTAL_
353 int id = 0;
354#endif
265 id = 0; 355 id = 0;
356 QMap<QString, QString> customMap = m_contact.toExtraMap();
266 for( QMap<QString, QString>::Iterator it = customMap.begin(); 357 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){ 358 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES(" 359 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() ) 360 + QString::number( m_contact.uid() )
270 + "," 361 + ","
271 + QString::number( id++ ) 362 + QString::number( id++ )
272 + ",'" 363 + ",'"
273 + it.key() //.latin1() 364 + it.key() //.latin1()
274 + "'," 365 + "',"
275 + "0" // Priority for future enhancements 366 + "0" // Priority for future enhancements
276 + ",'" 367 + ",'"
277 + it.data() //.latin1() 368 + it.data() //.latin1()
278 + "');"; 369 + "');";
279 } 370 }
280
281 // qu += "commit;"; 371 // qu += "commit;";
282 qWarning("add %s", qu.latin1() ); 372 qWarning("add %s", qu.latin1() );
283 return qu; 373 return qu;
284 } 374 }
285 375
286 376
287 RemoveQuery::RemoveQuery(int uid ) 377 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {} 378 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {} 379 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const { 380 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = " 381 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";"; 382 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = " 383 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";"; 384 + QString::number(m_uid) + ";";
297 return qu; 385 return qu;
298 } 386 }
299 387
300 388
301 389
302 390
303 FindQuery::FindQuery(int uid) 391 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) { 392 : OSQLQuery(), m_uid( uid ) {
305 } 393 }
306 FindQuery::FindQuery(const QArray<int>& ints) 394 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){ 395 : OSQLQuery(), m_uids( ints ){
308 } 396 }
309 FindQuery::~FindQuery() { 397 FindQuery::~FindQuery() {
310 } 398 }
311 QString FindQuery::query()const{ 399 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 ) 400 // if ( m_uids.count() == 0 )
313 return single(); 401 return single();
314 } 402 }
315 /* 403 /*
316 else 404 else
317 return multi(); 405 return multi();
318 } 406 }
319 QString FindQuery::multi()const { 407 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where"; 408 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) { 409 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 410 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 } 411 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 412 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu; 413 return qu;
326 } 414 }
327 */ 415 */
416#ifdef __STORE_HORIZONTAL_
417 QString FindQuery::single()const{
418 QString qu = "select *";
419 qu += " from addressbook where uid = " + QString::number(m_uid);
420
421 // qWarning("find query: %s", qu.latin1() );
422 return qu;
423 }
424#else
328 QString FindQuery::single()const{ 425 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = "; 426 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid); 427 qu += QString::number(m_uid);
331 return qu; 428 return qu;
332 } 429 }
430#endif
333 431
334 432
335 FindCustomQuery::FindCustomQuery(int uid) 433 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) { 434 : OSQLQuery(), m_uid( uid ) {
337 } 435 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 436 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){ 437 : OSQLQuery(), m_uids( ints ){
340 } 438 }
341 FindCustomQuery::~FindCustomQuery() { 439 FindCustomQuery::~FindCustomQuery() {
342 } 440 }
343 QString FindCustomQuery::query()const{ 441 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 ) 442 // if ( m_uids.count() == 0 )
345 return single(); 443 return single();
346 } 444 }
347 QString FindCustomQuery::single()const{ 445 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = "; 446 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid); 447 qu += QString::number(m_uid);
350 return qu; 448 return qu;
351 } 449 }
352 450
353}; 451};
354 452
355 453
356/* --------------------------------------------------------------------------- */ 454/* --------------------------------------------------------------------------- */
357 455
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, 456OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false) 457 const QString& filename ): m_changed(false)
360{ 458{
361 qWarning("C'tor OContactAccessBackend_SQL starts"); 459 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t; 460 QTime t;
363 t.start(); 461 t.start();
364 462
365 /* Expecting to access the default filename if nothing else is set */ 463 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){ 464 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 465 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else 466 } else
369 m_fileName = filename; 467 m_fileName = filename;
370 468
371 // Get the standart sql-driver from the OSQLManager.. 469 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man; 470 OSQLManager man;
373 m_driver = man.standard(); 471 m_driver = man.standard();
374 m_driver->setUrl( m_fileName ); 472 m_driver->setUrl( m_fileName );
375 473
376 load(); 474 load();
377 475
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() ); 476 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
379} 477}
380 478
381 479
382bool OContactAccessBackend_SQL::load () 480bool OContactAccessBackend_SQL::load ()
383{ 481{
384 if (!m_driver->open() ) 482 if (!m_driver->open() )
385 return false; 483 return false;
386 484
387 // Don't expect that the database exists. 485 // Don't expect that the database exists.
388 // It is save here to create the table, even if it 486 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? ) 487 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat; 488 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat ); 489 OSQLResult res = m_driver->query( &creat );
392 490
393 update(); 491 update();
394 492
395 return true; 493 return true;
396 494
397} 495}
398 496
399bool OContactAccessBackend_SQL::reload() 497bool OContactAccessBackend_SQL::reload()
400{ 498{
401 return load(); 499 return load();
402} 500}
@@ -457,146 +555,303 @@ bool OContactAccessBackend_SQL::remove ( int uid )
457 555
458 m_changed = true; 556 m_changed = true;
459 557
460 return true; 558 return true;
461} 559}
462 560
463bool OContactAccessBackend_SQL::replace ( const OContact &contact ) 561bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{ 562{
465 if ( !remove( contact.uid() ) ) 563 if ( !remove( contact.uid() ) )
466 return false; 564 return false;
467 565
468 return add( contact ); 566 return add( contact );
469} 567}
470 568
471 569
472OContact OContactAccessBackend_SQL::find ( int uid ) const 570OContact OContactAccessBackend_SQL::find ( int uid ) const
473{ 571{
474 qWarning("OContactAccessBackend_SQL::find()"); 572 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t; 573 QTime t;
476 t.start(); 574 t.start();
477 575
478 OContact retContact( requestNonCustom( uid ) ); 576 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) ); 577 retContact.setExtraMap( requestCustom( uid ) );
480 578
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() ); 579 qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
482 return retContact; 580 return retContact;
483} 581}
484 582
485 583
486 584
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) 585QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{ 586{
489 QArray<int> nix(0); 587 QString qu = "SELECT uid FROM addressbook WHERE";
490 return nix; 588
589 QMap<int, QString> queryFields = query.toMap();
590 QStringList fieldList = OContactFields::untrfields( false );
591 QMap<QString, int> translate = OContactFields::untrFieldsToId();
592
593 // Convert every filled field to a SQL-Query
594 bool isAnyFieldSelected = false;
595 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
596 int id = translate[*it];
597 QString queryStr = queryFields[id];
598 if ( !queryStr.isEmpty() ){
599 isAnyFieldSelected = true;
600 switch( id ){
601 default:
602 // Switching between case sensitive and insensitive...
603 // LIKE is not case sensitive, GLOB is case sensitive
604 // Do exist a better solution to switch this ?
605 if ( settings & OContactAccess::IgnoreCase )
606 qu += "(\"" + *it + "\"" + " LIKE " + "'"
607 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND ";
608 else
609 qu += "(\"" + *it + "\"" + " GLOB " + "'"
610 + queryStr + "'" + ") AND ";
611
612 }
613 }
614 }
615 // Skip trailing "AND"
616 if ( isAnyFieldSelected )
617 qu = qu.left( qu.length() - 4 );
618
619 qWarning( "queryByExample query: %s", qu.latin1() );
620
621 // Execute query and return the received uid's
622 OSQLRawQuery raw( qu );
623 OSQLResult res = m_driver->query( &raw );
624 if ( res.state() != OSQLResult::Success ){
625 QArray<int> empty;
626 return empty;
627 }
628
629 QArray<int> list = extractUids( res );
630
631 return list;
491} 632}
492 633
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 634QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{ 635{
495 QArray<int> nix(0); 636 QArray<int> nix(0);
496 return nix; 637 return nix;
497} 638}
498 639
499const uint OContactAccessBackend_SQL::querySettings() 640const uint OContactAccessBackend_SQL::querySettings()
500{ 641{
501 return 0; 642 return OContactAccess::IgnoreCase
643 || OContactAccess::WildCards;
502} 644}
503 645
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 646bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{ 647{
506 return false; 648 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
649 * may be added with any of the other settings. IgnoreCase should never used alone.
650 * Wildcards, RegExp, ExactMatch should never used at the same time...
651 */
652
653 // Step 1: Check whether the given settings are supported by this backend
654 if ( ( querySettings & (
655 OContactAccess::IgnoreCase
656 | OContactAccess::WildCards
657 // | OContactAccess::DateDiff
658 // | OContactAccess::DateYear
659 // | OContactAccess::DateMonth
660 // | OContactAccess::DateDay
661 // | OContactAccess::RegExp
662 // | OContactAccess::ExactMatch
663 ) ) != querySettings )
664 return false;
665
666 // Step 2: Check whether the given combinations are ok..
667
668 // IngoreCase alone is invalid
669 if ( querySettings == OContactAccess::IgnoreCase )
670 return false;
671
672 // WildCards, RegExp and ExactMatch should never used at the same time
673 switch ( querySettings & ~( OContactAccess::IgnoreCase
674 | OContactAccess::DateDiff
675 | OContactAccess::DateYear
676 | OContactAccess::DateMonth
677 | OContactAccess::DateDay
678 )
679 ){
680 case OContactAccess::RegExp:
681 return ( true );
682 case OContactAccess::WildCards:
683 return ( true );
684 case OContactAccess::ExactMatch:
685 return ( true );
686 case 0: // one of the upper removed bits were set..
687 return ( true );
688 default:
689 return ( false );
690 }
691
507} 692}
508 693
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 694QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{ 695{
511 QTime t; 696 QTime t;
512 t.start(); 697 t.start();
513 698
514 // Not implemented.. 699#ifdef __STORE_HORIZONTAL_
700 QString query = "SELECT uid FROM addressbook ";
701 query += "ORDER BY \"Last Name\" ";
702#else
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; 703 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
704 query += "ORDER BY upper( value )";
705#endif
516 706
517 query += "ORDER BY value ";
518 if ( !asc ) 707 if ( !asc )
519 query += "DESC"; 708 query += "DESC";
520 709
521 qWarning("sorted query is: %s", query.latin1() ); 710 // qWarning("sorted query is: %s", query.latin1() );
522 711
523 OSQLRawQuery raw( query ); 712 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw ); 713 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){ 714 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty; 715 QArray<int> empty;
527 return empty; 716 return empty;
528 } 717 }
529 718
530 QArray<int> list = extractUids( res ); 719 QArray<int> list = extractUids( res );
531 720
532 qWarning("sorted needed %d ms!", t.elapsed() ); 721 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list; 722 return list;
534} 723}
535 724
536 725
537void OContactAccessBackend_SQL::update() 726void OContactAccessBackend_SQL::update()
538{ 727{
539 qWarning("Update starts"); 728 qWarning("Update starts");
540 QTime t; 729 QTime t;
541 t.start(); 730 t.start();
542 731
543 // Now load the database set and extract the uid's 732 // Now load the database set and extract the uid's
544 // which will be held locally 733 // which will be held locally
545 734
546 LoadQuery lo; 735 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo); 736 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success ) 737 if ( res.state() != OSQLResult::Success )
549 return; 738 return;
550 739
551 m_uids = extractUids( res ); 740 m_uids = extractUids( res );
552 741
553 m_changed = false; 742 m_changed = false;
554 743
555 qWarning("Update ends %d", t.elapsed() ); 744 qWarning("Update ends %d ms", t.elapsed() );
556} 745}
557 746
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const 747QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{ 748{
560 qWarning("extractUids"); 749 qWarning("extractUids");
561 QTime t; 750 QTime t;
562 t.start(); 751 t.start();
563 OSQLResultItem::ValueList list = res.results(); 752 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it; 753 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() ); 754 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() ); 755 qWarning(" count = %d", list.count() );
567 756
568 int i = 0; 757 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) { 758 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt(); 759 ints[i] = (*it).data("uid").toInt();
571 i++; 760 i++;
572 } 761 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 762 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574 763
575 return ints; 764 return ints;
576 765
577} 766}
578 767
768#ifdef __STORE_HORIZONTAL_
769QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
770{
771 QTime t;
772 t.start();
773
774 QMap<int, QString> nonCustomMap;
775
776 int t2needed = 0;
777 int t3needed = 0;
778 QTime t2;
779 t2.start();
780 FindQuery query( uid );
781 OSQLResult res_noncustom = m_driver->query( &query );
782 t2needed = t2.elapsed();
783
784 OSQLResultItem resItem = res_noncustom.first();
785
786 QTime t3;
787 t3.start();
788 // Now loop through all columns
789 QStringList fieldList = OContactFields::untrfields( false );
790 QMap<QString, int> translate = OContactFields::untrFieldsToId();
791 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
792 // Get data for the selected column and store it with the
793 // corresponding id into the map..
794
795 int id = translate[*it];
796 QString value = resItem.data( (*it) );
797
798 // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() );
799
800 switch( id ){
801 case Qtopia::Birthday:
802 case Qtopia::Anniversary:{
803 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
804 QStringList list = QStringList::split( '-', value );
805 QStringList::Iterator lit = list.begin();
806 int year = (*lit).toInt();
807 int month = (*(++lit)).toInt();
808 int day = (*(++lit)).toInt();
809 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){
810 QDate date( year, month, day );
811 nonCustomMap.insert( id, OConversion::dateToString( date ) );
812 }
813 }
814 break;
815 case Qtopia::AddressCategory:
816 qWarning("Category is: %s", value.latin1() );
817 default:
818 nonCustomMap.insert( id, value );
819 }
820 }
821
822 // First insert uid
823 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
824 t3needed = t3.elapsed();
825
826 // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() );
827 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms",
828 t.elapsed(), t2needed, t3needed );
829
830 return nonCustomMap;
831}
832#else
833
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const 834QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{ 835{
581 QTime t; 836 QTime t;
582 t.start(); 837 t.start();
583 838
584 QMap<int, QString> nonCustomMap; 839 QMap<int, QString> nonCustomMap;
585 840
586 int t2needed = 0; 841 int t2needed = 0;
587 QTime t2; 842 QTime t2;
588 t2.start(); 843 t2.start();
589 FindQuery query( uid ); 844 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query ); 845 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed(); 846 t2needed = t2.elapsed();
592 847
593 if ( res_noncustom.state() == OSQLResult::Failure ) { 848 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!"); 849 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty; 850 QMap<int, QString> empty;
596 return empty; 851 return empty;
597 } 852 }
598 853
599 int t3needed = 0; 854 int t3needed = 0;
600 QTime t3; 855 QTime t3;
601 t3.start(); 856 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId(); 857 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
@@ -612,53 +867,55 @@ QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 867 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) ); 868 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin(); 869 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt(); 870 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1()); 871 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt(); 872 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1()); 873 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt(); 874 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1()); 875 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day ); 876 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day ); 877 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) ); 878 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 } 879 }
625 break; 880 break;
626 default: 881 default:
627 nonCustomMap.insert( typeId, 882 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) ); 883 (*it).data( "value" ) );
629 } 884 }
630 } 885 }
631 } 886 }
632 // Add UID to Map.. 887 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) ); 888 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed(); 889 t3needed = t3.elapsed();
635 890
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed ); 891 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap; 892 return nonCustomMap;
638} 893}
639 894
895#endif // __STORE_HORIZONTAL_
896
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const 897QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{ 898{
642 QTime t; 899 QTime t;
643 t.start(); 900 t.start();
644 901
645 QMap<QString, QString> customMap; 902 QMap<QString, QString> customMap;
646 903
647 FindCustomQuery query( uid ); 904 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query ); 905 OSQLResult res_custom = m_driver->query( &query );
649 906
650 if ( res_custom.state() == OSQLResult::Failure ) { 907 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!"); 908 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty; 909 QMap<QString, QString> empty;
653 return empty; 910 return empty;
654 } 911 }
655 912
656 OSQLResultItem::ValueList list = res_custom.results(); 913 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin(); 914 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) { 915 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 916 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 } 917 }
661 918
662 qWarning("RequestCustom needed: %d", t.elapsed() ); 919 qWarning("RequestCustom needed: %d ms", t.elapsed() );
663 return customMap; 920 return customMap;
664} 921}
diff --git a/libopie/pim/ocontactfields.cpp b/libopie/pim/ocontactfields.cpp
index 831a596..7206f0d 100644
--- a/libopie/pim/ocontactfields.cpp
+++ b/libopie/pim/ocontactfields.cpp
@@ -152,86 +152,92 @@ QStringList OContactFields::trfields( bool sorted )
152 list.append( mapIdToStr[Qtopia::HomeCity] ); 152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] ); 153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] ); 154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] ); 155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156 156
157 list += trdetailsfields( sorted ); 157 list += trdetailsfields( sorted );
158 158
159 list.append( mapIdToStr[Qtopia::Notes] ); 159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] ); 160 list.append( mapIdToStr[Qtopia::Groups] );
161 161
162 if (sorted) list.sort(); 162 if (sorted) list.sort();
163 163
164 return list; 164 return list;
165} 165}
166 166
167/*! 167/*!
168 \internal 168 \internal
169 Returns an untranslated list of field names for a contact. 169 Returns an untranslated list of field names for a contact.
170*/ 170*/
171QStringList OContactFields::untrfields( bool sorted ) 171QStringList OContactFields::untrfields( bool sorted )
172{ 172{
173 QStringList list; 173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields(); 174 QMap<int, QString> mapIdToStr = idToUntrFields();
175 175
176 list.append( mapIdToStr[ Qtopia::AddressUid ] );
177 list.append( mapIdToStr[ Qtopia::AddressCategory ] );
178
176 list.append( mapIdToStr[ Qtopia::Title ] ); 179 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] ); 180 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] ); 181 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] ); 182 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] ); 183 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] ); 184 list.append( mapIdToStr[ Qtopia::FileAs ] );
182 185
183 list.append( mapIdToStr[ Qtopia::JobTitle ] ); 186 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] ); 187 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] ); 188 list.append( mapIdToStr[ Qtopia::Company ] );
186 189
187 list += untrphonefields( sorted ); 190 list += untrphonefields( sorted );
188 191
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] ); 192 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] ); 193 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] ); 194 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] ); 195 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] ); 196 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194 197
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] ); 198 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] ); 199 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] ); 200 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] ); 201 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] ); 202 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200 203
201 list += untrdetailsfields( sorted ); 204 list += untrdetailsfields( sorted );
202 205
203 list.append( mapIdToStr[ Qtopia::Notes ] ); 206 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] ); 207 list.append( mapIdToStr[ Qtopia::Groups ] );
205 208
206 if (sorted) list.sort(); 209 if (sorted) list.sort();
207 210
208 return list; 211 return list;
209} 212}
210QMap<int, QString> OContactFields::idToTrFields() 213QMap<int, QString> OContactFields::idToTrFields()
211{ 214{
212 QMap<int, QString> ret_map; 215 QMap<int, QString> ret_map;
213 216
217 ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) );
218 ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) );
219
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") ); 220 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) ); 221 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) ); 222 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) ); 223 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" )); 224 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) ); 225 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220 226
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) ); 227 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) ); 228 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) ); 229 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) ); 230 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) ); 231 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" )); 232 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227 233
228 // email 234 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) ); 235 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) ); 236 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231 237
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) ); 238 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) ); 239 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) ); 240 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235 241
236 // business 242 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) ); 243 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
@@ -253,48 +259,51 @@ QMap<int, QString> OContactFields::idToTrFields()
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) ); 259 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) ); 260 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) ); 261 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) ); 262 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257 263
258 //personal 264 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) ); 265 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) ); 266 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) ); 267 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) ); 268 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) ); 269 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) ); 270 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265 271
266 // other 272 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) ); 273 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268 274
269 275
270 return ret_map; 276 return ret_map;
271} 277}
272 278
273QMap<int, QString> OContactFields::idToUntrFields() 279QMap<int, QString> OContactFields::idToUntrFields()
274{ 280{
275 QMap<int, QString> ret_map; 281 QMap<int, QString> ret_map;
276 282
283 ret_map.insert( Qtopia::AddressUid, "User Id" );
284 ret_map.insert( Qtopia::AddressCategory, "Categories" );
285
277 ret_map.insert( Qtopia::Title, "Name Title" ); 286 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" ); 287 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" ); 288 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" ); 289 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" ); 290 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" ); 291 ret_map.insert( Qtopia::FileAs, "File As" );
283 292
284 ret_map.insert( Qtopia::JobTitle, "Job Title" ); 293 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" ); 294 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" ); 295 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" ); 296 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" ); 297 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" ); 298 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290 299
291 // email 300 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" ); 301 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" ); 302 ret_map.insert( Qtopia::Emails, "Emails" );
294 303
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" ); 304 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" ); 305 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" ); 306 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298 307
299 // business 308 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" ); 309 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
@@ -307,48 +316,49 @@ QMap<int, QString> OContactFields::idToUntrFields()
307 316
308 ret_map.insert( Qtopia::Office, "Office" ); 317 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" ); 318 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" ); 319 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" ); 320 ret_map.insert( Qtopia::Manager, "Manager" );
312 321
313 // home 322 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" ); 323 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" ); 324 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" ); 325 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" ); 326 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" ); 327 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" ); 328 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320 329
321 //personal 330 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" ); 331 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" ); 332 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" ); 333 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" ); 334 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" ); 335 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" ); 336 ret_map.insert( Qtopia::Children, "Children" );
328 337
329 // other 338 // other
330 ret_map.insert( Qtopia::Notes, "Notes" ); 339 ret_map.insert( Qtopia::Notes, "Notes" );
340 ret_map.insert( Qtopia::Groups, "Groups" );
331 341
332 342
333 return ret_map; 343 return ret_map;
334} 344}
335 345
336QMap<QString, int> OContactFields::trFieldsToId() 346QMap<QString, int> OContactFields::trFieldsToId()
337{ 347{
338 QMap<int, QString> idtostr = idToTrFields(); 348 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map; 349 QMap<QString, int> ret_map;
340 350
341 351
342 QMap<int, QString>::Iterator it; 352 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it ) 353 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() ); 354 ret_map.insert( *it, it.key() );
345 355
346 356
347 return ret_map; 357 return ret_map;
348} 358}
349 359
350QMap<QString, int> OContactFields::untrFieldsToId() 360QMap<QString, int> OContactFields::untrFieldsToId()
351{ 361{
352 QMap<int, QString> idtostr = idToUntrFields(); 362 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map; 363 QMap<QString, int> ret_map;
354 364
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index 23e0c3e..d255c66 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -97,129 +97,164 @@ namespace {
97 class OverDueQuery : public OSQLQuery { 97 class OverDueQuery : public OSQLQuery {
98 public: 98 public:
99 OverDueQuery(); 99 OverDueQuery();
100 ~OverDueQuery(); 100 ~OverDueQuery();
101 QString query()const; 101 QString query()const;
102 }; 102 };
103 class EffQuery : public OSQLQuery { 103 class EffQuery : public OSQLQuery {
104 public: 104 public:
105 EffQuery( const QDate&, const QDate&, bool inc ); 105 EffQuery( const QDate&, const QDate&, bool inc );
106 ~EffQuery(); 106 ~EffQuery();
107 QString query()const; 107 QString query()const;
108 private: 108 private:
109 QString with()const; 109 QString with()const;
110 QString out()const; 110 QString out()const;
111 QDate m_start; 111 QDate m_start;
112 QDate m_end; 112 QDate m_end;
113 bool m_inc :1; 113 bool m_inc :1;
114 }; 114 };
115 115
116 116
117 CreateQuery::CreateQuery() : OSQLQuery() {} 117 CreateQuery::CreateQuery() : OSQLQuery() {}
118 CreateQuery::~CreateQuery() {} 118 CreateQuery::~CreateQuery() {}
119 QString CreateQuery::query()const { 119 QString CreateQuery::query()const {
120 QString qu; 120 QString qu;
121 qu += "create table todolist( uid, categories, completed, progress, "; 121 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
122 qu += "summary, DueDate, priority, description )"; 122 qu += "description, summary, priority, DueDate, progress , state, ";
123 qu += "Recurrence, notifiers, maintainer, startdate, completeddate)";
123 return qu; 124 return qu;
124 } 125 }
125 126
126 LoadQuery::LoadQuery() : OSQLQuery() {} 127 LoadQuery::LoadQuery() : OSQLQuery() {}
127 LoadQuery::~LoadQuery() {} 128 LoadQuery::~LoadQuery() {}
128 QString LoadQuery::query()const { 129 QString LoadQuery::query()const {
129 QString qu; 130 QString qu;
130 qu += "select distinct uid from todolist"; 131 // We do not need "distinct" here. The primary key is always unique..
132 //qu += "select distinct uid from todolist";
133 qu += "select uid from todolist";
131 134
132 return qu; 135 return qu;
133 } 136 }
134 137
135 InsertQuery::InsertQuery( const OTodo& todo ) 138 InsertQuery::InsertQuery( const OTodo& todo )
136 : OSQLQuery(), m_todo( todo ) { 139 : OSQLQuery(), m_todo( todo ) {
137 } 140 }
138 InsertQuery::~InsertQuery() { 141 InsertQuery::~InsertQuery() {
139 } 142 }
140 /* 143 /*
141 * converts from a OTodo to a query 144 * converts from a OTodo to a query
142 * we leave out X-Ref + Alarms 145 * we leave out X-Ref + Alarms
143 */ 146 */
144 QString InsertQuery::query()const{ 147 QString InsertQuery::query()const{
145 148
146 int year, month, day; 149 int year, month, day;
147 year = month = day = 0; 150 year = month = day = 0;
148 if (m_todo.hasDueDate() ) { 151 if (m_todo.hasDueDate() ) {
149 QDate date = m_todo.dueDate(); 152 QDate date = m_todo.dueDate();
150 year = date.year(); 153 year = date.year();
151 month = date.month(); 154 month = date.month();
152 day = date.day(); 155 day = date.day();
153 } 156 }
157 int sYear = 0, sMonth = 0, sDay = 0;
158 if( m_todo.hasStartDate() ){
159 QDate sDate = m_todo.startDate();
160 sYear = sDate.year();
161 sMonth= sDate.month();
162 sDay = sDate.day();
163 }
164
165 int eYear = 0, eMonth = 0, eDay = 0;
166 if( m_todo.hasCompletedDate() ){
167 QDate eDate = m_todo.completedDate();
168 eYear = eDate.year();
169 eMonth= eDate.month();
170 eDay = eDate.day();
171 }
154 QString qu; 172 QString qu;
155 qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',"; 173 qu = "insert into todolist VALUES("
156 qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ","; 174 + QString::number( m_todo.uid() ) + ","
157 qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',"; 175 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
158 qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')"; 176 + QString::number( m_todo.isCompleted() ) + ","
177 + "'" + m_todo.description() + "'" + ","
178 + "'" + m_todo.summary() + "'" + ","
179 + QString::number(m_todo.priority() ) + ","
180 + "'" + QString::number(year) + "-"
181 + QString::number(month)
182 + "-" + QString::number( day ) + "'" + ","
183 + QString::number( m_todo.progress() ) + ","
184 + "''" + "," // state (conversion needed)
185 // + QString::number( m_todo.state() ) + ","
186 + "''" + "," // Recurrence (conversion needed)
187 + "''" + "," // Notifiers (conversion needed)
188 + "''" + "," // Maintainers (conversion needed)
189 + "'" + QString::number(sYear) + "-"
190 + QString::number(sMonth)
191 + "-" + QString::number(sDay) + "'" + ","
192 + "'" + QString::number(eYear) + "-"
193 + QString::number(eMonth)
194 + "-"+QString::number(eDay) + "'"
195 + ")";
159 196
160 qWarning("add %s", qu.latin1() ); 197 qWarning("add %s", qu.latin1() );
161 return qu; 198 return qu;
162 } 199 }
163 200
164 RemoveQuery::RemoveQuery(int uid ) 201 RemoveQuery::RemoveQuery(int uid )
165 : OSQLQuery(), m_uid( uid ) {} 202 : OSQLQuery(), m_uid( uid ) {}
166 RemoveQuery::~RemoveQuery() {} 203 RemoveQuery::~RemoveQuery() {}
167 QString RemoveQuery::query()const { 204 QString RemoveQuery::query()const {
168 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 205 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
169 return qu; 206 return qu;
170 } 207 }
171 208
172 209
173 ClearQuery::ClearQuery() 210 ClearQuery::ClearQuery()
174 : OSQLQuery() {} 211 : OSQLQuery() {}
175 ClearQuery::~ClearQuery() {} 212 ClearQuery::~ClearQuery() {}
176 QString ClearQuery::query()const { 213 QString ClearQuery::query()const {
177 QString qu = "drop table todolist"; 214 QString qu = "drop table todolist";
178 return qu; 215 return qu;
179 } 216 }
180 FindQuery::FindQuery(int uid) 217 FindQuery::FindQuery(int uid)
181 : OSQLQuery(), m_uid(uid ) { 218 : OSQLQuery(), m_uid(uid ) {
182 } 219 }
183 FindQuery::FindQuery(const QArray<int>& ints) 220 FindQuery::FindQuery(const QArray<int>& ints)
184 : OSQLQuery(), m_uids(ints){ 221 : OSQLQuery(), m_uids(ints){
185 } 222 }
186 FindQuery::~FindQuery() { 223 FindQuery::~FindQuery() {
187 } 224 }
188 QString FindQuery::query()const{ 225 QString FindQuery::query()const{
189 if (m_uids.count() == 0 ) 226 if (m_uids.count() == 0 )
190 return single(); 227 return single();
191 else 228 else
192 return multi(); 229 return multi();
193 } 230 }
194 QString FindQuery::single()const{ 231 QString FindQuery::single()const{
195 QString qu = "select uid, categories, completed, progress, summary, "; 232 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
197 return qu; 233 return qu;
198 } 234 }
199 QString FindQuery::multi()const { 235 QString FindQuery::multi()const {
200 QString qu = "select uid, categories, completed, progress, summary, "; 236 QString qu = "select * from todolist where ";
201 qu += "DueDate, priority, description from todolist where ";
202 for (uint i = 0; i < m_uids.count(); i++ ) { 237 for (uint i = 0; i < m_uids.count(); i++ ) {
203 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 238 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
204 } 239 }
205 qu.remove( qu.length()-2, 2 ); 240 qu.remove( qu.length()-2, 2 );
206 return qu; 241 return qu;
207 } 242 }
208 243
209 OverDueQuery::OverDueQuery(): OSQLQuery() {} 244 OverDueQuery::OverDueQuery(): OSQLQuery() {}
210 OverDueQuery::~OverDueQuery() {} 245 OverDueQuery::~OverDueQuery() {}
211 QString OverDueQuery::query()const { 246 QString OverDueQuery::query()const {
212 QDate date = QDate::currentDate(); 247 QDate date = QDate::currentDate();
213 QString str; 248 QString str;
214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 249 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
215 250
216 return str; 251 return str;
217 } 252 }
218 253
219 254
220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 255 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 256 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
222 EffQuery::~EffQuery() {} 257 EffQuery::~EffQuery() {}
223 QString EffQuery::query()const { 258 QString EffQuery::query()const {
224 return m_inc ? with() : out(); 259 return m_inc ? with() : out();
225 } 260 }
@@ -267,49 +302,49 @@ bool OTodoAccessBackendSQL::load(){
267bool OTodoAccessBackendSQL::reload(){ 302bool OTodoAccessBackendSQL::reload(){
268 return load(); 303 return load();
269} 304}
270 305
271bool OTodoAccessBackendSQL::save(){ 306bool OTodoAccessBackendSQL::save(){
272 return m_driver->close(); 307 return m_driver->close();
273} 308}
274QArray<int> OTodoAccessBackendSQL::allRecords()const { 309QArray<int> OTodoAccessBackendSQL::allRecords()const {
275 if (m_dirty ) 310 if (m_dirty )
276 update(); 311 update();
277 312
278 return m_uids; 313 return m_uids;
279} 314}
280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 315QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
281 QArray<int> ints(0); 316 QArray<int> ints(0);
282 return ints; 317 return ints;
283} 318}
284OTodo OTodoAccessBackendSQL::find(int uid ) const{ 319OTodo OTodoAccessBackendSQL::find(int uid ) const{
285 FindQuery query( uid ); 320 FindQuery query( uid );
286 return todo( m_driver->query(&query) ); 321 return todo( m_driver->query(&query) );
287 322
288} 323}
289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 324OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
290 uint cur, Frontend::CacheDirection dir ) const{ 325 uint cur, Frontend::CacheDirection dir ) const{
291 int CACHE = readAhead(); 326 uint CACHE = readAhead();
292 qWarning("searching for %d", uid ); 327 qWarning("searching for %d", uid );
293 QArray<int> search( CACHE ); 328 QArray<int> search( CACHE );
294 uint size =0; 329 uint size =0;
295 OTodo to; 330 OTodo to;
296 331
297 // we try to cache CACHE items 332 // we try to cache CACHE items
298 switch( dir ) { 333 switch( dir ) {
299 /* forward */ 334 /* forward */
300 case 0: // FIXME: Not a good style to use magic numbers here (eilers) 335 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 336 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 337 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 338 search[size] = ints[i];
304 size++; 339 size++;
305 } 340 }
306 break; 341 break;
307 /* reverse */ 342 /* reverse */
308 case 1: // FIXME: Not a good style to use magic numbers here (eilers) 343 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 344 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 345 search[size] = ints[i];
311 size++; 346 size++;
312 } 347 }
313 break; 348 break;
314 } 349 }
315 search.resize( size ); 350 search.resize( size );
@@ -451,56 +486,72 @@ bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
451 return true; 486 return true;
452 } 487 }
453} 488}
454OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 489OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
455 if ( res.state() == OSQLResult::Failure ) { 490 if ( res.state() == OSQLResult::Failure ) {
456 OTodo to; 491 OTodo to;
457 return to; 492 return to;
458 } 493 }
459 494
460 OSQLResultItem::ValueList list = res.results(); 495 OSQLResultItem::ValueList list = res.results();
461 OSQLResultItem::ValueList::Iterator it = list.begin(); 496 OSQLResultItem::ValueList::Iterator it = list.begin();
462 qWarning("todo1"); 497 qWarning("todo1");
463 OTodo to = todo( (*it) ); 498 OTodo to = todo( (*it) );
464 cache( to ); 499 cache( to );
465 ++it; 500 ++it;
466 501
467 for ( ; it != list.end(); ++it ) { 502 for ( ; it != list.end(); ++it ) {
468 qWarning("caching"); 503 qWarning("caching");
469 cache( todo( (*it) ) ); 504 cache( todo( (*it) ) );
470 } 505 }
471 return to; 506 return to;
472} 507}
473OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 508OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
474 qWarning("todo"); 509 qWarning("todo");
475 bool has = false; QDate da = QDate::currentDate(); 510 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
476 has = date( da, item.data("DueDate") ); 511 hasDueDate = date( dueDate, item.data("DueDate") );
477 QStringList cats = QStringList::split(";", item.data("categories") ); 512 QStringList cats = QStringList::split(";", item.data("categories") );
478 513
479 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 514 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
480 cats, item.data("summary"), item.data("description"), 515 cats, item.data("summary"), item.data("description"),
481 item.data("progress").toUShort(), has, da, 516 item.data("progress").toUShort(), hasDueDate, dueDate,
482 item.data("uid").toInt() ); 517 item.data("uid").toInt() );
518
519 bool isOk;
520 int prioInt = QString( item.data("priority") ).toInt( &isOk );
521 if ( isOk )
522 to.setPriority( prioInt );
523
524 bool hasStartDate = false; QDate startDate = QDate::currentDate();
525 hasStartDate = date( startDate, item.data("startdate") );
526 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
527 hasCompletedDate = date( completedDate, item.data("completeddate") );
528
529 if ( hasStartDate )
530 to.setStartDate( startDate );
531 if ( hasCompletedDate )
532 to.setCompletedDate( completedDate );
533
483 return to; 534 return to;
484} 535}
485OTodo OTodoAccessBackendSQL::todo( int uid )const { 536OTodo OTodoAccessBackendSQL::todo( int uid )const {
486 FindQuery find( uid ); 537 FindQuery find( uid );
487 return todo( m_driver->query(&find) ); 538 return todo( m_driver->query(&find) );
488} 539}
489/* 540/*
490 * update the dict 541 * update the dict
491 */ 542 */
492void OTodoAccessBackendSQL::fillDict() { 543void OTodoAccessBackendSQL::fillDict() {
493 /* initialize dict */ 544 /* initialize dict */
494 /* 545 /*
495 * UPDATE dict if you change anything!!! 546 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers) 547 * FIXME: Isn't this dict obsolete ? (eilers)
497 */ 548 */
498 m_dict.setAutoDelete( TRUE ); 549 m_dict.setAutoDelete( TRUE );
499 m_dict.insert("Categories" , new int(OTodo::Category) ); 550 m_dict.insert("Categories" , new int(OTodo::Category) );
500 m_dict.insert("Uid" , new int(OTodo::Uid) ); 551 m_dict.insert("Uid" , new int(OTodo::Uid) );
501 m_dict.insert("HasDate" , new int(OTodo::HasDate) ); 552 m_dict.insert("HasDate" , new int(OTodo::HasDate) );
502 m_dict.insert("Completed" , new int(OTodo::Completed) ); 553 m_dict.insert("Completed" , new int(OTodo::Completed) );
503 m_dict.insert("Description" , new int(OTodo::Description) ); 554 m_dict.insert("Description" , new int(OTodo::Description) );
504 m_dict.insert("Summary" , new int(OTodo::Summary) ); 555 m_dict.insert("Summary" , new int(OTodo::Summary) );
505 m_dict.insert("Priority" , new int(OTodo::Priority) ); 556 m_dict.insert("Priority" , new int(OTodo::Priority) );
506 m_dict.insert("DateDay" , new int(OTodo::DateDay) ); 557 m_dict.insert("DateDay" , new int(OTodo::DateDay) );
@@ -549,45 +600,52 @@ QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
549 600
550 Copied from xml-backend by not adapted to sql (eilers) 601 Copied from xml-backend by not adapted to sql (eilers)
551 602
552 QArray<int> m_currentQuery( m_events.count() ); 603 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0; 604 uint arraycounter = 0;
554 605
555 606
556 607
557 QMap<int, OTodo>::ConstIterator it; 608 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) { 609 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) ) 610 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid(); 611 m_currentQuery[arraycounter++] = it.data().uid();
561 612
562 } 613 }
563 // Shrink to fit.. 614 // Shrink to fit..
564 m_currentQuery.resize(arraycounter); 615 m_currentQuery.resize(arraycounter);
565 616
566 return m_currentQuery; 617 return m_currentQuery;
567#endif 618#endif
568 QArray<int> empty; 619 QArray<int> empty;
569 return empty; 620 return empty;
570} 621}
571QBitArray OTodoAccessBackendSQL::supports()const { 622QBitArray OTodoAccessBackendSQL::supports()const {
572 623
573 static QBitArray ar = sup(); 624 QBitArray ar( OTodo::CompletedDate + 1 );
625 ar.fill( true );
626 ar[OTodo::CrossReference] = false;
627 ar[OTodo::State ] = false;
628 ar[OTodo::Reminders] = false;
629 ar[OTodo::Notifiers] = false;
630 ar[OTodo::Maintainer] = false;
631
574 return ar; 632 return ar;
575} 633}
576 634
577QBitArray OTodoAccessBackendSQL::sup() { 635QBitArray OTodoAccessBackendSQL::sup() {
578 636
579 QBitArray ar( OTodo::CompletedDate + 1 ); 637 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true ); 638 ar.fill( true );
581 ar[OTodo::CrossReference] = false; 639 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false; 640 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false; 641 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false; 642 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false; 643 ar[OTodo::Maintainer] = false;
586 644
587 return ar; 645 return ar;
588} 646}
589 647
590void OTodoAccessBackendSQL::removeAllCompleted(){ 648void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !! 649#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592 650
593} 651}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 4afa5f3..132c9fc 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -1,63 +1,84 @@
1/* 1/*
2 * SQL Backend for the OPIE-Contact Database. 2 * SQL Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ===================================================================== 12 * =====================================================================
13 * Version: $Id$ 13 * Version: $Id$
14 * ===================================================================== 14 * =====================================================================
15 * History: 15 * History:
16 * $Log$ 16 * $Log$
17 * Revision 1.2 2003/09/29 07:44:26 eilers
18 * Improvement of PIM-SQL Databases, but search queries are still limited.
19 * Addressbook: Changed table layout. Now, we just need 1/3 of disk-space.
20 * Todo: Started to add new attributes. Some type conversions missing.
21 *
17 * Revision 1.1 2003/09/22 14:31:16 eilers 22 * Revision 1.1 2003/09/22 14:31:16 eilers
18 * Added first experimental incarnation of sql-backend for addressbook. 23 * Added first experimental incarnation of sql-backend for addressbook.
19 * Some modifications to be able to compile the todo sql-backend. 24 * Some modifications to be able to compile the todo sql-backend.
20 * A lot of changes fill follow... 25 * A lot of changes fill follow...
21 * 26 *
22 */ 27 */
23 28
24#include "ocontactaccessbackend_sql.h" 29#include "ocontactaccessbackend_sql.h"
25 30
26#include <qarray.h> 31#include <qarray.h>
27#include <qdatetime.h> 32#include <qdatetime.h>
28#include <qstringlist.h> 33#include <qstringlist.h>
29 34
30#include <qpe/global.h> 35#include <qpe/global.h>
31#include <qpe/recordfields.h> 36#include <qpe/recordfields.h>
32 37
33#include <opie/ocontactfields.h> 38#include <opie/ocontactfields.h>
34#include <opie/oconversion.h> 39#include <opie/oconversion.h>
35#include <opie2/osqldriver.h> 40#include <opie2/osqldriver.h>
36#include <opie2/osqlresult.h> 41#include <opie2/osqlresult.h>
37#include <opie2/osqlmanager.h> 42#include <opie2/osqlmanager.h>
38#include <opie2/osqlquery.h> 43#include <opie2/osqlquery.h>
39 44
45
46
47
48// If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead
49// vertical like "uid, type, value".
50// DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !!
51#define __STORE_HORIZONTAL_
52
53// Distinct loading is not very fast. If I expect that every person has just
54// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
55// which is faster..
56// But this may not be true for all entries, like company contacts..
57// The current AddressBook application handles this problem, but other may not.. (eilers)
58#define __USE_SUPERFAST_LOADQUERY
59
60
40/* 61/*
41 * Implementation of used query types 62 * Implementation of used query types
42 * CREATE query 63 * CREATE query
43 * LOAD query 64 * LOAD query
44 * INSERT 65 * INSERT
45 * REMOVE 66 * REMOVE
46 * CLEAR 67 * CLEAR
47 */ 68 */
48namespace { 69namespace {
49 /** 70 /**
50 * CreateQuery for the Todolist Table 71 * CreateQuery for the Todolist Table
51 */ 72 */
52 class CreateQuery : public OSQLQuery { 73 class CreateQuery : public OSQLQuery {
53 public: 74 public:
54 CreateQuery(); 75 CreateQuery();
55 ~CreateQuery(); 76 ~CreateQuery();
56 QString query()const; 77 QString query()const;
57 }; 78 };
58 79
59 /** 80 /**
60 * Clears (delete) a Table 81 * Clears (delete) a Table
61 */ 82 */
62 class ClearQuery : public OSQLQuery { 83 class ClearQuery : public OSQLQuery {
63 public: 84 public:
@@ -119,109 +140,174 @@ namespace {
119 QArray<int> m_uids; 140 QArray<int> m_uids;
120 int m_uid; 141 int m_uid;
121 }; 142 };
122 143
123 /** 144 /**
124 * a find query for custom elements 145 * a find query for custom elements
125 */ 146 */
126 class FindCustomQuery : public OSQLQuery { 147 class FindCustomQuery : public OSQLQuery {
127 public: 148 public:
128 FindCustomQuery(int uid); 149 FindCustomQuery(int uid);
129 FindCustomQuery(const QArray<int>& ); 150 FindCustomQuery(const QArray<int>& );
130 ~FindCustomQuery(); 151 ~FindCustomQuery();
131 QString query()const; 152 QString query()const;
132 private: 153 private:
133 QString single()const; 154 QString single()const;
134 QString multi()const; 155 QString multi()const;
135 QArray<int> m_uids; 156 QArray<int> m_uids;
136 int m_uid; 157 int m_uid;
137 }; 158 };
138 159
139 160
140 161
141 // We using three tables to store the information: 162 // We using three tables to store the information:
142 // 1. addressbook : It contains General information about the contact (non custom) 163 // 1. addressbook : It contains General information about the contact (non custom)
143 // 2. dates : Stuff like birthdays, anniversaries, etc. 164 // 2. custom_data : Not official supported entries
144 // 3. custom_data : Not official supported entries
145 // All tables are connected by the uid of the contact. 165 // All tables are connected by the uid of the contact.
146 // Maybe I should add a table for meta-information ? 166 // Maybe I should add a table for meta-information ?
147 CreateQuery::CreateQuery() : OSQLQuery() {} 167 CreateQuery::CreateQuery() : OSQLQuery() {}
148 CreateQuery::~CreateQuery() {} 168 CreateQuery::~CreateQuery() {}
149 QString CreateQuery::query()const { 169 QString CreateQuery::query()const {
150 QString qu; 170 QString qu;
171#ifdef __STORE_HORIZONTAL_
172
173 qu += "create table addressbook( uid PRIMARY KEY ";
174
175 QStringList fieldList = OContactFields::untrfields( false );
176 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
177 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
178 }
179 qu += " );";
180
181 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
182
183#else
184
151 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; 185 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
152 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 186 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
153 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; 187 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
188
189#endif // __STORE_HORIZONTAL_
154 return qu; 190 return qu;
155 } 191 }
156 192
157 ClearQuery::ClearQuery() 193 ClearQuery::ClearQuery()
158 : OSQLQuery() {} 194 : OSQLQuery() {}
159 ClearQuery::~ClearQuery() {} 195 ClearQuery::~ClearQuery() {}
160 QString ClearQuery::query()const { 196 QString ClearQuery::query()const {
161 QString qu = "drop table addressbook;"; 197 QString qu = "drop table addressbook;";
162 qu += "drop table custom_data;"; 198 qu += "drop table custom_data;";
163 qu += "drop table dates;"; 199 // qu += "drop table dates;";
164 return qu; 200 return qu;
165 } 201 }
166 202
167// Distinct loading is not very fast. If I expect that every person has just
168// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
169// which is faster..
170// But this may not be true for all entries, like company contacts..
171// The current AddressBook application handles this problem, but other may not.. (eilers)
172#define __USE_SUPERFAST_LOADQUERY
173 203
174 LoadQuery::LoadQuery() : OSQLQuery() {} 204 LoadQuery::LoadQuery() : OSQLQuery() {}
175 LoadQuery::~LoadQuery() {} 205 LoadQuery::~LoadQuery() {}
176 QString LoadQuery::query()const { 206 QString LoadQuery::query()const {
177 QString qu; 207 QString qu;
178#ifndef __USE_SUPERFAST_LOADQUERY 208#ifdef __STORE_HORIZONTAL_
179 qu += "select distinct uid from addressbook"; 209 qu += "select uid from addressbook";
180#else 210#else
211# ifndef __USE_SUPERFAST_LOADQUERY
212 qu += "select distinct uid from addressbook";
213# else
181 qu += "select uid from addressbook where type = 'Last Name'"; 214 qu += "select uid from addressbook where type = 'Last Name'";
182#endif 215# endif // __USE_SUPERFAST_LOADQUERY
216#endif // __STORE_HORIZONTAL_
183 217
184 return qu; 218 return qu;
185 } 219 }
186 220
187 221
188 InsertQuery::InsertQuery( const OContact& contact ) 222 InsertQuery::InsertQuery( const OContact& contact )
189 : OSQLQuery(), m_contact( contact ) { 223 : OSQLQuery(), m_contact( contact ) {
190 } 224 }
191 225
192 InsertQuery::~InsertQuery() { 226 InsertQuery::~InsertQuery() {
193 } 227 }
194 228
195 /* 229 /*
196 * converts from a OContact to a query 230 * converts from a OContact to a query
197 */ 231 */
198 QString InsertQuery::query()const{ 232 QString InsertQuery::query()const{
199 233
234#ifdef __STORE_HORIZONTAL_
235 QString qu;
236 qu += "insert into addressbook VALUES( " +
237 QString::number( m_contact.uid() );
238
239 // Get all information out of the contact-class
240 // Remember: The category is stored in contactMap, too !
241 QMap<int, QString> contactMap = m_contact.toMap();
242
243 QStringList fieldList = OContactFields::untrfields( false );
244 QMap<QString, int> translate = OContactFields::untrFieldsToId();
245 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
246 // Convert Column-String to Id and get value for this id..
247 // Hmmm.. Maybe not very cute solution..
248 int id = translate[*it];
249 switch ( id ){
250 case Qtopia::Birthday:{
251 // These entries should stored in a special format
252 // year-month-day
253 QDate day = m_contact.birthday();
254 if ( day.isValid() ){
255 qu += QString(",\"%1-%2-%3\"")
256 .arg( day.year() )
257 .arg( day.month() )
258 .arg( day.day() );
259 } else {
260 qu += ",\"\"";
261 }
262 }
263 break;
264 case Qtopia::Anniversary:{
265 // These entries should stored in a special format
266 // year-month-day
267 QDate day = m_contact.anniversary();
268 if ( day.isValid() ){
269 qu += QString(",\"%1-%2-%3\"")
270 .arg( day.year() )
271 .arg( day.month() )
272 .arg( day.day() );
273 } else {
274 qu += ",\"\"";
275 }
276 }
277 break;
278
279 default:
280 qu += QString( ",\"%1\"" ).arg( contactMap[id] );
281 }
282 }
283 qu += " );";
284
285
286#else
200 // Get all information out of the contact-class 287 // Get all information out of the contact-class
201 // Remember: The category is stored in contactMap, too ! 288 // Remember: The category is stored in contactMap, too !
202 QMap<int, QString> contactMap = m_contact.toMap(); 289 QMap<int, QString> contactMap = m_contact.toMap();
203 QMap<QString, QString> customMap = m_contact.toExtraMap();
204 290
205 QMap<QString, QString> addressbook_db; 291 QMap<QString, QString> addressbook_db;
206 292
207 // Get the translation from the ID to the String 293 // Get the translation from the ID to the String
208 QMap<int, QString> transMap = OContactFields::idToUntrFields(); 294 QMap<int, QString> transMap = OContactFields::idToUntrFields();
209 295
210 for( QMap<int, QString>::Iterator it = contactMap.begin(); 296 for( QMap<int, QString>::Iterator it = contactMap.begin();
211 it != contactMap.end(); ++it ){ 297 it != contactMap.end(); ++it ){
212 switch ( it.key() ){ 298 switch ( it.key() ){
213 case Qtopia::Birthday:{ 299 case Qtopia::Birthday:{
214 // These entries should stored in a special format 300 // These entries should stored in a special format
215 // year-month-day 301 // year-month-day
216 QDate day = m_contact.birthday(); 302 QDate day = m_contact.birthday();
217 addressbook_db.insert( transMap[it.key()], 303 addressbook_db.insert( transMap[it.key()],
218 QString("%1-%2-%3") 304 QString("%1-%2-%3")
219 .arg( day.year() ) 305 .arg( day.year() )
220 .arg( day.month() ) 306 .arg( day.month() )
221 .arg( day.day() ) ); 307 .arg( day.day() ) );
222 } 308 }
223 break; 309 break;
224 case Qtopia::Anniversary:{ 310 case Qtopia::Anniversary:{
225 // These entries should stored in a special format 311 // These entries should stored in a special format
226 // year-month-day 312 // year-month-day
227 QDate day = m_contact.anniversary(); 313 QDate day = m_contact.anniversary();
@@ -240,163 +326,175 @@ namespace {
240 } 326 }
241 327
242 } 328 }
243 329
244 // Now convert this whole stuff into a SQL String, beginning with 330 // Now convert this whole stuff into a SQL String, beginning with
245 // the addressbook table.. 331 // the addressbook table..
246 QString qu; 332 QString qu;
247 // qu += "begin transaction;"; 333 // qu += "begin transaction;";
248 int id = 0; 334 int id = 0;
249 for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); 335 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
250 it != addressbook_db.end(); ++it ){ 336 it != addressbook_db.end(); ++it ){
251 qu += "insert into addressbook VALUES(" 337 qu += "insert into addressbook VALUES("
252 + QString::number( m_contact.uid() ) 338 + QString::number( m_contact.uid() )
253 + "," 339 + ","
254 + QString::number( id++ ) 340 + QString::number( id++ )
255 + ",'" 341 + ",'"
256 + it.key() //.latin1() 342 + it.key() //.latin1()
257 + "'," 343 + "',"
258 + "0" // Priority for future enhancements 344 + "0" // Priority for future enhancements
259 + ",'" 345 + ",'"
260 + it.data() //.latin1() 346 + it.data() //.latin1()
261 + "');"; 347 + "');";
262 } 348 }
263 349
350 #endif //__STORE_HORIZONTAL_
264 // Now add custom data.. 351 // Now add custom data..
352#ifdef __STORE_HORIZONTAL_
353 int id = 0;
354#endif
265 id = 0; 355 id = 0;
356 QMap<QString, QString> customMap = m_contact.toExtraMap();
266 for( QMap<QString, QString>::Iterator it = customMap.begin(); 357 for( QMap<QString, QString>::Iterator it = customMap.begin();
267 it != customMap.end(); ++it ){ 358 it != customMap.end(); ++it ){
268 qu += "insert into custom_data VALUES(" 359 qu += "insert into custom_data VALUES("
269 + QString::number( m_contact.uid() ) 360 + QString::number( m_contact.uid() )
270 + "," 361 + ","
271 + QString::number( id++ ) 362 + QString::number( id++ )
272 + ",'" 363 + ",'"
273 + it.key() //.latin1() 364 + it.key() //.latin1()
274 + "'," 365 + "',"
275 + "0" // Priority for future enhancements 366 + "0" // Priority for future enhancements
276 + ",'" 367 + ",'"
277 + it.data() //.latin1() 368 + it.data() //.latin1()
278 + "');"; 369 + "');";
279 } 370 }
280
281 // qu += "commit;"; 371 // qu += "commit;";
282 qWarning("add %s", qu.latin1() ); 372 qWarning("add %s", qu.latin1() );
283 return qu; 373 return qu;
284 } 374 }
285 375
286 376
287 RemoveQuery::RemoveQuery(int uid ) 377 RemoveQuery::RemoveQuery(int uid )
288 : OSQLQuery(), m_uid( uid ) {} 378 : OSQLQuery(), m_uid( uid ) {}
289 RemoveQuery::~RemoveQuery() {} 379 RemoveQuery::~RemoveQuery() {}
290 QString RemoveQuery::query()const { 380 QString RemoveQuery::query()const {
291 QString qu = "DELETE from addressbook where uid = " 381 QString qu = "DELETE from addressbook where uid = "
292 + QString::number(m_uid) + ";"; 382 + QString::number(m_uid) + ";";
293 qu += "DELETE from dates where uid = "
294 + QString::number(m_uid) + ";";
295 qu += "DELETE from custom_data where uid = " 383 qu += "DELETE from custom_data where uid = "
296 + QString::number(m_uid) + ";"; 384 + QString::number(m_uid) + ";";
297 return qu; 385 return qu;
298 } 386 }
299 387
300 388
301 389
302 390
303 FindQuery::FindQuery(int uid) 391 FindQuery::FindQuery(int uid)
304 : OSQLQuery(), m_uid( uid ) { 392 : OSQLQuery(), m_uid( uid ) {
305 } 393 }
306 FindQuery::FindQuery(const QArray<int>& ints) 394 FindQuery::FindQuery(const QArray<int>& ints)
307 : OSQLQuery(), m_uids( ints ){ 395 : OSQLQuery(), m_uids( ints ){
308 } 396 }
309 FindQuery::~FindQuery() { 397 FindQuery::~FindQuery() {
310 } 398 }
311 QString FindQuery::query()const{ 399 QString FindQuery::query()const{
312 // if ( m_uids.count() == 0 ) 400 // if ( m_uids.count() == 0 )
313 return single(); 401 return single();
314 } 402 }
315 /* 403 /*
316 else 404 else
317 return multi(); 405 return multi();
318 } 406 }
319 QString FindQuery::multi()const { 407 QString FindQuery::multi()const {
320 QString qu = "select uid, type, value from addressbook where"; 408 QString qu = "select uid, type, value from addressbook where";
321 for (uint i = 0; i < m_uids.count(); i++ ) { 409 for (uint i = 0; i < m_uids.count(); i++ ) {
322 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 410 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
323 } 411 }
324 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 412 qu.remove( qu.length()-2, 2 ); // Hmmmm..
325 return qu; 413 return qu;
326 } 414 }
327 */ 415 */
416#ifdef __STORE_HORIZONTAL_
417 QString FindQuery::single()const{
418 QString qu = "select *";
419 qu += " from addressbook where uid = " + QString::number(m_uid);
420
421 // qWarning("find query: %s", qu.latin1() );
422 return qu;
423 }
424#else
328 QString FindQuery::single()const{ 425 QString FindQuery::single()const{
329 QString qu = "select uid, type, value from addressbook where uid = "; 426 QString qu = "select uid, type, value from addressbook where uid = ";
330 qu += QString::number(m_uid); 427 qu += QString::number(m_uid);
331 return qu; 428 return qu;
332 } 429 }
430#endif
333 431
334 432
335 FindCustomQuery::FindCustomQuery(int uid) 433 FindCustomQuery::FindCustomQuery(int uid)
336 : OSQLQuery(), m_uid( uid ) { 434 : OSQLQuery(), m_uid( uid ) {
337 } 435 }
338 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 436 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
339 : OSQLQuery(), m_uids( ints ){ 437 : OSQLQuery(), m_uids( ints ){
340 } 438 }
341 FindCustomQuery::~FindCustomQuery() { 439 FindCustomQuery::~FindCustomQuery() {
342 } 440 }
343 QString FindCustomQuery::query()const{ 441 QString FindCustomQuery::query()const{
344 // if ( m_uids.count() == 0 ) 442 // if ( m_uids.count() == 0 )
345 return single(); 443 return single();
346 } 444 }
347 QString FindCustomQuery::single()const{ 445 QString FindCustomQuery::single()const{
348 QString qu = "select uid, type, value from custom_data where uid = "; 446 QString qu = "select uid, type, value from custom_data where uid = ";
349 qu += QString::number(m_uid); 447 qu += QString::number(m_uid);
350 return qu; 448 return qu;
351 } 449 }
352 450
353}; 451};
354 452
355 453
356/* --------------------------------------------------------------------------- */ 454/* --------------------------------------------------------------------------- */
357 455
358OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */, 456OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname */,
359 const QString& filename ): m_changed(false) 457 const QString& filename ): m_changed(false)
360{ 458{
361 qWarning("C'tor OContactAccessBackend_SQL starts"); 459 qWarning("C'tor OContactAccessBackend_SQL starts");
362 QTime t; 460 QTime t;
363 t.start(); 461 t.start();
364 462
365 /* Expecting to access the default filename if nothing else is set */ 463 /* Expecting to access the default filename if nothing else is set */
366 if ( filename.isEmpty() ){ 464 if ( filename.isEmpty() ){
367 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 465 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
368 } else 466 } else
369 m_fileName = filename; 467 m_fileName = filename;
370 468
371 // Get the standart sql-driver from the OSQLManager.. 469 // Get the standart sql-driver from the OSQLManager..
372 OSQLManager man; 470 OSQLManager man;
373 m_driver = man.standard(); 471 m_driver = man.standard();
374 m_driver->setUrl( m_fileName ); 472 m_driver->setUrl( m_fileName );
375 473
376 load(); 474 load();
377 475
378 qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() ); 476 qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
379} 477}
380 478
381 479
382bool OContactAccessBackend_SQL::load () 480bool OContactAccessBackend_SQL::load ()
383{ 481{
384 if (!m_driver->open() ) 482 if (!m_driver->open() )
385 return false; 483 return false;
386 484
387 // Don't expect that the database exists. 485 // Don't expect that the database exists.
388 // It is save here to create the table, even if it 486 // It is save here to create the table, even if it
389 // do exist. ( Is that correct for all databases ?? ) 487 // do exist. ( Is that correct for all databases ?? )
390 CreateQuery creat; 488 CreateQuery creat;
391 OSQLResult res = m_driver->query( &creat ); 489 OSQLResult res = m_driver->query( &creat );
392 490
393 update(); 491 update();
394 492
395 return true; 493 return true;
396 494
397} 495}
398 496
399bool OContactAccessBackend_SQL::reload() 497bool OContactAccessBackend_SQL::reload()
400{ 498{
401 return load(); 499 return load();
402} 500}
@@ -457,146 +555,303 @@ bool OContactAccessBackend_SQL::remove ( int uid )
457 555
458 m_changed = true; 556 m_changed = true;
459 557
460 return true; 558 return true;
461} 559}
462 560
463bool OContactAccessBackend_SQL::replace ( const OContact &contact ) 561bool OContactAccessBackend_SQL::replace ( const OContact &contact )
464{ 562{
465 if ( !remove( contact.uid() ) ) 563 if ( !remove( contact.uid() ) )
466 return false; 564 return false;
467 565
468 return add( contact ); 566 return add( contact );
469} 567}
470 568
471 569
472OContact OContactAccessBackend_SQL::find ( int uid ) const 570OContact OContactAccessBackend_SQL::find ( int uid ) const
473{ 571{
474 qWarning("OContactAccessBackend_SQL::find()"); 572 qWarning("OContactAccessBackend_SQL::find()");
475 QTime t; 573 QTime t;
476 t.start(); 574 t.start();
477 575
478 OContact retContact( requestNonCustom( uid ) ); 576 OContact retContact( requestNonCustom( uid ) );
479 retContact.setExtraMap( requestCustom( uid ) ); 577 retContact.setExtraMap( requestCustom( uid ) );
480 578
481 qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() ); 579 qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
482 return retContact; 580 return retContact;
483} 581}
484 582
485 583
486 584
487QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() ) 585QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
488{ 586{
489 QArray<int> nix(0); 587 QString qu = "SELECT uid FROM addressbook WHERE";
490 return nix; 588
589 QMap<int, QString> queryFields = query.toMap();
590 QStringList fieldList = OContactFields::untrfields( false );
591 QMap<QString, int> translate = OContactFields::untrFieldsToId();
592
593 // Convert every filled field to a SQL-Query
594 bool isAnyFieldSelected = false;
595 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
596 int id = translate[*it];
597 QString queryStr = queryFields[id];
598 if ( !queryStr.isEmpty() ){
599 isAnyFieldSelected = true;
600 switch( id ){
601 default:
602 // Switching between case sensitive and insensitive...
603 // LIKE is not case sensitive, GLOB is case sensitive
604 // Do exist a better solution to switch this ?
605 if ( settings & OContactAccess::IgnoreCase )
606 qu += "(\"" + *it + "\"" + " LIKE " + "'"
607 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND ";
608 else
609 qu += "(\"" + *it + "\"" + " GLOB " + "'"
610 + queryStr + "'" + ") AND ";
611
612 }
613 }
614 }
615 // Skip trailing "AND"
616 if ( isAnyFieldSelected )
617 qu = qu.left( qu.length() - 4 );
618
619 qWarning( "queryByExample query: %s", qu.latin1() );
620
621 // Execute query and return the received uid's
622 OSQLRawQuery raw( qu );
623 OSQLResult res = m_driver->query( &raw );
624 if ( res.state() != OSQLResult::Success ){
625 QArray<int> empty;
626 return empty;
627 }
628
629 QArray<int> list = extractUids( res );
630
631 return list;
491} 632}
492 633
493QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 634QArray<int> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
494{ 635{
495 QArray<int> nix(0); 636 QArray<int> nix(0);
496 return nix; 637 return nix;
497} 638}
498 639
499const uint OContactAccessBackend_SQL::querySettings() 640const uint OContactAccessBackend_SQL::querySettings()
500{ 641{
501 return 0; 642 return OContactAccess::IgnoreCase
643 || OContactAccess::WildCards;
502} 644}
503 645
504bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 646bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
505{ 647{
506 return false; 648 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
649 * may be added with any of the other settings. IgnoreCase should never used alone.
650 * Wildcards, RegExp, ExactMatch should never used at the same time...
651 */
652
653 // Step 1: Check whether the given settings are supported by this backend
654 if ( ( querySettings & (
655 OContactAccess::IgnoreCase
656 | OContactAccess::WildCards
657 // | OContactAccess::DateDiff
658 // | OContactAccess::DateYear
659 // | OContactAccess::DateMonth
660 // | OContactAccess::DateDay
661 // | OContactAccess::RegExp
662 // | OContactAccess::ExactMatch
663 ) ) != querySettings )
664 return false;
665
666 // Step 2: Check whether the given combinations are ok..
667
668 // IngoreCase alone is invalid
669 if ( querySettings == OContactAccess::IgnoreCase )
670 return false;
671
672 // WildCards, RegExp and ExactMatch should never used at the same time
673 switch ( querySettings & ~( OContactAccess::IgnoreCase
674 | OContactAccess::DateDiff
675 | OContactAccess::DateYear
676 | OContactAccess::DateMonth
677 | OContactAccess::DateDay
678 )
679 ){
680 case OContactAccess::RegExp:
681 return ( true );
682 case OContactAccess::WildCards:
683 return ( true );
684 case OContactAccess::ExactMatch:
685 return ( true );
686 case 0: // one of the upper removed bits were set..
687 return ( true );
688 default:
689 return ( false );
690 }
691
507} 692}
508 693
509QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 694QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
510{ 695{
511 QTime t; 696 QTime t;
512 t.start(); 697 t.start();
513 698
514 // Not implemented.. 699#ifdef __STORE_HORIZONTAL_
700 QString query = "SELECT uid FROM addressbook ";
701 query += "ORDER BY \"Last Name\" ";
702#else
515 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; 703 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
704 query += "ORDER BY upper( value )";
705#endif
516 706
517 query += "ORDER BY value ";
518 if ( !asc ) 707 if ( !asc )
519 query += "DESC"; 708 query += "DESC";
520 709
521 qWarning("sorted query is: %s", query.latin1() ); 710 // qWarning("sorted query is: %s", query.latin1() );
522 711
523 OSQLRawQuery raw( query ); 712 OSQLRawQuery raw( query );
524 OSQLResult res = m_driver->query( &raw ); 713 OSQLResult res = m_driver->query( &raw );
525 if ( res.state() != OSQLResult::Success ){ 714 if ( res.state() != OSQLResult::Success ){
526 QArray<int> empty; 715 QArray<int> empty;
527 return empty; 716 return empty;
528 } 717 }
529 718
530 QArray<int> list = extractUids( res ); 719 QArray<int> list = extractUids( res );
531 720
532 qWarning("sorted needed %d ms!", t.elapsed() ); 721 qWarning("sorted needed %d ms!", t.elapsed() );
533 return list; 722 return list;
534} 723}
535 724
536 725
537void OContactAccessBackend_SQL::update() 726void OContactAccessBackend_SQL::update()
538{ 727{
539 qWarning("Update starts"); 728 qWarning("Update starts");
540 QTime t; 729 QTime t;
541 t.start(); 730 t.start();
542 731
543 // Now load the database set and extract the uid's 732 // Now load the database set and extract the uid's
544 // which will be held locally 733 // which will be held locally
545 734
546 LoadQuery lo; 735 LoadQuery lo;
547 OSQLResult res = m_driver->query(&lo); 736 OSQLResult res = m_driver->query(&lo);
548 if ( res.state() != OSQLResult::Success ) 737 if ( res.state() != OSQLResult::Success )
549 return; 738 return;
550 739
551 m_uids = extractUids( res ); 740 m_uids = extractUids( res );
552 741
553 m_changed = false; 742 m_changed = false;
554 743
555 qWarning("Update ends %d", t.elapsed() ); 744 qWarning("Update ends %d ms", t.elapsed() );
556} 745}
557 746
558QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const 747QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
559{ 748{
560 qWarning("extractUids"); 749 qWarning("extractUids");
561 QTime t; 750 QTime t;
562 t.start(); 751 t.start();
563 OSQLResultItem::ValueList list = res.results(); 752 OSQLResultItem::ValueList list = res.results();
564 OSQLResultItem::ValueList::Iterator it; 753 OSQLResultItem::ValueList::Iterator it;
565 QArray<int> ints(list.count() ); 754 QArray<int> ints(list.count() );
566 qWarning(" count = %d", list.count() ); 755 qWarning(" count = %d", list.count() );
567 756
568 int i = 0; 757 int i = 0;
569 for (it = list.begin(); it != list.end(); ++it ) { 758 for (it = list.begin(); it != list.end(); ++it ) {
570 ints[i] = (*it).data("uid").toInt(); 759 ints[i] = (*it).data("uid").toInt();
571 i++; 760 i++;
572 } 761 }
573 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 762 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
574 763
575 return ints; 764 return ints;
576 765
577} 766}
578 767
768#ifdef __STORE_HORIZONTAL_
769QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
770{
771 QTime t;
772 t.start();
773
774 QMap<int, QString> nonCustomMap;
775
776 int t2needed = 0;
777 int t3needed = 0;
778 QTime t2;
779 t2.start();
780 FindQuery query( uid );
781 OSQLResult res_noncustom = m_driver->query( &query );
782 t2needed = t2.elapsed();
783
784 OSQLResultItem resItem = res_noncustom.first();
785
786 QTime t3;
787 t3.start();
788 // Now loop through all columns
789 QStringList fieldList = OContactFields::untrfields( false );
790 QMap<QString, int> translate = OContactFields::untrFieldsToId();
791 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
792 // Get data for the selected column and store it with the
793 // corresponding id into the map..
794
795 int id = translate[*it];
796 QString value = resItem.data( (*it) );
797
798 // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() );
799
800 switch( id ){
801 case Qtopia::Birthday:
802 case Qtopia::Anniversary:{
803 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
804 QStringList list = QStringList::split( '-', value );
805 QStringList::Iterator lit = list.begin();
806 int year = (*lit).toInt();
807 int month = (*(++lit)).toInt();
808 int day = (*(++lit)).toInt();
809 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){
810 QDate date( year, month, day );
811 nonCustomMap.insert( id, OConversion::dateToString( date ) );
812 }
813 }
814 break;
815 case Qtopia::AddressCategory:
816 qWarning("Category is: %s", value.latin1() );
817 default:
818 nonCustomMap.insert( id, value );
819 }
820 }
821
822 // First insert uid
823 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
824 t3needed = t3.elapsed();
825
826 // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() );
827 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms",
828 t.elapsed(), t2needed, t3needed );
829
830 return nonCustomMap;
831}
832#else
833
579QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const 834QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
580{ 835{
581 QTime t; 836 QTime t;
582 t.start(); 837 t.start();
583 838
584 QMap<int, QString> nonCustomMap; 839 QMap<int, QString> nonCustomMap;
585 840
586 int t2needed = 0; 841 int t2needed = 0;
587 QTime t2; 842 QTime t2;
588 t2.start(); 843 t2.start();
589 FindQuery query( uid ); 844 FindQuery query( uid );
590 OSQLResult res_noncustom = m_driver->query( &query ); 845 OSQLResult res_noncustom = m_driver->query( &query );
591 t2needed = t2.elapsed(); 846 t2needed = t2.elapsed();
592 847
593 if ( res_noncustom.state() == OSQLResult::Failure ) { 848 if ( res_noncustom.state() == OSQLResult::Failure ) {
594 qWarning("OSQLResult::Failure in find query !!"); 849 qWarning("OSQLResult::Failure in find query !!");
595 QMap<int, QString> empty; 850 QMap<int, QString> empty;
596 return empty; 851 return empty;
597 } 852 }
598 853
599 int t3needed = 0; 854 int t3needed = 0;
600 QTime t3; 855 QTime t3;
601 t3.start(); 856 t3.start();
602 QMap<QString, int> translateMap = OContactFields::untrFieldsToId(); 857 QMap<QString, int> translateMap = OContactFields::untrFieldsToId();
@@ -612,53 +867,55 @@ QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
612 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 867 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
613 QStringList list = QStringList::split( '-', (*it).data( "value" ) ); 868 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
614 QStringList::Iterator lit = list.begin(); 869 QStringList::Iterator lit = list.begin();
615 int year = (*lit).toInt(); 870 int year = (*lit).toInt();
616 qWarning("1. %s", (*lit).latin1()); 871 qWarning("1. %s", (*lit).latin1());
617 int month = (*(++lit)).toInt(); 872 int month = (*(++lit)).toInt();
618 qWarning("2. %s", (*lit).latin1()); 873 qWarning("2. %s", (*lit).latin1());
619 int day = (*(++lit)).toInt(); 874 int day = (*(++lit)).toInt();
620 qWarning("3. %s", (*lit).latin1()); 875 qWarning("3. %s", (*lit).latin1());
621 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day ); 876 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
622 QDate date( year, month, day ); 877 QDate date( year, month, day );
623 nonCustomMap.insert( typeId, OConversion::dateToString( date ) ); 878 nonCustomMap.insert( typeId, OConversion::dateToString( date ) );
624 } 879 }
625 break; 880 break;
626 default: 881 default:
627 nonCustomMap.insert( typeId, 882 nonCustomMap.insert( typeId,
628 (*it).data( "value" ) ); 883 (*it).data( "value" ) );
629 } 884 }
630 } 885 }
631 } 886 }
632 // Add UID to Map.. 887 // Add UID to Map..
633 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) ); 888 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
634 t3needed = t3.elapsed(); 889 t3needed = t3.elapsed();
635 890
636 qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed ); 891 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed );
637 return nonCustomMap; 892 return nonCustomMap;
638} 893}
639 894
895#endif // __STORE_HORIZONTAL_
896
640QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const 897QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
641{ 898{
642 QTime t; 899 QTime t;
643 t.start(); 900 t.start();
644 901
645 QMap<QString, QString> customMap; 902 QMap<QString, QString> customMap;
646 903
647 FindCustomQuery query( uid ); 904 FindCustomQuery query( uid );
648 OSQLResult res_custom = m_driver->query( &query ); 905 OSQLResult res_custom = m_driver->query( &query );
649 906
650 if ( res_custom.state() == OSQLResult::Failure ) { 907 if ( res_custom.state() == OSQLResult::Failure ) {
651 qWarning("OSQLResult::Failure in find query !!"); 908 qWarning("OSQLResult::Failure in find query !!");
652 QMap<QString, QString> empty; 909 QMap<QString, QString> empty;
653 return empty; 910 return empty;
654 } 911 }
655 912
656 OSQLResultItem::ValueList list = res_custom.results(); 913 OSQLResultItem::ValueList list = res_custom.results();
657 OSQLResultItem::ValueList::Iterator it = list.begin(); 914 OSQLResultItem::ValueList::Iterator it = list.begin();
658 for ( ; it != list.end(); ++it ) { 915 for ( ; it != list.end(); ++it ) {
659 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 916 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
660 } 917 }
661 918
662 qWarning("RequestCustom needed: %d", t.elapsed() ); 919 qWarning("RequestCustom needed: %d ms", t.elapsed() );
663 return customMap; 920 return customMap;
664} 921}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index 23e0c3e..d255c66 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -97,129 +97,164 @@ namespace {
97 class OverDueQuery : public OSQLQuery { 97 class OverDueQuery : public OSQLQuery {
98 public: 98 public:
99 OverDueQuery(); 99 OverDueQuery();
100 ~OverDueQuery(); 100 ~OverDueQuery();
101 QString query()const; 101 QString query()const;
102 }; 102 };
103 class EffQuery : public OSQLQuery { 103 class EffQuery : public OSQLQuery {
104 public: 104 public:
105 EffQuery( const QDate&, const QDate&, bool inc ); 105 EffQuery( const QDate&, const QDate&, bool inc );
106 ~EffQuery(); 106 ~EffQuery();
107 QString query()const; 107 QString query()const;
108 private: 108 private:
109 QString with()const; 109 QString with()const;
110 QString out()const; 110 QString out()const;
111 QDate m_start; 111 QDate m_start;
112 QDate m_end; 112 QDate m_end;
113 bool m_inc :1; 113 bool m_inc :1;
114 }; 114 };
115 115
116 116
117 CreateQuery::CreateQuery() : OSQLQuery() {} 117 CreateQuery::CreateQuery() : OSQLQuery() {}
118 CreateQuery::~CreateQuery() {} 118 CreateQuery::~CreateQuery() {}
119 QString CreateQuery::query()const { 119 QString CreateQuery::query()const {
120 QString qu; 120 QString qu;
121 qu += "create table todolist( uid, categories, completed, progress, "; 121 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
122 qu += "summary, DueDate, priority, description )"; 122 qu += "description, summary, priority, DueDate, progress , state, ";
123 qu += "Recurrence, notifiers, maintainer, startdate, completeddate)";
123 return qu; 124 return qu;
124 } 125 }
125 126
126 LoadQuery::LoadQuery() : OSQLQuery() {} 127 LoadQuery::LoadQuery() : OSQLQuery() {}
127 LoadQuery::~LoadQuery() {} 128 LoadQuery::~LoadQuery() {}
128 QString LoadQuery::query()const { 129 QString LoadQuery::query()const {
129 QString qu; 130 QString qu;
130 qu += "select distinct uid from todolist"; 131 // We do not need "distinct" here. The primary key is always unique..
132 //qu += "select distinct uid from todolist";
133 qu += "select uid from todolist";
131 134
132 return qu; 135 return qu;
133 } 136 }
134 137
135 InsertQuery::InsertQuery( const OTodo& todo ) 138 InsertQuery::InsertQuery( const OTodo& todo )
136 : OSQLQuery(), m_todo( todo ) { 139 : OSQLQuery(), m_todo( todo ) {
137 } 140 }
138 InsertQuery::~InsertQuery() { 141 InsertQuery::~InsertQuery() {
139 } 142 }
140 /* 143 /*
141 * converts from a OTodo to a query 144 * converts from a OTodo to a query
142 * we leave out X-Ref + Alarms 145 * we leave out X-Ref + Alarms
143 */ 146 */
144 QString InsertQuery::query()const{ 147 QString InsertQuery::query()const{
145 148
146 int year, month, day; 149 int year, month, day;
147 year = month = day = 0; 150 year = month = day = 0;
148 if (m_todo.hasDueDate() ) { 151 if (m_todo.hasDueDate() ) {
149 QDate date = m_todo.dueDate(); 152 QDate date = m_todo.dueDate();
150 year = date.year(); 153 year = date.year();
151 month = date.month(); 154 month = date.month();
152 day = date.day(); 155 day = date.day();
153 } 156 }
157 int sYear = 0, sMonth = 0, sDay = 0;
158 if( m_todo.hasStartDate() ){
159 QDate sDate = m_todo.startDate();
160 sYear = sDate.year();
161 sMonth= sDate.month();
162 sDay = sDate.day();
163 }
164
165 int eYear = 0, eMonth = 0, eDay = 0;
166 if( m_todo.hasCompletedDate() ){
167 QDate eDate = m_todo.completedDate();
168 eYear = eDate.year();
169 eMonth= eDate.month();
170 eDay = eDate.day();
171 }
154 QString qu; 172 QString qu;
155 qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',"; 173 qu = "insert into todolist VALUES("
156 qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ","; 174 + QString::number( m_todo.uid() ) + ","
157 qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',"; 175 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
158 qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')"; 176 + QString::number( m_todo.isCompleted() ) + ","
177 + "'" + m_todo.description() + "'" + ","
178 + "'" + m_todo.summary() + "'" + ","
179 + QString::number(m_todo.priority() ) + ","
180 + "'" + QString::number(year) + "-"
181 + QString::number(month)
182 + "-" + QString::number( day ) + "'" + ","
183 + QString::number( m_todo.progress() ) + ","
184 + "''" + "," // state (conversion needed)
185 // + QString::number( m_todo.state() ) + ","
186 + "''" + "," // Recurrence (conversion needed)
187 + "''" + "," // Notifiers (conversion needed)
188 + "''" + "," // Maintainers (conversion needed)
189 + "'" + QString::number(sYear) + "-"
190 + QString::number(sMonth)
191 + "-" + QString::number(sDay) + "'" + ","
192 + "'" + QString::number(eYear) + "-"
193 + QString::number(eMonth)
194 + "-"+QString::number(eDay) + "'"
195 + ")";
159 196
160 qWarning("add %s", qu.latin1() ); 197 qWarning("add %s", qu.latin1() );
161 return qu; 198 return qu;
162 } 199 }
163 200
164 RemoveQuery::RemoveQuery(int uid ) 201 RemoveQuery::RemoveQuery(int uid )
165 : OSQLQuery(), m_uid( uid ) {} 202 : OSQLQuery(), m_uid( uid ) {}
166 RemoveQuery::~RemoveQuery() {} 203 RemoveQuery::~RemoveQuery() {}
167 QString RemoveQuery::query()const { 204 QString RemoveQuery::query()const {
168 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 205 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
169 return qu; 206 return qu;
170 } 207 }
171 208
172 209
173 ClearQuery::ClearQuery() 210 ClearQuery::ClearQuery()
174 : OSQLQuery() {} 211 : OSQLQuery() {}
175 ClearQuery::~ClearQuery() {} 212 ClearQuery::~ClearQuery() {}
176 QString ClearQuery::query()const { 213 QString ClearQuery::query()const {
177 QString qu = "drop table todolist"; 214 QString qu = "drop table todolist";
178 return qu; 215 return qu;
179 } 216 }
180 FindQuery::FindQuery(int uid) 217 FindQuery::FindQuery(int uid)
181 : OSQLQuery(), m_uid(uid ) { 218 : OSQLQuery(), m_uid(uid ) {
182 } 219 }
183 FindQuery::FindQuery(const QArray<int>& ints) 220 FindQuery::FindQuery(const QArray<int>& ints)
184 : OSQLQuery(), m_uids(ints){ 221 : OSQLQuery(), m_uids(ints){
185 } 222 }
186 FindQuery::~FindQuery() { 223 FindQuery::~FindQuery() {
187 } 224 }
188 QString FindQuery::query()const{ 225 QString FindQuery::query()const{
189 if (m_uids.count() == 0 ) 226 if (m_uids.count() == 0 )
190 return single(); 227 return single();
191 else 228 else
192 return multi(); 229 return multi();
193 } 230 }
194 QString FindQuery::single()const{ 231 QString FindQuery::single()const{
195 QString qu = "select uid, categories, completed, progress, summary, "; 232 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
196 qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
197 return qu; 233 return qu;
198 } 234 }
199 QString FindQuery::multi()const { 235 QString FindQuery::multi()const {
200 QString qu = "select uid, categories, completed, progress, summary, "; 236 QString qu = "select * from todolist where ";
201 qu += "DueDate, priority, description from todolist where ";
202 for (uint i = 0; i < m_uids.count(); i++ ) { 237 for (uint i = 0; i < m_uids.count(); i++ ) {
203 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 238 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
204 } 239 }
205 qu.remove( qu.length()-2, 2 ); 240 qu.remove( qu.length()-2, 2 );
206 return qu; 241 return qu;
207 } 242 }
208 243
209 OverDueQuery::OverDueQuery(): OSQLQuery() {} 244 OverDueQuery::OverDueQuery(): OSQLQuery() {}
210 OverDueQuery::~OverDueQuery() {} 245 OverDueQuery::~OverDueQuery() {}
211 QString OverDueQuery::query()const { 246 QString OverDueQuery::query()const {
212 QDate date = QDate::currentDate(); 247 QDate date = QDate::currentDate();
213 QString str; 248 QString str;
214 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 249 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
215 250
216 return str; 251 return str;
217 } 252 }
218 253
219 254
220 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 255 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
221 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 256 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
222 EffQuery::~EffQuery() {} 257 EffQuery::~EffQuery() {}
223 QString EffQuery::query()const { 258 QString EffQuery::query()const {
224 return m_inc ? with() : out(); 259 return m_inc ? with() : out();
225 } 260 }
@@ -267,49 +302,49 @@ bool OTodoAccessBackendSQL::load(){
267bool OTodoAccessBackendSQL::reload(){ 302bool OTodoAccessBackendSQL::reload(){
268 return load(); 303 return load();
269} 304}
270 305
271bool OTodoAccessBackendSQL::save(){ 306bool OTodoAccessBackendSQL::save(){
272 return m_driver->close(); 307 return m_driver->close();
273} 308}
274QArray<int> OTodoAccessBackendSQL::allRecords()const { 309QArray<int> OTodoAccessBackendSQL::allRecords()const {
275 if (m_dirty ) 310 if (m_dirty )
276 update(); 311 update();
277 312
278 return m_uids; 313 return m_uids;
279} 314}
280QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 315QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
281 QArray<int> ints(0); 316 QArray<int> ints(0);
282 return ints; 317 return ints;
283} 318}
284OTodo OTodoAccessBackendSQL::find(int uid ) const{ 319OTodo OTodoAccessBackendSQL::find(int uid ) const{
285 FindQuery query( uid ); 320 FindQuery query( uid );
286 return todo( m_driver->query(&query) ); 321 return todo( m_driver->query(&query) );
287 322
288} 323}
289OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 324OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
290 uint cur, Frontend::CacheDirection dir ) const{ 325 uint cur, Frontend::CacheDirection dir ) const{
291 int CACHE = readAhead(); 326 uint CACHE = readAhead();
292 qWarning("searching for %d", uid ); 327 qWarning("searching for %d", uid );
293 QArray<int> search( CACHE ); 328 QArray<int> search( CACHE );
294 uint size =0; 329 uint size =0;
295 OTodo to; 330 OTodo to;
296 331
297 // we try to cache CACHE items 332 // we try to cache CACHE items
298 switch( dir ) { 333 switch( dir ) {
299 /* forward */ 334 /* forward */
300 case 0: // FIXME: Not a good style to use magic numbers here (eilers) 335 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
301 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 336 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
302 qWarning("size %d %d", size, ints[i] ); 337 qWarning("size %d %d", size, ints[i] );
303 search[size] = ints[i]; 338 search[size] = ints[i];
304 size++; 339 size++;
305 } 340 }
306 break; 341 break;
307 /* reverse */ 342 /* reverse */
308 case 1: // FIXME: Not a good style to use magic numbers here (eilers) 343 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
309 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 344 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
310 search[size] = ints[i]; 345 search[size] = ints[i];
311 size++; 346 size++;
312 } 347 }
313 break; 348 break;
314 } 349 }
315 search.resize( size ); 350 search.resize( size );
@@ -451,56 +486,72 @@ bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
451 return true; 486 return true;
452 } 487 }
453} 488}
454OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 489OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
455 if ( res.state() == OSQLResult::Failure ) { 490 if ( res.state() == OSQLResult::Failure ) {
456 OTodo to; 491 OTodo to;
457 return to; 492 return to;
458 } 493 }
459 494
460 OSQLResultItem::ValueList list = res.results(); 495 OSQLResultItem::ValueList list = res.results();
461 OSQLResultItem::ValueList::Iterator it = list.begin(); 496 OSQLResultItem::ValueList::Iterator it = list.begin();
462 qWarning("todo1"); 497 qWarning("todo1");
463 OTodo to = todo( (*it) ); 498 OTodo to = todo( (*it) );
464 cache( to ); 499 cache( to );
465 ++it; 500 ++it;
466 501
467 for ( ; it != list.end(); ++it ) { 502 for ( ; it != list.end(); ++it ) {
468 qWarning("caching"); 503 qWarning("caching");
469 cache( todo( (*it) ) ); 504 cache( todo( (*it) ) );
470 } 505 }
471 return to; 506 return to;
472} 507}
473OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 508OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
474 qWarning("todo"); 509 qWarning("todo");
475 bool has = false; QDate da = QDate::currentDate(); 510 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
476 has = date( da, item.data("DueDate") ); 511 hasDueDate = date( dueDate, item.data("DueDate") );
477 QStringList cats = QStringList::split(";", item.data("categories") ); 512 QStringList cats = QStringList::split(";", item.data("categories") );
478 513
479 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 514 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
480 cats, item.data("summary"), item.data("description"), 515 cats, item.data("summary"), item.data("description"),
481 item.data("progress").toUShort(), has, da, 516 item.data("progress").toUShort(), hasDueDate, dueDate,
482 item.data("uid").toInt() ); 517 item.data("uid").toInt() );
518
519 bool isOk;
520 int prioInt = QString( item.data("priority") ).toInt( &isOk );
521 if ( isOk )
522 to.setPriority( prioInt );
523
524 bool hasStartDate = false; QDate startDate = QDate::currentDate();
525 hasStartDate = date( startDate, item.data("startdate") );
526 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
527 hasCompletedDate = date( completedDate, item.data("completeddate") );
528
529 if ( hasStartDate )
530 to.setStartDate( startDate );
531 if ( hasCompletedDate )
532 to.setCompletedDate( completedDate );
533
483 return to; 534 return to;
484} 535}
485OTodo OTodoAccessBackendSQL::todo( int uid )const { 536OTodo OTodoAccessBackendSQL::todo( int uid )const {
486 FindQuery find( uid ); 537 FindQuery find( uid );
487 return todo( m_driver->query(&find) ); 538 return todo( m_driver->query(&find) );
488} 539}
489/* 540/*
490 * update the dict 541 * update the dict
491 */ 542 */
492void OTodoAccessBackendSQL::fillDict() { 543void OTodoAccessBackendSQL::fillDict() {
493 /* initialize dict */ 544 /* initialize dict */
494 /* 545 /*
495 * UPDATE dict if you change anything!!! 546 * UPDATE dict if you change anything!!!
496 * FIXME: Isn't this dict obsolete ? (eilers) 547 * FIXME: Isn't this dict obsolete ? (eilers)
497 */ 548 */
498 m_dict.setAutoDelete( TRUE ); 549 m_dict.setAutoDelete( TRUE );
499 m_dict.insert("Categories" , new int(OTodo::Category) ); 550 m_dict.insert("Categories" , new int(OTodo::Category) );
500 m_dict.insert("Uid" , new int(OTodo::Uid) ); 551 m_dict.insert("Uid" , new int(OTodo::Uid) );
501 m_dict.insert("HasDate" , new int(OTodo::HasDate) ); 552 m_dict.insert("HasDate" , new int(OTodo::HasDate) );
502 m_dict.insert("Completed" , new int(OTodo::Completed) ); 553 m_dict.insert("Completed" , new int(OTodo::Completed) );
503 m_dict.insert("Description" , new int(OTodo::Description) ); 554 m_dict.insert("Description" , new int(OTodo::Description) );
504 m_dict.insert("Summary" , new int(OTodo::Summary) ); 555 m_dict.insert("Summary" , new int(OTodo::Summary) );
505 m_dict.insert("Priority" , new int(OTodo::Priority) ); 556 m_dict.insert("Priority" , new int(OTodo::Priority) );
506 m_dict.insert("DateDay" , new int(OTodo::DateDay) ); 557 m_dict.insert("DateDay" , new int(OTodo::DateDay) );
@@ -549,45 +600,52 @@ QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
549 600
550 Copied from xml-backend by not adapted to sql (eilers) 601 Copied from xml-backend by not adapted to sql (eilers)
551 602
552 QArray<int> m_currentQuery( m_events.count() ); 603 QArray<int> m_currentQuery( m_events.count() );
553 uint arraycounter = 0; 604 uint arraycounter = 0;
554 605
555 606
556 607
557 QMap<int, OTodo>::ConstIterator it; 608 QMap<int, OTodo>::ConstIterator it;
558 for (it = m_events.begin(); it != m_events.end(); ++it ) { 609 for (it = m_events.begin(); it != m_events.end(); ++it ) {
559 if ( it.data().match( r ) ) 610 if ( it.data().match( r ) )
560 m_currentQuery[arraycounter++] = it.data().uid(); 611 m_currentQuery[arraycounter++] = it.data().uid();
561 612
562 } 613 }
563 // Shrink to fit.. 614 // Shrink to fit..
564 m_currentQuery.resize(arraycounter); 615 m_currentQuery.resize(arraycounter);
565 616
566 return m_currentQuery; 617 return m_currentQuery;
567#endif 618#endif
568 QArray<int> empty; 619 QArray<int> empty;
569 return empty; 620 return empty;
570} 621}
571QBitArray OTodoAccessBackendSQL::supports()const { 622QBitArray OTodoAccessBackendSQL::supports()const {
572 623
573 static QBitArray ar = sup(); 624 QBitArray ar( OTodo::CompletedDate + 1 );
625 ar.fill( true );
626 ar[OTodo::CrossReference] = false;
627 ar[OTodo::State ] = false;
628 ar[OTodo::Reminders] = false;
629 ar[OTodo::Notifiers] = false;
630 ar[OTodo::Maintainer] = false;
631
574 return ar; 632 return ar;
575} 633}
576 634
577QBitArray OTodoAccessBackendSQL::sup() { 635QBitArray OTodoAccessBackendSQL::sup() {
578 636
579 QBitArray ar( OTodo::CompletedDate + 1 ); 637 QBitArray ar( OTodo::CompletedDate + 1 );
580 ar.fill( true ); 638 ar.fill( true );
581 ar[OTodo::CrossReference] = false; 639 ar[OTodo::CrossReference] = false;
582 ar[OTodo::State ] = false; 640 ar[OTodo::State ] = false;
583 ar[OTodo::Reminders] = false; 641 ar[OTodo::Reminders] = false;
584 ar[OTodo::Notifiers] = false; 642 ar[OTodo::Notifiers] = false;
585 ar[OTodo::Maintainer] = false; 643 ar[OTodo::Maintainer] = false;
586 644
587 return ar; 645 return ar;
588} 646}
589 647
590void OTodoAccessBackendSQL::removeAllCompleted(){ 648void OTodoAccessBackendSQL::removeAllCompleted(){
591#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !! 649#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
592 650
593} 651}
diff --git a/libopie2/opiepim/ocontactfields.cpp b/libopie2/opiepim/ocontactfields.cpp
index 831a596..7206f0d 100644
--- a/libopie2/opiepim/ocontactfields.cpp
+++ b/libopie2/opiepim/ocontactfields.cpp
@@ -152,86 +152,92 @@ QStringList OContactFields::trfields( bool sorted )
152 list.append( mapIdToStr[Qtopia::HomeCity] ); 152 list.append( mapIdToStr[Qtopia::HomeCity] );
153 list.append( mapIdToStr[Qtopia::HomeState] ); 153 list.append( mapIdToStr[Qtopia::HomeState] );
154 list.append( mapIdToStr[Qtopia::HomeZip] ); 154 list.append( mapIdToStr[Qtopia::HomeZip] );
155 list.append( mapIdToStr[Qtopia::HomeCountry] ); 155 list.append( mapIdToStr[Qtopia::HomeCountry] );
156 156
157 list += trdetailsfields( sorted ); 157 list += trdetailsfields( sorted );
158 158
159 list.append( mapIdToStr[Qtopia::Notes] ); 159 list.append( mapIdToStr[Qtopia::Notes] );
160 list.append( mapIdToStr[Qtopia::Groups] ); 160 list.append( mapIdToStr[Qtopia::Groups] );
161 161
162 if (sorted) list.sort(); 162 if (sorted) list.sort();
163 163
164 return list; 164 return list;
165} 165}
166 166
167/*! 167/*!
168 \internal 168 \internal
169 Returns an untranslated list of field names for a contact. 169 Returns an untranslated list of field names for a contact.
170*/ 170*/
171QStringList OContactFields::untrfields( bool sorted ) 171QStringList OContactFields::untrfields( bool sorted )
172{ 172{
173 QStringList list; 173 QStringList list;
174 QMap<int, QString> mapIdToStr = idToUntrFields(); 174 QMap<int, QString> mapIdToStr = idToUntrFields();
175 175
176 list.append( mapIdToStr[ Qtopia::AddressUid ] );
177 list.append( mapIdToStr[ Qtopia::AddressCategory ] );
178
176 list.append( mapIdToStr[ Qtopia::Title ] ); 179 list.append( mapIdToStr[ Qtopia::Title ] );
177 list.append( mapIdToStr[ Qtopia::FirstName ] ); 180 list.append( mapIdToStr[ Qtopia::FirstName ] );
178 list.append( mapIdToStr[ Qtopia::MiddleName ] ); 181 list.append( mapIdToStr[ Qtopia::MiddleName ] );
179 list.append( mapIdToStr[ Qtopia::LastName ] ); 182 list.append( mapIdToStr[ Qtopia::LastName ] );
180 list.append( mapIdToStr[ Qtopia::Suffix ] ); 183 list.append( mapIdToStr[ Qtopia::Suffix ] );
181 list.append( mapIdToStr[ Qtopia::FileAs ] ); 184 list.append( mapIdToStr[ Qtopia::FileAs ] );
182 185
183 list.append( mapIdToStr[ Qtopia::JobTitle ] ); 186 list.append( mapIdToStr[ Qtopia::JobTitle ] );
184 list.append( mapIdToStr[ Qtopia::Department ] ); 187 list.append( mapIdToStr[ Qtopia::Department ] );
185 list.append( mapIdToStr[ Qtopia::Company ] ); 188 list.append( mapIdToStr[ Qtopia::Company ] );
186 189
187 list += untrphonefields( sorted ); 190 list += untrphonefields( sorted );
188 191
189 list.append( mapIdToStr[ Qtopia::BusinessStreet ] ); 192 list.append( mapIdToStr[ Qtopia::BusinessStreet ] );
190 list.append( mapIdToStr[ Qtopia::BusinessCity ] ); 193 list.append( mapIdToStr[ Qtopia::BusinessCity ] );
191 list.append( mapIdToStr[ Qtopia::BusinessState ] ); 194 list.append( mapIdToStr[ Qtopia::BusinessState ] );
192 list.append( mapIdToStr[ Qtopia::BusinessZip ] ); 195 list.append( mapIdToStr[ Qtopia::BusinessZip ] );
193 list.append( mapIdToStr[ Qtopia::BusinessCountry ] ); 196 list.append( mapIdToStr[ Qtopia::BusinessCountry ] );
194 197
195 list.append( mapIdToStr[ Qtopia::HomeStreet ] ); 198 list.append( mapIdToStr[ Qtopia::HomeStreet ] );
196 list.append( mapIdToStr[ Qtopia::HomeCity ] ); 199 list.append( mapIdToStr[ Qtopia::HomeCity ] );
197 list.append( mapIdToStr[ Qtopia::HomeState ] ); 200 list.append( mapIdToStr[ Qtopia::HomeState ] );
198 list.append( mapIdToStr[ Qtopia::HomeZip ] ); 201 list.append( mapIdToStr[ Qtopia::HomeZip ] );
199 list.append( mapIdToStr[ Qtopia::HomeCountry ] ); 202 list.append( mapIdToStr[ Qtopia::HomeCountry ] );
200 203
201 list += untrdetailsfields( sorted ); 204 list += untrdetailsfields( sorted );
202 205
203 list.append( mapIdToStr[ Qtopia::Notes ] ); 206 list.append( mapIdToStr[ Qtopia::Notes ] );
204 list.append( mapIdToStr[ Qtopia::Groups ] ); 207 list.append( mapIdToStr[ Qtopia::Groups ] );
205 208
206 if (sorted) list.sort(); 209 if (sorted) list.sort();
207 210
208 return list; 211 return list;
209} 212}
210QMap<int, QString> OContactFields::idToTrFields() 213QMap<int, QString> OContactFields::idToTrFields()
211{ 214{
212 QMap<int, QString> ret_map; 215 QMap<int, QString> ret_map;
213 216
217 ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) );
218 ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) );
219
214 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") ); 220 ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
215 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) ); 221 ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
216 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) ); 222 ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
217 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) ); 223 ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
218 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" )); 224 ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
219 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) ); 225 ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
220 226
221 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) ); 227 ret_map.insert( Qtopia::JobTitle, QObject::tr( "Job Title" ) );
222 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) ); 228 ret_map.insert( Qtopia::Department, QObject::tr( "Department" ) );
223 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) ); 229 ret_map.insert( Qtopia::Company, QObject::tr( "Company" ) );
224 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) ); 230 ret_map.insert( Qtopia::BusinessPhone, QObject::tr( "Business Phone" ) );
225 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) ); 231 ret_map.insert( Qtopia::BusinessFax, QObject::tr( "Business Fax" ) );
226 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" )); 232 ret_map.insert( Qtopia::BusinessMobile, QObject::tr( "Business Mobile" ));
227 233
228 // email 234 // email
229 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) ); 235 ret_map.insert( Qtopia::DefaultEmail, QObject::tr( "Default Email" ) );
230 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) ); 236 ret_map.insert( Qtopia::Emails, QObject::tr( "Emails" ) );
231 237
232 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) ); 238 ret_map.insert( Qtopia::HomePhone, QObject::tr( "Home Phone" ) );
233 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) ); 239 ret_map.insert( Qtopia::HomeFax, QObject::tr( "Home Fax" ) );
234 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) ); 240 ret_map.insert( Qtopia::HomeMobile, QObject::tr( "Home Mobile" ) );
235 241
236 // business 242 // business
237 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) ); 243 ret_map.insert( Qtopia::BusinessStreet, QObject::tr( "Business Street" ) );
@@ -253,48 +259,51 @@ QMap<int, QString> OContactFields::idToTrFields()
253 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) ); 259 ret_map.insert( Qtopia::HomeState, QObject::tr( "Home State" ) );
254 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) ); 260 ret_map.insert( Qtopia::HomeZip, QObject::tr( "Home Zip" ) );
255 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) ); 261 ret_map.insert( Qtopia::HomeCountry, QObject::tr( "Home Country" ) );
256 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) ); 262 ret_map.insert( Qtopia::HomeWebPage, QObject::tr( "Home Web Page" ) );
257 263
258 //personal 264 //personal
259 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) ); 265 ret_map.insert( Qtopia::Spouse, QObject::tr( "Spouse" ) );
260 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) ); 266 ret_map.insert( Qtopia::Gender, QObject::tr( "Gender" ) );
261 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) ); 267 ret_map.insert( Qtopia::Birthday, QObject::tr( "Birthday" ) );
262 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) ); 268 ret_map.insert( Qtopia::Anniversary, QObject::tr( "Anniversary" ) );
263 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) ); 269 ret_map.insert( Qtopia::Nickname, QObject::tr( "Nickname" ) );
264 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) ); 270 ret_map.insert( Qtopia::Children, QObject::tr( "Children" ) );
265 271
266 // other 272 // other
267 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) ); 273 ret_map.insert( Qtopia::Notes, QObject::tr( "Notes" ) );
268 274
269 275
270 return ret_map; 276 return ret_map;
271} 277}
272 278
273QMap<int, QString> OContactFields::idToUntrFields() 279QMap<int, QString> OContactFields::idToUntrFields()
274{ 280{
275 QMap<int, QString> ret_map; 281 QMap<int, QString> ret_map;
276 282
283 ret_map.insert( Qtopia::AddressUid, "User Id" );
284 ret_map.insert( Qtopia::AddressCategory, "Categories" );
285
277 ret_map.insert( Qtopia::Title, "Name Title" ); 286 ret_map.insert( Qtopia::Title, "Name Title" );
278 ret_map.insert( Qtopia::FirstName, "First Name" ); 287 ret_map.insert( Qtopia::FirstName, "First Name" );
279 ret_map.insert( Qtopia::MiddleName, "Middle Name" ); 288 ret_map.insert( Qtopia::MiddleName, "Middle Name" );
280 ret_map.insert( Qtopia::LastName, "Last Name" ); 289 ret_map.insert( Qtopia::LastName, "Last Name" );
281 ret_map.insert( Qtopia::Suffix, "Suffix" ); 290 ret_map.insert( Qtopia::Suffix, "Suffix" );
282 ret_map.insert( Qtopia::FileAs, "File As" ); 291 ret_map.insert( Qtopia::FileAs, "File As" );
283 292
284 ret_map.insert( Qtopia::JobTitle, "Job Title" ); 293 ret_map.insert( Qtopia::JobTitle, "Job Title" );
285 ret_map.insert( Qtopia::Department, "Department" ); 294 ret_map.insert( Qtopia::Department, "Department" );
286 ret_map.insert( Qtopia::Company, "Company" ); 295 ret_map.insert( Qtopia::Company, "Company" );
287 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" ); 296 ret_map.insert( Qtopia::BusinessPhone, "Business Phone" );
288 ret_map.insert( Qtopia::BusinessFax, "Business Fax" ); 297 ret_map.insert( Qtopia::BusinessFax, "Business Fax" );
289 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" ); 298 ret_map.insert( Qtopia::BusinessMobile, "Business Mobile" );
290 299
291 // email 300 // email
292 ret_map.insert( Qtopia::DefaultEmail, "Default Email" ); 301 ret_map.insert( Qtopia::DefaultEmail, "Default Email" );
293 ret_map.insert( Qtopia::Emails, "Emails" ); 302 ret_map.insert( Qtopia::Emails, "Emails" );
294 303
295 ret_map.insert( Qtopia::HomePhone, "Home Phone" ); 304 ret_map.insert( Qtopia::HomePhone, "Home Phone" );
296 ret_map.insert( Qtopia::HomeFax, "Home Fax" ); 305 ret_map.insert( Qtopia::HomeFax, "Home Fax" );
297 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" ); 306 ret_map.insert( Qtopia::HomeMobile, "Home Mobile" );
298 307
299 // business 308 // business
300 ret_map.insert( Qtopia::BusinessStreet, "Business Street" ); 309 ret_map.insert( Qtopia::BusinessStreet, "Business Street" );
@@ -307,48 +316,49 @@ QMap<int, QString> OContactFields::idToUntrFields()
307 316
308 ret_map.insert( Qtopia::Office, "Office" ); 317 ret_map.insert( Qtopia::Office, "Office" );
309 ret_map.insert( Qtopia::Profession, "Profession" ); 318 ret_map.insert( Qtopia::Profession, "Profession" );
310 ret_map.insert( Qtopia::Assistant, "Assistant" ); 319 ret_map.insert( Qtopia::Assistant, "Assistant" );
311 ret_map.insert( Qtopia::Manager, "Manager" ); 320 ret_map.insert( Qtopia::Manager, "Manager" );
312 321
313 // home 322 // home
314 ret_map.insert( Qtopia::HomeStreet, "Home Street" ); 323 ret_map.insert( Qtopia::HomeStreet, "Home Street" );
315 ret_map.insert( Qtopia::HomeCity, "Home City" ); 324 ret_map.insert( Qtopia::HomeCity, "Home City" );
316 ret_map.insert( Qtopia::HomeState, "Home State" ); 325 ret_map.insert( Qtopia::HomeState, "Home State" );
317 ret_map.insert( Qtopia::HomeZip, "Home Zip" ); 326 ret_map.insert( Qtopia::HomeZip, "Home Zip" );
318 ret_map.insert( Qtopia::HomeCountry, "Home Country" ); 327 ret_map.insert( Qtopia::HomeCountry, "Home Country" );
319 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" ); 328 ret_map.insert( Qtopia::HomeWebPage, "Home Web Page" );
320 329
321 //personal 330 //personal
322 ret_map.insert( Qtopia::Spouse, "Spouse" ); 331 ret_map.insert( Qtopia::Spouse, "Spouse" );
323 ret_map.insert( Qtopia::Gender, "Gender" ); 332 ret_map.insert( Qtopia::Gender, "Gender" );
324 ret_map.insert( Qtopia::Birthday, "Birthday" ); 333 ret_map.insert( Qtopia::Birthday, "Birthday" );
325 ret_map.insert( Qtopia::Anniversary, "Anniversary" ); 334 ret_map.insert( Qtopia::Anniversary, "Anniversary" );
326 ret_map.insert( Qtopia::Nickname, "Nickname" ); 335 ret_map.insert( Qtopia::Nickname, "Nickname" );
327 ret_map.insert( Qtopia::Children, "Children" ); 336 ret_map.insert( Qtopia::Children, "Children" );
328 337
329 // other 338 // other
330 ret_map.insert( Qtopia::Notes, "Notes" ); 339 ret_map.insert( Qtopia::Notes, "Notes" );
340 ret_map.insert( Qtopia::Groups, "Groups" );
331 341
332 342
333 return ret_map; 343 return ret_map;
334} 344}
335 345
336QMap<QString, int> OContactFields::trFieldsToId() 346QMap<QString, int> OContactFields::trFieldsToId()
337{ 347{
338 QMap<int, QString> idtostr = idToTrFields(); 348 QMap<int, QString> idtostr = idToTrFields();
339 QMap<QString, int> ret_map; 349 QMap<QString, int> ret_map;
340 350
341 351
342 QMap<int, QString>::Iterator it; 352 QMap<int, QString>::Iterator it;
343 for( it = idtostr.begin(); it != idtostr.end(); ++it ) 353 for( it = idtostr.begin(); it != idtostr.end(); ++it )
344 ret_map.insert( *it, it.key() ); 354 ret_map.insert( *it, it.key() );
345 355
346 356
347 return ret_map; 357 return ret_map;
348} 358}
349 359
350QMap<QString, int> OContactFields::untrFieldsToId() 360QMap<QString, int> OContactFields::untrFieldsToId()
351{ 361{
352 QMap<int, QString> idtostr = idToUntrFields(); 362 QMap<int, QString> idtostr = idToUntrFields();
353 QMap<QString, int> ret_map; 363 QMap<QString, int> ret_map;
354 364