summaryrefslogtreecommitdiff
authoreilers <eilers>2003-09-29 07:44:26 (UTC)
committer eilers <eilers>2003-09-29 07:44:26 (UTC)
commit36d6b0096c41b01e69bb0d12e6c29648cbbf8290 (patch) (unidiff)
treec87f4f92c4a1fbdf57e502a9c5e3e44fd9e98540
parentb2e22408970ef548e23e9bbdcd87302f35fc6d4d (diff)
downloadopie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.zip
opie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.tar.gz
opie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.tar.bz2
Improvement of PIM-SQL Databases, but search queries are still limited.
Addressbook: Changed table layout. Now, we just need 1/3 of disk-space. Todo: Started to add new attributes. Some type conversions missing.
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,664 +1,921 @@
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:
64 ClearQuery(); 85 ClearQuery();
65 ~ClearQuery(); 86 ~ClearQuery();
66 QString query()const; 87 QString query()const;
67 88
68 }; 89 };
69 90
70 91
71 /** 92 /**
72 * LoadQuery 93 * LoadQuery
73 * this one queries for all uids 94 * this one queries for all uids
74 */ 95 */
75 class LoadQuery : public OSQLQuery { 96 class LoadQuery : public OSQLQuery {
76 public: 97 public:
77 LoadQuery(); 98 LoadQuery();
78 ~LoadQuery(); 99 ~LoadQuery();
79 QString query()const; 100 QString query()const;
80 }; 101 };
81 102
82 /** 103 /**
83 * inserts/adds a OContact to the table 104 * inserts/adds a OContact to the table
84 */ 105 */
85 class InsertQuery : public OSQLQuery { 106 class InsertQuery : public OSQLQuery {
86 public: 107 public:
87 InsertQuery(const OContact& ); 108 InsertQuery(const OContact& );
88 ~InsertQuery(); 109 ~InsertQuery();
89 QString query()const; 110 QString query()const;
90 private: 111 private:
91 OContact m_contact; 112 OContact m_contact;
92 }; 113 };
93 114
94 115
95 /** 116 /**
96 * removes one from the table 117 * removes one from the table
97 */ 118 */
98 class RemoveQuery : public OSQLQuery { 119 class RemoveQuery : public OSQLQuery {
99 public: 120 public:
100 RemoveQuery(int uid ); 121 RemoveQuery(int uid );
101 ~RemoveQuery(); 122 ~RemoveQuery();
102 QString query()const; 123 QString query()const;
103 private: 124 private:
104 int m_uid; 125 int m_uid;
105 }; 126 };
106 127
107 /** 128 /**
108 * a find query for noncustom elements 129 * a find query for noncustom elements
109 */ 130 */
110 class FindQuery : public OSQLQuery { 131 class FindQuery : public OSQLQuery {
111 public: 132 public:
112 FindQuery(int uid); 133 FindQuery(int uid);
113 FindQuery(const QArray<int>& ); 134 FindQuery(const QArray<int>& );
114 ~FindQuery(); 135 ~FindQuery();
115 QString query()const; 136 QString query()const;
116 private: 137 private:
117 QString single()const; 138 QString single()const;
118 QString multi()const; 139 QString multi()const;
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();
228 addressbook_db.insert( transMap[it.key()], 314 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3") 315 QString("%1-%2-%3")
230 .arg( day.year() ) 316 .arg( day.year() )
231 .arg( day.month() ) 317 .arg( day.month() )
232 .arg( day.day() ) ); 318 .arg( day.day() ) );
233 } 319 }
234 break; 320 break;
235 case Qtopia::AddressUid: // Ignore UID 321 case Qtopia::AddressUid: // Ignore UID
236 break; 322 break;
237 default: // Translate id to String 323 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() ); 324 addressbook_db.insert( transMap[it.key()], it.data() );
239 break; 325 break;
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}
403 501
404bool OContactAccessBackend_SQL::save() 502bool OContactAccessBackend_SQL::save()
405{ 503{
406 return m_driver->close(); 504 return m_driver->close();
407} 505}
408 506
409 507
410void OContactAccessBackend_SQL::clear () 508void OContactAccessBackend_SQL::clear ()
411{ 509{
412 ClearQuery cle; 510 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle ); 511 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu; 512 CreateQuery qu;
415 res = m_driver->query(&qu); 513 res = m_driver->query(&qu);
416} 514}
417 515
418bool OContactAccessBackend_SQL::wasChangedExternally() 516bool OContactAccessBackend_SQL::wasChangedExternally()
419{ 517{
420 return false; 518 return false;
421} 519}
422 520
423QArray<int> OContactAccessBackend_SQL::allRecords() const 521QArray<int> OContactAccessBackend_SQL::allRecords() const
424{ 522{
425 523
426 // FIXME: Think about cute handling of changed tables.. 524 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here... 525 // Thus, we don't have to call update here...
428 if ( m_changed ) 526 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update(); 527 ((OContactAccessBackend_SQL*)this)->update();
430 528
431 return m_uids; 529 return m_uids;
432} 530}
433 531
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) 532bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{ 533{
436 InsertQuery ins( newcontact ); 534 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins ); 535 OSQLResult res = m_driver->query( &ins );
438 536
439 if ( res.state() == OSQLResult::Failure ) 537 if ( res.state() == OSQLResult::Failure )
440 return false; 538 return false;
441 539
442 int c = m_uids.count(); 540 int c = m_uids.count();
443 m_uids.resize( c+1 ); 541 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid(); 542 m_uids[c] = newcontact.uid();
445 543
446 return true; 544 return true;
447} 545}
448 546
449 547
450bool OContactAccessBackend_SQL::remove ( int uid ) 548bool OContactAccessBackend_SQL::remove ( int uid )
451{ 549{
452 RemoveQuery rem( uid ); 550 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem ); 551 OSQLResult res = m_driver->query(&rem );
454 552
455 if ( res.state() == OSQLResult::Failure ) 553 if ( res.state() == OSQLResult::Failure )
456 return false; 554 return false;
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();
603 858
604 OSQLResultItem::ValueList list = res_noncustom.results(); 859 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin(); 860 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) { 861 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){ 862 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )]; 863 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){ 864 switch( typeId ){
610 case Qtopia::Birthday: 865 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{ 866 case Qtopia::Anniversary:{
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
@@ -80,347 +80,357 @@ QStringList OContactFields::trphonefields( bool sorted )
80 80
81 list.append( mapIdToStr[Qtopia::HomePhone] ); 81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] ); 82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] ); 83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] ); 84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] ); 85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86 86
87 if (sorted) list.sort(); 87 if (sorted) list.sort();
88 88
89 return list; 89 return list;
90} 90}
91 91
92 92
93/*! 93/*!
94 \internal 94 \internal
95 Returns a list of phone field names for a contact. 95 Returns a list of phone field names for a contact.
96*/ 96*/
97QStringList OContactFields::untrphonefields( bool sorted ) 97QStringList OContactFields::untrphonefields( bool sorted )
98{ 98{
99 QStringList list; 99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields(); 100 QMap<int, QString> mapIdToStr = idToUntrFields();
101 101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] ); 102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] ); 103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] ); 104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] ); 105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] ); 106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107 107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] ); 108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] ); 109 list.append( mapIdToStr[ Qtopia::Emails ] );
110 110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] ); 111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] ); 112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] ); 113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] ); 114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] ); 115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116 116
117 if (sorted) list.sort(); 117 if (sorted) list.sort();
118 118
119 return list; 119 return list;
120} 120}
121 121
122 122
123/*! 123/*!
124 \internal 124 \internal
125 Returns a translated list of field names for a contact. 125 Returns a translated list of field names for a contact.
126*/ 126*/
127QStringList OContactFields::trfields( bool sorted ) 127QStringList OContactFields::trfields( bool sorted )
128{ 128{
129 QStringList list; 129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields(); 130 QMap<int, QString> mapIdToStr = idToTrFields();
131 131
132 list.append( mapIdToStr[Qtopia::Title]); 132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] ); 133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] ); 134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] ); 135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] ); 136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] ); 137 list.append( mapIdToStr[Qtopia::FileAs] );
138 138
139 list.append( mapIdToStr[Qtopia::JobTitle] ); 139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] ); 140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] ); 141 list.append( mapIdToStr[Qtopia::Company] );
142 142
143 list += trphonefields( sorted ); 143 list += trphonefields( sorted );
144 144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] ); 145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] ); 146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] ); 147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] ); 148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] ); 149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150 150
151 list.append( mapIdToStr[Qtopia::HomeStreet] ); 151 list.append( mapIdToStr[Qtopia::HomeStreet] );
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" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) ); 244 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) ); 245 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) ); 246 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) ); 247 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) ); 248 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) ); 249 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244 250
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) ); 251 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) ); 252 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) ); 253 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) ); 254 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249 255
250 // home 256 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) ); 257 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) ); 258 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
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" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" ); 310 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" ); 311 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" ); 312 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" ); 313 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" ); 314 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" ); 315 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
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
355 365
356 QMap<int, QString>::Iterator it; 366 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it ) 367 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() ); 368 ret_map.insert( *it, it.key() );
359 369
360 370
361 return ret_map; 371 return ret_map;
362} 372}
363 373
364 374
365OContactFields::OContactFields(): 375OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ), 376 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false ) 377 changedFieldOrder( false )
368{ 378{
369 // Get the global field order from the config file and 379 // Get the global field order from the config file and
370 // use it as a start pattern 380 // use it as a start pattern
371 Config cfg ( "AddressBook" ); 381 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" ); 382 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER ); 383 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374} 384}
375 385
376OContactFields::~OContactFields(){ 386OContactFields::~OContactFields(){
377 387
378 // We will store the fieldorder into the config file 388 // We will store the fieldorder into the config file
379 // to reuse it for the future.. 389 // to reuse it for the future..
380 if ( changedFieldOrder ){ 390 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" ); 391 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" ); 392 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder ); 393 cfg.writeEntry( "General", globalFieldOrder );
384 } 394 }
385} 395}
386 396
387 397
388 398
389void OContactFields::saveToRecord( OContact &cnt ){ 399void OContactFields::saveToRecord( OContact &cnt ){
390 400
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1()); 401 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392 402
393 // Store fieldorder into this contact. 403 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder ); 404 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395 405
396 globalFieldOrder = fieldOrder; 406 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true; 407 changedFieldOrder = true;
398 408
399} 409}
400 410
401void OContactFields::loadFromRecord( const OContact &cnt ){ 411void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord"); 412 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1()); 413 qDebug("loading >%s<",cnt.fullName().latin1());
404 414
405 // Get fieldorder for this contact. If none is defined, 415 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file.. 416 // we will use the global one from the config file..
407 417
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME ); 418 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409 419
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1()); 420 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411 421
412 if (fieldOrder.isEmpty()){ 422 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder; 423 fieldOrder = globalFieldOrder;
414 } 424 }
415 425
416 426
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1()); 427 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418} 428}
419 429
420void OContactFields::setFieldOrder( int num, int index ){ 430void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index); 431 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422 432
423 fieldOrder[num] = QString::number( index, 16 )[0]; 433 fieldOrder[num] = QString::number( index, 16 )[0];
424 434
425 // We will store this new fieldorder globally to 435 // We will store this new fieldorder globally to
426 // remember it for contacts which have none 436 // remember it for contacts which have none
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
@@ -25,569 +25,627 @@ namespace {
25 class CreateQuery : public OSQLQuery { 25 class CreateQuery : public OSQLQuery {
26 public: 26 public:
27 CreateQuery(); 27 CreateQuery();
28 ~CreateQuery(); 28 ~CreateQuery();
29 QString query()const; 29 QString query()const;
30 }; 30 };
31 31
32 /** 32 /**
33 * LoadQuery 33 * LoadQuery
34 * this one queries for all uids 34 * this one queries for all uids
35 */ 35 */
36 class LoadQuery : public OSQLQuery { 36 class LoadQuery : public OSQLQuery {
37 public: 37 public:
38 LoadQuery(); 38 LoadQuery();
39 ~LoadQuery(); 39 ~LoadQuery();
40 QString query()const; 40 QString query()const;
41 }; 41 };
42 42
43 /** 43 /**
44 * inserts/adds a OTodo to the table 44 * inserts/adds a OTodo to the table
45 */ 45 */
46 class InsertQuery : public OSQLQuery { 46 class InsertQuery : public OSQLQuery {
47 public: 47 public:
48 InsertQuery(const OTodo& ); 48 InsertQuery(const OTodo& );
49 ~InsertQuery(); 49 ~InsertQuery();
50 QString query()const; 50 QString query()const;
51 private: 51 private:
52 OTodo m_todo; 52 OTodo m_todo;
53 }; 53 };
54 54
55 /** 55 /**
56 * removes one from the table 56 * removes one from the table
57 */ 57 */
58 class RemoveQuery : public OSQLQuery { 58 class RemoveQuery : public OSQLQuery {
59 public: 59 public:
60 RemoveQuery(int uid ); 60 RemoveQuery(int uid );
61 ~RemoveQuery(); 61 ~RemoveQuery();
62 QString query()const; 62 QString query()const;
63 private: 63 private:
64 int m_uid; 64 int m_uid;
65 }; 65 };
66 66
67 /** 67 /**
68 * Clears (delete) a Table 68 * Clears (delete) a Table
69 */ 69 */
70 class ClearQuery : public OSQLQuery { 70 class ClearQuery : public OSQLQuery {
71 public: 71 public:
72 ClearQuery(); 72 ClearQuery();
73 ~ClearQuery(); 73 ~ClearQuery();
74 QString query()const; 74 QString query()const;
75 75
76 }; 76 };
77 77
78 /** 78 /**
79 * a find query 79 * a find query
80 */ 80 */
81 class FindQuery : public OSQLQuery { 81 class FindQuery : public OSQLQuery {
82 public: 82 public:
83 FindQuery(int uid); 83 FindQuery(int uid);
84 FindQuery(const QArray<int>& ); 84 FindQuery(const QArray<int>& );
85 ~FindQuery(); 85 ~FindQuery();
86 QString query()const; 86 QString query()const;
87 private: 87 private:
88 QString single()const; 88 QString single()const;
89 QString multi()const; 89 QString multi()const;
90 QArray<int> m_uids; 90 QArray<int> m_uids;
91 int m_uid; 91 int m_uid;
92 }; 92 };
93 93
94 /** 94 /**
95 * overdue query 95 * overdue query
96 */ 96 */
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 }
226 QString EffQuery::with()const { 261 QString EffQuery::with()const {
227 QString str; 262 QString str;
228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 263 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 264 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 265 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
231 return str; 266 return str;
232 } 267 }
233 QString EffQuery::out()const { 268 QString EffQuery::out()const {
234 QString str; 269 QString str;
235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 270 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 271 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 272 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
238 273
239 return str; 274 return str;
240 } 275 }
241}; 276};
242 277
243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 278OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
244 : OTodoAccessBackend(), m_dict(15), m_dirty(true) 279 : OTodoAccessBackend(), m_dict(15), m_dirty(true)
245{ 280{
246 QString fi = file; 281 QString fi = file;
247 if ( fi.isEmpty() ) 282 if ( fi.isEmpty() )
248 fi = Global::applicationFileName( "todolist", "todolist.db" ); 283 fi = Global::applicationFileName( "todolist", "todolist.db" );
249 OSQLManager man; 284 OSQLManager man;
250 m_driver = man.standard(); 285 m_driver = man.standard();
251 m_driver->setUrl(fi); 286 m_driver->setUrl(fi);
252 // fillDict(); 287 // fillDict();
253} 288}
254 289
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 290OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
256} 291}
257bool OTodoAccessBackendSQL::load(){ 292bool OTodoAccessBackendSQL::load(){
258 if (!m_driver->open() ) 293 if (!m_driver->open() )
259 return false; 294 return false;
260 295
261 CreateQuery creat; 296 CreateQuery creat;
262 OSQLResult res = m_driver->query(&creat ); 297 OSQLResult res = m_driver->query(&creat );
263 298
264 m_dirty = true; 299 m_dirty = true;
265 return true; 300 return true;
266} 301}
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 );
316 FindQuery query( search ); 351 FindQuery query( search );
317 OSQLResult res = m_driver->query( &query ); 352 OSQLResult res = m_driver->query( &query );
318 if ( res.state() != OSQLResult::Success ) 353 if ( res.state() != OSQLResult::Success )
319 return to; 354 return to;
320 355
321 return todo( res ); 356 return todo( res );
322} 357}
323void OTodoAccessBackendSQL::clear() { 358void OTodoAccessBackendSQL::clear() {
324 ClearQuery cle; 359 ClearQuery cle;
325 OSQLResult res = m_driver->query( &cle ); 360 OSQLResult res = m_driver->query( &cle );
326 CreateQuery qu; 361 CreateQuery qu;
327 res = m_driver->query(&qu); 362 res = m_driver->query(&qu);
328} 363}
329bool OTodoAccessBackendSQL::add( const OTodo& t) { 364bool OTodoAccessBackendSQL::add( const OTodo& t) {
330 InsertQuery ins( t ); 365 InsertQuery ins( t );
331 OSQLResult res = m_driver->query( &ins ); 366 OSQLResult res = m_driver->query( &ins );
332 367
333 if ( res.state() == OSQLResult::Failure ) 368 if ( res.state() == OSQLResult::Failure )
334 return false; 369 return false;
335 int c = m_uids.count(); 370 int c = m_uids.count();
336 m_uids.resize( c+1 ); 371 m_uids.resize( c+1 );
337 m_uids[c] = t.uid(); 372 m_uids[c] = t.uid();
338 373
339 return true; 374 return true;
340} 375}
341bool OTodoAccessBackendSQL::remove( int uid ) { 376bool OTodoAccessBackendSQL::remove( int uid ) {
342 RemoveQuery rem( uid ); 377 RemoveQuery rem( uid );
343 OSQLResult res = m_driver->query(&rem ); 378 OSQLResult res = m_driver->query(&rem );
344 379
345 if ( res.state() == OSQLResult::Failure ) 380 if ( res.state() == OSQLResult::Failure )
346 return false; 381 return false;
347 382
348 m_dirty = true; 383 m_dirty = true;
349 return true; 384 return true;
350} 385}
351/* 386/*
352 * FIXME better set query 387 * FIXME better set query
353 * but we need the cache for that 388 * but we need the cache for that
354 * now we remove 389 * now we remove
355 */ 390 */
356bool OTodoAccessBackendSQL::replace( const OTodo& t) { 391bool OTodoAccessBackendSQL::replace( const OTodo& t) {
357 remove( t.uid() ); 392 remove( t.uid() );
358 bool b= add(t); 393 bool b= add(t);
359 m_dirty = false; // we changed some stuff but the UID stayed the same 394 m_dirty = false; // we changed some stuff but the UID stayed the same
360 return b; 395 return b;
361} 396}
362QArray<int> OTodoAccessBackendSQL::overDue() { 397QArray<int> OTodoAccessBackendSQL::overDue() {
363 OverDueQuery qu; 398 OverDueQuery qu;
364 return uids( m_driver->query(&qu ) ); 399 return uids( m_driver->query(&qu ) );
365} 400}
366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 401QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
367 const QDate& t, 402 const QDate& t,
368 bool u) { 403 bool u) {
369 EffQuery ef(s, t, u ); 404 EffQuery ef(s, t, u );
370 return uids (m_driver->query(&ef) ); 405 return uids (m_driver->query(&ef) );
371} 406}
372/* 407/*
373 * 408 *
374 */ 409 */
375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 410QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
376 int sortFilter, int cat ) { 411 int sortFilter, int cat ) {
377 qWarning("sorted %d, %d", asc, sortOrder ); 412 qWarning("sorted %d, %d", asc, sortOrder );
378 QString query; 413 QString query;
379 query = "select uid from todolist WHERE "; 414 query = "select uid from todolist WHERE ";
380 415
381 /* 416 /*
382 * Sort Filter stuff 417 * Sort Filter stuff
383 * not that straight forward 418 * not that straight forward
384 * FIXME: Replace magic numbers 419 * FIXME: Replace magic numbers
385 * 420 *
386 */ 421 */
387 /* Category */ 422 /* Category */
388 if ( sortFilter & 1 ) { 423 if ( sortFilter & 1 ) {
389 QString str; 424 QString str;
390 if (cat != 0 ) str = QString::number( cat ); 425 if (cat != 0 ) str = QString::number( cat );
391 query += " categories like '%" +str+"%' AND"; 426 query += " categories like '%" +str+"%' AND";
392 } 427 }
393 /* Show only overdue */ 428 /* Show only overdue */
394 if ( sortFilter & 2 ) { 429 if ( sortFilter & 2 ) {
395 QDate date = QDate::currentDate(); 430 QDate date = QDate::currentDate();
396 QString due; 431 QString due;
397 QString base; 432 QString base;
398 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 433 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
399 query += " " + base + " AND"; 434 query += " " + base + " AND";
400 } 435 }
401 /* not show completed */ 436 /* not show completed */
402 if ( sortFilter & 4 ) { 437 if ( sortFilter & 4 ) {
403 query += " completed = 0 AND"; 438 query += " completed = 0 AND";
404 }else{ 439 }else{
405 query += " ( completed = 1 OR completed = 0) AND"; 440 query += " ( completed = 1 OR completed = 0) AND";
406 } 441 }
407 /* srtip the end */ 442 /* srtip the end */
408 query = query.remove( query.length()-3, 3 ); 443 query = query.remove( query.length()-3, 3 );
409 444
410 445
411 /* 446 /*
412 * sort order stuff 447 * sort order stuff
413 * quite straight forward 448 * quite straight forward
414 */ 449 */
415 query += "ORDER BY "; 450 query += "ORDER BY ";
416 switch( sortOrder ) { 451 switch( sortOrder ) {
417 /* completed */ 452 /* completed */
418 case 0: 453 case 0:
419 query += "completed"; 454 query += "completed";
420 break; 455 break;
421 case 1: 456 case 1:
422 query += "priority"; 457 query += "priority";
423 break; 458 break;
424 case 2: 459 case 2:
425 query += "summary"; 460 query += "summary";
426 break; 461 break;
427 case 3: 462 case 3:
428 query += "DueDate"; 463 query += "DueDate";
429 break; 464 break;
430 } 465 }
431 466
432 if ( !asc ) { 467 if ( !asc ) {
433 qWarning("not ascending!"); 468 qWarning("not ascending!");
434 query += " DESC"; 469 query += " DESC";
435 } 470 }
436 471
437 qWarning( query ); 472 qWarning( query );
438 OSQLRawQuery raw(query ); 473 OSQLRawQuery raw(query );
439 return uids( m_driver->query(&raw) ); 474 return uids( m_driver->query(&raw) );
440} 475}
441bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 476bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
442 if ( str == "0-0-0" ) 477 if ( str == "0-0-0" )
443 return false; 478 return false;
444 else{ 479 else{
445 int day, year, month; 480 int day, year, month;
446 QStringList list = QStringList::split("-", str ); 481 QStringList list = QStringList::split("-", str );
447 year = list[0].toInt(); 482 year = list[0].toInt();
448 month = list[1].toInt(); 483 month = list[1].toInt();
449 day = list[2].toInt(); 484 day = list[2].toInt();
450 da.setYMD( year, month, day ); 485 da.setYMD( year, month, day );
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) );
507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 558 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
508 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 559 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
509 m_dict.insert("Progress" , new int(OTodo::Progress) ); 560 m_dict.insert("Progress" , new int(OTodo::Progress) );
510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers) 561 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 562 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers) 563// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers) 564// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
514} 565}
515/* 566/*
516 * need to be const so let's fool the 567 * need to be const so let's fool the
517 * compiler :( 568 * compiler :(
518 */ 569 */
519void OTodoAccessBackendSQL::update()const { 570void OTodoAccessBackendSQL::update()const {
520 ((OTodoAccessBackendSQL*)this)->m_dirty = false; 571 ((OTodoAccessBackendSQL*)this)->m_dirty = false;
521 LoadQuery lo; 572 LoadQuery lo;
522 OSQLResult res = m_driver->query(&lo); 573 OSQLResult res = m_driver->query(&lo);
523 if ( res.state() != OSQLResult::Success ) 574 if ( res.state() != OSQLResult::Success )
524 return; 575 return;
525 576
526 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); 577 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res );
527} 578}
528QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 579QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
529 580
530 OSQLResultItem::ValueList list = res.results(); 581 OSQLResultItem::ValueList list = res.results();
531 OSQLResultItem::ValueList::Iterator it; 582 OSQLResultItem::ValueList::Iterator it;
532 QArray<int> ints(list.count() ); 583 QArray<int> ints(list.count() );
533 qWarning(" count = %d", list.count() ); 584 qWarning(" count = %d", list.count() );
534 585
535 int i = 0; 586 int i = 0;
536 for (it = list.begin(); it != list.end(); ++it ) { 587 for (it = list.begin(); it != list.end(); ++it ) {
537 ints[i] = (*it).data("uid").toInt(); 588 ints[i] = (*it).data("uid").toInt();
538 i++; 589 i++;
539 } 590 }
540 return ints; 591 return ints;
541} 592}
542 593
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 594QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{ 595{
545 596
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !! 597#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547 598
548#if 0 599#if 0
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,664 +1,921 @@
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:
64 ClearQuery(); 85 ClearQuery();
65 ~ClearQuery(); 86 ~ClearQuery();
66 QString query()const; 87 QString query()const;
67 88
68 }; 89 };
69 90
70 91
71 /** 92 /**
72 * LoadQuery 93 * LoadQuery
73 * this one queries for all uids 94 * this one queries for all uids
74 */ 95 */
75 class LoadQuery : public OSQLQuery { 96 class LoadQuery : public OSQLQuery {
76 public: 97 public:
77 LoadQuery(); 98 LoadQuery();
78 ~LoadQuery(); 99 ~LoadQuery();
79 QString query()const; 100 QString query()const;
80 }; 101 };
81 102
82 /** 103 /**
83 * inserts/adds a OContact to the table 104 * inserts/adds a OContact to the table
84 */ 105 */
85 class InsertQuery : public OSQLQuery { 106 class InsertQuery : public OSQLQuery {
86 public: 107 public:
87 InsertQuery(const OContact& ); 108 InsertQuery(const OContact& );
88 ~InsertQuery(); 109 ~InsertQuery();
89 QString query()const; 110 QString query()const;
90 private: 111 private:
91 OContact m_contact; 112 OContact m_contact;
92 }; 113 };
93 114
94 115
95 /** 116 /**
96 * removes one from the table 117 * removes one from the table
97 */ 118 */
98 class RemoveQuery : public OSQLQuery { 119 class RemoveQuery : public OSQLQuery {
99 public: 120 public:
100 RemoveQuery(int uid ); 121 RemoveQuery(int uid );
101 ~RemoveQuery(); 122 ~RemoveQuery();
102 QString query()const; 123 QString query()const;
103 private: 124 private:
104 int m_uid; 125 int m_uid;
105 }; 126 };
106 127
107 /** 128 /**
108 * a find query for noncustom elements 129 * a find query for noncustom elements
109 */ 130 */
110 class FindQuery : public OSQLQuery { 131 class FindQuery : public OSQLQuery {
111 public: 132 public:
112 FindQuery(int uid); 133 FindQuery(int uid);
113 FindQuery(const QArray<int>& ); 134 FindQuery(const QArray<int>& );
114 ~FindQuery(); 135 ~FindQuery();
115 QString query()const; 136 QString query()const;
116 private: 137 private:
117 QString single()const; 138 QString single()const;
118 QString multi()const; 139 QString multi()const;
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();
228 addressbook_db.insert( transMap[it.key()], 314 addressbook_db.insert( transMap[it.key()],
229 QString("%1-%2-%3") 315 QString("%1-%2-%3")
230 .arg( day.year() ) 316 .arg( day.year() )
231 .arg( day.month() ) 317 .arg( day.month() )
232 .arg( day.day() ) ); 318 .arg( day.day() ) );
233 } 319 }
234 break; 320 break;
235 case Qtopia::AddressUid: // Ignore UID 321 case Qtopia::AddressUid: // Ignore UID
236 break; 322 break;
237 default: // Translate id to String 323 default: // Translate id to String
238 addressbook_db.insert( transMap[it.key()], it.data() ); 324 addressbook_db.insert( transMap[it.key()], it.data() );
239 break; 325 break;
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}
403 501
404bool OContactAccessBackend_SQL::save() 502bool OContactAccessBackend_SQL::save()
405{ 503{
406 return m_driver->close(); 504 return m_driver->close();
407} 505}
408 506
409 507
410void OContactAccessBackend_SQL::clear () 508void OContactAccessBackend_SQL::clear ()
411{ 509{
412 ClearQuery cle; 510 ClearQuery cle;
413 OSQLResult res = m_driver->query( &cle ); 511 OSQLResult res = m_driver->query( &cle );
414 CreateQuery qu; 512 CreateQuery qu;
415 res = m_driver->query(&qu); 513 res = m_driver->query(&qu);
416} 514}
417 515
418bool OContactAccessBackend_SQL::wasChangedExternally() 516bool OContactAccessBackend_SQL::wasChangedExternally()
419{ 517{
420 return false; 518 return false;
421} 519}
422 520
423QArray<int> OContactAccessBackend_SQL::allRecords() const 521QArray<int> OContactAccessBackend_SQL::allRecords() const
424{ 522{
425 523
426 // FIXME: Think about cute handling of changed tables.. 524 // FIXME: Think about cute handling of changed tables..
427 // Thus, we don't have to call update here... 525 // Thus, we don't have to call update here...
428 if ( m_changed ) 526 if ( m_changed )
429 ((OContactAccessBackend_SQL*)this)->update(); 527 ((OContactAccessBackend_SQL*)this)->update();
430 528
431 return m_uids; 529 return m_uids;
432} 530}
433 531
434bool OContactAccessBackend_SQL::add ( const OContact &newcontact ) 532bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
435{ 533{
436 InsertQuery ins( newcontact ); 534 InsertQuery ins( newcontact );
437 OSQLResult res = m_driver->query( &ins ); 535 OSQLResult res = m_driver->query( &ins );
438 536
439 if ( res.state() == OSQLResult::Failure ) 537 if ( res.state() == OSQLResult::Failure )
440 return false; 538 return false;
441 539
442 int c = m_uids.count(); 540 int c = m_uids.count();
443 m_uids.resize( c+1 ); 541 m_uids.resize( c+1 );
444 m_uids[c] = newcontact.uid(); 542 m_uids[c] = newcontact.uid();
445 543
446 return true; 544 return true;
447} 545}
448 546
449 547
450bool OContactAccessBackend_SQL::remove ( int uid ) 548bool OContactAccessBackend_SQL::remove ( int uid )
451{ 549{
452 RemoveQuery rem( uid ); 550 RemoveQuery rem( uid );
453 OSQLResult res = m_driver->query(&rem ); 551 OSQLResult res = m_driver->query(&rem );
454 552
455 if ( res.state() == OSQLResult::Failure ) 553 if ( res.state() == OSQLResult::Failure )
456 return false; 554 return false;
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();
603 858
604 OSQLResultItem::ValueList list = res_noncustom.results(); 859 OSQLResultItem::ValueList list = res_noncustom.results();
605 OSQLResultItem::ValueList::Iterator it = list.begin(); 860 OSQLResultItem::ValueList::Iterator it = list.begin();
606 for ( ; it != list.end(); ++it ) { 861 for ( ; it != list.end(); ++it ) {
607 if ( (*it).data("type") != "" ){ 862 if ( (*it).data("type") != "" ){
608 int typeId = translateMap[(*it).data( "type" )]; 863 int typeId = translateMap[(*it).data( "type" )];
609 switch( typeId ){ 864 switch( typeId ){
610 case Qtopia::Birthday: 865 case Qtopia::Birthday:
611 case Qtopia::Anniversary:{ 866 case Qtopia::Anniversary:{
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
@@ -25,569 +25,627 @@ namespace {
25 class CreateQuery : public OSQLQuery { 25 class CreateQuery : public OSQLQuery {
26 public: 26 public:
27 CreateQuery(); 27 CreateQuery();
28 ~CreateQuery(); 28 ~CreateQuery();
29 QString query()const; 29 QString query()const;
30 }; 30 };
31 31
32 /** 32 /**
33 * LoadQuery 33 * LoadQuery
34 * this one queries for all uids 34 * this one queries for all uids
35 */ 35 */
36 class LoadQuery : public OSQLQuery { 36 class LoadQuery : public OSQLQuery {
37 public: 37 public:
38 LoadQuery(); 38 LoadQuery();
39 ~LoadQuery(); 39 ~LoadQuery();
40 QString query()const; 40 QString query()const;
41 }; 41 };
42 42
43 /** 43 /**
44 * inserts/adds a OTodo to the table 44 * inserts/adds a OTodo to the table
45 */ 45 */
46 class InsertQuery : public OSQLQuery { 46 class InsertQuery : public OSQLQuery {
47 public: 47 public:
48 InsertQuery(const OTodo& ); 48 InsertQuery(const OTodo& );
49 ~InsertQuery(); 49 ~InsertQuery();
50 QString query()const; 50 QString query()const;
51 private: 51 private:
52 OTodo m_todo; 52 OTodo m_todo;
53 }; 53 };
54 54
55 /** 55 /**
56 * removes one from the table 56 * removes one from the table
57 */ 57 */
58 class RemoveQuery : public OSQLQuery { 58 class RemoveQuery : public OSQLQuery {
59 public: 59 public:
60 RemoveQuery(int uid ); 60 RemoveQuery(int uid );
61 ~RemoveQuery(); 61 ~RemoveQuery();
62 QString query()const; 62 QString query()const;
63 private: 63 private:
64 int m_uid; 64 int m_uid;
65 }; 65 };
66 66
67 /** 67 /**
68 * Clears (delete) a Table 68 * Clears (delete) a Table
69 */ 69 */
70 class ClearQuery : public OSQLQuery { 70 class ClearQuery : public OSQLQuery {
71 public: 71 public:
72 ClearQuery(); 72 ClearQuery();
73 ~ClearQuery(); 73 ~ClearQuery();
74 QString query()const; 74 QString query()const;
75 75
76 }; 76 };
77 77
78 /** 78 /**
79 * a find query 79 * a find query
80 */ 80 */
81 class FindQuery : public OSQLQuery { 81 class FindQuery : public OSQLQuery {
82 public: 82 public:
83 FindQuery(int uid); 83 FindQuery(int uid);
84 FindQuery(const QArray<int>& ); 84 FindQuery(const QArray<int>& );
85 ~FindQuery(); 85 ~FindQuery();
86 QString query()const; 86 QString query()const;
87 private: 87 private:
88 QString single()const; 88 QString single()const;
89 QString multi()const; 89 QString multi()const;
90 QArray<int> m_uids; 90 QArray<int> m_uids;
91 int m_uid; 91 int m_uid;
92 }; 92 };
93 93
94 /** 94 /**
95 * overdue query 95 * overdue query
96 */ 96 */
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 }
226 QString EffQuery::with()const { 261 QString EffQuery::with()const {
227 QString str; 262 QString str;
228 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 263 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
229 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 264 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
230 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 265 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
231 return str; 266 return str;
232 } 267 }
233 QString EffQuery::out()const { 268 QString EffQuery::out()const {
234 QString str; 269 QString str;
235 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 270 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
236 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 271 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
237 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 272 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
238 273
239 return str; 274 return str;
240 } 275 }
241}; 276};
242 277
243OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 278OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
244 : OTodoAccessBackend(), m_dict(15), m_dirty(true) 279 : OTodoAccessBackend(), m_dict(15), m_dirty(true)
245{ 280{
246 QString fi = file; 281 QString fi = file;
247 if ( fi.isEmpty() ) 282 if ( fi.isEmpty() )
248 fi = Global::applicationFileName( "todolist", "todolist.db" ); 283 fi = Global::applicationFileName( "todolist", "todolist.db" );
249 OSQLManager man; 284 OSQLManager man;
250 m_driver = man.standard(); 285 m_driver = man.standard();
251 m_driver->setUrl(fi); 286 m_driver->setUrl(fi);
252 // fillDict(); 287 // fillDict();
253} 288}
254 289
255OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 290OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
256} 291}
257bool OTodoAccessBackendSQL::load(){ 292bool OTodoAccessBackendSQL::load(){
258 if (!m_driver->open() ) 293 if (!m_driver->open() )
259 return false; 294 return false;
260 295
261 CreateQuery creat; 296 CreateQuery creat;
262 OSQLResult res = m_driver->query(&creat ); 297 OSQLResult res = m_driver->query(&creat );
263 298
264 m_dirty = true; 299 m_dirty = true;
265 return true; 300 return true;
266} 301}
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 );
316 FindQuery query( search ); 351 FindQuery query( search );
317 OSQLResult res = m_driver->query( &query ); 352 OSQLResult res = m_driver->query( &query );
318 if ( res.state() != OSQLResult::Success ) 353 if ( res.state() != OSQLResult::Success )
319 return to; 354 return to;
320 355
321 return todo( res ); 356 return todo( res );
322} 357}
323void OTodoAccessBackendSQL::clear() { 358void OTodoAccessBackendSQL::clear() {
324 ClearQuery cle; 359 ClearQuery cle;
325 OSQLResult res = m_driver->query( &cle ); 360 OSQLResult res = m_driver->query( &cle );
326 CreateQuery qu; 361 CreateQuery qu;
327 res = m_driver->query(&qu); 362 res = m_driver->query(&qu);
328} 363}
329bool OTodoAccessBackendSQL::add( const OTodo& t) { 364bool OTodoAccessBackendSQL::add( const OTodo& t) {
330 InsertQuery ins( t ); 365 InsertQuery ins( t );
331 OSQLResult res = m_driver->query( &ins ); 366 OSQLResult res = m_driver->query( &ins );
332 367
333 if ( res.state() == OSQLResult::Failure ) 368 if ( res.state() == OSQLResult::Failure )
334 return false; 369 return false;
335 int c = m_uids.count(); 370 int c = m_uids.count();
336 m_uids.resize( c+1 ); 371 m_uids.resize( c+1 );
337 m_uids[c] = t.uid(); 372 m_uids[c] = t.uid();
338 373
339 return true; 374 return true;
340} 375}
341bool OTodoAccessBackendSQL::remove( int uid ) { 376bool OTodoAccessBackendSQL::remove( int uid ) {
342 RemoveQuery rem( uid ); 377 RemoveQuery rem( uid );
343 OSQLResult res = m_driver->query(&rem ); 378 OSQLResult res = m_driver->query(&rem );
344 379
345 if ( res.state() == OSQLResult::Failure ) 380 if ( res.state() == OSQLResult::Failure )
346 return false; 381 return false;
347 382
348 m_dirty = true; 383 m_dirty = true;
349 return true; 384 return true;
350} 385}
351/* 386/*
352 * FIXME better set query 387 * FIXME better set query
353 * but we need the cache for that 388 * but we need the cache for that
354 * now we remove 389 * now we remove
355 */ 390 */
356bool OTodoAccessBackendSQL::replace( const OTodo& t) { 391bool OTodoAccessBackendSQL::replace( const OTodo& t) {
357 remove( t.uid() ); 392 remove( t.uid() );
358 bool b= add(t); 393 bool b= add(t);
359 m_dirty = false; // we changed some stuff but the UID stayed the same 394 m_dirty = false; // we changed some stuff but the UID stayed the same
360 return b; 395 return b;
361} 396}
362QArray<int> OTodoAccessBackendSQL::overDue() { 397QArray<int> OTodoAccessBackendSQL::overDue() {
363 OverDueQuery qu; 398 OverDueQuery qu;
364 return uids( m_driver->query(&qu ) ); 399 return uids( m_driver->query(&qu ) );
365} 400}
366QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 401QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
367 const QDate& t, 402 const QDate& t,
368 bool u) { 403 bool u) {
369 EffQuery ef(s, t, u ); 404 EffQuery ef(s, t, u );
370 return uids (m_driver->query(&ef) ); 405 return uids (m_driver->query(&ef) );
371} 406}
372/* 407/*
373 * 408 *
374 */ 409 */
375QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 410QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
376 int sortFilter, int cat ) { 411 int sortFilter, int cat ) {
377 qWarning("sorted %d, %d", asc, sortOrder ); 412 qWarning("sorted %d, %d", asc, sortOrder );
378 QString query; 413 QString query;
379 query = "select uid from todolist WHERE "; 414 query = "select uid from todolist WHERE ";
380 415
381 /* 416 /*
382 * Sort Filter stuff 417 * Sort Filter stuff
383 * not that straight forward 418 * not that straight forward
384 * FIXME: Replace magic numbers 419 * FIXME: Replace magic numbers
385 * 420 *
386 */ 421 */
387 /* Category */ 422 /* Category */
388 if ( sortFilter & 1 ) { 423 if ( sortFilter & 1 ) {
389 QString str; 424 QString str;
390 if (cat != 0 ) str = QString::number( cat ); 425 if (cat != 0 ) str = QString::number( cat );
391 query += " categories like '%" +str+"%' AND"; 426 query += " categories like '%" +str+"%' AND";
392 } 427 }
393 /* Show only overdue */ 428 /* Show only overdue */
394 if ( sortFilter & 2 ) { 429 if ( sortFilter & 2 ) {
395 QDate date = QDate::currentDate(); 430 QDate date = QDate::currentDate();
396 QString due; 431 QString due;
397 QString base; 432 QString base;
398 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 433 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
399 query += " " + base + " AND"; 434 query += " " + base + " AND";
400 } 435 }
401 /* not show completed */ 436 /* not show completed */
402 if ( sortFilter & 4 ) { 437 if ( sortFilter & 4 ) {
403 query += " completed = 0 AND"; 438 query += " completed = 0 AND";
404 }else{ 439 }else{
405 query += " ( completed = 1 OR completed = 0) AND"; 440 query += " ( completed = 1 OR completed = 0) AND";
406 } 441 }
407 /* srtip the end */ 442 /* srtip the end */
408 query = query.remove( query.length()-3, 3 ); 443 query = query.remove( query.length()-3, 3 );
409 444
410 445
411 /* 446 /*
412 * sort order stuff 447 * sort order stuff
413 * quite straight forward 448 * quite straight forward
414 */ 449 */
415 query += "ORDER BY "; 450 query += "ORDER BY ";
416 switch( sortOrder ) { 451 switch( sortOrder ) {
417 /* completed */ 452 /* completed */
418 case 0: 453 case 0:
419 query += "completed"; 454 query += "completed";
420 break; 455 break;
421 case 1: 456 case 1:
422 query += "priority"; 457 query += "priority";
423 break; 458 break;
424 case 2: 459 case 2:
425 query += "summary"; 460 query += "summary";
426 break; 461 break;
427 case 3: 462 case 3:
428 query += "DueDate"; 463 query += "DueDate";
429 break; 464 break;
430 } 465 }
431 466
432 if ( !asc ) { 467 if ( !asc ) {
433 qWarning("not ascending!"); 468 qWarning("not ascending!");
434 query += " DESC"; 469 query += " DESC";
435 } 470 }
436 471
437 qWarning( query ); 472 qWarning( query );
438 OSQLRawQuery raw(query ); 473 OSQLRawQuery raw(query );
439 return uids( m_driver->query(&raw) ); 474 return uids( m_driver->query(&raw) );
440} 475}
441bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 476bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
442 if ( str == "0-0-0" ) 477 if ( str == "0-0-0" )
443 return false; 478 return false;
444 else{ 479 else{
445 int day, year, month; 480 int day, year, month;
446 QStringList list = QStringList::split("-", str ); 481 QStringList list = QStringList::split("-", str );
447 year = list[0].toInt(); 482 year = list[0].toInt();
448 month = list[1].toInt(); 483 month = list[1].toInt();
449 day = list[2].toInt(); 484 day = list[2].toInt();
450 da.setYMD( year, month, day ); 485 da.setYMD( year, month, day );
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) );
507 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 558 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
508 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 559 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
509 m_dict.insert("Progress" , new int(OTodo::Progress) ); 560 m_dict.insert("Progress" , new int(OTodo::Progress) );
510 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers) 561 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
511 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 562 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
512// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers) 563// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
513// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers) 564// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
514} 565}
515/* 566/*
516 * need to be const so let's fool the 567 * need to be const so let's fool the
517 * compiler :( 568 * compiler :(
518 */ 569 */
519void OTodoAccessBackendSQL::update()const { 570void OTodoAccessBackendSQL::update()const {
520 ((OTodoAccessBackendSQL*)this)->m_dirty = false; 571 ((OTodoAccessBackendSQL*)this)->m_dirty = false;
521 LoadQuery lo; 572 LoadQuery lo;
522 OSQLResult res = m_driver->query(&lo); 573 OSQLResult res = m_driver->query(&lo);
523 if ( res.state() != OSQLResult::Success ) 574 if ( res.state() != OSQLResult::Success )
524 return; 575 return;
525 576
526 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); 577 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res );
527} 578}
528QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 579QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
529 580
530 OSQLResultItem::ValueList list = res.results(); 581 OSQLResultItem::ValueList list = res.results();
531 OSQLResultItem::ValueList::Iterator it; 582 OSQLResultItem::ValueList::Iterator it;
532 QArray<int> ints(list.count() ); 583 QArray<int> ints(list.count() );
533 qWarning(" count = %d", list.count() ); 584 qWarning(" count = %d", list.count() );
534 585
535 int i = 0; 586 int i = 0;
536 for (it = list.begin(); it != list.end(); ++it ) { 587 for (it = list.begin(); it != list.end(); ++it ) {
537 ints[i] = (*it).data("uid").toInt(); 588 ints[i] = (*it).data("uid").toInt();
538 i++; 589 i++;
539 } 590 }
540 return ints; 591 return ints;
541} 592}
542 593
543QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 594QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
544{ 595{
545 596
546#warning OTodoAccessBackendSQL::matchRegexp() not implemented !! 597#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
547 598
548#if 0 599#if 0
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
@@ -80,347 +80,357 @@ QStringList OContactFields::trphonefields( bool sorted )
80 80
81 list.append( mapIdToStr[Qtopia::HomePhone] ); 81 list.append( mapIdToStr[Qtopia::HomePhone] );
82 list.append( mapIdToStr[Qtopia::HomeFax] ); 82 list.append( mapIdToStr[Qtopia::HomeFax] );
83 list.append( mapIdToStr[Qtopia::HomeMobile] ); 83 list.append( mapIdToStr[Qtopia::HomeMobile] );
84 // list.append( mapIdToStr[Qtopia::HomePager] ); 84 // list.append( mapIdToStr[Qtopia::HomePager] );
85 list.append( mapIdToStr[Qtopia::HomeWebPage] ); 85 list.append( mapIdToStr[Qtopia::HomeWebPage] );
86 86
87 if (sorted) list.sort(); 87 if (sorted) list.sort();
88 88
89 return list; 89 return list;
90} 90}
91 91
92 92
93/*! 93/*!
94 \internal 94 \internal
95 Returns a list of phone field names for a contact. 95 Returns a list of phone field names for a contact.
96*/ 96*/
97QStringList OContactFields::untrphonefields( bool sorted ) 97QStringList OContactFields::untrphonefields( bool sorted )
98{ 98{
99 QStringList list; 99 QStringList list;
100 QMap<int, QString> mapIdToStr = idToUntrFields(); 100 QMap<int, QString> mapIdToStr = idToUntrFields();
101 101
102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] ); 102 list.append( mapIdToStr[ Qtopia::BusinessPhone ] );
103 list.append( mapIdToStr[ Qtopia::BusinessFax ] ); 103 list.append( mapIdToStr[ Qtopia::BusinessFax ] );
104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] ); 104 list.append( mapIdToStr[ Qtopia::BusinessMobile ] );
105 list.append( mapIdToStr[ Qtopia::BusinessPager ] ); 105 list.append( mapIdToStr[ Qtopia::BusinessPager ] );
106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] ); 106 list.append( mapIdToStr[ Qtopia::BusinessWebPage ] );
107 107
108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] ); 108 list.append( mapIdToStr[ Qtopia::DefaultEmail ] );
109 list.append( mapIdToStr[ Qtopia::Emails ] ); 109 list.append( mapIdToStr[ Qtopia::Emails ] );
110 110
111 list.append( mapIdToStr[ Qtopia::HomePhone ] ); 111 list.append( mapIdToStr[ Qtopia::HomePhone ] );
112 list.append( mapIdToStr[ Qtopia::HomeFax ] ); 112 list.append( mapIdToStr[ Qtopia::HomeFax ] );
113 list.append( mapIdToStr[ Qtopia::HomeMobile ] ); 113 list.append( mapIdToStr[ Qtopia::HomeMobile ] );
114 //list.append( mapIdToStr[Qtopia::HomePager] ); 114 //list.append( mapIdToStr[Qtopia::HomePager] );
115 list.append( mapIdToStr[Qtopia::HomeWebPage] ); 115 list.append( mapIdToStr[Qtopia::HomeWebPage] );
116 116
117 if (sorted) list.sort(); 117 if (sorted) list.sort();
118 118
119 return list; 119 return list;
120} 120}
121 121
122 122
123/*! 123/*!
124 \internal 124 \internal
125 Returns a translated list of field names for a contact. 125 Returns a translated list of field names for a contact.
126*/ 126*/
127QStringList OContactFields::trfields( bool sorted ) 127QStringList OContactFields::trfields( bool sorted )
128{ 128{
129 QStringList list; 129 QStringList list;
130 QMap<int, QString> mapIdToStr = idToTrFields(); 130 QMap<int, QString> mapIdToStr = idToTrFields();
131 131
132 list.append( mapIdToStr[Qtopia::Title]); 132 list.append( mapIdToStr[Qtopia::Title]);
133 list.append( mapIdToStr[Qtopia::FirstName] ); 133 list.append( mapIdToStr[Qtopia::FirstName] );
134 list.append( mapIdToStr[Qtopia::MiddleName] ); 134 list.append( mapIdToStr[Qtopia::MiddleName] );
135 list.append( mapIdToStr[Qtopia::LastName] ); 135 list.append( mapIdToStr[Qtopia::LastName] );
136 list.append( mapIdToStr[Qtopia::Suffix] ); 136 list.append( mapIdToStr[Qtopia::Suffix] );
137 list.append( mapIdToStr[Qtopia::FileAs] ); 137 list.append( mapIdToStr[Qtopia::FileAs] );
138 138
139 list.append( mapIdToStr[Qtopia::JobTitle] ); 139 list.append( mapIdToStr[Qtopia::JobTitle] );
140 list.append( mapIdToStr[Qtopia::Department] ); 140 list.append( mapIdToStr[Qtopia::Department] );
141 list.append( mapIdToStr[Qtopia::Company] ); 141 list.append( mapIdToStr[Qtopia::Company] );
142 142
143 list += trphonefields( sorted ); 143 list += trphonefields( sorted );
144 144
145 list.append( mapIdToStr[Qtopia::BusinessStreet] ); 145 list.append( mapIdToStr[Qtopia::BusinessStreet] );
146 list.append( mapIdToStr[Qtopia::BusinessCity] ); 146 list.append( mapIdToStr[Qtopia::BusinessCity] );
147 list.append( mapIdToStr[Qtopia::BusinessState] ); 147 list.append( mapIdToStr[Qtopia::BusinessState] );
148 list.append( mapIdToStr[Qtopia::BusinessZip] ); 148 list.append( mapIdToStr[Qtopia::BusinessZip] );
149 list.append( mapIdToStr[Qtopia::BusinessCountry] ); 149 list.append( mapIdToStr[Qtopia::BusinessCountry] );
150 150
151 list.append( mapIdToStr[Qtopia::HomeStreet] ); 151 list.append( mapIdToStr[Qtopia::HomeStreet] );
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" ) );
238 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) ); 244 ret_map.insert( Qtopia::BusinessCity, QObject::tr( "Business City" ) );
239 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) ); 245 ret_map.insert( Qtopia::BusinessState, QObject::tr( "Business State" ) );
240 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) ); 246 ret_map.insert( Qtopia::BusinessZip, QObject::tr( "Business Zip" ) );
241 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) ); 247 ret_map.insert( Qtopia::BusinessCountry, QObject::tr( "Business Country" ) );
242 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) ); 248 ret_map.insert( Qtopia::BusinessPager, QObject::tr( "Business Pager" ) );
243 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) ); 249 ret_map.insert( Qtopia::BusinessWebPage, QObject::tr( "Business WebPage" ) );
244 250
245 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) ); 251 ret_map.insert( Qtopia::Office, QObject::tr( "Office" ) );
246 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) ); 252 ret_map.insert( Qtopia::Profession, QObject::tr( "Profession" ) );
247 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) ); 253 ret_map.insert( Qtopia::Assistant, QObject::tr( "Assistant" ) );
248 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) ); 254 ret_map.insert( Qtopia::Manager, QObject::tr( "Manager" ) );
249 255
250 // home 256 // home
251 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) ); 257 ret_map.insert( Qtopia::HomeStreet, QObject::tr( "Home Street" ) );
252 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) ); 258 ret_map.insert( Qtopia::HomeCity, QObject::tr( "Home City" ) );
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" );
301 ret_map.insert( Qtopia::BusinessCity, "Business City" ); 310 ret_map.insert( Qtopia::BusinessCity, "Business City" );
302 ret_map.insert( Qtopia::BusinessState, "Business State" ); 311 ret_map.insert( Qtopia::BusinessState, "Business State" );
303 ret_map.insert( Qtopia::BusinessZip, "Business Zip" ); 312 ret_map.insert( Qtopia::BusinessZip, "Business Zip" );
304 ret_map.insert( Qtopia::BusinessCountry, "Business Country" ); 313 ret_map.insert( Qtopia::BusinessCountry, "Business Country" );
305 ret_map.insert( Qtopia::BusinessPager, "Business Pager" ); 314 ret_map.insert( Qtopia::BusinessPager, "Business Pager" );
306 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" ); 315 ret_map.insert( Qtopia::BusinessWebPage, "Business WebPage" );
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
355 365
356 QMap<int, QString>::Iterator it; 366 QMap<int, QString>::Iterator it;
357 for( it = idtostr.begin(); it != idtostr.end(); ++it ) 367 for( it = idtostr.begin(); it != idtostr.end(); ++it )
358 ret_map.insert( *it, it.key() ); 368 ret_map.insert( *it, it.key() );
359 369
360 370
361 return ret_map; 371 return ret_map;
362} 372}
363 373
364 374
365OContactFields::OContactFields(): 375OContactFields::OContactFields():
366 fieldOrder( DEFAULT_FIELD_ORDER ), 376 fieldOrder( DEFAULT_FIELD_ORDER ),
367 changedFieldOrder( false ) 377 changedFieldOrder( false )
368{ 378{
369 // Get the global field order from the config file and 379 // Get the global field order from the config file and
370 // use it as a start pattern 380 // use it as a start pattern
371 Config cfg ( "AddressBook" ); 381 Config cfg ( "AddressBook" );
372 cfg.setGroup( "ContactFieldOrder" ); 382 cfg.setGroup( "ContactFieldOrder" );
373 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER ); 383 globalFieldOrder = cfg.readEntry( "General", DEFAULT_FIELD_ORDER );
374} 384}
375 385
376OContactFields::~OContactFields(){ 386OContactFields::~OContactFields(){
377 387
378 // We will store the fieldorder into the config file 388 // We will store the fieldorder into the config file
379 // to reuse it for the future.. 389 // to reuse it for the future..
380 if ( changedFieldOrder ){ 390 if ( changedFieldOrder ){
381 Config cfg ( "AddressBook" ); 391 Config cfg ( "AddressBook" );
382 cfg.setGroup( "ContactFieldOrder" ); 392 cfg.setGroup( "ContactFieldOrder" );
383 cfg.writeEntry( "General", globalFieldOrder ); 393 cfg.writeEntry( "General", globalFieldOrder );
384 } 394 }
385} 395}
386 396
387 397
388 398
389void OContactFields::saveToRecord( OContact &cnt ){ 399void OContactFields::saveToRecord( OContact &cnt ){
390 400
391 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1()); 401 qDebug("ocontactfields saveToRecord: >%s<",fieldOrder.latin1());
392 402
393 // Store fieldorder into this contact. 403 // Store fieldorder into this contact.
394 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder ); 404 cnt.setCustomField( CONTACT_FIELD_ORDER_NAME, fieldOrder );
395 405
396 globalFieldOrder = fieldOrder; 406 globalFieldOrder = fieldOrder;
397 changedFieldOrder = true; 407 changedFieldOrder = true;
398 408
399} 409}
400 410
401void OContactFields::loadFromRecord( const OContact &cnt ){ 411void OContactFields::loadFromRecord( const OContact &cnt ){
402 qDebug("ocontactfields loadFromRecord"); 412 qDebug("ocontactfields loadFromRecord");
403 qDebug("loading >%s<",cnt.fullName().latin1()); 413 qDebug("loading >%s<",cnt.fullName().latin1());
404 414
405 // Get fieldorder for this contact. If none is defined, 415 // Get fieldorder for this contact. If none is defined,
406 // we will use the global one from the config file.. 416 // we will use the global one from the config file..
407 417
408 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME ); 418 fieldOrder = cnt.customField( CONTACT_FIELD_ORDER_NAME );
409 419
410 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1()); 420 qDebug("fieldOrder from contact>%s<",fieldOrder.latin1());
411 421
412 if (fieldOrder.isEmpty()){ 422 if (fieldOrder.isEmpty()){
413 fieldOrder = globalFieldOrder; 423 fieldOrder = globalFieldOrder;
414 } 424 }
415 425
416 426
417 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1()); 427 qDebug("effective fieldOrder in loadFromRecord >%s<",fieldOrder.latin1());
418} 428}
419 429
420void OContactFields::setFieldOrder( int num, int index ){ 430void OContactFields::setFieldOrder( int num, int index ){
421 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index); 431 qDebug("qcontactfields setfieldorder pos %i -> %i",num,index);
422 432
423 fieldOrder[num] = QString::number( index, 16 )[0]; 433 fieldOrder[num] = QString::number( index, 16 )[0];
424 434
425 // We will store this new fieldorder globally to 435 // We will store this new fieldorder globally to
426 // remember it for contacts which have none 436 // remember it for contacts which have none