summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
authorzecke <zecke>2004-03-13 19:51:45 (UTC)
committer zecke <zecke>2004-03-13 19:51:45 (UTC)
commit6d08277737e22b7a1527124623f3571969073ddf (patch) (unidiff)
tree4129e674e21df767b31299e873dd44e33a308e1b /libopie2/opiepim
parent8e28911f7199f4450ac5eef09482069f9b9caea2 (diff)
downloadopie-6d08277737e22b7a1527124623f3571969073ddf.zip
opie-6d08277737e22b7a1527124623f3571969073ddf.tar.gz
opie-6d08277737e22b7a1527124623f3571969073ddf.tar.bz2
Move XML class to internal PIM
Add namespaces!!! Opie::Core and Opie::Core::Private Opie::Net and Opie::Net::Private Opie::Ui and Opie::Ui::Private Opie::MM and Opie::MM::Private Opie::DB and Opie::DB::Private PIM classes are not yet converted because we will do other work on it as well
Diffstat (limited to 'libopie2/opiepim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/backends.pro6
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp2
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h8
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp3
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp2
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.h8
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp2
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.h12
-rw-r--r--libopie2/opiepim/core/backends/private/xmltree.cc323
-rw-r--r--libopie2/opiepim/core/backends/private/xmltree.h122
10 files changed, 476 insertions, 12 deletions
diff --git a/libopie2/opiepim/backend/backends.pro b/libopie2/opiepim/backend/backends.pro
index 4231a00..d4867ba 100644
--- a/libopie2/opiepim/backend/backends.pro
+++ b/libopie2/opiepim/backend/backends.pro
@@ -1,31 +1,33 @@
1SOURCES += core/backends/ocontactaccessbackend_sql.cpp \ 1SOURCES += core/backends/ocontactaccessbackend_sql.cpp \
2 core/backends/ocontactaccessbackend_vcard.cpp \ 2 core/backends/ocontactaccessbackend_vcard.cpp \
3 core/backends/ocontactaccessbackend_xml.cpp \ 3 core/backends/ocontactaccessbackend_xml.cpp \
4 core/backends/ocontactaccess.cpp \ 4 core/backends/ocontactaccess.cpp \
5 core/backends/odatebookaccessbackend.cpp \ 5 core/backends/odatebookaccessbackend.cpp \
6 core/backends/odatebookaccessbackend_xml.cpp \ 6 core/backends/odatebookaccessbackend_xml.cpp \
7 core/backends/otodoaccessbackend.cpp \ 7 core/backends/otodoaccessbackend.cpp \
8 core/backends/otodoaccess.cpp \ 8 core/backends/otodoaccess.cpp \
9 core/backends/otodoaccesssql.cpp \ 9 core/backends/otodoaccesssql.cpp \
10 core/backends/otodoaccessvcal.cpp \ 10 core/backends/otodoaccessvcal.cpp \
11 core/backends/otodoaccessxml.cpp \ 11 core/backends/otodoaccessxml.cpp \
12 core/backends/odatebookaccess.cpp \ 12 core/backends/odatebookaccess.cpp \
13 core/backends/odatebookaccessbackend_sql.cpp 13 core/backends/odatebookaccessbackend_sql.cpp \
14 core/backends/private/xmltree.cc
14 15
15HEADERS += core/backends/obackendfactory.h \ 16HEADERS += core/backends/obackendfactory.h \
16 core/backends/ocontactaccessbackend.h \ 17 core/backends/ocontactaccessbackend.h \
17 core/backends/ocontactaccessbackend_sql.h \ 18 core/backends/ocontactaccessbackend_sql.h \
18 core/backends/ocontactaccessbackend_vcard.h \ 19 core/backends/ocontactaccessbackend_vcard.h \
19 core/backends/ocontactaccessbackend_xml.h \ 20 core/backends/ocontactaccessbackend_xml.h \
20 core/backends/ocontactaccess.h \ 21 core/backends/ocontactaccess.h \
21 core/backends/odatebookaccessbackend.h \ 22 core/backends/odatebookaccessbackend.h \
22 core/backends/odatebookaccessbackend_sql.h \ 23 core/backends/odatebookaccessbackend_sql.h \
23 core/backends/odatebookaccessbackend_xml.h \ 24 core/backends/odatebookaccessbackend_xml.h \
24 core/backends/opimaccessbackend.h \ 25 core/backends/opimaccessbackend.h \
25 core/backends/opimaccesstemplate.h \ 26 core/backends/opimaccesstemplate.h \
26 core/backends/otodoaccessbackend.h \ 27 core/backends/otodoaccessbackend.h \
27 core/backends/otodoaccess.h \ 28 core/backends/otodoaccess.h \
28 core/backends/otodoaccesssql.h \ 29 core/backends/otodoaccesssql.h \
29 core/backends/otodoaccessvcal.h \ 30 core/backends/otodoaccessvcal.h \
30 core/backends/otodoaccessxml.h \ 31 core/backends/otodoaccessxml.h \
31 core/backends/odatebookaccess.h 32 core/backends/odatebookaccess.h \
33 core/backends/private/xmltree.h
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index f121cc2..d16d692 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -1,935 +1,935 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Contact Database. 30 * SQL Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#include "ocontactaccessbackend_sql.h" 33#include "ocontactaccessbackend_sql.h"
34 34
35#include <qarray.h> 35#include <qarray.h>
36#include <qdatetime.h> 36#include <qdatetime.h>
37#include <qstringlist.h> 37#include <qstringlist.h>
38 38
39#include <qpe/global.h> 39#include <qpe/global.h>
40#include <qpe/recordfields.h> 40#include <qpe/recordfields.h>
41 41
42#include <opie2/opimcontactfields.h> 42#include <opie2/opimcontactfields.h>
43#include <opie2/opimdateconversion.h> 43#include <opie2/opimdateconversion.h>
44#include <opie2/osqldriver.h> 44#include <opie2/osqldriver.h>
45#include <opie2/osqlresult.h> 45#include <opie2/osqlresult.h>
46#include <opie2/osqlmanager.h> 46#include <opie2/osqlmanager.h>
47#include <opie2/osqlquery.h> 47#include <opie2/osqlquery.h>
48 48
49 49using namespace Opie::DB;
50 50
51 51
52// If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead 52// If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead
53// vertical like "uid, type, value". 53// vertical like "uid, type, value".
54// DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !! 54// DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !!
55#define __STORE_HORIZONTAL_ 55#define __STORE_HORIZONTAL_
56 56
57// Distinct loading is not very fast. If I expect that every person has just 57// Distinct loading is not very fast. If I expect that every person has just
58// one (and always one) 'Last Name', I can request all uid's for existing lastnames, 58// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
59// which is faster.. 59// which is faster..
60// But this may not be true for all entries, like company contacts.. 60// But this may not be true for all entries, like company contacts..
61// The current AddressBook application handles this problem, but other may not.. (eilers) 61// The current AddressBook application handles this problem, but other may not.. (eilers)
62#define __USE_SUPERFAST_LOADQUERY 62#define __USE_SUPERFAST_LOADQUERY
63 63
64 64
65/* 65/*
66 * Implementation of used query types 66 * Implementation of used query types
67 * CREATE query 67 * CREATE query
68 * LOAD query 68 * LOAD query
69 * INSERT 69 * INSERT
70 * REMOVE 70 * REMOVE
71 * CLEAR 71 * CLEAR
72 */ 72 */
73namespace Opie { 73namespace Opie {
74 /** 74 /**
75 * CreateQuery for the Todolist Table 75 * CreateQuery for the Todolist Table
76 */ 76 */
77 class CreateQuery : public OSQLQuery { 77 class CreateQuery : public OSQLQuery {
78 public: 78 public:
79 CreateQuery(); 79 CreateQuery();
80 ~CreateQuery(); 80 ~CreateQuery();
81 QString query()const; 81 QString query()const;
82 }; 82 };
83 83
84 /** 84 /**
85 * Clears (delete) a Table 85 * Clears (delete) a Table
86 */ 86 */
87 class ClearQuery : public OSQLQuery { 87 class ClearQuery : public OSQLQuery {
88 public: 88 public:
89 ClearQuery(); 89 ClearQuery();
90 ~ClearQuery(); 90 ~ClearQuery();
91 QString query()const; 91 QString query()const;
92 92
93 }; 93 };
94 94
95 95
96 /** 96 /**
97 * LoadQuery 97 * LoadQuery
98 * this one queries for all uids 98 * this one queries for all uids
99 */ 99 */
100 class LoadQuery : public OSQLQuery { 100 class LoadQuery : public OSQLQuery {
101 public: 101 public:
102 LoadQuery(); 102 LoadQuery();
103 ~LoadQuery(); 103 ~LoadQuery();
104 QString query()const; 104 QString query()const;
105 }; 105 };
106 106
107 /** 107 /**
108 * inserts/adds a OPimContact to the table 108 * inserts/adds a OPimContact to the table
109 */ 109 */
110 class InsertQuery : public OSQLQuery { 110 class InsertQuery : public OSQLQuery {
111 public: 111 public:
112 InsertQuery(const OPimContact& ); 112 InsertQuery(const OPimContact& );
113 ~InsertQuery(); 113 ~InsertQuery();
114 QString query()const; 114 QString query()const;
115 private: 115 private:
116 OPimContact m_contact; 116 OPimContact m_contact;
117 }; 117 };
118 118
119 119
120 /** 120 /**
121 * removes one from the table 121 * removes one from the table
122 */ 122 */
123 class RemoveQuery : public OSQLQuery { 123 class RemoveQuery : public OSQLQuery {
124 public: 124 public:
125 RemoveQuery(int uid ); 125 RemoveQuery(int uid );
126 ~RemoveQuery(); 126 ~RemoveQuery();
127 QString query()const; 127 QString query()const;
128 private: 128 private:
129 int m_uid; 129 int m_uid;
130 }; 130 };
131 131
132 /** 132 /**
133 * a find query for noncustom elements 133 * a find query for noncustom elements
134 */ 134 */
135 class FindQuery : public OSQLQuery { 135 class FindQuery : public OSQLQuery {
136 public: 136 public:
137 FindQuery(int uid); 137 FindQuery(int uid);
138 FindQuery(const QArray<int>& ); 138 FindQuery(const QArray<int>& );
139 ~FindQuery(); 139 ~FindQuery();
140 QString query()const; 140 QString query()const;
141 private: 141 private:
142 QString single()const; 142 QString single()const;
143 QString multi()const; 143 QString multi()const;
144 QArray<int> m_uids; 144 QArray<int> m_uids;
145 int m_uid; 145 int m_uid;
146 }; 146 };
147 147
148 /** 148 /**
149 * a find query for custom elements 149 * a find query for custom elements
150 */ 150 */
151 class FindCustomQuery : public OSQLQuery { 151 class FindCustomQuery : public OSQLQuery {
152 public: 152 public:
153 FindCustomQuery(int uid); 153 FindCustomQuery(int uid);
154 FindCustomQuery(const QArray<int>& ); 154 FindCustomQuery(const QArray<int>& );
155 ~FindCustomQuery(); 155 ~FindCustomQuery();
156 QString query()const; 156 QString query()const;
157 private: 157 private:
158 QString single()const; 158 QString single()const;
159 QString multi()const; 159 QString multi()const;
160 QArray<int> m_uids; 160 QArray<int> m_uids;
161 int m_uid; 161 int m_uid;
162 }; 162 };
163 163
164 164
165 165
166 // We using three tables to store the information: 166 // We using three tables to store the information:
167 // 1. addressbook : It contains General information about the contact (non custom) 167 // 1. addressbook : It contains General information about the contact (non custom)
168 // 2. custom_data : Not official supported entries 168 // 2. custom_data : Not official supported entries
169 // All tables are connected by the uid of the contact. 169 // All tables are connected by the uid of the contact.
170 // Maybe I should add a table for meta-information ? 170 // Maybe I should add a table for meta-information ?
171 CreateQuery::CreateQuery() : OSQLQuery() {} 171 CreateQuery::CreateQuery() : OSQLQuery() {}
172 CreateQuery::~CreateQuery() {} 172 CreateQuery::~CreateQuery() {}
173 QString CreateQuery::query()const { 173 QString CreateQuery::query()const {
174 QString qu; 174 QString qu;
175#ifdef __STORE_HORIZONTAL_ 175#ifdef __STORE_HORIZONTAL_
176 176
177 qu += "create table addressbook( uid PRIMARY KEY "; 177 qu += "create table addressbook( uid PRIMARY KEY ";
178 178
179 QStringList fieldList = OPimContactFields::untrfields( false ); 179 QStringList fieldList = OPimContactFields::untrfields( false );
180 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 180 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
181 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); 181 qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it );
182 } 182 }
183 qu += " );"; 183 qu += " );";
184 184
185 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 185 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
186 186
187#else 187#else
188 188
189 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));"; 189 qu += "create table addressbook( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id));";
190 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 190 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
191 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );"; 191 // qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
192 192
193#endif // __STORE_HORIZONTAL_ 193#endif // __STORE_HORIZONTAL_
194 return qu; 194 return qu;
195 } 195 }
196 196
197 ClearQuery::ClearQuery() 197 ClearQuery::ClearQuery()
198 : OSQLQuery() {} 198 : OSQLQuery() {}
199 ClearQuery::~ClearQuery() {} 199 ClearQuery::~ClearQuery() {}
200 QString ClearQuery::query()const { 200 QString ClearQuery::query()const {
201 QString qu = "drop table addressbook;"; 201 QString qu = "drop table addressbook;";
202 qu += "drop table custom_data;"; 202 qu += "drop table custom_data;";
203 // qu += "drop table dates;"; 203 // qu += "drop table dates;";
204 return qu; 204 return qu;
205 } 205 }
206 206
207 207
208 LoadQuery::LoadQuery() : OSQLQuery() {} 208 LoadQuery::LoadQuery() : OSQLQuery() {}
209 LoadQuery::~LoadQuery() {} 209 LoadQuery::~LoadQuery() {}
210 QString LoadQuery::query()const { 210 QString LoadQuery::query()const {
211 QString qu; 211 QString qu;
212#ifdef __STORE_HORIZONTAL_ 212#ifdef __STORE_HORIZONTAL_
213 qu += "select uid from addressbook"; 213 qu += "select uid from addressbook";
214#else 214#else
215# ifndef __USE_SUPERFAST_LOADQUERY 215# ifndef __USE_SUPERFAST_LOADQUERY
216 qu += "select distinct uid from addressbook"; 216 qu += "select distinct uid from addressbook";
217# else 217# else
218 qu += "select uid from addressbook where type = 'Last Name'"; 218 qu += "select uid from addressbook where type = 'Last Name'";
219# endif // __USE_SUPERFAST_LOADQUERY 219# endif // __USE_SUPERFAST_LOADQUERY
220#endif // __STORE_HORIZONTAL_ 220#endif // __STORE_HORIZONTAL_
221 221
222 return qu; 222 return qu;
223 } 223 }
224 224
225 225
226 InsertQuery::InsertQuery( const OPimContact& contact ) 226 InsertQuery::InsertQuery( const OPimContact& contact )
227 : OSQLQuery(), m_contact( contact ) { 227 : OSQLQuery(), m_contact( contact ) {
228 } 228 }
229 229
230 InsertQuery::~InsertQuery() { 230 InsertQuery::~InsertQuery() {
231 } 231 }
232 232
233 /* 233 /*
234 * converts from a OPimContact to a query 234 * converts from a OPimContact to a query
235 */ 235 */
236 QString InsertQuery::query()const{ 236 QString InsertQuery::query()const{
237 237
238#ifdef __STORE_HORIZONTAL_ 238#ifdef __STORE_HORIZONTAL_
239 QString qu; 239 QString qu;
240 qu += "insert into addressbook VALUES( " + 240 qu += "insert into addressbook VALUES( " +
241 QString::number( m_contact.uid() ); 241 QString::number( m_contact.uid() );
242 242
243 // Get all information out of the contact-class 243 // Get all information out of the contact-class
244 // Remember: The category is stored in contactMap, too ! 244 // Remember: The category is stored in contactMap, too !
245 QMap<int, QString> contactMap = m_contact.toMap(); 245 QMap<int, QString> contactMap = m_contact.toMap();
246 246
247 QStringList fieldList = OPimContactFields::untrfields( false ); 247 QStringList fieldList = OPimContactFields::untrfields( false );
248 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 248 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
249 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 249 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
250 // Convert Column-String to Id and get value for this id.. 250 // Convert Column-String to Id and get value for this id..
251 // Hmmm.. Maybe not very cute solution.. 251 // Hmmm.. Maybe not very cute solution..
252 int id = translate[*it]; 252 int id = translate[*it];
253 switch ( id ){ 253 switch ( id ){
254 case Qtopia::Birthday:{ 254 case Qtopia::Birthday:{
255 // These entries should stored in a special format 255 // These entries should stored in a special format
256 // year-month-day 256 // year-month-day
257 QDate day = m_contact.birthday(); 257 QDate day = m_contact.birthday();
258 if ( day.isValid() ){ 258 if ( day.isValid() ){
259 qu += QString(",\"%1-%2-%3\"") 259 qu += QString(",\"%1-%2-%3\"")
260 .arg( day.year() ) 260 .arg( day.year() )
261 .arg( day.month() ) 261 .arg( day.month() )
262 .arg( day.day() ); 262 .arg( day.day() );
263 } else { 263 } else {
264 qu += ",\"\""; 264 qu += ",\"\"";
265 } 265 }
266 } 266 }
267 break; 267 break;
268 case Qtopia::Anniversary:{ 268 case Qtopia::Anniversary:{
269 // These entries should stored in a special format 269 // These entries should stored in a special format
270 // year-month-day 270 // year-month-day
271 QDate day = m_contact.anniversary(); 271 QDate day = m_contact.anniversary();
272 if ( day.isValid() ){ 272 if ( day.isValid() ){
273 qu += QString(",\"%1-%2-%3\"") 273 qu += QString(",\"%1-%2-%3\"")
274 .arg( day.year() ) 274 .arg( day.year() )
275 .arg( day.month() ) 275 .arg( day.month() )
276 .arg( day.day() ); 276 .arg( day.day() );
277 } else { 277 } else {
278 qu += ",\"\""; 278 qu += ",\"\"";
279 } 279 }
280 } 280 }
281 break; 281 break;
282 282
283 default: 283 default:
284 qu += QString( ",\"%1\"" ).arg( contactMap[id] ); 284 qu += QString( ",\"%1\"" ).arg( contactMap[id] );
285 } 285 }
286 } 286 }
287 qu += " );"; 287 qu += " );";
288 288
289 289
290#else 290#else
291 // Get all information out of the contact-class 291 // Get all information out of the contact-class
292 // Remember: The category is stored in contactMap, too ! 292 // Remember: The category is stored in contactMap, too !
293 QMap<int, QString> contactMap = m_contact.toMap(); 293 QMap<int, QString> contactMap = m_contact.toMap();
294 294
295 QMap<QString, QString> addressbook_db; 295 QMap<QString, QString> addressbook_db;
296 296
297 // Get the translation from the ID to the String 297 // Get the translation from the ID to the String
298 QMap<int, QString> transMap = OPimContactFields::idToUntrFields(); 298 QMap<int, QString> transMap = OPimContactFields::idToUntrFields();
299 299
300 for( QMap<int, QString>::Iterator it = contactMap.begin(); 300 for( QMap<int, QString>::Iterator it = contactMap.begin();
301 it != contactMap.end(); ++it ){ 301 it != contactMap.end(); ++it ){
302 switch ( it.key() ){ 302 switch ( it.key() ){
303 case Qtopia::Birthday:{ 303 case Qtopia::Birthday:{
304 // These entries should stored in a special format 304 // These entries should stored in a special format
305 // year-month-day 305 // year-month-day
306 QDate day = m_contact.birthday(); 306 QDate day = m_contact.birthday();
307 addressbook_db.insert( transMap[it.key()], 307 addressbook_db.insert( transMap[it.key()],
308 QString("%1-%2-%3") 308 QString("%1-%2-%3")
309 .arg( day.year() ) 309 .arg( day.year() )
310 .arg( day.month() ) 310 .arg( day.month() )
311 .arg( day.day() ) ); 311 .arg( day.day() ) );
312 } 312 }
313 break; 313 break;
314 case Qtopia::Anniversary:{ 314 case Qtopia::Anniversary:{
315 // These entries should stored in a special format 315 // These entries should stored in a special format
316 // year-month-day 316 // year-month-day
317 QDate day = m_contact.anniversary(); 317 QDate day = m_contact.anniversary();
318 addressbook_db.insert( transMap[it.key()], 318 addressbook_db.insert( transMap[it.key()],
319 QString("%1-%2-%3") 319 QString("%1-%2-%3")
320 .arg( day.year() ) 320 .arg( day.year() )
321 .arg( day.month() ) 321 .arg( day.month() )
322 .arg( day.day() ) ); 322 .arg( day.day() ) );
323 } 323 }
324 break; 324 break;
325 case Qtopia::AddressUid: // Ignore UID 325 case Qtopia::AddressUid: // Ignore UID
326 break; 326 break;
327 default: // Translate id to String 327 default: // Translate id to String
328 addressbook_db.insert( transMap[it.key()], it.data() ); 328 addressbook_db.insert( transMap[it.key()], it.data() );
329 break; 329 break;
330 } 330 }
331 331
332 } 332 }
333 333
334 // Now convert this whole stuff into a SQL String, beginning with 334 // Now convert this whole stuff into a SQL String, beginning with
335 // the addressbook table.. 335 // the addressbook table..
336 QString qu; 336 QString qu;
337 // qu += "begin transaction;"; 337 // qu += "begin transaction;";
338 int id = 0; 338 int id = 0;
339 for( QMap<QString, QString>::Iterator it = addressbook_db.begin(); 339 for( QMap<QString, QString>::Iterator it = addressbook_db.begin();
340 it != addressbook_db.end(); ++it ){ 340 it != addressbook_db.end(); ++it ){
341 qu += "insert into addressbook VALUES(" 341 qu += "insert into addressbook VALUES("
342 + QString::number( m_contact.uid() ) 342 + QString::number( m_contact.uid() )
343 + "," 343 + ","
344 + QString::number( id++ ) 344 + QString::number( id++ )
345 + ",'" 345 + ",'"
346 + it.key() //.latin1() 346 + it.key() //.latin1()
347 + "'," 347 + "',"
348 + "0" // Priority for future enhancements 348 + "0" // Priority for future enhancements
349 + ",'" 349 + ",'"
350 + it.data() //.latin1() 350 + it.data() //.latin1()
351 + "');"; 351 + "');";
352 } 352 }
353 353
354 #endif //__STORE_HORIZONTAL_ 354 #endif //__STORE_HORIZONTAL_
355 // Now add custom data.. 355 // Now add custom data..
356#ifdef __STORE_HORIZONTAL_ 356#ifdef __STORE_HORIZONTAL_
357 int id = 0; 357 int id = 0;
358#endif 358#endif
359 id = 0; 359 id = 0;
360 QMap<QString, QString> customMap = m_contact.toExtraMap(); 360 QMap<QString, QString> customMap = m_contact.toExtraMap();
361 for( QMap<QString, QString>::Iterator it = customMap.begin(); 361 for( QMap<QString, QString>::Iterator it = customMap.begin();
362 it != customMap.end(); ++it ){ 362 it != customMap.end(); ++it ){
363 qu += "insert into custom_data VALUES(" 363 qu += "insert into custom_data VALUES("
364 + QString::number( m_contact.uid() ) 364 + QString::number( m_contact.uid() )
365 + "," 365 + ","
366 + QString::number( id++ ) 366 + QString::number( id++ )
367 + ",'" 367 + ",'"
368 + it.key() //.latin1() 368 + it.key() //.latin1()
369 + "'," 369 + "',"
370 + "0" // Priority for future enhancements 370 + "0" // Priority for future enhancements
371 + ",'" 371 + ",'"
372 + it.data() //.latin1() 372 + it.data() //.latin1()
373 + "');"; 373 + "');";
374 } 374 }
375 // qu += "commit;"; 375 // qu += "commit;";
376 qWarning("add %s", qu.latin1() ); 376 qWarning("add %s", qu.latin1() );
377 return qu; 377 return qu;
378 } 378 }
379 379
380 380
381 RemoveQuery::RemoveQuery(int uid ) 381 RemoveQuery::RemoveQuery(int uid )
382 : OSQLQuery(), m_uid( uid ) {} 382 : OSQLQuery(), m_uid( uid ) {}
383 RemoveQuery::~RemoveQuery() {} 383 RemoveQuery::~RemoveQuery() {}
384 QString RemoveQuery::query()const { 384 QString RemoveQuery::query()const {
385 QString qu = "DELETE from addressbook where uid = " 385 QString qu = "DELETE from addressbook where uid = "
386 + QString::number(m_uid) + ";"; 386 + QString::number(m_uid) + ";";
387 qu += "DELETE from custom_data where uid = " 387 qu += "DELETE from custom_data where uid = "
388 + QString::number(m_uid) + ";"; 388 + QString::number(m_uid) + ";";
389 return qu; 389 return qu;
390 } 390 }
391 391
392 392
393 393
394 394
395 FindQuery::FindQuery(int uid) 395 FindQuery::FindQuery(int uid)
396 : OSQLQuery(), m_uid( uid ) { 396 : OSQLQuery(), m_uid( uid ) {
397 } 397 }
398 FindQuery::FindQuery(const QArray<int>& ints) 398 FindQuery::FindQuery(const QArray<int>& ints)
399 : OSQLQuery(), m_uids( ints ){ 399 : OSQLQuery(), m_uids( ints ){
400 } 400 }
401 FindQuery::~FindQuery() { 401 FindQuery::~FindQuery() {
402 } 402 }
403 QString FindQuery::query()const{ 403 QString FindQuery::query()const{
404 // if ( m_uids.count() == 0 ) 404 // if ( m_uids.count() == 0 )
405 return single(); 405 return single();
406 } 406 }
407 /* 407 /*
408 else 408 else
409 return multi(); 409 return multi();
410 } 410 }
411 QString FindQuery::multi()const { 411 QString FindQuery::multi()const {
412 QString qu = "select uid, type, value from addressbook where"; 412 QString qu = "select uid, type, value from addressbook where";
413 for (uint i = 0; i < m_uids.count(); i++ ) { 413 for (uint i = 0; i < m_uids.count(); i++ ) {
414 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 414 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
415 } 415 }
416 qu.remove( qu.length()-2, 2 ); // Hmmmm.. 416 qu.remove( qu.length()-2, 2 ); // Hmmmm..
417 return qu; 417 return qu;
418 } 418 }
419 */ 419 */
420#ifdef __STORE_HORIZONTAL_ 420#ifdef __STORE_HORIZONTAL_
421 QString FindQuery::single()const{ 421 QString FindQuery::single()const{
422 QString qu = "select *"; 422 QString qu = "select *";
423 qu += " from addressbook where uid = " + QString::number(m_uid); 423 qu += " from addressbook where uid = " + QString::number(m_uid);
424 424
425 // qWarning("find query: %s", qu.latin1() ); 425 // qWarning("find query: %s", qu.latin1() );
426 return qu; 426 return qu;
427 } 427 }
428#else 428#else
429 QString FindQuery::single()const{ 429 QString FindQuery::single()const{
430 QString qu = "select uid, type, value from addressbook where uid = "; 430 QString qu = "select uid, type, value from addressbook where uid = ";
431 qu += QString::number(m_uid); 431 qu += QString::number(m_uid);
432 return qu; 432 return qu;
433 } 433 }
434#endif 434#endif
435 435
436 436
437 FindCustomQuery::FindCustomQuery(int uid) 437 FindCustomQuery::FindCustomQuery(int uid)
438 : OSQLQuery(), m_uid( uid ) { 438 : OSQLQuery(), m_uid( uid ) {
439 } 439 }
440 FindCustomQuery::FindCustomQuery(const QArray<int>& ints) 440 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
441 : OSQLQuery(), m_uids( ints ){ 441 : OSQLQuery(), m_uids( ints ){
442 } 442 }
443 FindCustomQuery::~FindCustomQuery() { 443 FindCustomQuery::~FindCustomQuery() {
444 } 444 }
445 QString FindCustomQuery::query()const{ 445 QString FindCustomQuery::query()const{
446 // if ( m_uids.count() == 0 ) 446 // if ( m_uids.count() == 0 )
447 return single(); 447 return single();
448 } 448 }
449 QString FindCustomQuery::single()const{ 449 QString FindCustomQuery::single()const{
450 QString qu = "select uid, type, value from custom_data where uid = "; 450 QString qu = "select uid, type, value from custom_data where uid = ";
451 qu += QString::number(m_uid); 451 qu += QString::number(m_uid);
452 return qu; 452 return qu;
453 } 453 }
454 454
455}; 455};
456 456
457 457
458/* --------------------------------------------------------------------------- */ 458/* --------------------------------------------------------------------------- */
459 459
460namespace Opie { 460namespace Opie {
461 461
462OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, 462OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */,
463 const QString& filename ): 463 const QString& filename ):
464 OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) 464 OPimContactAccessBackend(), m_changed(false), m_driver( NULL )
465{ 465{
466 qWarning("C'tor OPimContactAccessBackend_SQL starts"); 466 qWarning("C'tor OPimContactAccessBackend_SQL starts");
467 QTime t; 467 QTime t;
468 t.start(); 468 t.start();
469 469
470 /* Expecting to access the default filename if nothing else is set */ 470 /* Expecting to access the default filename if nothing else is set */
471 if ( filename.isEmpty() ){ 471 if ( filename.isEmpty() ){
472 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); 472 m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
473 } else 473 } else
474 m_fileName = filename; 474 m_fileName = filename;
475 475
476 // Get the standart sql-driver from the OSQLManager.. 476 // Get the standart sql-driver from the OSQLManager..
477 OSQLManager man; 477 OSQLManager man;
478 m_driver = man.standard(); 478 m_driver = man.standard();
479 m_driver->setUrl( m_fileName ); 479 m_driver->setUrl( m_fileName );
480 480
481 load(); 481 load();
482 482
483 qWarning("C'tor OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() ); 483 qWarning("C'tor OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() );
484} 484}
485 485
486OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () 486OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL ()
487{ 487{
488 if( m_driver ) 488 if( m_driver )
489 delete m_driver; 489 delete m_driver;
490} 490}
491 491
492bool OPimContactAccessBackend_SQL::load () 492bool OPimContactAccessBackend_SQL::load ()
493{ 493{
494 if (!m_driver->open() ) 494 if (!m_driver->open() )
495 return false; 495 return false;
496 496
497 // Don't expect that the database exists. 497 // Don't expect that the database exists.
498 // It is save here to create the table, even if it 498 // It is save here to create the table, even if it
499 // do exist. ( Is that correct for all databases ?? ) 499 // do exist. ( Is that correct for all databases ?? )
500 CreateQuery creat; 500 CreateQuery creat;
501 OSQLResult res = m_driver->query( &creat ); 501 OSQLResult res = m_driver->query( &creat );
502 502
503 update(); 503 update();
504 504
505 return true; 505 return true;
506 506
507} 507}
508 508
509bool OPimContactAccessBackend_SQL::reload() 509bool OPimContactAccessBackend_SQL::reload()
510{ 510{
511 return load(); 511 return load();
512} 512}
513 513
514bool OPimContactAccessBackend_SQL::save() 514bool OPimContactAccessBackend_SQL::save()
515{ 515{
516 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 516 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
517} 517}
518 518
519 519
520void OPimContactAccessBackend_SQL::clear () 520void OPimContactAccessBackend_SQL::clear ()
521{ 521{
522 ClearQuery cle; 522 ClearQuery cle;
523 OSQLResult res = m_driver->query( &cle ); 523 OSQLResult res = m_driver->query( &cle );
524 524
525 reload(); 525 reload();
526} 526}
527 527
528bool OPimContactAccessBackend_SQL::wasChangedExternally() 528bool OPimContactAccessBackend_SQL::wasChangedExternally()
529{ 529{
530 return false; 530 return false;
531} 531}
532 532
533QArray<int> OPimContactAccessBackend_SQL::allRecords() const 533QArray<int> OPimContactAccessBackend_SQL::allRecords() const
534{ 534{
535 535
536 // FIXME: Think about cute handling of changed tables.. 536 // FIXME: Think about cute handling of changed tables..
537 // Thus, we don't have to call update here... 537 // Thus, we don't have to call update here...
538 if ( m_changed ) 538 if ( m_changed )
539 ((OPimContactAccessBackend_SQL*)this)->update(); 539 ((OPimContactAccessBackend_SQL*)this)->update();
540 540
541 return m_uids; 541 return m_uids;
542} 542}
543 543
544bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) 544bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact )
545{ 545{
546 InsertQuery ins( newcontact ); 546 InsertQuery ins( newcontact );
547 OSQLResult res = m_driver->query( &ins ); 547 OSQLResult res = m_driver->query( &ins );
548 548
549 if ( res.state() == OSQLResult::Failure ) 549 if ( res.state() == OSQLResult::Failure )
550 return false; 550 return false;
551 551
552 int c = m_uids.count(); 552 int c = m_uids.count();
553 m_uids.resize( c+1 ); 553 m_uids.resize( c+1 );
554 m_uids[c] = newcontact.uid(); 554 m_uids[c] = newcontact.uid();
555 555
556 return true; 556 return true;
557} 557}
558 558
559 559
560bool OPimContactAccessBackend_SQL::remove ( int uid ) 560bool OPimContactAccessBackend_SQL::remove ( int uid )
561{ 561{
562 RemoveQuery rem( uid ); 562 RemoveQuery rem( uid );
563 OSQLResult res = m_driver->query(&rem ); 563 OSQLResult res = m_driver->query(&rem );
564 564
565 if ( res.state() == OSQLResult::Failure ) 565 if ( res.state() == OSQLResult::Failure )
566 return false; 566 return false;
567 567
568 m_changed = true; 568 m_changed = true;
569 569
570 return true; 570 return true;
571} 571}
572 572
573bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) 573bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
574{ 574{
575 if ( !remove( contact.uid() ) ) 575 if ( !remove( contact.uid() ) )
576 return false; 576 return false;
577 577
578 return add( contact ); 578 return add( contact );
579} 579}
580 580
581 581
582OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const 582OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
583{ 583{
584 qWarning("OPimContactAccessBackend_SQL::find()"); 584 qWarning("OPimContactAccessBackend_SQL::find()");
585 QTime t; 585 QTime t;
586 t.start(); 586 t.start();
587 587
588 OPimContact retContact( requestNonCustom( uid ) ); 588 OPimContact retContact( requestNonCustom( uid ) );
589 retContact.setExtraMap( requestCustom( uid ) ); 589 retContact.setExtraMap( requestCustom( uid ) );
590 590
591 qWarning("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); 591 qWarning("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
592 return retContact; 592 return retContact;
593} 593}
594 594
595 595
596 596
597QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ) 597QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() )
598{ 598{
599 QString qu = "SELECT uid FROM addressbook WHERE"; 599 QString qu = "SELECT uid FROM addressbook WHERE";
600 600
601 QMap<int, QString> queryFields = query.toMap(); 601 QMap<int, QString> queryFields = query.toMap();
602 QStringList fieldList = OPimContactFields::untrfields( false ); 602 QStringList fieldList = OPimContactFields::untrfields( false );
603 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 603 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
604 604
605 // Convert every filled field to a SQL-Query 605 // Convert every filled field to a SQL-Query
606 bool isAnyFieldSelected = false; 606 bool isAnyFieldSelected = false;
607 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 607 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
608 int id = translate[*it]; 608 int id = translate[*it];
609 QString queryStr = queryFields[id]; 609 QString queryStr = queryFields[id];
610 if ( !queryStr.isEmpty() ){ 610 if ( !queryStr.isEmpty() ){
611 isAnyFieldSelected = true; 611 isAnyFieldSelected = true;
612 switch( id ){ 612 switch( id ){
613 default: 613 default:
614 // Switching between case sensitive and insensitive... 614 // Switching between case sensitive and insensitive...
615 // LIKE is not case sensitive, GLOB is case sensitive 615 // LIKE is not case sensitive, GLOB is case sensitive
616 // Do exist a better solution to switch this ? 616 // Do exist a better solution to switch this ?
617 if ( settings & OPimContactAccess::IgnoreCase ) 617 if ( settings & OPimContactAccess::IgnoreCase )
618 qu += "(\"" + *it + "\"" + " LIKE " + "'" 618 qu += "(\"" + *it + "\"" + " LIKE " + "'"
619 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; 619 + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND ";
620 else 620 else
621 qu += "(\"" + *it + "\"" + " GLOB " + "'" 621 qu += "(\"" + *it + "\"" + " GLOB " + "'"
622 + queryStr + "'" + ") AND "; 622 + queryStr + "'" + ") AND ";
623 623
624 } 624 }
625 } 625 }
626 } 626 }
627 // Skip trailing "AND" 627 // Skip trailing "AND"
628 if ( isAnyFieldSelected ) 628 if ( isAnyFieldSelected )
629 qu = qu.left( qu.length() - 4 ); 629 qu = qu.left( qu.length() - 4 );
630 630
631 qWarning( "queryByExample query: %s", qu.latin1() ); 631 qWarning( "queryByExample query: %s", qu.latin1() );
632 632
633 // Execute query and return the received uid's 633 // Execute query and return the received uid's
634 OSQLRawQuery raw( qu ); 634 OSQLRawQuery raw( qu );
635 OSQLResult res = m_driver->query( &raw ); 635 OSQLResult res = m_driver->query( &raw );
636 if ( res.state() != OSQLResult::Success ){ 636 if ( res.state() != OSQLResult::Success ){
637 QArray<int> empty; 637 QArray<int> empty;
638 return empty; 638 return empty;
639 } 639 }
640 640
641 QArray<int> list = extractUids( res ); 641 QArray<int> list = extractUids( res );
642 642
643 return list; 643 return list;
644} 644}
645 645
646QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 646QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
647{ 647{
648 QArray<int> nix(0); 648 QArray<int> nix(0);
649 return nix; 649 return nix;
650} 650}
651 651
652const uint OPimContactAccessBackend_SQL::querySettings() 652const uint OPimContactAccessBackend_SQL::querySettings()
653{ 653{
654 return OPimContactAccess::IgnoreCase 654 return OPimContactAccess::IgnoreCase
655 || OPimContactAccess::WildCards; 655 || OPimContactAccess::WildCards;
656} 656}
657 657
658bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const 658bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
659{ 659{
660 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 660 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
661 * may be added with any of the other settings. IgnoreCase should never used alone. 661 * may be added with any of the other settings. IgnoreCase should never used alone.
662 * Wildcards, RegExp, ExactMatch should never used at the same time... 662 * Wildcards, RegExp, ExactMatch should never used at the same time...
663 */ 663 */
664 664
665 // Step 1: Check whether the given settings are supported by this backend 665 // Step 1: Check whether the given settings are supported by this backend
666 if ( ( querySettings & ( 666 if ( ( querySettings & (
667 OPimContactAccess::IgnoreCase 667 OPimContactAccess::IgnoreCase
668 | OPimContactAccess::WildCards 668 | OPimContactAccess::WildCards
669 // | OPimContactAccess::DateDiff 669 // | OPimContactAccess::DateDiff
670 // | OPimContactAccess::DateYear 670 // | OPimContactAccess::DateYear
671 // | OPimContactAccess::DateMonth 671 // | OPimContactAccess::DateMonth
672 // | OPimContactAccess::DateDay 672 // | OPimContactAccess::DateDay
673 // | OPimContactAccess::RegExp 673 // | OPimContactAccess::RegExp
674 // | OPimContactAccess::ExactMatch 674 // | OPimContactAccess::ExactMatch
675 ) ) != querySettings ) 675 ) ) != querySettings )
676 return false; 676 return false;
677 677
678 // Step 2: Check whether the given combinations are ok.. 678 // Step 2: Check whether the given combinations are ok..
679 679
680 // IngoreCase alone is invalid 680 // IngoreCase alone is invalid
681 if ( querySettings == OPimContactAccess::IgnoreCase ) 681 if ( querySettings == OPimContactAccess::IgnoreCase )
682 return false; 682 return false;
683 683
684 // WildCards, RegExp and ExactMatch should never used at the same time 684 // WildCards, RegExp and ExactMatch should never used at the same time
685 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 685 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
686 | OPimContactAccess::DateDiff 686 | OPimContactAccess::DateDiff
687 | OPimContactAccess::DateYear 687 | OPimContactAccess::DateYear
688 | OPimContactAccess::DateMonth 688 | OPimContactAccess::DateMonth
689 | OPimContactAccess::DateDay 689 | OPimContactAccess::DateDay
690 ) 690 )
691 ){ 691 ){
692 case OPimContactAccess::RegExp: 692 case OPimContactAccess::RegExp:
693 return ( true ); 693 return ( true );
694 case OPimContactAccess::WildCards: 694 case OPimContactAccess::WildCards:
695 return ( true ); 695 return ( true );
696 case OPimContactAccess::ExactMatch: 696 case OPimContactAccess::ExactMatch:
697 return ( true ); 697 return ( true );
698 case 0: // one of the upper removed bits were set.. 698 case 0: // one of the upper removed bits were set..
699 return ( true ); 699 return ( true );
700 default: 700 default:
701 return ( false ); 701 return ( false );
702 } 702 }
703 703
704} 704}
705 705
706QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) 706QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int )
707{ 707{
708 QTime t; 708 QTime t;
709 t.start(); 709 t.start();
710 710
711#ifdef __STORE_HORIZONTAL_ 711#ifdef __STORE_HORIZONTAL_
712 QString query = "SELECT uid FROM addressbook "; 712 QString query = "SELECT uid FROM addressbook ";
713 query += "ORDER BY \"Last Name\" "; 713 query += "ORDER BY \"Last Name\" ";
714#else 714#else
715 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' "; 715 QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
716 query += "ORDER BY upper( value )"; 716 query += "ORDER BY upper( value )";
717#endif 717#endif
718 718
719 if ( !asc ) 719 if ( !asc )
720 query += "DESC"; 720 query += "DESC";
721 721
722 // qWarning("sorted query is: %s", query.latin1() ); 722 // qWarning("sorted query is: %s", query.latin1() );
723 723
724 OSQLRawQuery raw( query ); 724 OSQLRawQuery raw( query );
725 OSQLResult res = m_driver->query( &raw ); 725 OSQLResult res = m_driver->query( &raw );
726 if ( res.state() != OSQLResult::Success ){ 726 if ( res.state() != OSQLResult::Success ){
727 QArray<int> empty; 727 QArray<int> empty;
728 return empty; 728 return empty;
729 } 729 }
730 730
731 QArray<int> list = extractUids( res ); 731 QArray<int> list = extractUids( res );
732 732
733 qWarning("sorted needed %d ms!", t.elapsed() ); 733 qWarning("sorted needed %d ms!", t.elapsed() );
734 return list; 734 return list;
735} 735}
736 736
737 737
738void OPimContactAccessBackend_SQL::update() 738void OPimContactAccessBackend_SQL::update()
739{ 739{
740 qWarning("Update starts"); 740 qWarning("Update starts");
741 QTime t; 741 QTime t;
742 t.start(); 742 t.start();
743 743
744 // Now load the database set and extract the uid's 744 // Now load the database set and extract the uid's
745 // which will be held locally 745 // which will be held locally
746 746
747 LoadQuery lo; 747 LoadQuery lo;
748 OSQLResult res = m_driver->query(&lo); 748 OSQLResult res = m_driver->query(&lo);
749 if ( res.state() != OSQLResult::Success ) 749 if ( res.state() != OSQLResult::Success )
750 return; 750 return;
751 751
752 m_uids = extractUids( res ); 752 m_uids = extractUids( res );
753 753
754 m_changed = false; 754 m_changed = false;
755 755
756 qWarning("Update ends %d ms", t.elapsed() ); 756 qWarning("Update ends %d ms", t.elapsed() );
757} 757}
758 758
759QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const 759QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
760{ 760{
761 qWarning("extractUids"); 761 qWarning("extractUids");
762 QTime t; 762 QTime t;
763 t.start(); 763 t.start();
764 OSQLResultItem::ValueList list = res.results(); 764 OSQLResultItem::ValueList list = res.results();
765 OSQLResultItem::ValueList::Iterator it; 765 OSQLResultItem::ValueList::Iterator it;
766 QArray<int> ints(list.count() ); 766 QArray<int> ints(list.count() );
767 qWarning(" count = %d", list.count() ); 767 qWarning(" count = %d", list.count() );
768 768
769 int i = 0; 769 int i = 0;
770 for (it = list.begin(); it != list.end(); ++it ) { 770 for (it = list.begin(); it != list.end(); ++it ) {
771 ints[i] = (*it).data("uid").toInt(); 771 ints[i] = (*it).data("uid").toInt();
772 i++; 772 i++;
773 } 773 }
774 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 774 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
775 775
776 return ints; 776 return ints;
777 777
778} 778}
779 779
780#ifdef __STORE_HORIZONTAL_ 780#ifdef __STORE_HORIZONTAL_
781QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const 781QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const
782{ 782{
783 QTime t; 783 QTime t;
784 t.start(); 784 t.start();
785 785
786 QMap<int, QString> nonCustomMap; 786 QMap<int, QString> nonCustomMap;
787 787
788 int t2needed = 0; 788 int t2needed = 0;
789 int t3needed = 0; 789 int t3needed = 0;
790 QTime t2; 790 QTime t2;
791 t2.start(); 791 t2.start();
792 FindQuery query( uid ); 792 FindQuery query( uid );
793 OSQLResult res_noncustom = m_driver->query( &query ); 793 OSQLResult res_noncustom = m_driver->query( &query );
794 t2needed = t2.elapsed(); 794 t2needed = t2.elapsed();
795 795
796 OSQLResultItem resItem = res_noncustom.first(); 796 OSQLResultItem resItem = res_noncustom.first();
797 797
798 QTime t3; 798 QTime t3;
799 t3.start(); 799 t3.start();
800 // Now loop through all columns 800 // Now loop through all columns
801 QStringList fieldList = OPimContactFields::untrfields( false ); 801 QStringList fieldList = OPimContactFields::untrfields( false );
802 QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); 802 QMap<QString, int> translate = OPimContactFields::untrFieldsToId();
803 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ 803 for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
804 // Get data for the selected column and store it with the 804 // Get data for the selected column and store it with the
805 // corresponding id into the map.. 805 // corresponding id into the map..
806 806
807 int id = translate[*it]; 807 int id = translate[*it];
808 QString value = resItem.data( (*it) ); 808 QString value = resItem.data( (*it) );
809 809
810 // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() ); 810 // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() );
811 811
812 switch( id ){ 812 switch( id ){
813 case Qtopia::Birthday: 813 case Qtopia::Birthday:
814 case Qtopia::Anniversary:{ 814 case Qtopia::Anniversary:{
815 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 815 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
816 QStringList list = QStringList::split( '-', value ); 816 QStringList list = QStringList::split( '-', value );
817 QStringList::Iterator lit = list.begin(); 817 QStringList::Iterator lit = list.begin();
818 int year = (*lit).toInt(); 818 int year = (*lit).toInt();
819 int month = (*(++lit)).toInt(); 819 int month = (*(++lit)).toInt();
820 int day = (*(++lit)).toInt(); 820 int day = (*(++lit)).toInt();
821 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ 821 if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){
822 QDate date( year, month, day ); 822 QDate date( year, month, day );
823 nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); 823 nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) );
824 } 824 }
825 } 825 }
826 break; 826 break;
827 case Qtopia::AddressCategory: 827 case Qtopia::AddressCategory:
828 qWarning("Category is: %s", value.latin1() ); 828 qWarning("Category is: %s", value.latin1() );
829 default: 829 default:
830 nonCustomMap.insert( id, value ); 830 nonCustomMap.insert( id, value );
831 } 831 }
832 } 832 }
833 833
834 // First insert uid 834 // First insert uid
835 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) ); 835 nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
836 t3needed = t3.elapsed(); 836 t3needed = t3.elapsed();
837 837
838 // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() ); 838 // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() );
839 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", 839 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms",
840 t.elapsed(), t2needed, t3needed ); 840 t.elapsed(), t2needed, t3needed );
841 841
842 return nonCustomMap; 842 return nonCustomMap;
843} 843}
844#else 844#else
845 845
846QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const 846QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const
847{ 847{
848 QTime t; 848 QTime t;
849 t.start(); 849 t.start();
850 850
851 QMap<int, QString> nonCustomMap; 851 QMap<int, QString> nonCustomMap;
852 852
853 int t2needed = 0; 853 int t2needed = 0;
854 QTime t2; 854 QTime t2;
855 t2.start(); 855 t2.start();
856 FindQuery query( uid ); 856 FindQuery query( uid );
857 OSQLResult res_noncustom = m_driver->query( &query ); 857 OSQLResult res_noncustom = m_driver->query( &query );
858 t2needed = t2.elapsed(); 858 t2needed = t2.elapsed();
859 859
860 if ( res_noncustom.state() == OSQLResult::Failure ) { 860 if ( res_noncustom.state() == OSQLResult::Failure ) {
861 qWarning("OSQLResult::Failure in find query !!"); 861 qWarning("OSQLResult::Failure in find query !!");
862 QMap<int, QString> empty; 862 QMap<int, QString> empty;
863 return empty; 863 return empty;
864 } 864 }
865 865
866 int t3needed = 0; 866 int t3needed = 0;
867 QTime t3; 867 QTime t3;
868 t3.start(); 868 t3.start();
869 QMap<QString, int> translateMap = OPimContactFields::untrFieldsToId(); 869 QMap<QString, int> translateMap = OPimContactFields::untrFieldsToId();
870 870
871 OSQLResultItem::ValueList list = res_noncustom.results(); 871 OSQLResultItem::ValueList list = res_noncustom.results();
872 OSQLResultItem::ValueList::Iterator it = list.begin(); 872 OSQLResultItem::ValueList::Iterator it = list.begin();
873 for ( ; it != list.end(); ++it ) { 873 for ( ; it != list.end(); ++it ) {
874 if ( (*it).data("type") != "" ){ 874 if ( (*it).data("type") != "" ){
875 int typeId = translateMap[(*it).data( "type" )]; 875 int typeId = translateMap[(*it).data( "type" )];
876 switch( typeId ){ 876 switch( typeId ){
877 case Qtopia::Birthday: 877 case Qtopia::Birthday:
878 case Qtopia::Anniversary:{ 878 case Qtopia::Anniversary:{
879 // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) 879 // Birthday and Anniversary are encoded special ( yyyy-mm-dd )
880 QStringList list = QStringList::split( '-', (*it).data( "value" ) ); 880 QStringList list = QStringList::split( '-', (*it).data( "value" ) );
881 QStringList::Iterator lit = list.begin(); 881 QStringList::Iterator lit = list.begin();
882 int year = (*lit).toInt(); 882 int year = (*lit).toInt();
883 qWarning("1. %s", (*lit).latin1()); 883 qWarning("1. %s", (*lit).latin1());
884 int month = (*(++lit)).toInt(); 884 int month = (*(++lit)).toInt();
885 qWarning("2. %s", (*lit).latin1()); 885 qWarning("2. %s", (*lit).latin1());
886 int day = (*(++lit)).toInt(); 886 int day = (*(++lit)).toInt();
887 qWarning("3. %s", (*lit).latin1()); 887 qWarning("3. %s", (*lit).latin1());
888 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day ); 888 qWarning( "RequestNonCustom->Converting:%s to Year: %d, Month: %d, Day: %d ", (*it).data( "value" ).latin1(), year, month, day );
889 QDate date( year, month, day ); 889 QDate date( year, month, day );
890 nonCustomMap.insert( typeId, OPimDateConversion::dateToString( date ) ); 890 nonCustomMap.insert( typeId, OPimDateConversion::dateToString( date ) );
891 } 891 }
892 break; 892 break;
893 default: 893 default:
894 nonCustomMap.insert( typeId, 894 nonCustomMap.insert( typeId,
895 (*it).data( "value" ) ); 895 (*it).data( "value" ) );
896 } 896 }
897 } 897 }
898 } 898 }
899 // Add UID to Map.. 899 // Add UID to Map..
900 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) ); 900 nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
901 t3needed = t3.elapsed(); 901 t3needed = t3.elapsed();
902 902
903 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed ); 903 qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed );
904 return nonCustomMap; 904 return nonCustomMap;
905} 905}
906 906
907#endif // __STORE_HORIZONTAL_ 907#endif // __STORE_HORIZONTAL_
908 908
909QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const 909QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const
910{ 910{
911 QTime t; 911 QTime t;
912 t.start(); 912 t.start();
913 913
914 QMap<QString, QString> customMap; 914 QMap<QString, QString> customMap;
915 915
916 FindCustomQuery query( uid ); 916 FindCustomQuery query( uid );
917 OSQLResult res_custom = m_driver->query( &query ); 917 OSQLResult res_custom = m_driver->query( &query );
918 918
919 if ( res_custom.state() == OSQLResult::Failure ) { 919 if ( res_custom.state() == OSQLResult::Failure ) {
920 qWarning("OSQLResult::Failure in find query !!"); 920 qWarning("OSQLResult::Failure in find query !!");
921 QMap<QString, QString> empty; 921 QMap<QString, QString> empty;
922 return empty; 922 return empty;
923 } 923 }
924 924
925 OSQLResultItem::ValueList list = res_custom.results(); 925 OSQLResultItem::ValueList list = res_custom.results();
926 OSQLResultItem::ValueList::Iterator it = list.begin(); 926 OSQLResultItem::ValueList::Iterator it = list.begin();
927 for ( ; it != list.end(); ++it ) { 927 for ( ; it != list.end(); ++it ) {
928 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); 928 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
929 } 929 }
930 930
931 qWarning("RequestCustom needed: %d ms", t.elapsed() ); 931 qWarning("RequestCustom needed: %d ms", t.elapsed() );
932 return customMap; 932 return customMap;
933} 933}
934 934
935} 935}
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
index 58ae2ae..ba122ec 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -1,109 +1,113 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Contact Database. 30 * SQL Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#ifndef _OPimContactAccessBackend_SQL_ 33#ifndef _OPimContactAccessBackend_SQL_
34#define _OPimContactAccessBackend_SQL_ 34#define _OPimContactAccessBackend_SQL_
35 35
36#include <opie2/ocontactaccessbackend.h> 36#include <opie2/ocontactaccessbackend.h>
37#include <opie2/ocontactaccess.h> 37#include <opie2/ocontactaccess.h>
38 38
39#include <qlist.h> 39#include <qlist.h>
40#include <qdict.h> 40#include <qdict.h>
41 41
42/* aren't in namespace Opie yet - alwin */ 42/* aren't in namespace Opie yet - alwin */
43namespace Opie {
44namespace DB {
43class OSQLDriver; 45class OSQLDriver;
44class OSQLResult; 46class OSQLResult;
45class OSQLResultItem; 47class OSQLResultItem;
48}
49}
46 50
47namespace Opie { 51namespace Opie {
48 52
49/* the default xml implementation */ 53/* the default xml implementation */
50/** 54/**
51 * This class is the SQL implementation of a Contact backend 55 * This class is the SQL implementation of a Contact backend
52 * it does implement everything available for OPimContact. 56 * it does implement everything available for OPimContact.
53 * @see OPimAccessBackend for more information of available methods 57 * @see OPimAccessBackend for more information of available methods
54 */ 58 */
55class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { 59class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
56 public: 60 public:
57 OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); 61 OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null );
58 62
59 ~OPimContactAccessBackend_SQL (); 63 ~OPimContactAccessBackend_SQL ();
60 64
61 bool save(); 65 bool save();
62 66
63 bool load (); 67 bool load ();
64 68
65 void clear (); 69 void clear ();
66 70
67 bool wasChangedExternally(); 71 bool wasChangedExternally();
68 72
69 QArray<int> allRecords() const; 73 QArray<int> allRecords() const;
70 74
71 OPimContact find ( int uid ) const; 75 OPimContact find ( int uid ) const;
72 // FIXME: Add lookahead-cache support ! 76 // FIXME: Add lookahead-cache support !
73 //OPimContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 77 //OPimContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
74 78
75 QArray<int> queryByExample ( const OPimContact &query, int settings, 79 QArray<int> queryByExample ( const OPimContact &query, int settings,
76 const QDateTime& d ); 80 const QDateTime& d );
77 81
78 QArray<int> matchRegexp( const QRegExp &r ) const; 82 QArray<int> matchRegexp( const QRegExp &r ) const;
79 83
80 const uint querySettings(); 84 const uint querySettings();
81 85
82 bool hasQuerySettings (uint querySettings) const; 86 bool hasQuerySettings (uint querySettings) const;
83 87
84 // Currently only asc implemented.. 88 // Currently only asc implemented..
85 QArray<int> sorted( bool asc, int , int , int ); 89 QArray<int> sorted( bool asc, int , int , int );
86 bool add ( const OPimContact &newcontact ); 90 bool add ( const OPimContact &newcontact );
87 91
88 bool replace ( const OPimContact &contact ); 92 bool replace ( const OPimContact &contact );
89 93
90 bool remove ( int uid ); 94 bool remove ( int uid );
91 bool reload(); 95 bool reload();
92 96
93 private: 97 private:
94 QArray<int> extractUids( OSQLResult& res ) const; 98 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const;
95 QMap<int, QString> requestNonCustom( int uid ) const; 99 QMap<int, QString> requestNonCustom( int uid ) const;
96 QMap<QString, QString> requestCustom( int uid ) const; 100 QMap<QString, QString> requestCustom( int uid ) const;
97 void update(); 101 void update();
98 102
99 protected: 103 protected:
100 bool m_changed; 104 bool m_changed;
101 QString m_fileName; 105 QString m_fileName;
102 QArray<int> m_uids; 106 QArray<int> m_uids;
103 107
104 OSQLDriver* m_driver; 108 Opie::DB::OSQLDriver* m_driver;
105}; 109};
106 110
107} 111}
108 112
109#endif 113#endif
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 5d92b8f..f5e76d5 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,749 +1,750 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * XML Backend for the OPIE-Contact Database. 30 * XML Backend for the OPIE-Contact Database.
31 */ 31 */
32 32
33#include <opie2/ocontactaccessbackend_xml.h> 33#include <opie2/ocontactaccessbackend_xml.h>
34 34
35#include <qasciidict.h> 35#include <qasciidict.h>
36#include <qfile.h> 36#include <qfile.h>
37#include <qfileinfo.h> 37#include <qfileinfo.h>
38#include <qregexp.h> 38#include <qregexp.h>
39#include <qarray.h> 39#include <qarray.h>
40#include <qmap.h> 40#include <qmap.h>
41 41
42#include <qpe/global.h> 42#include <qpe/global.h>
43 43
44#include <opie2/xmltree.h> 44#include "private/xmltree.h"
45#include <opie2/ocontactaccessbackend.h> 45#include <opie2/ocontactaccessbackend.h>
46#include <opie2/ocontactaccess.h> 46#include <opie2/ocontactaccess.h>
47 47
48#include <stdlib.h> 48#include <stdlib.h>
49#include <errno.h> 49#include <errno.h>
50 50
51using namespace Opie; 51using namespace Opie;
52using namespace Opie::Pim::Private;
52 53
53 54
54namespace Opie { 55namespace Opie {
55OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): 56OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ):
56 m_changed( false ) 57 m_changed( false )
57{ 58{
58 // Just m_contactlist should call delete if an entry 59 // Just m_contactlist should call delete if an entry
59 // is removed. 60 // is removed.
60 m_contactList.setAutoDelete( true ); 61 m_contactList.setAutoDelete( true );
61 m_uidToContact.setAutoDelete( false ); 62 m_uidToContact.setAutoDelete( false );
62 63
63 m_appName = appname; 64 m_appName = appname;
64 65
65 /* Set journalfile name ... */ 66 /* Set journalfile name ... */
66 m_journalName = getenv("HOME"); 67 m_journalName = getenv("HOME");
67 m_journalName +="/.abjournal" + appname; 68 m_journalName +="/.abjournal" + appname;
68 69
69 /* Expecting to access the default filename if nothing else is set */ 70 /* Expecting to access the default filename if nothing else is set */
70 if ( filename.isEmpty() ){ 71 if ( filename.isEmpty() ){
71 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 72 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
72 } else 73 } else
73 m_fileName = filename; 74 m_fileName = filename;
74 75
75 /* Load Database now */ 76 /* Load Database now */
76 load (); 77 load ();
77} 78}
78 79
79bool OPimContactAccessBackend_XML::save() 80bool OPimContactAccessBackend_XML::save()
80{ 81{
81 82
82 if ( !m_changed ) 83 if ( !m_changed )
83 return true; 84 return true;
84 85
85 QString strNewFile = m_fileName + ".new"; 86 QString strNewFile = m_fileName + ".new";
86 QFile f( strNewFile ); 87 QFile f( strNewFile );
87 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 88 if ( !f.open( IO_WriteOnly|IO_Raw ) )
88 return false; 89 return false;
89 90
90 int total_written; 91 int total_written;
91 int idx_offset = 0; 92 int idx_offset = 0;
92 QString out; 93 QString out;
93 94
94 // Write Header 95 // Write Header
95 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 96 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
96 " <Groups>\n" 97 " <Groups>\n"
97 " </Groups>\n" 98 " </Groups>\n"
98 " <Contacts>\n"; 99 " <Contacts>\n";
99 QCString cstr = out.utf8(); 100 QCString cstr = out.utf8();
100 f.writeBlock( cstr.data(), cstr.length() ); 101 f.writeBlock( cstr.data(), cstr.length() );
101 idx_offset += cstr.length(); 102 idx_offset += cstr.length();
102 out = ""; 103 out = "";
103 104
104 // Write all contacts 105 // Write all contacts
105 QListIterator<OPimContact> it( m_contactList ); 106 QListIterator<OPimContact> it( m_contactList );
106 for ( ; it.current(); ++it ) { 107 for ( ; it.current(); ++it ) {
107 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 108 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
108 out += "<Contact "; 109 out += "<Contact ";
109 (*it)->save( out ); 110 (*it)->save( out );
110 out += "/>\n"; 111 out += "/>\n";
111 cstr = out.utf8(); 112 cstr = out.utf8();
112 total_written = f.writeBlock( cstr.data(), cstr.length() ); 113 total_written = f.writeBlock( cstr.data(), cstr.length() );
113 idx_offset += cstr.length(); 114 idx_offset += cstr.length();
114 if ( total_written != int(cstr.length()) ) { 115 if ( total_written != int(cstr.length()) ) {
115 f.close(); 116 f.close();
116 QFile::remove( strNewFile ); 117 QFile::remove( strNewFile );
117 return false; 118 return false;
118 } 119 }
119 out = ""; 120 out = "";
120 } 121 }
121 out += " </Contacts>\n</AddressBook>\n"; 122 out += " </Contacts>\n</AddressBook>\n";
122 123
123 // Write Footer 124 // Write Footer
124 cstr = out.utf8(); 125 cstr = out.utf8();
125 total_written = f.writeBlock( cstr.data(), cstr.length() ); 126 total_written = f.writeBlock( cstr.data(), cstr.length() );
126 if ( total_written != int( cstr.length() ) ) { 127 if ( total_written != int( cstr.length() ) ) {
127 f.close(); 128 f.close();
128 QFile::remove( strNewFile ); 129 QFile::remove( strNewFile );
129 return false; 130 return false;
130 } 131 }
131 f.close(); 132 f.close();
132 133
133 // move the file over, I'm just going to use the system call 134 // move the file over, I'm just going to use the system call
134 // because, I don't feel like using QDir. 135 // because, I don't feel like using QDir.
135 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 136 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
136 qWarning( "problem renaming file %s to %s, errno: %d", 137 qWarning( "problem renaming file %s to %s, errno: %d",
137 strNewFile.latin1(), m_journalName.latin1(), errno ); 138 strNewFile.latin1(), m_journalName.latin1(), errno );
138 // remove the tmp file... 139 // remove the tmp file...
139 QFile::remove( strNewFile ); 140 QFile::remove( strNewFile );
140 } 141 }
141 142
142 /* The journalfile should be removed now... */ 143 /* The journalfile should be removed now... */
143 removeJournal(); 144 removeJournal();
144 145
145 m_changed = false; 146 m_changed = false;
146 return true; 147 return true;
147} 148}
148 149
149bool OPimContactAccessBackend_XML::load () 150bool OPimContactAccessBackend_XML::load ()
150{ 151{
151 m_contactList.clear(); 152 m_contactList.clear();
152 m_uidToContact.clear(); 153 m_uidToContact.clear();
153 154
154 /* Load XML-File and journal if it exists */ 155 /* Load XML-File and journal if it exists */
155 if ( !load ( m_fileName, false ) ) 156 if ( !load ( m_fileName, false ) )
156 return false; 157 return false;
157 /* The returncode of the journalfile is ignored due to the 158 /* The returncode of the journalfile is ignored due to the
158 * fact that it does not exist when this class is instantiated ! 159 * fact that it does not exist when this class is instantiated !
159 * But there may such a file exist, if the application crashed. 160 * But there may such a file exist, if the application crashed.
160 * Therefore we try to load it to get the changes before the # 161 * Therefore we try to load it to get the changes before the #
161 * crash happened... 162 * crash happened...
162 */ 163 */
163 load (m_journalName, true); 164 load (m_journalName, true);
164 165
165 return true; 166 return true;
166} 167}
167 168
168void OPimContactAccessBackend_XML::clear () 169void OPimContactAccessBackend_XML::clear ()
169{ 170{
170 m_contactList.clear(); 171 m_contactList.clear();
171 m_uidToContact.clear(); 172 m_uidToContact.clear();
172 173
173 m_changed = false; 174 m_changed = false;
174} 175}
175 176
176bool OPimContactAccessBackend_XML::wasChangedExternally() 177bool OPimContactAccessBackend_XML::wasChangedExternally()
177{ 178{
178 QFileInfo fi( m_fileName ); 179 QFileInfo fi( m_fileName );
179 180
180 QDateTime lastmod = fi.lastModified (); 181 QDateTime lastmod = fi.lastModified ();
181 182
182 return (lastmod != m_readtime); 183 return (lastmod != m_readtime);
183} 184}
184 185
185QArray<int> OPimContactAccessBackend_XML::allRecords() const 186QArray<int> OPimContactAccessBackend_XML::allRecords() const
186{ 187{
187 QArray<int> uid_list( m_contactList.count() ); 188 QArray<int> uid_list( m_contactList.count() );
188 189
189 uint counter = 0; 190 uint counter = 0;
190 QListIterator<OPimContact> it( m_contactList ); 191 QListIterator<OPimContact> it( m_contactList );
191 for( ; it.current(); ++it ){ 192 for( ; it.current(); ++it ){
192 uid_list[counter++] = (*it)->uid(); 193 uid_list[counter++] = (*it)->uid();
193 } 194 }
194 195
195 return ( uid_list ); 196 return ( uid_list );
196} 197}
197 198
198OPimContact OPimContactAccessBackend_XML::find ( int uid ) const 199OPimContact OPimContactAccessBackend_XML::find ( int uid ) const
199{ 200{
200 OPimContact foundContact; //Create empty contact 201 OPimContact foundContact; //Create empty contact
201 202
202 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); 203 OPimContact* found = m_uidToContact.find( QString().setNum( uid ) );
203 204
204 if ( found ){ 205 if ( found ){
205 foundContact = *found; 206 foundContact = *found;
206 } 207 }
207 208
208 return ( foundContact ); 209 return ( foundContact );
209} 210}
210 211
211QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, 212QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings,
212 const QDateTime& d ) 213 const QDateTime& d )
213{ 214{
214 215
215 QArray<int> m_currentQuery( m_contactList.count() ); 216 QArray<int> m_currentQuery( m_contactList.count() );
216 QListIterator<OPimContact> it( m_contactList ); 217 QListIterator<OPimContact> it( m_contactList );
217 uint arraycounter = 0; 218 uint arraycounter = 0;
218 219
219 for( ; it.current(); ++it ){ 220 for( ; it.current(); ++it ){
220 /* Search all fields and compare them with query object. Store them into list 221 /* Search all fields and compare them with query object. Store them into list
221 * if all fields matches. 222 * if all fields matches.
222 */ 223 */
223 QDate* queryDate = 0l; 224 QDate* queryDate = 0l;
224 QDate* checkDate = 0l; 225 QDate* checkDate = 0l;
225 bool allcorrect = true; 226 bool allcorrect = true;
226 for ( int i = 0; i < Qtopia::Groups; i++ ) { 227 for ( int i = 0; i < Qtopia::Groups; i++ ) {
227 // Birthday and anniversary are special nonstring fields and should 228 // Birthday and anniversary are special nonstring fields and should
228 // be handled specially 229 // be handled specially
229 switch ( i ){ 230 switch ( i ){
230 case Qtopia::Birthday: 231 case Qtopia::Birthday:
231 queryDate = new QDate( query.birthday() ); 232 queryDate = new QDate( query.birthday() );
232 checkDate = new QDate( (*it)->birthday() ); 233 checkDate = new QDate( (*it)->birthday() );
233 case Qtopia::Anniversary: 234 case Qtopia::Anniversary:
234 if ( queryDate == 0l ){ 235 if ( queryDate == 0l ){
235 queryDate = new QDate( query.anniversary() ); 236 queryDate = new QDate( query.anniversary() );
236 checkDate = new QDate( (*it)->anniversary() ); 237 checkDate = new QDate( (*it)->anniversary() );
237 } 238 }
238 239
239 if ( queryDate->isValid() ){ 240 if ( queryDate->isValid() ){
240 if( checkDate->isValid() ){ 241 if( checkDate->isValid() ){
241 if ( settings & OPimContactAccess::DateYear ){ 242 if ( settings & OPimContactAccess::DateYear ){
242 if ( queryDate->year() != checkDate->year() ) 243 if ( queryDate->year() != checkDate->year() )
243 allcorrect = false; 244 allcorrect = false;
244 } 245 }
245 if ( settings & OPimContactAccess::DateMonth ){ 246 if ( settings & OPimContactAccess::DateMonth ){
246 if ( queryDate->month() != checkDate->month() ) 247 if ( queryDate->month() != checkDate->month() )
247 allcorrect = false; 248 allcorrect = false;
248 } 249 }
249 if ( settings & OPimContactAccess::DateDay ){ 250 if ( settings & OPimContactAccess::DateDay ){
250 if ( queryDate->day() != checkDate->day() ) 251 if ( queryDate->day() != checkDate->day() )
251 allcorrect = false; 252 allcorrect = false;
252 } 253 }
253 if ( settings & OPimContactAccess::DateDiff ) { 254 if ( settings & OPimContactAccess::DateDiff ) {
254 QDate current; 255 QDate current;
255 // If we get an additional date, we 256 // If we get an additional date, we
256 // will take this date instead of 257 // will take this date instead of
257 // the current one.. 258 // the current one..
258 if ( !d.date().isValid() ) 259 if ( !d.date().isValid() )
259 current = QDate::currentDate(); 260 current = QDate::currentDate();
260 else 261 else
261 current = d.date(); 262 current = d.date();
262 263
263 // We have to equalize the year, otherwise 264 // We have to equalize the year, otherwise
264 // the search will fail.. 265 // the search will fail..
265 checkDate->setYMD( current.year(), 266 checkDate->setYMD( current.year(),
266 checkDate->month(), 267 checkDate->month(),
267 checkDate->day() ); 268 checkDate->day() );
268 if ( *checkDate < current ) 269 if ( *checkDate < current )
269 checkDate->setYMD( current.year()+1, 270 checkDate->setYMD( current.year()+1,
270 checkDate->month(), 271 checkDate->month(),
271 checkDate->day() ); 272 checkDate->day() );
272 273
273 // Check whether the birthday/anniversary date is between 274 // Check whether the birthday/anniversary date is between
274 // the current/given date and the maximum date 275 // the current/given date and the maximum date
275 // ( maximum time range ) ! 276 // ( maximum time range ) !
276 qWarning("Checking if %s is between %s and %s ! ", 277 qWarning("Checking if %s is between %s and %s ! ",
277 checkDate->toString().latin1(), 278 checkDate->toString().latin1(),
278 current.toString().latin1(), 279 current.toString().latin1(),
279 queryDate->toString().latin1() ); 280 queryDate->toString().latin1() );
280 if ( current.daysTo( *queryDate ) >= 0 ){ 281 if ( current.daysTo( *queryDate ) >= 0 ){
281 if ( !( ( *checkDate >= current ) && 282 if ( !( ( *checkDate >= current ) &&
282 ( *checkDate <= *queryDate ) ) ){ 283 ( *checkDate <= *queryDate ) ) ){
283 allcorrect = false; 284 allcorrect = false;
284 qWarning (" Nope!.."); 285 qWarning (" Nope!..");
285 } 286 }
286 } 287 }
287 } 288 }
288 } else{ 289 } else{
289 // checkDate is invalid. Therefore this entry is always rejected 290 // checkDate is invalid. Therefore this entry is always rejected
290 allcorrect = false; 291 allcorrect = false;
291 } 292 }
292 } 293 }
293 294
294 delete queryDate; 295 delete queryDate;
295 queryDate = 0l; 296 queryDate = 0l;
296 delete checkDate; 297 delete checkDate;
297 checkDate = 0l; 298 checkDate = 0l;
298 break; 299 break;
299 default: 300 default:
300 /* Just compare fields which are not empty in the query object */ 301 /* Just compare fields which are not empty in the query object */
301 if ( !query.field(i).isEmpty() ){ 302 if ( !query.field(i).isEmpty() ){
302 switch ( settings & ~( OPimContactAccess::IgnoreCase 303 switch ( settings & ~( OPimContactAccess::IgnoreCase
303 | OPimContactAccess::DateDiff 304 | OPimContactAccess::DateDiff
304 | OPimContactAccess::DateYear 305 | OPimContactAccess::DateYear
305 | OPimContactAccess::DateMonth 306 | OPimContactAccess::DateMonth
306 | OPimContactAccess::DateDay 307 | OPimContactAccess::DateDay
307 | OPimContactAccess::MatchOne 308 | OPimContactAccess::MatchOne
308 ) ){ 309 ) ){
309 310
310 case OPimContactAccess::RegExp:{ 311 case OPimContactAccess::RegExp:{
311 QRegExp expr ( query.field(i), 312 QRegExp expr ( query.field(i),
312 !(settings & OPimContactAccess::IgnoreCase), 313 !(settings & OPimContactAccess::IgnoreCase),
313 false ); 314 false );
314 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 315 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
315 allcorrect = false; 316 allcorrect = false;
316 } 317 }
317 break; 318 break;
318 case OPimContactAccess::WildCards:{ 319 case OPimContactAccess::WildCards:{
319 QRegExp expr ( query.field(i), 320 QRegExp expr ( query.field(i),
320 !(settings & OPimContactAccess::IgnoreCase), 321 !(settings & OPimContactAccess::IgnoreCase),
321 true ); 322 true );
322 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 323 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
323 allcorrect = false; 324 allcorrect = false;
324 } 325 }
325 break; 326 break;
326 case OPimContactAccess::ExactMatch:{ 327 case OPimContactAccess::ExactMatch:{
327 if (settings & OPimContactAccess::IgnoreCase){ 328 if (settings & OPimContactAccess::IgnoreCase){
328 if ( query.field(i).upper() != 329 if ( query.field(i).upper() !=
329 (*it)->field(i).upper() ) 330 (*it)->field(i).upper() )
330 allcorrect = false; 331 allcorrect = false;
331 }else{ 332 }else{
332 if ( query.field(i) != (*it)->field(i) ) 333 if ( query.field(i) != (*it)->field(i) )
333 allcorrect = false; 334 allcorrect = false;
334 } 335 }
335 } 336 }
336 break; 337 break;
337 } 338 }
338 } 339 }
339 } 340 }
340 } 341 }
341 if ( allcorrect ){ 342 if ( allcorrect ){
342 m_currentQuery[arraycounter++] = (*it)->uid(); 343 m_currentQuery[arraycounter++] = (*it)->uid();
343 } 344 }
344 } 345 }
345 346
346 // Shrink to fit.. 347 // Shrink to fit..
347 m_currentQuery.resize(arraycounter); 348 m_currentQuery.resize(arraycounter);
348 349
349 return m_currentQuery; 350 return m_currentQuery;
350} 351}
351 352
352QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 353QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
353{ 354{
354 QArray<int> m_currentQuery( m_contactList.count() ); 355 QArray<int> m_currentQuery( m_contactList.count() );
355 QListIterator<OPimContact> it( m_contactList ); 356 QListIterator<OPimContact> it( m_contactList );
356 uint arraycounter = 0; 357 uint arraycounter = 0;
357 358
358 for( ; it.current(); ++it ){ 359 for( ; it.current(); ++it ){
359 if ( (*it)->match( r ) ){ 360 if ( (*it)->match( r ) ){
360 m_currentQuery[arraycounter++] = (*it)->uid(); 361 m_currentQuery[arraycounter++] = (*it)->uid();
361 } 362 }
362 363
363 } 364 }
364 // Shrink to fit.. 365 // Shrink to fit..
365 m_currentQuery.resize(arraycounter); 366 m_currentQuery.resize(arraycounter);
366 367
367 return m_currentQuery; 368 return m_currentQuery;
368} 369}
369 370
370const uint OPimContactAccessBackend_XML::querySettings() 371const uint OPimContactAccessBackend_XML::querySettings()
371{ 372{
372 return ( OPimContactAccess::WildCards 373 return ( OPimContactAccess::WildCards
373 | OPimContactAccess::IgnoreCase 374 | OPimContactAccess::IgnoreCase
374 | OPimContactAccess::RegExp 375 | OPimContactAccess::RegExp
375 | OPimContactAccess::ExactMatch 376 | OPimContactAccess::ExactMatch
376 | OPimContactAccess::DateDiff 377 | OPimContactAccess::DateDiff
377 | OPimContactAccess::DateYear 378 | OPimContactAccess::DateYear
378 | OPimContactAccess::DateMonth 379 | OPimContactAccess::DateMonth
379 | OPimContactAccess::DateDay 380 | OPimContactAccess::DateDay
380 ); 381 );
381} 382}
382 383
383bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 384bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
384{ 385{
385 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 386 /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
386 * may be added with any of the other settings. IgnoreCase should never used alone. 387 * may be added with any of the other settings. IgnoreCase should never used alone.
387 * Wildcards, RegExp, ExactMatch should never used at the same time... 388 * Wildcards, RegExp, ExactMatch should never used at the same time...
388 */ 389 */
389 390
390 // Step 1: Check whether the given settings are supported by this backend 391 // Step 1: Check whether the given settings are supported by this backend
391 if ( ( querySettings & ( 392 if ( ( querySettings & (
392 OPimContactAccess::IgnoreCase 393 OPimContactAccess::IgnoreCase
393 | OPimContactAccess::WildCards 394 | OPimContactAccess::WildCards
394 | OPimContactAccess::DateDiff 395 | OPimContactAccess::DateDiff
395 | OPimContactAccess::DateYear 396 | OPimContactAccess::DateYear
396 | OPimContactAccess::DateMonth 397 | OPimContactAccess::DateMonth
397 | OPimContactAccess::DateDay 398 | OPimContactAccess::DateDay
398 | OPimContactAccess::RegExp 399 | OPimContactAccess::RegExp
399 | OPimContactAccess::ExactMatch 400 | OPimContactAccess::ExactMatch
400 ) ) != querySettings ) 401 ) ) != querySettings )
401 return false; 402 return false;
402 403
403 // Step 2: Check whether the given combinations are ok.. 404 // Step 2: Check whether the given combinations are ok..
404 405
405 // IngoreCase alone is invalid 406 // IngoreCase alone is invalid
406 if ( querySettings == OPimContactAccess::IgnoreCase ) 407 if ( querySettings == OPimContactAccess::IgnoreCase )
407 return false; 408 return false;
408 409
409 // WildCards, RegExp and ExactMatch should never used at the same time 410 // WildCards, RegExp and ExactMatch should never used at the same time
410 switch ( querySettings & ~( OPimContactAccess::IgnoreCase 411 switch ( querySettings & ~( OPimContactAccess::IgnoreCase
411 | OPimContactAccess::DateDiff 412 | OPimContactAccess::DateDiff
412 | OPimContactAccess::DateYear 413 | OPimContactAccess::DateYear
413 | OPimContactAccess::DateMonth 414 | OPimContactAccess::DateMonth
414 | OPimContactAccess::DateDay 415 | OPimContactAccess::DateDay
415 ) 416 )
416 ){ 417 ){
417 case OPimContactAccess::RegExp: 418 case OPimContactAccess::RegExp:
418 return ( true ); 419 return ( true );
419 case OPimContactAccess::WildCards: 420 case OPimContactAccess::WildCards:
420 return ( true ); 421 return ( true );
421 case OPimContactAccess::ExactMatch: 422 case OPimContactAccess::ExactMatch:
422 return ( true ); 423 return ( true );
423 case 0: // one of the upper removed bits were set.. 424 case 0: // one of the upper removed bits were set..
424 return ( true ); 425 return ( true );
425 default: 426 default:
426 return ( false ); 427 return ( false );
427 } 428 }
428} 429}
429 430
430// Currently only asc implemented.. 431// Currently only asc implemented..
431QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) 432QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int )
432{ 433{
433 QMap<QString, int> nameToUid; 434 QMap<QString, int> nameToUid;
434 QStringList names; 435 QStringList names;
435 QArray<int> m_currentQuery( m_contactList.count() ); 436 QArray<int> m_currentQuery( m_contactList.count() );
436 437
437 // First fill map and StringList with all Names 438 // First fill map and StringList with all Names
438 // Afterwards sort namelist and use map to fill array to return.. 439 // Afterwards sort namelist and use map to fill array to return..
439 QListIterator<OPimContact> it( m_contactList ); 440 QListIterator<OPimContact> it( m_contactList );
440 for( ; it.current(); ++it ){ 441 for( ; it.current(); ++it ){
441 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 442 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
442 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 443 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
443 } 444 }
444 names.sort(); 445 names.sort();
445 446
446 int i = 0; 447 int i = 0;
447 if ( asc ){ 448 if ( asc ){
448 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 449 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
449 m_currentQuery[i++] = nameToUid[ (*it) ]; 450 m_currentQuery[i++] = nameToUid[ (*it) ];
450 }else{ 451 }else{
451 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 452 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
452 m_currentQuery[i++] = nameToUid[ (*it) ]; 453 m_currentQuery[i++] = nameToUid[ (*it) ];
453 } 454 }
454 455
455 return m_currentQuery; 456 return m_currentQuery;
456 457
457} 458}
458 459
459bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) 460bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact )
460{ 461{
461 //qWarning("odefaultbackend: ACTION::ADD"); 462 //qWarning("odefaultbackend: ACTION::ADD");
462 updateJournal (newcontact, ACTION_ADD); 463 updateJournal (newcontact, ACTION_ADD);
463 addContact_p( newcontact ); 464 addContact_p( newcontact );
464 465
465 m_changed = true; 466 m_changed = true;
466 467
467 return true; 468 return true;
468} 469}
469 470
470bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) 471bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact )
471{ 472{
472 m_changed = true; 473 m_changed = true;
473 474
474 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 475 OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
475 476
476 if ( found ) { 477 if ( found ) {
477 OPimContact* newCont = new OPimContact( contact ); 478 OPimContact* newCont = new OPimContact( contact );
478 479
479 updateJournal ( *newCont, ACTION_REPLACE); 480 updateJournal ( *newCont, ACTION_REPLACE);
480 m_contactList.removeRef ( found ); 481 m_contactList.removeRef ( found );
481 m_contactList.append ( newCont ); 482 m_contactList.append ( newCont );
482 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 483 m_uidToContact.remove( QString().setNum( contact.uid() ) );
483 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 484 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
484 485
485 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 486 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
486 487
487 return true; 488 return true;
488 } else 489 } else
489 return false; 490 return false;
490} 491}
491 492
492bool OPimContactAccessBackend_XML::remove ( int uid ) 493bool OPimContactAccessBackend_XML::remove ( int uid )
493{ 494{
494 m_changed = true; 495 m_changed = true;
495 496
496 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 497 OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) );
497 498
498 if ( found ) { 499 if ( found ) {
499 updateJournal ( *found, ACTION_REMOVE); 500 updateJournal ( *found, ACTION_REMOVE);
500 m_contactList.removeRef ( found ); 501 m_contactList.removeRef ( found );
501 m_uidToContact.remove( QString().setNum( uid ) ); 502 m_uidToContact.remove( QString().setNum( uid ) );
502 503
503 return true; 504 return true;
504 } else 505 } else
505 return false; 506 return false;
506} 507}
507 508
508bool OPimContactAccessBackend_XML::reload(){ 509bool OPimContactAccessBackend_XML::reload(){
509 /* Reload is the same as load in this implementation */ 510 /* Reload is the same as load in this implementation */
510 return ( load() ); 511 return ( load() );
511} 512}
512 513
513void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) 514void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact )
514{ 515{
515 OPimContact* contRef = new OPimContact( newcontact ); 516 OPimContact* contRef = new OPimContact( newcontact );
516 517
517 m_contactList.append ( contRef ); 518 m_contactList.append ( contRef );
518 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 519 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
519} 520}
520 521
521/* This function loads the xml-database and the journalfile */ 522/* This function loads the xml-database and the journalfile */
522bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal ) 523bool OPimContactAccessBackend_XML::load( const QString filename, bool isJournal )
523{ 524{
524 525
525 /* We use the time of the last read to check if the file was 526 /* We use the time of the last read to check if the file was
526 * changed externally. 527 * changed externally.
527 */ 528 */
528 if ( !isJournal ){ 529 if ( !isJournal ){
529 QFileInfo fi( filename ); 530 QFileInfo fi( filename );
530 m_readtime = fi.lastModified (); 531 m_readtime = fi.lastModified ();
531 } 532 }
532 533
533 const int JOURNALACTION = Qtopia::Notes + 1; 534 const int JOURNALACTION = Qtopia::Notes + 1;
534 const int JOURNALROW = JOURNALACTION + 1; 535 const int JOURNALROW = JOURNALACTION + 1;
535 536
536 bool foundAction = false; 537 bool foundAction = false;
537 journal_action action = ACTION_ADD; 538 journal_action action = ACTION_ADD;
538 int journalKey = 0; 539 int journalKey = 0;
539 QMap<int, QString> contactMap; 540 QMap<int, QString> contactMap;
540 QMap<QString, QString> customMap; 541 QMap<QString, QString> customMap;
541 QMap<QString, QString>::Iterator customIt; 542 QMap<QString, QString>::Iterator customIt;
542 QAsciiDict<int> dict( 47 ); 543 QAsciiDict<int> dict( 47 );
543 544
544 dict.setAutoDelete( TRUE ); 545 dict.setAutoDelete( TRUE );
545 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 546 dict.insert( "Uid", new int(Qtopia::AddressUid) );
546 dict.insert( "Title", new int(Qtopia::Title) ); 547 dict.insert( "Title", new int(Qtopia::Title) );
547 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 548 dict.insert( "FirstName", new int(Qtopia::FirstName) );
548 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 549 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
549 dict.insert( "LastName", new int(Qtopia::LastName) ); 550 dict.insert( "LastName", new int(Qtopia::LastName) );
550 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 551 dict.insert( "Suffix", new int(Qtopia::Suffix) );
551 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 552 dict.insert( "FileAs", new int(Qtopia::FileAs) );
552 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 553 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
553 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 554 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
554 dict.insert( "Emails", new int(Qtopia::Emails) ); 555 dict.insert( "Emails", new int(Qtopia::Emails) );
555 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 556 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
556 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 557 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
557 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 558 dict.insert( "HomeState", new int(Qtopia::HomeState) );
558 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 559 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
559 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 560 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
560 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 561 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
561 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 562 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
562 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 563 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
563 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 564 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
564 dict.insert( "Company", new int(Qtopia::Company) ); 565 dict.insert( "Company", new int(Qtopia::Company) );
565 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 566 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
566 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 567 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
567 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 568 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
568 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 569 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
569 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 570 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
570 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 571 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
571 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 572 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
572 dict.insert( "Department", new int(Qtopia::Department) ); 573 dict.insert( "Department", new int(Qtopia::Department) );
573 dict.insert( "Office", new int(Qtopia::Office) ); 574 dict.insert( "Office", new int(Qtopia::Office) );
574 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 575 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
575 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 576 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
576 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 577 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
577 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 578 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
578 dict.insert( "Profession", new int(Qtopia::Profession) ); 579 dict.insert( "Profession", new int(Qtopia::Profession) );
579 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 580 dict.insert( "Assistant", new int(Qtopia::Assistant) );
580 dict.insert( "Manager", new int(Qtopia::Manager) ); 581 dict.insert( "Manager", new int(Qtopia::Manager) );
581 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 582 dict.insert( "Spouse", new int(Qtopia::Spouse) );
582 dict.insert( "Children", new int(Qtopia::Children) ); 583 dict.insert( "Children", new int(Qtopia::Children) );
583 dict.insert( "Gender", new int(Qtopia::Gender) ); 584 dict.insert( "Gender", new int(Qtopia::Gender) );
584 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 585 dict.insert( "Birthday", new int(Qtopia::Birthday) );
585 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 586 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
586 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 587 dict.insert( "Nickname", new int(Qtopia::Nickname) );
587 dict.insert( "Notes", new int(Qtopia::Notes) ); 588 dict.insert( "Notes", new int(Qtopia::Notes) );
588 dict.insert( "action", new int(JOURNALACTION) ); 589 dict.insert( "action", new int(JOURNALACTION) );
589 dict.insert( "actionrow", new int(JOURNALROW) ); 590 dict.insert( "actionrow", new int(JOURNALROW) );
590 591
591 //qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() ); 592 //qWarning( "OPimContactDefaultBackEnd::loading %s", filename.latin1() );
592 593
593 XMLElement *root = XMLElement::load( filename ); 594 XMLElement *root = XMLElement::load( filename );
594 if(root != 0l ){ // start parsing 595 if(root != 0l ){ // start parsing
595 /* Parse all XML-Elements and put the data into the 596 /* Parse all XML-Elements and put the data into the
596 * Contact-Class 597 * Contact-Class
597 */ 598 */
598 XMLElement *element = root->firstChild(); 599 XMLElement *element = root->firstChild();
599 //qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() ); 600 //qWarning("OPimContactAccess::load tagName(): %s", root->tagName().latin1() );
600 element = element->firstChild(); 601 element = element->firstChild();
601 602
602 /* Search Tag "Contacts" which is the parent of all Contacts */ 603 /* Search Tag "Contacts" which is the parent of all Contacts */
603 while( element && !isJournal ){ 604 while( element && !isJournal ){
604 if( element->tagName() != QString::fromLatin1("Contacts") ){ 605 if( element->tagName() != QString::fromLatin1("Contacts") ){
605 //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 606 //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
606 // element->tagName().latin1()); 607 // element->tagName().latin1());
607 element = element->nextChild(); 608 element = element->nextChild();
608 } else { 609 } else {
609 element = element->firstChild(); 610 element = element->firstChild();
610 break; 611 break;
611 } 612 }
612 } 613 }
613 /* Parse all Contacts and ignore unknown tags */ 614 /* Parse all Contacts and ignore unknown tags */
614 while( element ){ 615 while( element ){
615 if( element->tagName() != QString::fromLatin1("Contact") ){ 616 if( element->tagName() != QString::fromLatin1("Contact") ){
616 //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s", 617 //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s",
617 // element->tagName().latin1()); 618 // element->tagName().latin1());
618 element = element->nextChild(); 619 element = element->nextChild();
619 continue; 620 continue;
620 } 621 }
621 /* Found alement with tagname "contact", now parse and store all 622 /* Found alement with tagname "contact", now parse and store all
622 * attributes contained 623 * attributes contained
623 */ 624 */
624 //qWarning("OPimContactDefBack::load element tagName() : %s", 625 //qWarning("OPimContactDefBack::load element tagName() : %s",
625 // element->tagName().latin1() ); 626 // element->tagName().latin1() );
626 QString dummy; 627 QString dummy;
627 foundAction = false; 628 foundAction = false;
628 629
629 XMLElement::AttributeMap aMap = element->attributes(); 630 XMLElement::AttributeMap aMap = element->attributes();
630 XMLElement::AttributeMap::Iterator it; 631 XMLElement::AttributeMap::Iterator it;
631 contactMap.clear(); 632 contactMap.clear();
632 customMap.clear(); 633 customMap.clear();
633 for( it = aMap.begin(); it != aMap.end(); ++it ){ 634 for( it = aMap.begin(); it != aMap.end(); ++it ){
634 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 635 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
635 636
636 int *find = dict[ it.key() ]; 637 int *find = dict[ it.key() ];
637 /* Unknown attributes will be stored as "Custom" elements */ 638 /* Unknown attributes will be stored as "Custom" elements */
638 if ( !find ) { 639 if ( !find ) {
639 // qWarning("Attribute %s not known.", it.key().latin1()); 640 // qWarning("Attribute %s not known.", it.key().latin1());
640 //contact.setCustomField(it.key(), it.data()); 641 //contact.setCustomField(it.key(), it.data());
641 customMap.insert( it.key(), it.data() ); 642 customMap.insert( it.key(), it.data() );
642 continue; 643 continue;
643 } 644 }
644 645
645 /* Check if special conversion is needed and add attribute 646 /* Check if special conversion is needed and add attribute
646 * into Contact class 647 * into Contact class
647 */ 648 */
648 switch( *find ) { 649 switch( *find ) {
649 /* 650 /*
650 case Qtopia::AddressUid: 651 case Qtopia::AddressUid:
651 contact.setUid( it.data().toInt() ); 652 contact.setUid( it.data().toInt() );
652 break; 653 break;
653 case Qtopia::AddressCategory: 654 case Qtopia::AddressCategory:
654 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 655 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
655 break; 656 break;
656 */ 657 */
657 case JOURNALACTION: 658 case JOURNALACTION:
658 action = journal_action(it.data().toInt()); 659 action = journal_action(it.data().toInt());
659 foundAction = true; 660 foundAction = true;
660 qWarning ("ODefBack(journal)::ACTION found: %d", action); 661 qWarning ("ODefBack(journal)::ACTION found: %d", action);
661 break; 662 break;
662 case JOURNALROW: 663 case JOURNALROW:
663 journalKey = it.data().toInt(); 664 journalKey = it.data().toInt();
664 break; 665 break;
665 default: // no conversion needed add them to the map 666 default: // no conversion needed add them to the map
666 contactMap.insert( *find, it.data() ); 667 contactMap.insert( *find, it.data() );
667 break; 668 break;
668 } 669 }
669 } 670 }
670 /* now generate the Contact contact */ 671 /* now generate the Contact contact */
671 OPimContact contact( contactMap ); 672 OPimContact contact( contactMap );
672 673
673 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 674 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
674 contact.setCustomField( customIt.key(), customIt.data() ); 675 contact.setCustomField( customIt.key(), customIt.data() );
675 } 676 }
676 677
677 if (foundAction){ 678 if (foundAction){
678 foundAction = false; 679 foundAction = false;
679 switch ( action ) { 680 switch ( action ) {
680 case ACTION_ADD: 681 case ACTION_ADD:
681 addContact_p (contact); 682 addContact_p (contact);
682 break; 683 break;
683 case ACTION_REMOVE: 684 case ACTION_REMOVE:
684 if ( !remove (contact.uid()) ) 685 if ( !remove (contact.uid()) )
685 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 686 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
686 contact.uid() ); 687 contact.uid() );
687 break; 688 break;
688 case ACTION_REPLACE: 689 case ACTION_REPLACE:
689 if ( !replace ( contact ) ) 690 if ( !replace ( contact ) )
690 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 691 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
691 contact.uid() ); 692 contact.uid() );
692 break; 693 break;
693 default: 694 default:
694 qWarning ("Unknown action: ignored !"); 695 qWarning ("Unknown action: ignored !");
695 break; 696 break;
696 } 697 }
697 }else{ 698 }else{
698 /* Add contact to list */ 699 /* Add contact to list */
699 addContact_p (contact); 700 addContact_p (contact);
700 } 701 }
701 702
702 /* Move to next element */ 703 /* Move to next element */
703 element = element->nextChild(); 704 element = element->nextChild();
704 } 705 }
705 }else { 706 }else {
706 qWarning("ODefBack::could not load"); 707 qWarning("ODefBack::could not load");
707 } 708 }
708 delete root; 709 delete root;
709 qWarning("returning from loading" ); 710 qWarning("returning from loading" );
710 return true; 711 return true;
711} 712}
712 713
713 714
714void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, 715void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt,
715 journal_action action ) 716 journal_action action )
716{ 717{
717 QFile f( m_journalName ); 718 QFile f( m_journalName );
718 bool created = !f.exists(); 719 bool created = !f.exists();
719 if ( !f.open(IO_WriteOnly|IO_Append) ) 720 if ( !f.open(IO_WriteOnly|IO_Append) )
720 return; 721 return;
721 722
722 QString buf; 723 QString buf;
723 QCString str; 724 QCString str;
724 725
725 // if the file was created, we have to set the Tag "<CONTACTS>" to 726 // if the file was created, we have to set the Tag "<CONTACTS>" to
726 // get a XML-File which is readable by our parser. 727 // get a XML-File which is readable by our parser.
727 // This is just a cheat, but better than rewrite the parser. 728 // This is just a cheat, but better than rewrite the parser.
728 if ( created ){ 729 if ( created ){
729 buf = "<Contacts>"; 730 buf = "<Contacts>";
730 QCString cstr = buf.utf8(); 731 QCString cstr = buf.utf8();
731 f.writeBlock( cstr.data(), cstr.length() ); 732 f.writeBlock( cstr.data(), cstr.length() );
732 } 733 }
733 734
734 buf = "<Contact "; 735 buf = "<Contact ";
735 cnt.save( buf ); 736 cnt.save( buf );
736 buf += " action=\"" + QString::number( (int)action ) + "\" "; 737 buf += " action=\"" + QString::number( (int)action ) + "\" ";
737 buf += "/>\n"; 738 buf += "/>\n";
738 QCString cstr = buf.utf8(); 739 QCString cstr = buf.utf8();
739 f.writeBlock( cstr.data(), cstr.length() ); 740 f.writeBlock( cstr.data(), cstr.length() );
740} 741}
741 742
742void OPimContactAccessBackend_XML::removeJournal() 743void OPimContactAccessBackend_XML::removeJournal()
743{ 744{
744 QFile f ( m_journalName ); 745 QFile f ( m_journalName );
745 if ( f.exists() ) 746 if ( f.exists() )
746 f.remove(); 747 f.remove();
747} 748}
748 749
749} 750}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
index 2ee76cc..a779dc1 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp
@@ -1,366 +1,368 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29/* 29/*
30 * SQL Backend for the OPIE-Calender Database. 30 * SQL Backend for the OPIE-Calender Database.
31 * 31 *
32 */ 32 */
33 33
34#include <stdio.h> 34#include <stdio.h>
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37#include <qarray.h> 37#include <qarray.h>
38#include <qstringlist.h> 38#include <qstringlist.h>
39 39
40#include <qpe/global.h> 40#include <qpe/global.h>
41 41
42#include <opie2/osqldriver.h> 42#include <opie2/osqldriver.h>
43#include <opie2/osqlmanager.h> 43#include <opie2/osqlmanager.h>
44#include <opie2/osqlquery.h> 44#include <opie2/osqlquery.h>
45 45
46#include <opie2/opimrecurrence.h> 46#include <opie2/opimrecurrence.h>
47#include <opie2/odatebookaccessbackend_sql.h> 47#include <opie2/odatebookaccessbackend_sql.h>
48 48
49using namespace Opie::DB;
50
49namespace Opie { 51namespace Opie {
50 52
51 53
52ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , 54ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
53 const QString& fileName ) 55 const QString& fileName )
54 : ODateBookAccessBackend(), m_driver( NULL ) 56 : ODateBookAccessBackend(), m_driver( NULL )
55{ 57{
56 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; 58 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
57 59
58 // Get the standart sql-driver from the OSQLManager.. 60 // Get the standart sql-driver from the OSQLManager..
59 OSQLManager man; 61 OSQLManager man;
60 m_driver = man.standard(); 62 m_driver = man.standard();
61 m_driver->setUrl( m_fileName ); 63 m_driver->setUrl( m_fileName );
62 64
63 initFields(); 65 initFields();
64 66
65 load(); 67 load();
66} 68}
67 69
68ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { 70ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
69 if( m_driver ) 71 if( m_driver )
70 delete m_driver; 72 delete m_driver;
71} 73}
72 74
73void ODateBookAccessBackend_SQL::initFields() 75void ODateBookAccessBackend_SQL::initFields()
74{ 76{
75 77
76 // This map contains the translation of the fieldtype id's to 78 // This map contains the translation of the fieldtype id's to
77 // the names of the table columns 79 // the names of the table columns
78 m_fieldMap.insert( OPimEvent::FUid, "uid" ); 80 m_fieldMap.insert( OPimEvent::FUid, "uid" );
79 m_fieldMap.insert( OPimEvent::FCategories, "Categories" ); 81 m_fieldMap.insert( OPimEvent::FCategories, "Categories" );
80 m_fieldMap.insert( OPimEvent::FDescription, "Description" ); 82 m_fieldMap.insert( OPimEvent::FDescription, "Description" );
81 m_fieldMap.insert( OPimEvent::FLocation, "Location" ); 83 m_fieldMap.insert( OPimEvent::FLocation, "Location" );
82 m_fieldMap.insert( OPimEvent::FType, "Type" ); 84 m_fieldMap.insert( OPimEvent::FType, "Type" );
83 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" ); 85 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" );
84 m_fieldMap.insert( OPimEvent::FSound, "Sound" ); 86 m_fieldMap.insert( OPimEvent::FSound, "Sound" );
85 m_fieldMap.insert( OPimEvent::FRType, "RType" ); 87 m_fieldMap.insert( OPimEvent::FRType, "RType" );
86 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" ); 88 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" );
87 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" ); 89 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" );
88 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" ); 90 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" );
89 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" ); 91 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" );
90 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" ); 92 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" );
91 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" ); 93 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" );
92 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" ); 94 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" );
93 m_fieldMap.insert( OPimEvent::FStart, "Start" ); 95 m_fieldMap.insert( OPimEvent::FStart, "Start" );
94 m_fieldMap.insert( OPimEvent::FEnd, "End" ); 96 m_fieldMap.insert( OPimEvent::FEnd, "End" );
95 m_fieldMap.insert( OPimEvent::FNote, "Note" ); 97 m_fieldMap.insert( OPimEvent::FNote, "Note" );
96 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" ); 98 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" );
97 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" ); 99 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" );
98 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" ); 100 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" );
99 101
100 // Create a map that maps the column name to the id 102 // Create a map that maps the column name to the id
101 QMapConstIterator<int, QString> it; 103 QMapConstIterator<int, QString> it;
102 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 104 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
103 m_reverseFieldMap.insert( it.data(), it.key() ); 105 m_reverseFieldMap.insert( it.data(), it.key() );
104 } 106 }
105 107
106} 108}
107 109
108bool ODateBookAccessBackend_SQL::load() 110bool ODateBookAccessBackend_SQL::load()
109{ 111{
110 if (!m_driver->open() ) 112 if (!m_driver->open() )
111 return false; 113 return false;
112 114
113 // Don't expect that the database exists. 115 // Don't expect that the database exists.
114 // It is save here to create the table, even if it 116 // It is save here to create the table, even if it
115 // do exist. ( Is that correct for all databases ?? ) 117 // do exist. ( Is that correct for all databases ?? )
116 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; 118 QStringqu = "create table datebook( uid INTEGER PRIMARY KEY ";
117 119
118 QMap<int, QString>::Iterator it; 120 QMap<int, QString>::Iterator it;
119 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 121 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
120 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); 122 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() );
121 } 123 }
122 qu += " );"; 124 qu += " );";
123 125
124 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; 126 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
125 127
126 qWarning( "command: %s", qu.latin1() ); 128 qWarning( "command: %s", qu.latin1() );
127 129
128 OSQLRawQuery raw( qu ); 130 OSQLRawQuery raw( qu );
129 OSQLResult res = m_driver->query( &raw ); 131 OSQLResult res = m_driver->query( &raw );
130 if ( res.state() != OSQLResult::Success ) 132 if ( res.state() != OSQLResult::Success )
131 return false; 133 return false;
132 134
133 update(); 135 update();
134 136
135 return true; 137 return true;
136} 138}
137 139
138void ODateBookAccessBackend_SQL::update() 140void ODateBookAccessBackend_SQL::update()
139{ 141{
140 142
141 QString qu = "select uid from datebook"; 143 QString qu = "select uid from datebook";
142 OSQLRawQuery raw( qu ); 144 OSQLRawQuery raw( qu );
143 OSQLResult res = m_driver->query( &raw ); 145 OSQLResult res = m_driver->query( &raw );
144 if ( res.state() != OSQLResult::Success ){ 146 if ( res.state() != OSQLResult::Success ){
145 // m_uids.clear(); 147 // m_uids.clear();
146 return; 148 return;
147 } 149 }
148 150
149 m_uids = extractUids( res ); 151 m_uids = extractUids( res );
150 152
151} 153}
152 154
153bool ODateBookAccessBackend_SQL::reload() 155bool ODateBookAccessBackend_SQL::reload()
154{ 156{
155 return load(); 157 return load();
156} 158}
157 159
158bool ODateBookAccessBackend_SQL::save() 160bool ODateBookAccessBackend_SQL::save()
159{ 161{
160 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 162 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
161} 163}
162 164
163QArray<int> ODateBookAccessBackend_SQL::allRecords()const 165QArray<int> ODateBookAccessBackend_SQL::allRecords()const
164{ 166{
165 return m_uids; 167 return m_uids;
166} 168}
167 169
168QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) { 170QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) {
169 return QArray<int>(); 171 return QArray<int>();
170} 172}
171 173
172void ODateBookAccessBackend_SQL::clear() 174void ODateBookAccessBackend_SQL::clear()
173{ 175{
174 QString qu = "drop table datebook;"; 176 QString qu = "drop table datebook;";
175 qu += "drop table custom_data;"; 177 qu += "drop table custom_data;";
176 178
177 OSQLRawQuery raw( qu ); 179 OSQLRawQuery raw( qu );
178 OSQLResult res = m_driver->query( &raw ); 180 OSQLResult res = m_driver->query( &raw );
179 181
180 reload(); 182 reload();
181} 183}
182 184
183 185
184OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ 186OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{
185 QString qu = "select *"; 187 QString qu = "select *";
186 qu += "from datebook where uid = " + QString::number(uid); 188 qu += "from datebook where uid = " + QString::number(uid);
187 189
188 OSQLRawQuery raw( qu ); 190 OSQLRawQuery raw( qu );
189 OSQLResult res = m_driver->query( &raw ); 191 OSQLResult res = m_driver->query( &raw );
190 192
191 OSQLResultItem resItem = res.first(); 193 OSQLResultItem resItem = res.first();
192 194
193 // Create Map for date event and insert UID 195 // Create Map for date event and insert UID
194 QMap<int,QString> dateEventMap; 196 QMap<int,QString> dateEventMap;
195 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) ); 197 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) );
196 198
197 // Now insert the data out of the columns into the map. 199 // Now insert the data out of the columns into the map.
198 QMapConstIterator<int, QString> it; 200 QMapConstIterator<int, QString> it;
199 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 201 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
200 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); 202 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) );
201 } 203 }
202 204
203 // Last step: Put map into date event and return it 205 // Last step: Put map into date event and return it
204 OPimEvent retDate( dateEventMap ); 206 OPimEvent retDate( dateEventMap );
205 207
206 return retDate; 208 return retDate;
207} 209}
208 210
209// FIXME: Speed up update of uid's.. 211// FIXME: Speed up update of uid's..
210bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) 212bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev )
211{ 213{
212 QMap<int,QString> eventMap = ev.toMap(); 214 QMap<int,QString> eventMap = ev.toMap();
213 215
214 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); 216 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() );
215 QMap<int, QString>::Iterator it; 217 QMap<int, QString>::Iterator it;
216 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ 218 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
217 if ( !eventMap[it.key()].isEmpty() ) 219 if ( !eventMap[it.key()].isEmpty() )
218 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); 220 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] );
219 else 221 else
220 qu += QString( ",\"\"" ); 222 qu += QString( ",\"\"" );
221 } 223 }
222 qu += " );"; 224 qu += " );";
223 225
224 // Add custom entries 226 // Add custom entries
225 int id = 0; 227 int id = 0;
226 QMap<QString, QString> customMap = ev.toExtraMap(); 228 QMap<QString, QString> customMap = ev.toExtraMap();
227 for( QMap<QString, QString>::Iterator it = customMap.begin(); 229 for( QMap<QString, QString>::Iterator it = customMap.begin();
228 it != customMap.end(); ++it ){ 230 it != customMap.end(); ++it ){
229 qu += "insert into custom_data VALUES(" 231 qu += "insert into custom_data VALUES("
230 + QString::number( ev.uid() ) 232 + QString::number( ev.uid() )
231 + "," 233 + ","
232 + QString::number( id++ ) 234 + QString::number( id++ )
233 + ",'" 235 + ",'"
234 + it.key() //.latin1() 236 + it.key() //.latin1()
235 + "'," 237 + "',"
236 + "0" // Priority for future enhancements 238 + "0" // Priority for future enhancements
237 + ",'" 239 + ",'"
238 + it.data() //.latin1() 240 + it.data() //.latin1()
239 + "');"; 241 + "');";
240 } 242 }
241 qWarning("add %s", qu.latin1() ); 243 qWarning("add %s", qu.latin1() );
242 244
243 OSQLRawQuery raw( qu ); 245 OSQLRawQuery raw( qu );
244 OSQLResult res = m_driver->query( &raw ); 246 OSQLResult res = m_driver->query( &raw );
245 if ( res.state() != OSQLResult::Success ){ 247 if ( res.state() != OSQLResult::Success ){
246 return false; 248 return false;
247 } 249 }
248 250
249 // Update list of uid's 251 // Update list of uid's
250 update(); 252 update();
251 253
252 return true; 254 return true;
253} 255}
254 256
255// FIXME: Speed up update of uid's.. 257// FIXME: Speed up update of uid's..
256bool ODateBookAccessBackend_SQL::remove( int uid ) 258bool ODateBookAccessBackend_SQL::remove( int uid )
257{ 259{
258 QString qu = "DELETE from datebook where uid = " 260 QString qu = "DELETE from datebook where uid = "
259 + QString::number( uid ) + ";"; 261 + QString::number( uid ) + ";";
260 qu += "DELETE from custom_data where uid = " 262 qu += "DELETE from custom_data where uid = "
261 + QString::number( uid ) + ";"; 263 + QString::number( uid ) + ";";
262 264
263 OSQLRawQuery raw( qu ); 265 OSQLRawQuery raw( qu );
264 OSQLResult res = m_driver->query( &raw ); 266 OSQLResult res = m_driver->query( &raw );
265 if ( res.state() != OSQLResult::Success ){ 267 if ( res.state() != OSQLResult::Success ){
266 return false; 268 return false;
267 } 269 }
268 270
269 // Update list of uid's 271 // Update list of uid's
270 update(); 272 update();
271 273
272 return true; 274 return true;
273} 275}
274 276
275bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev ) 277bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev )
276{ 278{
277 remove( ev.uid() ); 279 remove( ev.uid() );
278 return add( ev ); 280 return add( ev );
279} 281}
280 282
281QArray<int> ODateBookAccessBackend_SQL::rawEvents()const 283QArray<int> ODateBookAccessBackend_SQL::rawEvents()const
282{ 284{
283 return allRecords(); 285 return allRecords();
284} 286}
285 287
286QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const 288QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const
287{ 289{
288 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; 290 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\"";
289 OSQLRawQuery raw( qu ); 291 OSQLRawQuery raw( qu );
290 OSQLResult res = m_driver->query( &raw ); 292 OSQLResult res = m_driver->query( &raw );
291 if ( res.state() != OSQLResult::Success ){ 293 if ( res.state() != OSQLResult::Success ){
292 QArray<int> nix; 294 QArray<int> nix;
293 return nix; 295 return nix;
294 } 296 }
295 297
296 return extractUids( res ); 298 return extractUids( res );
297} 299}
298 300
299QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const 301QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const
300{ 302{
301 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; 303 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\"";
302 OSQLRawQuery raw( qu ); 304 OSQLRawQuery raw( qu );
303 OSQLResult res = m_driver->query( &raw ); 305 OSQLResult res = m_driver->query( &raw );
304 if ( res.state() != OSQLResult::Success ){ 306 if ( res.state() != OSQLResult::Success ){
305 QArray<int> nix; 307 QArray<int> nix;
306 return nix; 308 return nix;
307 } 309 }
308 310
309 return extractUids( res ); 311 return extractUids( res );
310} 312}
311 313
312OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() 314OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats()
313{ 315{
314 QArray<int> nonRepUids = nonRepeats(); 316 QArray<int> nonRepUids = nonRepeats();
315 OPimEvent::ValueList list; 317 OPimEvent::ValueList list;
316 318
317 for (uint i = 0; i < nonRepUids.count(); ++i ){ 319 for (uint i = 0; i < nonRepUids.count(); ++i ){
318 list.append( find( nonRepUids[i] ) ); 320 list.append( find( nonRepUids[i] ) );
319 } 321 }
320 322
321 return list; 323 return list;
322 324
323} 325}
324OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() 326OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()
325{ 327{
326 QArray<int> rawRepUids = rawRepeats(); 328 QArray<int> rawRepUids = rawRepeats();
327 OPimEvent::ValueList list; 329 OPimEvent::ValueList list;
328 330
329 for (uint i = 0; i < rawRepUids.count(); ++i ){ 331 for (uint i = 0; i < rawRepUids.count(); ++i ){
330 list.append( find( rawRepUids[i] ) ); 332 list.append( find( rawRepUids[i] ) );
331 } 333 }
332 334
333 return list; 335 return list;
334} 336}
335 337
336 338
337QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const 339QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
338{ 340{
339 QArray<int> null; 341 QArray<int> null;
340 return null; 342 return null;
341} 343}
342 344
343/* ===== Private Functions ========================================== */ 345/* ===== Private Functions ========================================== */
344 346
345QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const 347QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const
346{ 348{
347 qWarning("extractUids"); 349 qWarning("extractUids");
348 QTime t; 350 QTime t;
349 t.start(); 351 t.start();
350 OSQLResultItem::ValueList list = res.results(); 352 OSQLResultItem::ValueList list = res.results();
351 OSQLResultItem::ValueList::Iterator it; 353 OSQLResultItem::ValueList::Iterator it;
352 QArray<int> ints(list.count() ); 354 QArray<int> ints(list.count() );
353 qWarning(" count = %d", list.count() ); 355 qWarning(" count = %d", list.count() );
354 356
355 int i = 0; 357 int i = 0;
356 for (it = list.begin(); it != list.end(); ++it ) { 358 for (it = list.begin(); it != list.end(); ++it ) {
357 ints[i] = (*it).data("uid").toInt(); 359 ints[i] = (*it).data("uid").toInt();
358 i++; 360 i++;
359 } 361 }
360 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); 362 qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
361 363
362 return ints; 364 return ints;
363 365
364} 366}
365 367
366} 368}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
index cbfeb97..60d7f21 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h
@@ -1,93 +1,97 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H
31 31
32#include <qmap.h> 32#include <qmap.h>
33#include <opie2/osqlresult.h> 33#include <opie2/osqlresult.h>
34 34
35#include <opie2/odatebookaccessbackend.h> 35#include <opie2/odatebookaccessbackend.h>
36 36
37namespace Opie {
38namespace DB {
37class OSQLDriver; 39class OSQLDriver;
40}
41}
38 42
39namespace Opie { 43namespace Opie {
40/** 44/**
41 * This is the default SQL implementation for DateBoook SQL storage 45 * This is the default SQL implementation for DateBoook SQL storage
42 * It fully implements the interface 46 * It fully implements the interface
43 * @see ODateBookAccessBackend 47 * @see ODateBookAccessBackend
44 * @see OPimAccessBackend 48 * @see OPimAccessBackend
45 */ 49 */
46class ODateBookAccessBackend_SQL : public ODateBookAccessBackend { 50class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
47public: 51public:
48 ODateBookAccessBackend_SQL( const QString& appName, 52 ODateBookAccessBackend_SQL( const QString& appName,
49 const QString& fileName = QString::null); 53 const QString& fileName = QString::null);
50 ~ODateBookAccessBackend_SQL(); 54 ~ODateBookAccessBackend_SQL();
51 55
52 bool load(); 56 bool load();
53 bool reload(); 57 bool reload();
54 bool save(); 58 bool save();
55 59
56 QArray<int> allRecords()const; 60 QArray<int> allRecords()const;
57 QArray<int> matchRegexp(const QRegExp &r) const; 61 QArray<int> matchRegexp(const QRegExp &r) const;
58 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); 62 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() );
59 OPimEvent find( int uid )const; 63 OPimEvent find( int uid )const;
60 void clear(); 64 void clear();
61 bool add( const OPimEvent& ev ); 65 bool add( const OPimEvent& ev );
62 bool remove( int uid ); 66 bool remove( int uid );
63 bool replace( const OPimEvent& ev ); 67 bool replace( const OPimEvent& ev );
64 68
65 QArray<UID> rawEvents()const; 69 QArray<UID> rawEvents()const;
66 QArray<UID> rawRepeats()const; 70 QArray<UID> rawRepeats()const;
67 QArray<UID> nonRepeats()const; 71 QArray<UID> nonRepeats()const;
68 72
69 OPimEvent::ValueList directNonRepeats(); 73 OPimEvent::ValueList directNonRepeats();
70 OPimEvent::ValueList directRawRepeats(); 74 OPimEvent::ValueList directRawRepeats();
71 75
72private: 76private:
73 bool loadFile(); 77 bool loadFile();
74 QString m_fileName; 78 QString m_fileName;
75 QArray<int> m_uids; 79 QArray<int> m_uids;
76 80
77 QMap<int, QString> m_fieldMap; 81 QMap<int, QString> m_fieldMap;
78 QMap<QString, int> m_reverseFieldMap; 82 QMap<QString, int> m_reverseFieldMap;
79 83
80 OSQLDriver* m_driver; 84 Opie::DB::OSQLDriver* m_driver;
81 85
82 class Private; 86 class Private;
83 Private *d; 87 Private *d;
84 88
85 void initFields(); 89 void initFields();
86 void update(); 90 void update();
87 QArray<int> extractUids( OSQLResult& res ) const; 91 QArray<int> extractUids( Opie::DB::OSQLResult& res ) const;
88 92
89}; 93};
90 94
91} 95}
92 96
93#endif 97#endif
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index 72232e5..d218090 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -1,726 +1,728 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#include <qdatetime.h> 30#include <qdatetime.h>
31 31
32#include <qpe/global.h> 32#include <qpe/global.h>
33 33
34#include <opie2/osqldriver.h> 34#include <opie2/osqldriver.h>
35#include <opie2/osqlresult.h> 35#include <opie2/osqlresult.h>
36#include <opie2/osqlmanager.h> 36#include <opie2/osqlmanager.h>
37#include <opie2/osqlquery.h> 37#include <opie2/osqlquery.h>
38 38
39#include <opie2/otodoaccesssql.h> 39#include <opie2/otodoaccesssql.h>
40#include <opie2/opimstate.h> 40#include <opie2/opimstate.h>
41#include <opie2/opimnotifymanager.h> 41#include <opie2/opimnotifymanager.h>
42#include <opie2/opimrecurrence.h> 42#include <opie2/opimrecurrence.h>
43 43
44using namespace Opie::DB;
45
44using namespace Opie; 46using namespace Opie;
45/* 47/*
46 * first some query 48 * first some query
47 * CREATE query 49 * CREATE query
48 * LOAD query 50 * LOAD query
49 * INSERT 51 * INSERT
50 * REMOVE 52 * REMOVE
51 * CLEAR 53 * CLEAR
52 */ 54 */
53namespace { 55namespace {
54 /** 56 /**
55 * CreateQuery for the Todolist Table 57 * CreateQuery for the Todolist Table
56 */ 58 */
57 class CreateQuery : public OSQLQuery { 59 class CreateQuery : public OSQLQuery {
58 public: 60 public:
59 CreateQuery(); 61 CreateQuery();
60 ~CreateQuery(); 62 ~CreateQuery();
61 QString query()const; 63 QString query()const;
62 }; 64 };
63 65
64 /** 66 /**
65 * LoadQuery 67 * LoadQuery
66 * this one queries for all uids 68 * this one queries for all uids
67 */ 69 */
68 class LoadQuery : public OSQLQuery { 70 class LoadQuery : public OSQLQuery {
69 public: 71 public:
70 LoadQuery(); 72 LoadQuery();
71 ~LoadQuery(); 73 ~LoadQuery();
72 QString query()const; 74 QString query()const;
73 }; 75 };
74 76
75 /** 77 /**
76 * inserts/adds a OPimTodo to the table 78 * inserts/adds a OPimTodo to the table
77 */ 79 */
78 class InsertQuery : public OSQLQuery { 80 class InsertQuery : public OSQLQuery {
79 public: 81 public:
80 InsertQuery(const OPimTodo& ); 82 InsertQuery(const OPimTodo& );
81 ~InsertQuery(); 83 ~InsertQuery();
82 QString query()const; 84 QString query()const;
83 private: 85 private:
84 OPimTodo m_todo; 86 OPimTodo m_todo;
85 }; 87 };
86 88
87 /** 89 /**
88 * removes one from the table 90 * removes one from the table
89 */ 91 */
90 class RemoveQuery : public OSQLQuery { 92 class RemoveQuery : public OSQLQuery {
91 public: 93 public:
92 RemoveQuery(int uid ); 94 RemoveQuery(int uid );
93 ~RemoveQuery(); 95 ~RemoveQuery();
94 QString query()const; 96 QString query()const;
95 private: 97 private:
96 int m_uid; 98 int m_uid;
97 }; 99 };
98 100
99 /** 101 /**
100 * Clears (delete) a Table 102 * Clears (delete) a Table
101 */ 103 */
102 class ClearQuery : public OSQLQuery { 104 class ClearQuery : public OSQLQuery {
103 public: 105 public:
104 ClearQuery(); 106 ClearQuery();
105 ~ClearQuery(); 107 ~ClearQuery();
106 QString query()const; 108 QString query()const;
107 109
108 }; 110 };
109 111
110 /** 112 /**
111 * a find query 113 * a find query
112 */ 114 */
113 class FindQuery : public OSQLQuery { 115 class FindQuery : public OSQLQuery {
114 public: 116 public:
115 FindQuery(int uid); 117 FindQuery(int uid);
116 FindQuery(const QArray<int>& ); 118 FindQuery(const QArray<int>& );
117 ~FindQuery(); 119 ~FindQuery();
118 QString query()const; 120 QString query()const;
119 private: 121 private:
120 QString single()const; 122 QString single()const;
121 QString multi()const; 123 QString multi()const;
122 QArray<int> m_uids; 124 QArray<int> m_uids;
123 int m_uid; 125 int m_uid;
124 }; 126 };
125 127
126 /** 128 /**
127 * overdue query 129 * overdue query
128 */ 130 */
129 class OverDueQuery : public OSQLQuery { 131 class OverDueQuery : public OSQLQuery {
130 public: 132 public:
131 OverDueQuery(); 133 OverDueQuery();
132 ~OverDueQuery(); 134 ~OverDueQuery();
133 QString query()const; 135 QString query()const;
134 }; 136 };
135 class EffQuery : public OSQLQuery { 137 class EffQuery : public OSQLQuery {
136 public: 138 public:
137 EffQuery( const QDate&, const QDate&, bool inc ); 139 EffQuery( const QDate&, const QDate&, bool inc );
138 ~EffQuery(); 140 ~EffQuery();
139 QString query()const; 141 QString query()const;
140 private: 142 private:
141 QString with()const; 143 QString with()const;
142 QString out()const; 144 QString out()const;
143 QDate m_start; 145 QDate m_start;
144 QDate m_end; 146 QDate m_end;
145 bool m_inc :1; 147 bool m_inc :1;
146 }; 148 };
147 149
148 150
149 CreateQuery::CreateQuery() : OSQLQuery() {} 151 CreateQuery::CreateQuery() : OSQLQuery() {}
150 CreateQuery::~CreateQuery() {} 152 CreateQuery::~CreateQuery() {}
151 QString CreateQuery::query()const { 153 QString CreateQuery::query()const {
152 QString qu; 154 QString qu;
153 qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; 155 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
154 qu += "description, summary, priority, DueDate, progress , state, "; 156 qu += "description, summary, priority, DueDate, progress , state, ";
155 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) 157 // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers)
156 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; 158 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, ";
157 qu += "reminders, alarms, maintainer, startdate, completeddate);"; 159 qu += "reminders, alarms, maintainer, startdate, completeddate);";
158 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 160 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
159 return qu; 161 return qu;
160 } 162 }
161 163
162 LoadQuery::LoadQuery() : OSQLQuery() {} 164 LoadQuery::LoadQuery() : OSQLQuery() {}
163 LoadQuery::~LoadQuery() {} 165 LoadQuery::~LoadQuery() {}
164 QString LoadQuery::query()const { 166 QString LoadQuery::query()const {
165 QString qu; 167 QString qu;
166 // We do not need "distinct" here. The primary key is always unique.. 168 // We do not need "distinct" here. The primary key is always unique..
167 //qu += "select distinct uid from todolist"; 169 //qu += "select distinct uid from todolist";
168 qu += "select uid from todolist"; 170 qu += "select uid from todolist";
169 171
170 return qu; 172 return qu;
171 } 173 }
172 174
173 InsertQuery::InsertQuery( const OPimTodo& todo ) 175 InsertQuery::InsertQuery( const OPimTodo& todo )
174 : OSQLQuery(), m_todo( todo ) { 176 : OSQLQuery(), m_todo( todo ) {
175 } 177 }
176 InsertQuery::~InsertQuery() { 178 InsertQuery::~InsertQuery() {
177 } 179 }
178 /* 180 /*
179 * converts from a OPimTodo to a query 181 * converts from a OPimTodo to a query
180 * we leave out X-Ref + Alarms 182 * we leave out X-Ref + Alarms
181 */ 183 */
182 QString InsertQuery::query()const{ 184 QString InsertQuery::query()const{
183 185
184 int year, month, day; 186 int year, month, day;
185 year = month = day = 0; 187 year = month = day = 0;
186 if (m_todo.hasDueDate() ) { 188 if (m_todo.hasDueDate() ) {
187 QDate date = m_todo.dueDate(); 189 QDate date = m_todo.dueDate();
188 year = date.year(); 190 year = date.year();
189 month = date.month(); 191 month = date.month();
190 day = date.day(); 192 day = date.day();
191 } 193 }
192 int sYear = 0, sMonth = 0, sDay = 0; 194 int sYear = 0, sMonth = 0, sDay = 0;
193 if( m_todo.hasStartDate() ){ 195 if( m_todo.hasStartDate() ){
194 QDate sDate = m_todo.startDate(); 196 QDate sDate = m_todo.startDate();
195 sYear = sDate.year(); 197 sYear = sDate.year();
196 sMonth= sDate.month(); 198 sMonth= sDate.month();
197 sDay = sDate.day(); 199 sDay = sDate.day();
198 } 200 }
199 201
200 int eYear = 0, eMonth = 0, eDay = 0; 202 int eYear = 0, eMonth = 0, eDay = 0;
201 if( m_todo.hasCompletedDate() ){ 203 if( m_todo.hasCompletedDate() ){
202 QDate eDate = m_todo.completedDate(); 204 QDate eDate = m_todo.completedDate();
203 eYear = eDate.year(); 205 eYear = eDate.year();
204 eMonth= eDate.month(); 206 eMonth= eDate.month();
205 eDay = eDate.day(); 207 eDay = eDate.day();
206 } 208 }
207 QString qu; 209 QString qu;
208 QMap<int, QString> recMap = m_todo.recurrence().toMap(); 210 QMap<int, QString> recMap = m_todo.recurrence().toMap();
209 qu = "insert into todolist VALUES(" 211 qu = "insert into todolist VALUES("
210 + QString::number( m_todo.uid() ) + "," 212 + QString::number( m_todo.uid() ) + ","
211 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," 213 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
212 + QString::number( m_todo.isCompleted() ) + "," 214 + QString::number( m_todo.isCompleted() ) + ","
213 + "'" + m_todo.description() + "'" + "," 215 + "'" + m_todo.description() + "'" + ","
214 + "'" + m_todo.summary() + "'" + "," 216 + "'" + m_todo.summary() + "'" + ","
215 + QString::number(m_todo.priority() ) + "," 217 + QString::number(m_todo.priority() ) + ","
216 + "'" + QString::number(year) + "-" 218 + "'" + QString::number(year) + "-"
217 + QString::number(month) 219 + QString::number(month)
218 + "-" + QString::number( day ) + "'" + "," 220 + "-" + QString::number( day ) + "'" + ","
219 + QString::number( m_todo.progress() ) + "," 221 + QString::number( m_todo.progress() ) + ","
220 + QString::number( m_todo.state().state() ) + "," 222 + QString::number( m_todo.state().state() ) + ","
221 + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," 223 + "'" + recMap[ OPimRecurrence::RType ] + "'" + ","
222 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," 224 + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + ","
223 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," 225 + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + ","
224 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," 226 + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + ","
225 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," 227 + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + ","
226 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," 228 + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + ","
227 + "'" + recMap[ OPimRecurrence::Created ] + "'" + "," 229 + "'" + recMap[ OPimRecurrence::Created ] + "'" + ","
228 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ","; 230 + "'" + recMap[ OPimRecurrence::Exceptions ] + "'" + ",";
229 231
230 if ( m_todo.hasNotifiers() ) { 232 if ( m_todo.hasNotifiers() ) {
231 OPimNotifyManager manager = m_todo.notifiers(); 233 OPimNotifyManager manager = m_todo.notifiers();
232 qu += "'" + manager.remindersToString() + "'" + "," 234 qu += "'" + manager.remindersToString() + "'" + ","
233 + "'" + manager.alarmsToString() + "'" + ","; 235 + "'" + manager.alarmsToString() + "'" + ",";
234 } 236 }
235 else{ 237 else{
236 qu += QString( "''" ) + "," 238 qu += QString( "''" ) + ","
237 + "''" + ","; 239 + "''" + ",";
238 } 240 }
239 241
240 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) 242 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !)
241 + "'" + QString::number(sYear) + "-" 243 + "'" + QString::number(sYear) + "-"
242 + QString::number(sMonth) 244 + QString::number(sMonth)
243 + "-" + QString::number(sDay) + "'" + "," 245 + "-" + QString::number(sDay) + "'" + ","
244 + "'" + QString::number(eYear) + "-" 246 + "'" + QString::number(eYear) + "-"
245 + QString::number(eMonth) 247 + QString::number(eMonth)
246 + "-"+QString::number(eDay) + "'" 248 + "-"+QString::number(eDay) + "'"
247 + ")"; 249 + ")";
248 250
249 qWarning("add %s", qu.latin1() ); 251 qWarning("add %s", qu.latin1() );
250 return qu; 252 return qu;
251 } 253 }
252 254
253 RemoveQuery::RemoveQuery(int uid ) 255 RemoveQuery::RemoveQuery(int uid )
254 : OSQLQuery(), m_uid( uid ) {} 256 : OSQLQuery(), m_uid( uid ) {}
255 RemoveQuery::~RemoveQuery() {} 257 RemoveQuery::~RemoveQuery() {}
256 QString RemoveQuery::query()const { 258 QString RemoveQuery::query()const {
257 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 259 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
258 return qu; 260 return qu;
259 } 261 }
260 262
261 263
262 ClearQuery::ClearQuery() 264 ClearQuery::ClearQuery()
263 : OSQLQuery() {} 265 : OSQLQuery() {}
264 ClearQuery::~ClearQuery() {} 266 ClearQuery::~ClearQuery() {}
265 QString ClearQuery::query()const { 267 QString ClearQuery::query()const {
266 QString qu = "drop table todolist"; 268 QString qu = "drop table todolist";
267 return qu; 269 return qu;
268 } 270 }
269 FindQuery::FindQuery(int uid) 271 FindQuery::FindQuery(int uid)
270 : OSQLQuery(), m_uid(uid ) { 272 : OSQLQuery(), m_uid(uid ) {
271 } 273 }
272 FindQuery::FindQuery(const QArray<int>& ints) 274 FindQuery::FindQuery(const QArray<int>& ints)
273 : OSQLQuery(), m_uids(ints){ 275 : OSQLQuery(), m_uids(ints){
274 } 276 }
275 FindQuery::~FindQuery() { 277 FindQuery::~FindQuery() {
276 } 278 }
277 QString FindQuery::query()const{ 279 QString FindQuery::query()const{
278 if (m_uids.count() == 0 ) 280 if (m_uids.count() == 0 )
279 return single(); 281 return single();
280 else 282 else
281 return multi(); 283 return multi();
282 } 284 }
283 QString FindQuery::single()const{ 285 QString FindQuery::single()const{
284 QString qu = "select * from todolist where uid = " + QString::number(m_uid); 286 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
285 return qu; 287 return qu;
286 } 288 }
287 QString FindQuery::multi()const { 289 QString FindQuery::multi()const {
288 QString qu = "select * from todolist where "; 290 QString qu = "select * from todolist where ";
289 for (uint i = 0; i < m_uids.count(); i++ ) { 291 for (uint i = 0; i < m_uids.count(); i++ ) {
290 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 292 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
291 } 293 }
292 qu.remove( qu.length()-2, 2 ); 294 qu.remove( qu.length()-2, 2 );
293 return qu; 295 return qu;
294 } 296 }
295 297
296 OverDueQuery::OverDueQuery(): OSQLQuery() {} 298 OverDueQuery::OverDueQuery(): OSQLQuery() {}
297 OverDueQuery::~OverDueQuery() {} 299 OverDueQuery::~OverDueQuery() {}
298 QString OverDueQuery::query()const { 300 QString OverDueQuery::query()const {
299 QDate date = QDate::currentDate(); 301 QDate date = QDate::currentDate();
300 QString str; 302 QString str;
301 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 303 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
302 304
303 return str; 305 return str;
304 } 306 }
305 307
306 308
307 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 309 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
308 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 310 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
309 EffQuery::~EffQuery() {} 311 EffQuery::~EffQuery() {}
310 QString EffQuery::query()const { 312 QString EffQuery::query()const {
311 return m_inc ? with() : out(); 313 return m_inc ? with() : out();
312 } 314 }
313 QString EffQuery::with()const { 315 QString EffQuery::with()const {
314 QString str; 316 QString str;
315 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 317 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
316 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 318 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
317 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 319 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
318 return str; 320 return str;
319 } 321 }
320 QString EffQuery::out()const { 322 QString EffQuery::out()const {
321 QString str; 323 QString str;
322 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 324 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
323 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 325 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
324 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 326 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
325 327
326 return str; 328 return str;
327 } 329 }
328}; 330};
329 331
330 332
331namespace Opie { 333namespace Opie {
332OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) 334OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file )
333 : OPimTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) 335 : OPimTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true)
334{ 336{
335 QString fi = file; 337 QString fi = file;
336 if ( fi.isEmpty() ) 338 if ( fi.isEmpty() )
337 fi = Global::applicationFileName( "todolist", "todolist.db" ); 339 fi = Global::applicationFileName( "todolist", "todolist.db" );
338 OSQLManager man; 340 OSQLManager man;
339 m_driver = man.standard(); 341 m_driver = man.standard();
340 m_driver->setUrl(fi); 342 m_driver->setUrl(fi);
341 // fillDict(); 343 // fillDict();
342} 344}
343 345
344OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){ 346OPimTodoAccessBackendSQL::~OPimTodoAccessBackendSQL(){
345 if( m_driver ) 347 if( m_driver )
346 delete m_driver; 348 delete m_driver;
347} 349}
348 350
349bool OPimTodoAccessBackendSQL::load(){ 351bool OPimTodoAccessBackendSQL::load(){
350 if (!m_driver->open() ) 352 if (!m_driver->open() )
351 return false; 353 return false;
352 354
353 CreateQuery creat; 355 CreateQuery creat;
354 OSQLResult res = m_driver->query(&creat ); 356 OSQLResult res = m_driver->query(&creat );
355 357
356 m_dirty = true; 358 m_dirty = true;
357 return true; 359 return true;
358} 360}
359bool OPimTodoAccessBackendSQL::reload(){ 361bool OPimTodoAccessBackendSQL::reload(){
360 return load(); 362 return load();
361} 363}
362 364
363bool OPimTodoAccessBackendSQL::save(){ 365bool OPimTodoAccessBackendSQL::save(){
364 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) 366 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
365} 367}
366QArray<int> OPimTodoAccessBackendSQL::allRecords()const { 368QArray<int> OPimTodoAccessBackendSQL::allRecords()const {
367 if (m_dirty ) 369 if (m_dirty )
368 update(); 370 update();
369 371
370 return m_uids; 372 return m_uids;
371} 373}
372QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){ 374QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, const QDateTime& ){
373 QArray<int> ints(0); 375 QArray<int> ints(0);
374 return ints; 376 return ints;
375} 377}
376OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ 378OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{
377 FindQuery query( uid ); 379 FindQuery query( uid );
378 return todo( m_driver->query(&query) ); 380 return todo( m_driver->query(&query) );
379 381
380} 382}
381OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 383OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
382 uint cur, Frontend::CacheDirection dir ) const{ 384 uint cur, Frontend::CacheDirection dir ) const{
383 uint CACHE = readAhead(); 385 uint CACHE = readAhead();
384 qWarning("searching for %d", uid ); 386 qWarning("searching for %d", uid );
385 QArray<int> search( CACHE ); 387 QArray<int> search( CACHE );
386 uint size =0; 388 uint size =0;
387 OPimTodo to; 389 OPimTodo to;
388 390
389 // we try to cache CACHE items 391 // we try to cache CACHE items
390 switch( dir ) { 392 switch( dir ) {
391 /* forward */ 393 /* forward */
392 case 0: // FIXME: Not a good style to use magic numbers here (eilers) 394 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
393 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 395 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
394 qWarning("size %d %d", size, ints[i] ); 396 qWarning("size %d %d", size, ints[i] );
395 search[size] = ints[i]; 397 search[size] = ints[i];
396 size++; 398 size++;
397 } 399 }
398 break; 400 break;
399 /* reverse */ 401 /* reverse */
400 case 1: // FIXME: Not a good style to use magic numbers here (eilers) 402 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
401 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 403 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
402 search[size] = ints[i]; 404 search[size] = ints[i];
403 size++; 405 size++;
404 } 406 }
405 break; 407 break;
406 } 408 }
407 search.resize( size ); 409 search.resize( size );
408 FindQuery query( search ); 410 FindQuery query( search );
409 OSQLResult res = m_driver->query( &query ); 411 OSQLResult res = m_driver->query( &query );
410 if ( res.state() != OSQLResult::Success ) 412 if ( res.state() != OSQLResult::Success )
411 return to; 413 return to;
412 414
413 return todo( res ); 415 return todo( res );
414} 416}
415void OPimTodoAccessBackendSQL::clear() { 417void OPimTodoAccessBackendSQL::clear() {
416 ClearQuery cle; 418 ClearQuery cle;
417 OSQLResult res = m_driver->query( &cle ); 419 OSQLResult res = m_driver->query( &cle );
418 CreateQuery qu; 420 CreateQuery qu;
419 res = m_driver->query(&qu); 421 res = m_driver->query(&qu);
420} 422}
421bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) { 423bool OPimTodoAccessBackendSQL::add( const OPimTodo& t) {
422 InsertQuery ins( t ); 424 InsertQuery ins( t );
423 OSQLResult res = m_driver->query( &ins ); 425 OSQLResult res = m_driver->query( &ins );
424 426
425 if ( res.state() == OSQLResult::Failure ) 427 if ( res.state() == OSQLResult::Failure )
426 return false; 428 return false;
427 int c = m_uids.count(); 429 int c = m_uids.count();
428 m_uids.resize( c+1 ); 430 m_uids.resize( c+1 );
429 m_uids[c] = t.uid(); 431 m_uids[c] = t.uid();
430 432
431 return true; 433 return true;
432} 434}
433bool OPimTodoAccessBackendSQL::remove( int uid ) { 435bool OPimTodoAccessBackendSQL::remove( int uid ) {
434 RemoveQuery rem( uid ); 436 RemoveQuery rem( uid );
435 OSQLResult res = m_driver->query(&rem ); 437 OSQLResult res = m_driver->query(&rem );
436 438
437 if ( res.state() == OSQLResult::Failure ) 439 if ( res.state() == OSQLResult::Failure )
438 return false; 440 return false;
439 441
440 m_dirty = true; 442 m_dirty = true;
441 return true; 443 return true;
442} 444}
443/* 445/*
444 * FIXME better set query 446 * FIXME better set query
445 * but we need the cache for that 447 * but we need the cache for that
446 * now we remove 448 * now we remove
447 */ 449 */
448bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) { 450bool OPimTodoAccessBackendSQL::replace( const OPimTodo& t) {
449 remove( t.uid() ); 451 remove( t.uid() );
450 bool b= add(t); 452 bool b= add(t);
451 m_dirty = false; // we changed some stuff but the UID stayed the same 453 m_dirty = false; // we changed some stuff but the UID stayed the same
452 return b; 454 return b;
453} 455}
454QArray<int> OPimTodoAccessBackendSQL::overDue() { 456QArray<int> OPimTodoAccessBackendSQL::overDue() {
455 OverDueQuery qu; 457 OverDueQuery qu;
456 return uids( m_driver->query(&qu ) ); 458 return uids( m_driver->query(&qu ) );
457} 459}
458QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, 460QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s,
459 const QDate& t, 461 const QDate& t,
460 bool u) { 462 bool u) {
461 EffQuery ef(s, t, u ); 463 EffQuery ef(s, t, u );
462 return uids (m_driver->query(&ef) ); 464 return uids (m_driver->query(&ef) );
463} 465}
464/* 466/*
465 * 467 *
466 */ 468 */
467QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 469QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
468 int sortFilter, int cat ) { 470 int sortFilter, int cat ) {
469 qWarning("sorted %d, %d", asc, sortOrder ); 471 qWarning("sorted %d, %d", asc, sortOrder );
470 QString query; 472 QString query;
471 query = "select uid from todolist WHERE "; 473 query = "select uid from todolist WHERE ";
472 474
473 /* 475 /*
474 * Sort Filter stuff 476 * Sort Filter stuff
475 * not that straight forward 477 * not that straight forward
476 * FIXME: Replace magic numbers 478 * FIXME: Replace magic numbers
477 * 479 *
478 */ 480 */
479 /* Category */ 481 /* Category */
480 if ( sortFilter & 1 ) { 482 if ( sortFilter & 1 ) {
481 QString str; 483 QString str;
482 if (cat != 0 ) str = QString::number( cat ); 484 if (cat != 0 ) str = QString::number( cat );
483 query += " categories like '%" +str+"%' AND"; 485 query += " categories like '%" +str+"%' AND";
484 } 486 }
485 /* Show only overdue */ 487 /* Show only overdue */
486 if ( sortFilter & 2 ) { 488 if ( sortFilter & 2 ) {
487 QDate date = QDate::currentDate(); 489 QDate date = QDate::currentDate();
488 QString due; 490 QString due;
489 QString base; 491 QString base;
490 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 492 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
491 query += " " + base + " AND"; 493 query += " " + base + " AND";
492 } 494 }
493 /* not show completed */ 495 /* not show completed */
494 if ( sortFilter & 4 ) { 496 if ( sortFilter & 4 ) {
495 query += " completed = 0 AND"; 497 query += " completed = 0 AND";
496 }else{ 498 }else{
497 query += " ( completed = 1 OR completed = 0) AND"; 499 query += " ( completed = 1 OR completed = 0) AND";
498 } 500 }
499 /* srtip the end */ 501 /* srtip the end */
500 query = query.remove( query.length()-3, 3 ); 502 query = query.remove( query.length()-3, 3 );
501 503
502 504
503 /* 505 /*
504 * sort order stuff 506 * sort order stuff
505 * quite straight forward 507 * quite straight forward
506 */ 508 */
507 query += "ORDER BY "; 509 query += "ORDER BY ";
508 switch( sortOrder ) { 510 switch( sortOrder ) {
509 /* completed */ 511 /* completed */
510 case 0: 512 case 0:
511 query += "completed"; 513 query += "completed";
512 break; 514 break;
513 case 1: 515 case 1:
514 query += "priority"; 516 query += "priority";
515 break; 517 break;
516 case 2: 518 case 2:
517 query += "summary"; 519 query += "summary";
518 break; 520 break;
519 case 3: 521 case 3:
520 query += "DueDate"; 522 query += "DueDate";
521 break; 523 break;
522 } 524 }
523 525
524 if ( !asc ) { 526 if ( !asc ) {
525 qWarning("not ascending!"); 527 qWarning("not ascending!");
526 query += " DESC"; 528 query += " DESC";
527 } 529 }
528 530
529 qWarning( query ); 531 qWarning( query );
530 OSQLRawQuery raw(query ); 532 OSQLRawQuery raw(query );
531 return uids( m_driver->query(&raw) ); 533 return uids( m_driver->query(&raw) );
532} 534}
533bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 535bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
534 if ( str == "0-0-0" ) 536 if ( str == "0-0-0" )
535 return false; 537 return false;
536 else{ 538 else{
537 int day, year, month; 539 int day, year, month;
538 QStringList list = QStringList::split("-", str ); 540 QStringList list = QStringList::split("-", str );
539 year = list[0].toInt(); 541 year = list[0].toInt();
540 month = list[1].toInt(); 542 month = list[1].toInt();
541 day = list[2].toInt(); 543 day = list[2].toInt();
542 da.setYMD( year, month, day ); 544 da.setYMD( year, month, day );
543 return true; 545 return true;
544 } 546 }
545} 547}
546OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 548OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res) const{
547 if ( res.state() == OSQLResult::Failure ) { 549 if ( res.state() == OSQLResult::Failure ) {
548 OPimTodo to; 550 OPimTodo to;
549 return to; 551 return to;
550 } 552 }
551 553
552 OSQLResultItem::ValueList list = res.results(); 554 OSQLResultItem::ValueList list = res.results();
553 OSQLResultItem::ValueList::Iterator it = list.begin(); 555 OSQLResultItem::ValueList::Iterator it = list.begin();
554 qWarning("todo1"); 556 qWarning("todo1");
555 OPimTodo to = todo( (*it) ); 557 OPimTodo to = todo( (*it) );
556 cache( to ); 558 cache( to );
557 ++it; 559 ++it;
558 560
559 for ( ; it != list.end(); ++it ) { 561 for ( ; it != list.end(); ++it ) {
560 qWarning("caching"); 562 qWarning("caching");
561 cache( todo( (*it) ) ); 563 cache( todo( (*it) ) );
562 } 564 }
563 return to; 565 return to;
564} 566}
565OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 567OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
566 qWarning("todo"); 568 qWarning("todo");
567 bool hasDueDate = false; QDate dueDate = QDate::currentDate(); 569 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
568 hasDueDate = date( dueDate, item.data("DueDate") ); 570 hasDueDate = date( dueDate, item.data("DueDate") );
569 QStringList cats = QStringList::split(";", item.data("categories") ); 571 QStringList cats = QStringList::split(";", item.data("categories") );
570 572
571 qWarning("Item is completed: %d", item.data("completed").toInt() ); 573 qWarning("Item is completed: %d", item.data("completed").toInt() );
572 574
573 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 575 OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
574 cats, item.data("summary"), item.data("description"), 576 cats, item.data("summary"), item.data("description"),
575 item.data("progress").toUShort(), hasDueDate, dueDate, 577 item.data("progress").toUShort(), hasDueDate, dueDate,
576 item.data("uid").toInt() ); 578 item.data("uid").toInt() );
577 579
578 bool isOk; 580 bool isOk;
579 int prioInt = QString( item.data("priority") ).toInt( &isOk ); 581 int prioInt = QString( item.data("priority") ).toInt( &isOk );
580 if ( isOk ) 582 if ( isOk )
581 to.setPriority( prioInt ); 583 to.setPriority( prioInt );
582 584
583 bool hasStartDate = false; QDate startDate = QDate::currentDate(); 585 bool hasStartDate = false; QDate startDate = QDate::currentDate();
584 hasStartDate = date( startDate, item.data("startdate") ); 586 hasStartDate = date( startDate, item.data("startdate") );
585 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); 587 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
586 hasCompletedDate = date( completedDate, item.data("completeddate") ); 588 hasCompletedDate = date( completedDate, item.data("completeddate") );
587 589
588 if ( hasStartDate ) 590 if ( hasStartDate )
589 to.setStartDate( startDate ); 591 to.setStartDate( startDate );
590 if ( hasCompletedDate ) 592 if ( hasCompletedDate )
591 to.setCompletedDate( completedDate ); 593 to.setCompletedDate( completedDate );
592 594
593 OPimNotifyManager& manager = to.notifiers(); 595 OPimNotifyManager& manager = to.notifiers();
594 manager.alarmsFromString( item.data("alarms") ); 596 manager.alarmsFromString( item.data("alarms") );
595 manager.remindersFromString( item.data("reminders") ); 597 manager.remindersFromString( item.data("reminders") );
596 598
597 OPimState pimState; 599 OPimState pimState;
598 pimState.setState( QString( item.data("state") ).toInt() ); 600 pimState.setState( QString( item.data("state") ).toInt() );
599 to.setState( pimState ); 601 to.setState( pimState );
600 602
601 QMap<int, QString> recMap; 603 QMap<int, QString> recMap;
602 recMap.insert( OPimRecurrence::RType , item.data("RType") ); 604 recMap.insert( OPimRecurrence::RType , item.data("RType") );
603 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") ); 605 recMap.insert( OPimRecurrence::RWeekdays , item.data("RWeekdays") );
604 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") ); 606 recMap.insert( OPimRecurrence::RPosition , item.data("RPosition") );
605 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") ); 607 recMap.insert( OPimRecurrence::RFreq , item.data("RFreq") );
606 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") ); 608 recMap.insert( OPimRecurrence::RHasEndDate, item.data("RHasEndDate") );
607 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); 609 recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") );
608 recMap.insert( OPimRecurrence::Created , item.data("Created") ); 610 recMap.insert( OPimRecurrence::Created , item.data("Created") );
609 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); 611 recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") );
610 612
611 OPimRecurrence recur; 613 OPimRecurrence recur;
612 recur.fromMap( recMap ); 614 recur.fromMap( recMap );
613 to.setRecurrence( recur ); 615 to.setRecurrence( recur );
614 616
615 return to; 617 return to;
616} 618}
617OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { 619OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const {
618 FindQuery find( uid ); 620 FindQuery find( uid );
619 return todo( m_driver->query(&find) ); 621 return todo( m_driver->query(&find) );
620} 622}
621/* 623/*
622 * update the dict 624 * update the dict
623 */ 625 */
624void OPimTodoAccessBackendSQL::fillDict() { 626void OPimTodoAccessBackendSQL::fillDict() {
625 /* initialize dict */ 627 /* initialize dict */
626 /* 628 /*
627 * UPDATE dict if you change anything!!! 629 * UPDATE dict if you change anything!!!
628 * FIXME: Isn't this dict obsolete ? (eilers) 630 * FIXME: Isn't this dict obsolete ? (eilers)
629 */ 631 */
630 m_dict.setAutoDelete( TRUE ); 632 m_dict.setAutoDelete( TRUE );
631 m_dict.insert("Categories" , new int(OPimTodo::Category) ); 633 m_dict.insert("Categories" , new int(OPimTodo::Category) );
632 m_dict.insert("Uid" , new int(OPimTodo::Uid) ); 634 m_dict.insert("Uid" , new int(OPimTodo::Uid) );
633 m_dict.insert("HasDate" , new int(OPimTodo::HasDate) ); 635 m_dict.insert("HasDate" , new int(OPimTodo::HasDate) );
634 m_dict.insert("Completed" , new int(OPimTodo::Completed) ); 636 m_dict.insert("Completed" , new int(OPimTodo::Completed) );
635 m_dict.insert("Description" , new int(OPimTodo::Description) ); 637 m_dict.insert("Description" , new int(OPimTodo::Description) );
636 m_dict.insert("Summary" , new int(OPimTodo::Summary) ); 638 m_dict.insert("Summary" , new int(OPimTodo::Summary) );
637 m_dict.insert("Priority" , new int(OPimTodo::Priority) ); 639 m_dict.insert("Priority" , new int(OPimTodo::Priority) );
638 m_dict.insert("DateDay" , new int(OPimTodo::DateDay) ); 640 m_dict.insert("DateDay" , new int(OPimTodo::DateDay) );
639 m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); 641 m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
640 m_dict.insert("DateYear" , new int(OPimTodo::DateYear) ); 642 m_dict.insert("DateYear" , new int(OPimTodo::DateYear) );
641 m_dict.insert("Progress" , new int(OPimTodo::Progress) ); 643 m_dict.insert("Progress" , new int(OPimTodo::Progress) );
642 m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers) 644 m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers)
643 m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); 645 m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
644// m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers) 646// m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers)
645// m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers) 647// m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers)
646} 648}
647/* 649/*
648 * need to be const so let's fool the 650 * need to be const so let's fool the
649 * compiler :( 651 * compiler :(
650 */ 652 */
651void OPimTodoAccessBackendSQL::update()const { 653void OPimTodoAccessBackendSQL::update()const {
652 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; 654 ((OPimTodoAccessBackendSQL*)this)->m_dirty = false;
653 LoadQuery lo; 655 LoadQuery lo;
654 OSQLResult res = m_driver->query(&lo); 656 OSQLResult res = m_driver->query(&lo);
655 if ( res.state() != OSQLResult::Success ) 657 if ( res.state() != OSQLResult::Success )
656 return; 658 return;
657 659
658 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); 660 ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res );
659} 661}
660QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 662QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{
661 663
662 OSQLResultItem::ValueList list = res.results(); 664 OSQLResultItem::ValueList list = res.results();
663 OSQLResultItem::ValueList::Iterator it; 665 OSQLResultItem::ValueList::Iterator it;
664 QArray<int> ints(list.count() ); 666 QArray<int> ints(list.count() );
665 qWarning(" count = %d", list.count() ); 667 qWarning(" count = %d", list.count() );
666 668
667 int i = 0; 669 int i = 0;
668 for (it = list.begin(); it != list.end(); ++it ) { 670 for (it = list.begin(); it != list.end(); ++it ) {
669 ints[i] = (*it).data("uid").toInt(); 671 ints[i] = (*it).data("uid").toInt();
670 i++; 672 i++;
671 } 673 }
672 return ints; 674 return ints;
673} 675}
674 676
675QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 677QArray<int> OPimTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
676{ 678{
677 679
678#warning OPimTodoAccessBackendSQL::matchRegexp() not implemented !! 680#warning OPimTodoAccessBackendSQL::matchRegexp() not implemented !!
679 681
680#if 0 682#if 0
681 683
682 Copied from xml-backend by not adapted to sql (eilers) 684 Copied from xml-backend by not adapted to sql (eilers)
683 685
684 QArray<int> m_currentQuery( m_events.count() ); 686 QArray<int> m_currentQuery( m_events.count() );
685 uint arraycounter = 0; 687 uint arraycounter = 0;
686 688
687 689
688 690
689 QMap<int, OPimTodo>::ConstIterator it; 691 QMap<int, OPimTodo>::ConstIterator it;
690 for (it = m_events.begin(); it != m_events.end(); ++it ) { 692 for (it = m_events.begin(); it != m_events.end(); ++it ) {
691 if ( it.data().match( r ) ) 693 if ( it.data().match( r ) )
692 m_currentQuery[arraycounter++] = it.data().uid(); 694 m_currentQuery[arraycounter++] = it.data().uid();
693 695
694 } 696 }
695 // Shrink to fit.. 697 // Shrink to fit..
696 m_currentQuery.resize(arraycounter); 698 m_currentQuery.resize(arraycounter);
697 699
698 return m_currentQuery; 700 return m_currentQuery;
699#endif 701#endif
700 QArray<int> empty; 702 QArray<int> empty;
701 return empty; 703 return empty;
702} 704}
703QBitArray OPimTodoAccessBackendSQL::supports()const { 705QBitArray OPimTodoAccessBackendSQL::supports()const {
704 706
705 return sup(); 707 return sup();
706} 708}
707 709
708QBitArray OPimTodoAccessBackendSQL::sup() const{ 710QBitArray OPimTodoAccessBackendSQL::sup() const{
709 711
710 QBitArray ar( OPimTodo::CompletedDate + 1 ); 712 QBitArray ar( OPimTodo::CompletedDate + 1 );
711 ar.fill( true ); 713 ar.fill( true );
712 ar[OPimTodo::CrossReference] = false; 714 ar[OPimTodo::CrossReference] = false;
713 ar[OPimTodo::State ] = false; 715 ar[OPimTodo::State ] = false;
714 ar[OPimTodo::Reminders] = false; 716 ar[OPimTodo::Reminders] = false;
715 ar[OPimTodo::Notifiers] = false; 717 ar[OPimTodo::Notifiers] = false;
716 ar[OPimTodo::Maintainer] = false; 718 ar[OPimTodo::Maintainer] = false;
717 719
718 return ar; 720 return ar;
719} 721}
720 722
721void OPimTodoAccessBackendSQL::removeAllCompleted(){ 723void OPimTodoAccessBackendSQL::removeAllCompleted(){
722#warning OPimTodoAccessBackendSQL::removeAllCompleted() not implemented !! 724#warning OPimTodoAccessBackendSQL::removeAllCompleted() not implemented !!
723 725
724} 726}
725 727
726} 728}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h
index e945863..0ae2591 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.h
+++ b/libopie2/opiepim/backend/otodoaccesssql.h
@@ -1,88 +1,92 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_PIM_ACCESS_SQL_H 29#ifndef OPIE_PIM_ACCESS_SQL_H
30#define OPIE_PIM_ACCESS_SQL_H 30#define OPIE_PIM_ACCESS_SQL_H
31 31
32#include <qasciidict.h> 32#include <qasciidict.h>
33 33
34#include <opie2/otodoaccessbackend.h> 34#include <opie2/otodoaccessbackend.h>
35 35
36namespace Opie {
37namespace DB {
36class OSQLDriver; 38class OSQLDriver;
37class OSQLResult; 39class OSQLResult;
38class OSQLResultItem; 40class OSQLResultItem;
41}
42}
39 43
40namespace Opie { 44namespace Opie {
41 45
42class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend { 46class OPimTodoAccessBackendSQL : public OPimTodoAccessBackend {
43public: 47public:
44 OPimTodoAccessBackendSQL( const QString& file ); 48 OPimTodoAccessBackendSQL( const QString& file );
45 ~OPimTodoAccessBackendSQL(); 49 ~OPimTodoAccessBackendSQL();
46 50
47 bool load(); 51 bool load();
48 bool reload(); 52 bool reload();
49 bool save(); 53 bool save();
50 QArray<int> allRecords()const; 54 QArray<int> allRecords()const;
51 55
52 QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() ); 56 QArray<int> queryByExample( const OPimTodo& t, int settings, const QDateTime& d = QDateTime() );
53 OPimTodo find(int uid)const; 57 OPimTodo find(int uid)const;
54 OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const; 58 OPimTodo find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
55 void clear(); 59 void clear();
56 bool add( const OPimTodo& t ); 60 bool add( const OPimTodo& t );
57 bool remove( int uid ); 61 bool remove( int uid );
58 bool replace( const OPimTodo& t ); 62 bool replace( const OPimTodo& t );
59 63
60 QArray<int> overDue(); 64 QArray<int> overDue();
61 QArray<int> effectiveToDos( const QDate& start, 65 QArray<int> effectiveToDos( const QDate& start,
62 const QDate& end, bool includeNoDates ); 66 const QDate& end, bool includeNoDates );
63 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat ); 67 QArray<int> sorted(bool asc, int sortOrder, int sortFilter, int cat );
64 68
65 QBitArray supports()const; 69 QBitArray supports()const;
66 QArray<int> matchRegexp( const QRegExp &r ) const; 70 QArray<int> matchRegexp( const QRegExp &r ) const;
67 void removeAllCompleted(); 71 void removeAllCompleted();
68 72
69 73
70private: 74private:
71 void update()const; 75 void update()const;
72 void fillDict(); 76 void fillDict();
73 inline bool date( QDate& date, const QString& )const; 77 inline bool date( QDate& date, const QString& )const;
74 inline OPimTodo todo( const OSQLResult& )const; 78 inline OPimTodo todo( const Opie::DB::OSQLResult& )const;
75 inline OPimTodo todo( OSQLResultItem& )const; 79 inline OPimTodo todo( Opie::DB::OSQLResultItem& )const;
76 inline QArray<int> uids( const OSQLResult& )const; 80 inline QArray<int> uids( const Opie::DB::OSQLResult& )const;
77 OPimTodo todo( int uid )const; 81 OPimTodo todo( int uid )const;
78 QBitArray sup() const; 82 QBitArray sup() const;
79 83
80 QAsciiDict<int> m_dict; 84 QAsciiDict<int> m_dict;
81 OSQLDriver* m_driver; 85 Opie::DB::OSQLDriver* m_driver;
82 QArray<int> m_uids; 86 QArray<int> m_uids;
83 bool m_dirty : 1; 87 bool m_dirty : 1;
84}; 88};
85 89
86} 90}
87 91
88#endif 92#endif
diff --git a/libopie2/opiepim/core/backends/private/xmltree.cc b/libopie2/opiepim/core/backends/private/xmltree.cc
new file mode 100644
index 0000000..40749ca
--- a/dev/null
+++ b/libopie2/opiepim/core/backends/private/xmltree.cc
@@ -0,0 +1,323 @@
1/* This file is part of the KDE project
2 Copyright (C) 2001 Simon Hausmann <hausmann@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#include "xmltree.h"
21
22#include <qpe/stringutil.h>
23
24#include <qxml.h>
25
26#include <assert.h>
27
28using namespace Opie::Pim::Private;
29
30XMLElement::XMLElement()
31 : m_parent( 0 ), m_next( 0 ), m_prev( 0 ), m_first( 0 ), m_last( 0 )
32{
33}
34
35XMLElement::~XMLElement()
36{
37 XMLElement *n = m_first;
38
39 while ( n )
40 {
41 XMLElement *tmp = n;
42 n = n->m_next;
43 delete tmp;
44 }
45}
46
47void XMLElement::appendChild( XMLElement *child )
48{
49 if ( child->m_parent )
50 child->m_parent->removeChild( child );
51
52 child->m_parent = this;
53
54 if ( m_last )
55 m_last->m_next = child;
56
57 child->m_prev = m_last;
58
59 if ( !m_first )
60 m_first = child;
61
62 m_last = child;
63}
64
65void XMLElement::insertAfter( XMLElement *newChild, XMLElement *refChild )
66{
67 assert( newChild != refChild );
68
69 if ( refChild == m_last )
70 {
71 appendChild( newChild );
72 return;
73 }
74
75 assert( refChild );
76 assert( refChild->m_parent );
77 assert( refChild->m_parent == this );
78
79 if ( newChild->m_parent && newChild != refChild )
80 newChild->m_parent->removeChild( newChild );
81
82 newChild->m_parent = this;
83
84 XMLElement *next = refChild->m_next;
85
86 refChild->m_next = newChild;
87
88 newChild->m_prev = refChild;
89 newChild->m_next = next;
90
91 if ( next )
92 next->m_prev = newChild;
93}
94
95QString XMLElement::attribute( const QString &attr ) const
96{
97 AttributeMap::ConstIterator it = m_attributes.find( attr );
98 if ( it == m_attributes.end() )
99 return QString::null;
100 return it.data();
101}
102
103void XMLElement::setAttribute( const QString &attr, const QString &value )
104{
105 m_attributes.replace( attr, value );
106}
107
108void XMLElement::insertBefore( XMLElement *newChild, XMLElement *refChild )
109{
110 assert( refChild );
111 assert( refChild->m_parent );
112 assert( refChild->m_parent == this );
113 assert( newChild != refChild );
114
115 if ( newChild->m_parent && newChild != refChild )
116 newChild->m_parent->removeChild( newChild );
117
118 newChild->m_parent = this;
119
120 XMLElement *prev = refChild->m_prev;
121
122 refChild->m_prev = newChild;
123
124 newChild->m_prev = prev;
125 newChild->m_next = refChild;
126
127 if ( prev )
128 prev->m_next = newChild;
129
130 if ( refChild == m_first )
131 m_first = newChild;
132}
133
134void XMLElement::removeChild( XMLElement *child )
135{
136 if ( child->m_parent != this )
137 return;
138
139 if ( m_first == child )
140 m_first = child->m_next;
141
142 if ( m_last == child )
143 m_last = child->m_prev;
144
145 if ( child->m_prev )
146 child->m_prev->m_next = child->m_next;
147
148 if ( child->m_next )
149 child->m_next->m_prev = child->m_prev;
150
151 child->m_parent = 0;
152 child->m_prev = 0;
153 child->m_next = 0;
154}
155
156void XMLElement::save( QTextStream &s, uint indent )
157{
158 if ( !m_value.isEmpty() )
159 {
160 s << Qtopia::escapeString( m_value );
161 return;
162 }
163
164 for ( uint i = 0; i < indent; ++i )
165 s << " ";
166
167 s << "<" << m_tag;
168
169 if ( !m_attributes.isEmpty() )
170 {
171 s << " ";
172 AttributeMap::ConstIterator it = m_attributes.begin();
173 AttributeMap::ConstIterator end = m_attributes.end();
174 for (; it != end; ++it )
175 {
176 s << it.key() << "=\"" << Qtopia::escapeString( it.data() ) << "\"";
177 s << " ";
178 }
179 }
180
181 if ( m_last )
182 {
183 if ( ( m_first && !m_first->value().isEmpty() ) || !m_parent )
184 s << ">";
185 else
186 s << ">" << endl;
187
188 int newIndent = indent;
189 if ( m_parent )
190 newIndent++;
191
192 XMLElement *n = m_first;
193 while ( n )
194 {
195 n->save( s, newIndent );
196 n = n->nextChild();
197 }
198
199 if ( m_last && m_last->value().isEmpty() && m_parent )
200 for ( uint i = 0; i < indent; ++i )
201 s << " ";
202
203 if ( m_parent )
204 s << "</" << m_tag << ">" << endl;
205 }
206 else
207 s << "/>" << endl;
208}
209
210class Handler : public QXmlDefaultHandler
211{
212public:
213 Handler() : m_node( 0 ), m_root( 0 ) {}
214
215 XMLElement *root() const { return m_root; }
216
217 virtual bool startDocument();
218 virtual bool endDocument();
219 virtual bool startElement( const QString &ns, const QString &ln, const QString &qName,
220 const QXmlAttributes &attr );
221 virtual bool endElement( const QString &ns, const QString &ln, const QString &qName );
222 virtual bool characters( const QString &ch );
223
224private:
225 XMLElement *m_node;
226 XMLElement *m_root;
227};
228
229bool Handler::startDocument()
230{
231 m_root = m_node = new XMLElement;
232
233 return true;
234}
235
236bool Handler::endDocument()
237{
238 return m_root == m_node;
239}
240
241bool Handler::startElement( const QString &, const QString &, const QString &qName,
242 const QXmlAttributes &attr )
243{
244 XMLElement *bm = new XMLElement;
245
246 XMLElement::AttributeMap attributes;
247 for ( int i = 0; i < attr.length(); ++i )
248 attributes[ attr.qName( i ) ] = attr.value( i );
249
250 bm->setAttributes( attributes );
251
252 bm->setTagName( qName );
253
254 m_node->appendChild( bm );
255 m_node = bm;
256
257 return true;
258}
259
260bool Handler::endElement( const QString &, const QString &, const QString & )
261{
262 if ( m_node == m_root )
263 return false;
264
265 m_node = m_node->parent();
266 return true;
267}
268
269bool Handler::characters( const QString &ch )
270{
271 XMLElement *textNode = new XMLElement;
272 textNode->setValue( ch );
273 m_node->appendChild( textNode );
274 return true;
275}
276
277XMLElement *XMLElement::namedItem( const QString &name )
278{
279 XMLElement *e = m_first;
280
281 for (; e; e = e->nextChild() )
282 if ( e->tagName() == name )
283 return e;
284
285 return 0;
286}
287
288XMLElement *XMLElement::clone() const
289{
290 XMLElement *res = new XMLElement;
291
292 res->setTagName( m_tag );
293 res->setValue( m_value );
294 res->setAttributes( m_attributes );
295
296 XMLElement *e = m_first;
297 for (; e; e = e->m_next )
298 res->appendChild( e->clone() );
299
300 return res;
301}
302
303XMLElement *XMLElement::load( const QString &fileName )
304{
305 QFile f( fileName );
306 if ( !f.open( IO_ReadOnly ) )
307 return 0;
308
309 QTextStream stream( &f );
310 stream.setEncoding( QTextStream::UnicodeUTF8 );
311 QXmlInputSource src( stream );
312 QXmlSimpleReader reader;
313 Handler handler;
314
315 reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", false );
316 reader.setContentHandler( &handler );
317 reader.parse( src );
318
319 return handler.root();;
320}
321
322/* vim: et sw=4
323 */
diff --git a/libopie2/opiepim/core/backends/private/xmltree.h b/libopie2/opiepim/core/backends/private/xmltree.h
new file mode 100644
index 0000000..9817a02
--- a/dev/null
+++ b/libopie2/opiepim/core/backends/private/xmltree.h
@@ -0,0 +1,122 @@
1/* This file is part of the KDE project
2 Copyright (C) 2000,2001 Simon Hausmann <hausmann@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20
21#ifndef __bookmarks_h__
22#define __bookmarks_h__
23
24#include <qstring.h>
25#include <qmap.h>
26#include <qtextstream.h>
27
28namespace Opie {
29namespace Pim {
30namespace Private{
31
32/**
33 * A small xml lib written by Simon Hausmann.
34 */
35class XMLElement
36{
37public:
38 typedef QMap<QString, QString> AttributeMap;
39
40 /**
41 * The constructor of XMLElement
42 */
43 XMLElement();
44 ~XMLElement();
45
46 /** appendChild appends a child to the XMLElement behind the last element.
47 * The ownership of the child get's transfered to the
48 * this XMLElement.
49 * If child is already the child of another parent
50 * it's get removed from the other parent first.
51 */
52 void appendChild( XMLElement *child );
53
54 /** inserts newChild after refChild. If newChild is the child
55 * of another parent the child will get removed.
56 * The ownership of child gets transfered.
57 *
58 */
59 void insertAfter( XMLElement *newChild, XMLElement *refChild );
60
61 /** same as insertAfter but the element get's inserted before refChild.
62 *
63 */
64 void insertBefore( XMLElement *newChild, XMLElement *refChild );
65
66 /** removeChild removes the child from the XMLElement.
67 * The ownership gets dropped. You need to delete the
68 * child yourself.
69 */
70 void removeChild( XMLElement *child );
71
72 /** parent() returns the parent of this XMLElement
73 * If there is no parent 0l gets returned
74 */
75 XMLElement *parent() const { return m_parent; }
76 XMLElement *firstChild() const { return m_first; }
77 XMLElement *nextChild() const { return m_next; }
78 XMLElement *prevChild() const { return m_prev; }
79 XMLElement *lastChild() const { return m_last; }
80
81 void setTagName( const QString &tag ) { m_tag = tag; }
82 QString tagName() const { return m_tag; }
83
84 void setValue( const QString &val ) { m_value = val; }
85 QString value() const { return m_value; }
86
87 void setAttributes( const AttributeMap &attrs ) { m_attributes = attrs; }
88 AttributeMap attributes() const { return m_attributes; }
89 AttributeMap &attributes() { return m_attributes; }
90
91 QString attribute( const QString & ) const;
92 void setAttribute( const QString &attr, const QString &value );
93 void save( QTextStream &stream, uint indent = 0 );
94
95 XMLElement *namedItem( const QString &name );
96
97 XMLElement *clone() const;
98
99 static XMLElement *load( const QString &fileName );
100
101private:
102 QString m_tag;
103 QString m_value;
104 AttributeMap m_attributes;
105
106 XMLElement *m_parent;
107 XMLElement *m_next;
108 XMLElement *m_prev;
109 XMLElement *m_first;
110 XMLElement *m_last;
111
112 XMLElement( const XMLElement &rhs );
113 XMLElement &operator=( const XMLElement &rhs );
114 class Private;
115 Private* d;
116};
117
118}
119}
120} // namespace Opie
121
122#endif