-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 221e977..3d284f7 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | |||
@@ -1,953 +1,955 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> | 3 | Copyright (C) Stefan Eilers <eilers.stefan@epost.de> |
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | 4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> |
5 | .=l. | 5 | .=l. |
6 | .>+-= | 6 | .>+-= |
7 | _;:, .> :=|. This program is free software; you can | 7 | _;:, .> :=|. This program is free software; you can |
8 | .> <`_, > . <= redistribute it and/or modify it under | 8 | .> <`_, > . <= redistribute it and/or modify it under |
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
10 | .="- .-=="i, .._ License as published by the Free Software | 10 | .="- .-=="i, .._ License as published by the Free Software |
11 | - . .-<_> .<> Foundation; either version 2 of the License, | 11 | - . .-<_> .<> Foundation; either version 2 of the License, |
12 | ._= =} : or (at your option) any later version. | 12 | ._= =} : or (at your option) any later version. |
13 | .%`+i> _;_. | 13 | .%`+i> _;_. |
14 | .i_,=:_. -<s. This program is distributed in the hope that | 14 | .i_,=:_. -<s. This program is distributed in the hope that |
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
16 | : .. .:, . . . without even the implied warranty of | 16 | : .. .:, . . . without even the implied warranty of |
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
19 | ..}^=.= = ; Library General Public License for more | 19 | ..}^=.= = ; Library General Public License for more |
20 | ++= -. .` .: details. | 20 | ++= -. .` .: details. |
21 | : = ...= . :.=- | 21 | : = ...= . :.=- |
22 | -. .:....=;==+<; You should have received a copy of the GNU | 22 | -. .:....=;==+<; You should have received a copy of the GNU |
23 | -_. . . )=. = Library General Public License along with | 23 | -_. . . )=. = Library General Public License along with |
24 | -- :-=` this library; see the file COPYING.LIB. | 24 | -- :-=` this library; see the file COPYING.LIB. |
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | /* | 29 | /* |
30 | * SQL Backend for the OPIE-Contact Database. | 30 | * SQL Backend for the OPIE-Contact Database. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "ocontactaccessbackend_sql.h" | 33 | #include "ocontactaccessbackend_sql.h" |
34 | 34 | ||
35 | /* OPIE */ | 35 | /* OPIE */ |
36 | #include <opie2/opimcontact.h> | 36 | #include <opie2/opimcontact.h> |
37 | #include <opie2/opimcontactfields.h> | 37 | #include <opie2/opimcontactfields.h> |
38 | #include <opie2/opimdateconversion.h> | 38 | #include <opie2/opimdateconversion.h> |
39 | #include <opie2/osqldriver.h> | 39 | #include <opie2/osqldriver.h> |
40 | #include <opie2/osqlresult.h> | 40 | #include <opie2/osqlresult.h> |
41 | #include <opie2/osqlmanager.h> | 41 | #include <opie2/osqlmanager.h> |
42 | #include <opie2/osqlquery.h> | 42 | #include <opie2/osqlquery.h> |
43 | #include <opie2/odebug.h> | 43 | #include <opie2/odebug.h> |
44 | 44 | ||
45 | #include <qpe/global.h> | 45 | #include <qpe/global.h> |
46 | #include <qpe/recordfields.h> | 46 | #include <qpe/recordfields.h> |
47 | 47 | ||
48 | /* QT */ | 48 | /* QT */ |
49 | #include <qarray.h> | 49 | #include <qarray.h> |
50 | #include <qdatetime.h> | 50 | #include <qdatetime.h> |
51 | #include <qstringlist.h> | 51 | #include <qstringlist.h> |
52 | 52 | ||
53 | 53 | ||
54 | using namespace Opie; | 54 | using namespace Opie; |
55 | using namespace Opie::DB; | 55 | using namespace Opie::DB; |
56 | 56 | ||
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Implementation of used query types * CREATE query | 59 | * Implementation of used query types * CREATE query |
60 | * LOAD query | 60 | * LOAD query |
61 | * INSERT | 61 | * INSERT |
62 | * REMOVE | 62 | * REMOVE |
63 | * CLEAR | 63 | * CLEAR |
64 | */ | 64 | */ |
65 | namespace { | 65 | namespace { |
66 | /** | 66 | /** |
67 | * CreateQuery for the Todolist Table | 67 | * CreateQuery for the Todolist Table |
68 | */ | 68 | */ |
69 | class CreateQuery : public OSQLQuery { | 69 | class CreateQuery : public OSQLQuery { |
70 | public: | 70 | public: |
71 | CreateQuery(); | 71 | CreateQuery(); |
72 | ~CreateQuery(); | 72 | ~CreateQuery(); |
73 | QString query()const; | 73 | QString query()const; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | /** | 76 | /** |
77 | * Clears (delete) a Table | 77 | * Clears (delete) a Table |
78 | */ | 78 | */ |
79 | class ClearQuery : public OSQLQuery { | 79 | class ClearQuery : public OSQLQuery { |
80 | public: | 80 | public: |
81 | ClearQuery(); | 81 | ClearQuery(); |
82 | ~ClearQuery(); | 82 | ~ClearQuery(); |
83 | QString query()const; | 83 | QString query()const; |
84 | 84 | ||
85 | }; | 85 | }; |
86 | 86 | ||
87 | 87 | ||
88 | /** | 88 | /** |
89 | * LoadQuery | 89 | * LoadQuery |
90 | * this one queries for all uids | 90 | * this one queries for all uids |
91 | */ | 91 | */ |
92 | class LoadQuery : public OSQLQuery { | 92 | class LoadQuery : public OSQLQuery { |
93 | public: | 93 | public: |
94 | LoadQuery(); | 94 | LoadQuery(); |
95 | ~LoadQuery(); | 95 | ~LoadQuery(); |
96 | QString query()const; | 96 | QString query()const; |
97 | }; | 97 | }; |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * inserts/adds a OPimContact to the table | 100 | * inserts/adds a OPimContact to the table |
101 | */ | 101 | */ |
102 | class InsertQuery : public OSQLQuery { | 102 | class InsertQuery : public OSQLQuery { |
103 | public: | 103 | public: |
104 | InsertQuery(const OPimContact& ); | 104 | InsertQuery(const OPimContact& ); |
105 | ~InsertQuery(); | 105 | ~InsertQuery(); |
106 | QString query()const; | 106 | QString query()const; |
107 | private: | 107 | private: |
108 | OPimContact m_contact; | 108 | OPimContact m_contact; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | 111 | ||
112 | /** | 112 | /** |
113 | * removes one from the table | 113 | * removes one from the table |
114 | */ | 114 | */ |
115 | class RemoveQuery : public OSQLQuery { | 115 | class RemoveQuery : public OSQLQuery { |
116 | public: | 116 | public: |
117 | RemoveQuery(int uid ); | 117 | RemoveQuery(int uid ); |
118 | ~RemoveQuery(); | 118 | ~RemoveQuery(); |
119 | QString query()const; | 119 | QString query()const; |
120 | private: | 120 | private: |
121 | int m_uid; | 121 | int m_uid; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /** | 124 | /** |
125 | * a find query for noncustom elements | 125 | * a find query for noncustom elements |
126 | */ | 126 | */ |
127 | class FindQuery : public OSQLQuery { | 127 | class FindQuery : public OSQLQuery { |
128 | public: | 128 | public: |
129 | FindQuery(int uid); | 129 | FindQuery(int uid); |
130 | FindQuery(const QArray<int>& ); | 130 | FindQuery(const QArray<int>& ); |
131 | ~FindQuery(); | 131 | ~FindQuery(); |
132 | QString query()const; | 132 | QString query()const; |
133 | private: | 133 | private: |
134 | QString single()const; | 134 | QString single()const; |
135 | QString multi()const; | 135 | QString multi()const; |
136 | QArray<int> m_uids; | 136 | QArray<int> m_uids; |
137 | int m_uid; | 137 | int m_uid; |
138 | }; | 138 | }; |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * a find query for custom elements | 141 | * a find query for custom elements |
142 | */ | 142 | */ |
143 | class FindCustomQuery : public OSQLQuery { | 143 | class FindCustomQuery : public OSQLQuery { |
144 | public: | 144 | public: |
145 | FindCustomQuery(int uid); | 145 | FindCustomQuery(int uid); |
146 | FindCustomQuery(const QArray<int>& ); | 146 | FindCustomQuery(const QArray<int>& ); |
147 | ~FindCustomQuery(); | 147 | ~FindCustomQuery(); |
148 | QString query()const; | 148 | QString query()const; |
149 | private: | 149 | private: |
150 | QString single()const; | 150 | QString single()const; |
151 | QString multi()const; | 151 | QString multi()const; |
152 | QArray<int> m_uids; | 152 | QArray<int> m_uids; |
153 | int m_uid; | 153 | int m_uid; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | 156 | ||
157 | 157 | ||
158 | // We using two tables to store the information: | 158 | // We using two tables to store the information: |
159 | // 1. addressbook : It contains General information about the contact (non custom) | 159 | // 1. addressbook : It contains General information about the contact (non custom) |
160 | // 2. custom_data : Not official supported entries | 160 | // 2. custom_data : Not official supported entries |
161 | // All tables are connected by the uid of the contact. | 161 | // All tables are connected by the uid of the contact. |
162 | // Maybe I should add a table for meta-information ? | 162 | // Maybe I should add a table for meta-information ? |
163 | CreateQuery::CreateQuery() : OSQLQuery() {} | 163 | CreateQuery::CreateQuery() : OSQLQuery() {} |
164 | CreateQuery::~CreateQuery() {} | 164 | CreateQuery::~CreateQuery() {} |
165 | QString CreateQuery::query()const { | 165 | QString CreateQuery::query()const { |
166 | QString qu; | 166 | QString qu; |
167 | 167 | ||
168 | qu += "create table addressbook( uid PRIMARY KEY "; | 168 | qu += "create table addressbook( uid PRIMARY KEY "; |
169 | 169 | ||
170 | QStringList fieldList = OPimContactFields::untrfields( false ); | 170 | QStringList fieldList = OPimContactFields::untrfields( false ); |
171 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 171 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
172 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); | 172 | qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); |
173 | } | 173 | } |
174 | qu += " );"; | 174 | qu += " );"; |
175 | 175 | ||
176 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; | 176 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; |
177 | 177 | ||
178 | return qu; | 178 | return qu; |
179 | } | 179 | } |
180 | 180 | ||
181 | ClearQuery::ClearQuery() | 181 | ClearQuery::ClearQuery() |
182 | : OSQLQuery() {} | 182 | : OSQLQuery() {} |
183 | ClearQuery::~ClearQuery() {} | 183 | ClearQuery::~ClearQuery() {} |
184 | QString ClearQuery::query()const { | 184 | QString ClearQuery::query()const { |
185 | QString qu = "drop table addressbook;"; | 185 | QString qu = "drop table addressbook;"; |
186 | qu += "drop table custom_data;"; | 186 | qu += "drop table custom_data;"; |
187 | // qu += "drop table dates;"; | 187 | // qu += "drop table dates;"; |
188 | return qu; | 188 | return qu; |
189 | } | 189 | } |
190 | 190 | ||
191 | 191 | ||
192 | LoadQuery::LoadQuery() : OSQLQuery() {} | 192 | LoadQuery::LoadQuery() : OSQLQuery() {} |
193 | LoadQuery::~LoadQuery() {} | 193 | LoadQuery::~LoadQuery() {} |
194 | QString LoadQuery::query()const { | 194 | QString LoadQuery::query()const { |
195 | QString qu; | 195 | QString qu; |
196 | qu += "select uid from addressbook"; | 196 | qu += "select uid from addressbook"; |
197 | 197 | ||
198 | return qu; | 198 | return qu; |
199 | } | 199 | } |
200 | 200 | ||
201 | 201 | ||
202 | InsertQuery::InsertQuery( const OPimContact& contact ) | 202 | InsertQuery::InsertQuery( const OPimContact& contact ) |
203 | : OSQLQuery(), m_contact( contact ) { | 203 | : OSQLQuery(), m_contact( contact ) { |
204 | } | 204 | } |
205 | 205 | ||
206 | InsertQuery::~InsertQuery() { | 206 | InsertQuery::~InsertQuery() { |
207 | } | 207 | } |
208 | 208 | ||
209 | /* | 209 | /* |
210 | * converts from a OPimContact to a query | 210 | * converts from a OPimContact to a query |
211 | */ | 211 | */ |
212 | QString InsertQuery::query()const{ | 212 | QString InsertQuery::query()const{ |
213 | 213 | ||
214 | QString qu; | 214 | QString qu; |
215 | qu += "insert into addressbook VALUES( " + | 215 | qu += "insert into addressbook VALUES( " + |
216 | QString::number( m_contact.uid() ); | 216 | QString::number( m_contact.uid() ); |
217 | 217 | ||
218 | // Get all information out of the contact-class | 218 | // Get all information out of the contact-class |
219 | // Remember: The category is stored in contactMap, too ! | 219 | // Remember: The category is stored in contactMap, too ! |
220 | QMap<int, QString> contactMap = m_contact.toMap(); | 220 | QMap<int, QString> contactMap = m_contact.toMap(); |
221 | 221 | ||
222 | QStringList fieldList = OPimContactFields::untrfields( false ); | 222 | QStringList fieldList = OPimContactFields::untrfields( false ); |
223 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 223 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
224 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 224 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
225 | // Convert Column-String to Id and get value for this id.. | 225 | // Convert Column-String to Id and get value for this id.. |
226 | // Hmmm.. Maybe not very cute solution.. | 226 | // Hmmm.. Maybe not very cute solution.. |
227 | int id = translate[*it]; | 227 | int id = translate[*it]; |
228 | switch ( id ){ | 228 | switch ( id ){ |
229 | case Qtopia::Birthday: | 229 | case Qtopia::Birthday: |
230 | case Qtopia::Anniversary:{ | 230 | case Qtopia::Anniversary:{ |
231 | QDate day; | 231 | QDate day; |
232 | if ( id == Qtopia::Birthday ){ | 232 | if ( id == Qtopia::Birthday ){ |
233 | day = m_contact.birthday(); | 233 | day = m_contact.birthday(); |
234 | } else { | 234 | } else { |
235 | day = m_contact.anniversary(); | 235 | day = m_contact.anniversary(); |
236 | } | 236 | } |
237 | // These entries should stored in a special format | 237 | // These entries should stored in a special format |
238 | // year-month-day | 238 | // year-month-day |
239 | if ( day.isValid() ){ | 239 | if ( day.isValid() ){ |
240 | qu += QString(",\"%1-%2-%3\"") | 240 | qu += QString(",\"%1-%2-%3\"") |
241 | .arg( QString::number( day.year() ).rightJustify( 4, '0' ) ) | 241 | .arg( QString::number( day.year() ).rightJustify( 4, '0' ) ) |
242 | .arg( QString::number( day.month() ).rightJustify( 2, '0' ) ) | 242 | .arg( QString::number( day.month() ).rightJustify( 2, '0' ) ) |
243 | .arg( QString::number( day.day() ).rightJustify( 2, '0' ) ); | 243 | .arg( QString::number( day.day() ).rightJustify( 2, '0' ) ); |
244 | } else { | 244 | } else { |
245 | qu += ",\"\""; | 245 | qu += ",\"\""; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | break; | 248 | break; |
249 | default: | 249 | default: |
250 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); | 250 | qu += QString( ",\"%1\"" ).arg( contactMap[id] ); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | qu += " );"; | 253 | qu += " );"; |
254 | 254 | ||
255 | 255 | ||
256 | // Now add custom data.. | 256 | // Now add custom data.. |
257 | int id = 0; | 257 | int id = 0; |
258 | id = 0; | 258 | id = 0; |
259 | QMap<QString, QString> customMap = m_contact.toExtraMap(); | 259 | QMap<QString, QString> customMap = m_contact.toExtraMap(); |
260 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | 260 | for( QMap<QString, QString>::Iterator it = customMap.begin(); |
261 | it != customMap.end(); ++it ){ | 261 | it != customMap.end(); ++it ){ |
262 | qu += "insert into custom_data VALUES(" | 262 | qu += "insert into custom_data VALUES(" |
263 | + QString::number( m_contact.uid() ) | 263 | + QString::number( m_contact.uid() ) |
264 | + "," | 264 | + "," |
265 | + QString::number( id++ ) | 265 | + QString::number( id++ ) |
266 | + ",'" | 266 | + ",'" |
267 | + it.key() | 267 | + it.key() |
268 | + "'," | 268 | + "'," |
269 | + "0" // Priority for future enhancements | 269 | + "0" // Priority for future enhancements |
270 | + ",'" | 270 | + ",'" |
271 | + it.data() | 271 | + it.data() |
272 | + "');"; | 272 | + "');"; |
273 | } | 273 | } |
274 | // qu += "commit;"; | 274 | // qu += "commit;"; |
275 | odebug << "add " << qu << "" << oendl; | 275 | odebug << "add " << qu << "" << oendl; |
276 | return qu; | 276 | return qu; |
277 | } | 277 | } |
278 | 278 | ||
279 | 279 | ||
280 | RemoveQuery::RemoveQuery(int uid ) | 280 | RemoveQuery::RemoveQuery(int uid ) |
281 | : OSQLQuery(), m_uid( uid ) {} | 281 | : OSQLQuery(), m_uid( uid ) {} |
282 | RemoveQuery::~RemoveQuery() {} | 282 | RemoveQuery::~RemoveQuery() {} |
283 | QString RemoveQuery::query()const { | 283 | QString RemoveQuery::query()const { |
284 | QString qu = "DELETE from addressbook where uid = " | 284 | QString qu = "DELETE from addressbook where uid = " |
285 | + QString::number(m_uid) + ";"; | 285 | + QString::number(m_uid) + ";"; |
286 | qu += "DELETE from custom_data where uid = " | 286 | qu += "DELETE from custom_data where uid = " |
287 | + QString::number(m_uid) + ";"; | 287 | + QString::number(m_uid) + ";"; |
288 | return qu; | 288 | return qu; |
289 | } | 289 | } |
290 | 290 | ||
291 | 291 | ||
292 | 292 | ||
293 | 293 | ||
294 | FindQuery::FindQuery(int uid) | 294 | FindQuery::FindQuery(int uid) |
295 | : OSQLQuery(), m_uid( uid ) { | 295 | : OSQLQuery(), m_uid( uid ) { |
296 | } | 296 | } |
297 | FindQuery::FindQuery(const QArray<int>& ints) | 297 | FindQuery::FindQuery(const QArray<int>& ints) |
298 | : OSQLQuery(), m_uids( ints ){ | 298 | : OSQLQuery(), m_uids( ints ){ |
299 | } | 299 | } |
300 | FindQuery::~FindQuery() { | 300 | FindQuery::~FindQuery() { |
301 | } | 301 | } |
302 | QString FindQuery::query()const{ | 302 | QString FindQuery::query()const{ |
303 | if ( m_uids.count() == 0 ) | 303 | if ( m_uids.count() == 0 ) |
304 | return single(); | 304 | return single(); |
305 | else | 305 | else |
306 | return multi(); | 306 | return multi(); |
307 | } | 307 | } |
308 | 308 | ||
309 | QString FindQuery::multi()const { | 309 | QString FindQuery::multi()const { |
310 | QString qu = "select * from addressbook where"; | 310 | QString qu = "select * from addressbook where"; |
311 | for (uint i = 0; i < m_uids.count(); i++ ) { | 311 | for (uint i = 0; i < m_uids.count(); i++ ) { |
312 | qu += " uid = " + QString::number( m_uids[i] ) + " OR"; | 312 | qu += " uid = " + QString::number( m_uids[i] ) + " OR"; |
313 | } | 313 | } |
314 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 314 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
315 | 315 | ||
316 | odebug << "find query: " << qu << "" << oendl; | 316 | odebug << "find query: " << qu << "" << oendl; |
317 | return qu; | 317 | return qu; |
318 | } | 318 | } |
319 | 319 | ||
320 | QString FindQuery::single()const{ | 320 | QString FindQuery::single()const{ |
321 | QString qu = "select *"; | 321 | QString qu = "select *"; |
322 | qu += " from addressbook where uid = " + QString::number(m_uid); | 322 | qu += " from addressbook where uid = " + QString::number(m_uid); |
323 | 323 | ||
324 | // owarn << "find query: " << qu << "" << oendl; | 324 | // owarn << "find query: " << qu << "" << oendl; |
325 | return qu; | 325 | return qu; |
326 | } | 326 | } |
327 | 327 | ||
328 | 328 | ||
329 | FindCustomQuery::FindCustomQuery(int uid) | 329 | FindCustomQuery::FindCustomQuery(int uid) |
330 | : OSQLQuery(), m_uid( uid ) { | 330 | : OSQLQuery(), m_uid( uid ) { |
331 | } | 331 | } |
332 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) | 332 | FindCustomQuery::FindCustomQuery(const QArray<int>& ints) |
333 | : OSQLQuery(), m_uids( ints ){ | 333 | : OSQLQuery(), m_uids( ints ){ |
334 | } | 334 | } |
335 | FindCustomQuery::~FindCustomQuery() { | 335 | FindCustomQuery::~FindCustomQuery() { |
336 | } | 336 | } |
337 | QString FindCustomQuery::query()const{ | 337 | QString FindCustomQuery::query()const{ |
338 | // if ( m_uids.count() == 0 ) | 338 | // if ( m_uids.count() == 0 ) |
339 | return single(); | 339 | return single(); |
340 | } | 340 | } |
341 | QString FindCustomQuery::single()const{ | 341 | QString FindCustomQuery::single()const{ |
342 | QString qu = "select uid, type, value from custom_data where uid = "; | 342 | QString qu = "select uid, type, value from custom_data where uid = "; |
343 | qu += QString::number(m_uid); | 343 | qu += QString::number(m_uid); |
344 | return qu; | 344 | return qu; |
345 | } | 345 | } |
346 | 346 | ||
347 | }; | 347 | }; |
348 | 348 | ||
349 | 349 | ||
350 | /* --------------------------------------------------------------------------- */ | 350 | /* --------------------------------------------------------------------------- */ |
351 | 351 | ||
352 | namespace Opie { | 352 | namespace Opie { |
353 | 353 | ||
354 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, | 354 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, |
355 | const QString& filename ): | 355 | const QString& filename ): |
356 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) | 356 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) |
357 | { | 357 | { |
358 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; | 358 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; |
359 | QTime t; | 359 | QTime t; |
360 | t.start(); | 360 | t.start(); |
361 | 361 | ||
362 | /* Expecting to access the default filename if nothing else is set */ | 362 | /* Expecting to access the default filename if nothing else is set */ |
363 | if ( filename.isEmpty() ){ | 363 | if ( filename.isEmpty() ){ |
364 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 364 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
365 | } else | 365 | } else |
366 | m_fileName = filename; | 366 | m_fileName = filename; |
367 | 367 | ||
368 | // Get the standart sql-driver from the OSQLManager.. | 368 | // Get the standart sql-driver from the OSQLManager.. |
369 | OSQLManager man; | 369 | OSQLManager man; |
370 | m_driver = man.standard(); | 370 | m_driver = man.standard(); |
371 | m_driver->setUrl( m_fileName ); | 371 | m_driver->setUrl( m_fileName ); |
372 | 372 | ||
373 | load(); | 373 | load(); |
374 | 374 | ||
375 | odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; | 375 | odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; |
376 | } | 376 | } |
377 | 377 | ||
378 | OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () | 378 | OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () |
379 | { | 379 | { |
380 | if( m_driver ) | 380 | if( m_driver ) |
381 | delete m_driver; | 381 | delete m_driver; |
382 | } | 382 | } |
383 | 383 | ||
384 | bool OPimContactAccessBackend_SQL::load () | 384 | bool OPimContactAccessBackend_SQL::load () |
385 | { | 385 | { |
386 | if (!m_driver->open() ) | 386 | if (!m_driver->open() ) |
387 | return false; | 387 | return false; |
388 | 388 | ||
389 | // Don't expect that the database exists. | 389 | // Don't expect that the database exists. |
390 | // It is save here to create the table, even if it | 390 | // It is save here to create the table, even if it |
391 | // do exist. ( Is that correct for all databases ?? ) | 391 | // do exist. ( Is that correct for all databases ?? ) |
392 | CreateQuery creat; | 392 | CreateQuery creat; |
393 | OSQLResult res = m_driver->query( &creat ); | 393 | OSQLResult res = m_driver->query( &creat ); |
394 | 394 | ||
395 | update(); | 395 | update(); |
396 | 396 | ||
397 | return true; | 397 | return true; |
398 | 398 | ||
399 | } | 399 | } |
400 | 400 | ||
401 | bool OPimContactAccessBackend_SQL::reload() | 401 | bool OPimContactAccessBackend_SQL::reload() |
402 | { | 402 | { |
403 | return load(); | 403 | return load(); |
404 | } | 404 | } |
405 | 405 | ||
406 | bool OPimContactAccessBackend_SQL::save() | 406 | bool OPimContactAccessBackend_SQL::save() |
407 | { | 407 | { |
408 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) | 408 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
409 | } | 409 | } |
410 | 410 | ||
411 | 411 | ||
412 | void OPimContactAccessBackend_SQL::clear () | 412 | void OPimContactAccessBackend_SQL::clear () |
413 | { | 413 | { |
414 | ClearQuery cle; | 414 | ClearQuery cle; |
415 | OSQLResult res = m_driver->query( &cle ); | 415 | OSQLResult res = m_driver->query( &cle ); |
416 | 416 | ||
417 | reload(); | 417 | reload(); |
418 | } | 418 | } |
419 | 419 | ||
420 | bool OPimContactAccessBackend_SQL::wasChangedExternally() | 420 | bool OPimContactAccessBackend_SQL::wasChangedExternally() |
421 | { | 421 | { |
422 | return false; | 422 | return false; |
423 | } | 423 | } |
424 | 424 | ||
425 | QArray<int> OPimContactAccessBackend_SQL::allRecords() const | 425 | QArray<int> OPimContactAccessBackend_SQL::allRecords() const |
426 | { | 426 | { |
427 | 427 | ||
428 | // FIXME: Think about cute handling of changed tables.. | 428 | // FIXME: Think about cute handling of changed tables.. |
429 | // Thus, we don't have to call update here... | 429 | // Thus, we don't have to call update here... |
430 | if ( m_changed ) | 430 | if ( m_changed ) |
431 | ((OPimContactAccessBackend_SQL*)this)->update(); | 431 | ((OPimContactAccessBackend_SQL*)this)->update(); |
432 | 432 | ||
433 | return m_uids; | 433 | return m_uids; |
434 | } | 434 | } |
435 | 435 | ||
436 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) | 436 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) |
437 | { | 437 | { |
438 | odebug << "add in contact SQL-Backend" << oendl; | 438 | odebug << "add in contact SQL-Backend" << oendl; |
439 | InsertQuery ins( newcontact ); | 439 | InsertQuery ins( newcontact ); |
440 | OSQLResult res = m_driver->query( &ins ); | 440 | OSQLResult res = m_driver->query( &ins ); |
441 | 441 | ||
442 | if ( res.state() == OSQLResult::Failure ) | 442 | if ( res.state() == OSQLResult::Failure ) |
443 | return false; | 443 | return false; |
444 | 444 | ||
445 | int c = m_uids.count(); | 445 | int c = m_uids.count(); |
446 | m_uids.resize( c+1 ); | 446 | m_uids.resize( c+1 ); |
447 | m_uids[c] = newcontact.uid(); | 447 | m_uids[c] = newcontact.uid(); |
448 | 448 | ||
449 | return true; | 449 | return true; |
450 | } | 450 | } |
451 | 451 | ||
452 | 452 | ||
453 | bool OPimContactAccessBackend_SQL::remove ( int uid ) | 453 | bool OPimContactAccessBackend_SQL::remove ( int uid ) |
454 | { | 454 | { |
455 | RemoveQuery rem( uid ); | 455 | RemoveQuery rem( uid ); |
456 | OSQLResult res = m_driver->query(&rem ); | 456 | OSQLResult res = m_driver->query(&rem ); |
457 | 457 | ||
458 | if ( res.state() == OSQLResult::Failure ) | 458 | if ( res.state() == OSQLResult::Failure ) |
459 | return false; | 459 | return false; |
460 | 460 | ||
461 | m_changed = true; | 461 | m_changed = true; |
462 | 462 | ||
463 | return true; | 463 | return true; |
464 | } | 464 | } |
465 | 465 | ||
466 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) | 466 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) |
467 | { | 467 | { |
468 | if ( !remove( contact.uid() ) ) | 468 | if ( !remove( contact.uid() ) ) |
469 | return false; | 469 | return false; |
470 | 470 | ||
471 | return add( contact ); | 471 | return add( contact ); |
472 | } | 472 | } |
473 | 473 | ||
474 | 474 | ||
475 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const | 475 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const |
476 | { | 476 | { |
477 | odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; | 477 | odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; |
478 | QTime t; | 478 | QTime t; |
479 | t.start(); | 479 | t.start(); |
480 | 480 | ||
481 | OPimContact retContact( requestNonCustom( uid ) ); | 481 | OPimContact retContact( requestNonCustom( uid ) ); |
482 | retContact.setExtraMap( requestCustom( uid ) ); | 482 | retContact.setExtraMap( requestCustom( uid ) ); |
483 | 483 | ||
484 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; | 484 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; |
485 | return retContact; | 485 | return retContact; |
486 | } | 486 | } |
487 | 487 | ||
488 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const | 488 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const |
489 | { | 489 | { |
490 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; | 490 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; |
491 | odebug << "searching for " << uid << "" << oendl; | 491 | odebug << "searching for " << uid << "" << oendl; |
492 | 492 | ||
493 | QTime t; | 493 | QTime t; |
494 | t.start(); | 494 | t.start(); |
495 | 495 | ||
496 | uint numReadAhead = readAhead(); | 496 | uint numReadAhead = readAhead(); |
497 | QArray<int> searchList( numReadAhead ); | 497 | QArray<int> searchList( numReadAhead ); |
498 | 498 | ||
499 | uint size =0; | 499 | uint size =0; |
500 | 500 | ||
501 | // Build an array with all elements which should be requested and cached | 501 | // Build an array with all elements which should be requested and cached |
502 | // We will just request "numReadAhead" elements, starting from "current" position in | 502 | // We will just request "numReadAhead" elements, starting from "current" position in |
503 | // the list of many uids ! | 503 | // the list of many uids ! |
504 | switch( direction ) { | 504 | switch( direction ) { |
505 | /* forward */ | 505 | /* forward */ |
506 | case Frontend::Forward: | 506 | case Frontend::Forward: |
507 | for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { | 507 | for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { |
508 | searchList[size] = queryUids[i]; | 508 | searchList[size] = queryUids[i]; |
509 | size++; | 509 | size++; |
510 | } | 510 | } |
511 | break; | 511 | break; |
512 | /* reverse */ | 512 | /* reverse */ |
513 | case Frontend::Reverse: | 513 | case Frontend::Reverse: |
514 | for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { | 514 | for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { |
515 | searchList[size] = queryUids[i]; | 515 | searchList[size] = queryUids[i]; |
516 | size++; | 516 | size++; |
517 | } | 517 | } |
518 | break; | 518 | break; |
519 | } | 519 | } |
520 | 520 | ||
521 | //Shrink to real size.. | 521 | //Shrink to real size.. |
522 | searchList.resize( size ); | 522 | searchList.resize( size ); |
523 | 523 | ||
524 | OPimContact retContact( requestContactsAndCache( uid, searchList ) ); | 524 | OPimContact retContact( requestContactsAndCache( uid, searchList ) ); |
525 | 525 | ||
526 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; | 526 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; |
527 | return retContact; | 527 | return retContact; |
528 | } | 528 | } |
529 | 529 | ||
530 | 530 | ||
531 | QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) | 531 | QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) |
532 | { | 532 | { |
533 | QString qu = "SELECT uid FROM addressbook WHERE"; | 533 | QString qu = "SELECT uid FROM addressbook WHERE"; |
534 | QString searchQuery =""; | 534 | QString searchQuery =""; |
535 | 535 | ||
536 | QDate startDate; | 536 | QDate startDate; |
537 | 537 | ||
538 | if ( qd.isValid() ) | 538 | if ( qd.isValid() ) |
539 | startDate = qd.date(); | 539 | startDate = qd.date(); |
540 | else | 540 | else |
541 | startDate = QDate::currentDate(); | 541 | startDate = QDate::currentDate(); |
542 | 542 | ||
543 | 543 | ||
544 | QMap<int, QString> queryFields = query.toMap(); | 544 | QMap<int, QString> queryFields = query.toMap(); |
545 | QStringList fieldList = OPimContactFields::untrfields( false ); | 545 | QStringList fieldList = OPimContactFields::untrfields( false ); |
546 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 546 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
547 | 547 | ||
548 | // Convert every filled field to a SQL-Query | 548 | // Convert every filled field to a SQL-Query |
549 | // bool isAnyFieldSelected = false; | 549 | // bool isAnyFieldSelected = false; |
550 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 550 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
551 | 551 | ||
552 | int id = translate[*it]; | 552 | int id = translate[*it]; |
553 | QString queryStr = queryFields[id]; | 553 | QString queryStr = queryFields[id]; |
554 | QDate* endDate = 0l; | 554 | QDate* endDate = 0l; |
555 | 555 | ||
556 | if ( !queryStr.isEmpty() ){ | 556 | if ( !queryStr.isEmpty() ){ |
557 | // If something is alredy stored in the query, add an "AND" | 557 | // If something is alredy stored in the query, add an "AND" |
558 | // to the end of the string to prepare for the next .. | 558 | // to the end of the string to prepare for the next .. |
559 | if ( !searchQuery.isEmpty() ) | 559 | if ( !searchQuery.isEmpty() ) |
560 | searchQuery += " AND"; | 560 | searchQuery += " AND"; |
561 | 561 | ||
562 | // isAnyFieldSelected = true; | 562 | // isAnyFieldSelected = true; |
563 | switch( id ){ | 563 | switch( id ){ |
564 | case Qtopia::Birthday: | 564 | case Qtopia::Birthday: |
565 | endDate = new QDate( query.birthday() ); | 565 | endDate = new QDate( query.birthday() ); |
566 | // Fall through ! | 566 | // Fall through ! |
567 | case Qtopia::Anniversary: | 567 | case Qtopia::Anniversary: |
568 | if ( endDate == 0l ) | 568 | if ( endDate == 0l ) |
569 | endDate = new QDate( query.anniversary() ); | 569 | endDate = new QDate( query.anniversary() ); |
570 | 570 | ||
571 | if ( settings & OPimContactAccess::DateDiff ) { | 571 | if ( settings & OPimContactAccess::DateDiff ) { |
572 | searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) | 572 | searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) |
573 | .arg( *it ) | 573 | .arg( *it ) |
574 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) | 574 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) |
575 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) | 575 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) |
576 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) | 576 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) |
577 | .arg( *it ) | 577 | .arg( *it ) |
578 | .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) | 578 | .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) |
579 | .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) | 579 | .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) |
580 | .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; | 580 | .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; |
581 | } | 581 | } |
582 | 582 | ||
583 | if ( settings & OPimContactAccess::DateYear ){ | 583 | if ( settings & OPimContactAccess::DateYear ){ |
584 | if ( settings & OPimContactAccess::DateDiff ) | 584 | if ( settings & OPimContactAccess::DateDiff ) |
585 | searchQuery += " AND"; | 585 | searchQuery += " AND"; |
586 | 586 | ||
587 | searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) | 587 | searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) |
588 | .arg( *it ) | 588 | .arg( *it ) |
589 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); | 589 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); |
590 | } | 590 | } |
591 | 591 | ||
592 | if ( settings & OPimContactAccess::DateMonth ){ | 592 | if ( settings & OPimContactAccess::DateMonth ){ |
593 | if ( ( settings & OPimContactAccess::DateDiff ) | 593 | if ( ( settings & OPimContactAccess::DateDiff ) |
594 | || ( settings & OPimContactAccess::DateYear ) ) | 594 | || ( settings & OPimContactAccess::DateYear ) ) |
595 | searchQuery += " AND"; | 595 | searchQuery += " AND"; |
596 | 596 | ||
597 | searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) | 597 | searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) |
598 | .arg( *it ) | 598 | .arg( *it ) |
599 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); | 599 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); |
600 | } | 600 | } |
601 | 601 | ||
602 | if ( settings & OPimContactAccess::DateDay ){ | 602 | if ( settings & OPimContactAccess::DateDay ){ |
603 | if ( ( settings & OPimContactAccess::DateDiff ) | 603 | if ( ( settings & OPimContactAccess::DateDiff ) |
604 | || ( settings & OPimContactAccess::DateYear ) | 604 | || ( settings & OPimContactAccess::DateYear ) |
605 | || ( settings & OPimContactAccess::DateMonth ) ) | 605 | || ( settings & OPimContactAccess::DateMonth ) ) |
606 | searchQuery += " AND"; | 606 | searchQuery += " AND"; |
607 | 607 | ||
608 | searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) | 608 | searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) |
609 | .arg( *it ) | 609 | .arg( *it ) |
610 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); | 610 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); |
611 | } | 611 | } |
612 | 612 | ||
613 | break; | 613 | break; |
614 | default: | 614 | default: |
615 | // Switching between case sensitive and insensitive... | 615 | // Switching between case sensitive and insensitive... |
616 | // LIKE is not case sensitive, GLOB is case sensitive | 616 | // LIKE is not case sensitive, GLOB is case sensitive |
617 | // Do exist a better solution to switch this ? | 617 | // Do exist a better solution to switch this ? |
618 | if ( settings & OPimContactAccess::IgnoreCase ) | 618 | if ( settings & OPimContactAccess::IgnoreCase ) |
619 | searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" | 619 | searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" |
620 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; | 620 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; |
621 | else | 621 | else |
622 | searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" | 622 | searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" |
623 | + queryStr + "'" + ")"; | 623 | + queryStr + "'" + ")"; |
624 | 624 | ||
625 | } | 625 | } |
626 | } | 626 | } |
627 | |||
628 | delete endDate; | ||
627 | } | 629 | } |
628 | // Skip trailing "AND" | 630 | // Skip trailing "AND" |
629 | // if ( isAnyFieldSelected ) | 631 | // if ( isAnyFieldSelected ) |
630 | // qu = qu.left( qu.length() - 4 ); | 632 | // qu = qu.left( qu.length() - 4 ); |
631 | 633 | ||
632 | qu += searchQuery; | 634 | qu += searchQuery; |
633 | 635 | ||
634 | odebug << "queryByExample query: " << qu << "" << oendl; | 636 | odebug << "queryByExample query: " << qu << "" << oendl; |
635 | 637 | ||
636 | // Execute query and return the received uid's | 638 | // Execute query and return the received uid's |
637 | OSQLRawQuery raw( qu ); | 639 | OSQLRawQuery raw( qu ); |
638 | OSQLResult res = m_driver->query( &raw ); | 640 | OSQLResult res = m_driver->query( &raw ); |
639 | if ( res.state() != OSQLResult::Success ){ | 641 | if ( res.state() != OSQLResult::Success ){ |
640 | QArray<int> empty; | 642 | QArray<int> empty; |
641 | return empty; | 643 | return empty; |
642 | } | 644 | } |
643 | 645 | ||
644 | QArray<int> list = extractUids( res ); | 646 | QArray<int> list = extractUids( res ); |
645 | 647 | ||
646 | return list; | 648 | return list; |
647 | } | 649 | } |
648 | 650 | ||
649 | QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 651 | QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
650 | { | 652 | { |
651 | #if 0 | 653 | #if 0 |
652 | QArray<int> nix(0); | 654 | QArray<int> nix(0); |
653 | return nix; | 655 | return nix; |
654 | 656 | ||
655 | #else | 657 | #else |
656 | QString qu = "SELECT uid FROM addressbook WHERE ("; | 658 | QString qu = "SELECT uid FROM addressbook WHERE ("; |
657 | QString searchlist; | 659 | QString searchlist; |
658 | 660 | ||
659 | QStringList fieldList = OPimContactFields::untrfields( false ); | 661 | QStringList fieldList = OPimContactFields::untrfields( false ); |
660 | // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 662 | // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
661 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 663 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
662 | if ( !searchlist.isEmpty() ) | 664 | if ( !searchlist.isEmpty() ) |
663 | searchlist += " OR "; | 665 | searchlist += " OR "; |
664 | searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; | 666 | searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; |
665 | } | 667 | } |
666 | 668 | ||
667 | qu = qu + searchlist + ")"; | 669 | qu = qu + searchlist + ")"; |
668 | 670 | ||
669 | odebug << "query: " << qu << "" << oendl; | 671 | odebug << "query: " << qu << "" << oendl; |
670 | 672 | ||
671 | OSQLRawQuery raw( qu ); | 673 | OSQLRawQuery raw( qu ); |
672 | OSQLResult res = m_driver->query( &raw ); | 674 | OSQLResult res = m_driver->query( &raw ); |
673 | 675 | ||
674 | return extractUids( res ); | 676 | return extractUids( res ); |
675 | 677 | ||
676 | 678 | ||
677 | #endif | 679 | #endif |
678 | } | 680 | } |
679 | 681 | ||
680 | const uint OPimContactAccessBackend_SQL::querySettings() | 682 | const uint OPimContactAccessBackend_SQL::querySettings() |
681 | { | 683 | { |
682 | return OPimContactAccess::IgnoreCase | 684 | return OPimContactAccess::IgnoreCase |
683 | | OPimContactAccess::WildCards | 685 | | OPimContactAccess::WildCards |
684 | | OPimContactAccess::DateDiff | 686 | | OPimContactAccess::DateDiff |
685 | | OPimContactAccess::DateYear | 687 | | OPimContactAccess::DateYear |
686 | | OPimContactAccess::DateMonth | 688 | | OPimContactAccess::DateMonth |
687 | | OPimContactAccess::DateDay | 689 | | OPimContactAccess::DateDay |
688 | ; | 690 | ; |
689 | } | 691 | } |
690 | 692 | ||
691 | bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | 693 | bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const |
692 | { | 694 | { |
693 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 695 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
694 | * may be added with any of the other settings. IgnoreCase should never used alone. | 696 | * may be added with any of the other settings. IgnoreCase should never used alone. |
695 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 697 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
696 | */ | 698 | */ |
697 | 699 | ||
698 | // Step 1: Check whether the given settings are supported by this backend | 700 | // Step 1: Check whether the given settings are supported by this backend |
699 | if ( ( querySettings & ( | 701 | if ( ( querySettings & ( |
700 | OPimContactAccess::IgnoreCase | 702 | OPimContactAccess::IgnoreCase |
701 | | OPimContactAccess::WildCards | 703 | | OPimContactAccess::WildCards |
702 | | OPimContactAccess::DateDiff | 704 | | OPimContactAccess::DateDiff |
703 | | OPimContactAccess::DateYear | 705 | | OPimContactAccess::DateYear |
704 | | OPimContactAccess::DateMonth | 706 | | OPimContactAccess::DateMonth |
705 | | OPimContactAccess::DateDay | 707 | | OPimContactAccess::DateDay |
706 | // | OPimContactAccess::RegExp | 708 | // | OPimContactAccess::RegExp |
707 | // | OPimContactAccess::ExactMatch | 709 | // | OPimContactAccess::ExactMatch |
708 | ) ) != querySettings ) | 710 | ) ) != querySettings ) |
709 | return false; | 711 | return false; |
710 | 712 | ||
711 | // Step 2: Check whether the given combinations are ok.. | 713 | // Step 2: Check whether the given combinations are ok.. |
712 | 714 | ||
713 | // IngoreCase alone is invalid | 715 | // IngoreCase alone is invalid |
714 | if ( querySettings == OPimContactAccess::IgnoreCase ) | 716 | if ( querySettings == OPimContactAccess::IgnoreCase ) |
715 | return false; | 717 | return false; |
716 | 718 | ||
717 | // WildCards, RegExp and ExactMatch should never used at the same time | 719 | // WildCards, RegExp and ExactMatch should never used at the same time |
718 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase | 720 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase |
719 | | OPimContactAccess::DateDiff | 721 | | OPimContactAccess::DateDiff |
720 | | OPimContactAccess::DateYear | 722 | | OPimContactAccess::DateYear |
721 | | OPimContactAccess::DateMonth | 723 | | OPimContactAccess::DateMonth |
722 | | OPimContactAccess::DateDay | 724 | | OPimContactAccess::DateDay |
723 | ) | 725 | ) |
724 | ){ | 726 | ){ |
725 | case OPimContactAccess::RegExp: | 727 | case OPimContactAccess::RegExp: |
726 | return ( true ); | 728 | return ( true ); |
727 | case OPimContactAccess::WildCards: | 729 | case OPimContactAccess::WildCards: |
728 | return ( true ); | 730 | return ( true ); |
729 | case OPimContactAccess::ExactMatch: | 731 | case OPimContactAccess::ExactMatch: |
730 | return ( true ); | 732 | return ( true ); |
731 | case 0: // one of the upper removed bits were set.. | 733 | case 0: // one of the upper removed bits were set.. |
732 | return ( true ); | 734 | return ( true ); |
733 | default: | 735 | default: |
734 | return ( false ); | 736 | return ( false ); |
735 | } | 737 | } |
736 | 738 | ||
737 | } | 739 | } |
738 | 740 | ||
739 | QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) | 741 | QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) |
740 | { | 742 | { |
741 | QTime t; | 743 | QTime t; |
742 | t.start(); | 744 | t.start(); |
743 | 745 | ||
744 | QString query = "SELECT uid FROM addressbook "; | 746 | QString query = "SELECT uid FROM addressbook "; |
745 | query += "ORDER BY \"Last Name\" "; | 747 | query += "ORDER BY \"Last Name\" "; |
746 | 748 | ||
747 | if ( !asc ) | 749 | if ( !asc ) |
748 | query += "DESC"; | 750 | query += "DESC"; |
749 | 751 | ||
750 | // odebug << "sorted query is: " << query << "" << oendl; | 752 | // odebug << "sorted query is: " << query << "" << oendl; |
751 | 753 | ||
752 | OSQLRawQuery raw( query ); | 754 | OSQLRawQuery raw( query ); |
753 | OSQLResult res = m_driver->query( &raw ); | 755 | OSQLResult res = m_driver->query( &raw ); |
754 | if ( res.state() != OSQLResult::Success ){ | 756 | if ( res.state() != OSQLResult::Success ){ |
755 | QArray<int> empty; | 757 | QArray<int> empty; |
756 | return empty; | 758 | return empty; |
757 | } | 759 | } |
758 | 760 | ||
759 | QArray<int> list = extractUids( res ); | 761 | QArray<int> list = extractUids( res ); |
760 | 762 | ||
761 | odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; | 763 | odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; |
762 | return list; | 764 | return list; |
763 | } | 765 | } |
764 | 766 | ||
765 | 767 | ||
766 | void OPimContactAccessBackend_SQL::update() | 768 | void OPimContactAccessBackend_SQL::update() |
767 | { | 769 | { |
768 | odebug << "Update starts" << oendl; | 770 | odebug << "Update starts" << oendl; |
769 | QTime t; | 771 | QTime t; |
770 | t.start(); | 772 | t.start(); |
771 | 773 | ||
772 | // Now load the database set and extract the uid's | 774 | // Now load the database set and extract the uid's |
773 | // which will be held locally | 775 | // which will be held locally |
774 | 776 | ||
775 | LoadQuery lo; | 777 | LoadQuery lo; |
776 | OSQLResult res = m_driver->query(&lo); | 778 | OSQLResult res = m_driver->query(&lo); |
777 | if ( res.state() != OSQLResult::Success ) | 779 | if ( res.state() != OSQLResult::Success ) |
778 | return; | 780 | return; |
779 | 781 | ||
780 | m_uids = extractUids( res ); | 782 | m_uids = extractUids( res ); |
781 | 783 | ||
782 | m_changed = false; | 784 | m_changed = false; |
783 | 785 | ||
784 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; | 786 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; |
785 | } | 787 | } |
786 | 788 | ||
787 | QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const | 789 | QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const |
788 | { | 790 | { |
789 | odebug << "extractUids" << oendl; | 791 | odebug << "extractUids" << oendl; |
790 | QTime t; | 792 | QTime t; |
791 | t.start(); | 793 | t.start(); |
792 | OSQLResultItem::ValueList list = res.results(); | 794 | OSQLResultItem::ValueList list = res.results(); |
793 | OSQLResultItem::ValueList::Iterator it; | 795 | OSQLResultItem::ValueList::Iterator it; |
794 | QArray<int> ints(list.count() ); | 796 | QArray<int> ints(list.count() ); |
795 | odebug << " count = " << list.count() << "" << oendl; | 797 | odebug << " count = " << list.count() << "" << oendl; |
796 | 798 | ||
797 | int i = 0; | 799 | int i = 0; |
798 | for (it = list.begin(); it != list.end(); ++it ) { | 800 | for (it = list.begin(); it != list.end(); ++it ) { |
799 | ints[i] = (*it).data("uid").toInt(); | 801 | ints[i] = (*it).data("uid").toInt(); |
800 | i++; | 802 | i++; |
801 | } | 803 | } |
802 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; | 804 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; |
803 | 805 | ||
804 | return ints; | 806 | return ints; |
805 | 807 | ||
806 | } | 808 | } |
807 | 809 | ||
808 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const | 810 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const |
809 | { | 811 | { |
810 | QTime t; | 812 | QTime t; |
811 | t.start(); | 813 | t.start(); |
812 | 814 | ||
813 | int t2needed = 0; | 815 | int t2needed = 0; |
814 | int t3needed = 0; | 816 | int t3needed = 0; |
815 | QTime t2; | 817 | QTime t2; |
816 | t2.start(); | 818 | t2.start(); |
817 | FindQuery query( uid ); | 819 | FindQuery query( uid ); |
818 | OSQLResult res_noncustom = m_driver->query( &query ); | 820 | OSQLResult res_noncustom = m_driver->query( &query ); |
819 | t2needed = t2.elapsed(); | 821 | t2needed = t2.elapsed(); |
820 | 822 | ||
821 | OSQLResultItem resItem = res_noncustom.first(); | 823 | OSQLResultItem resItem = res_noncustom.first(); |
822 | 824 | ||
823 | QMap<int, QString> nonCustomMap; | 825 | QMap<int, QString> nonCustomMap; |
824 | QTime t3; | 826 | QTime t3; |
825 | t3.start(); | 827 | t3.start(); |
826 | nonCustomMap = fillNonCustomMap( resItem ); | 828 | nonCustomMap = fillNonCustomMap( resItem ); |
827 | t3needed = t3.elapsed(); | 829 | t3needed = t3.elapsed(); |
828 | 830 | ||
829 | 831 | ||
830 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | 832 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; |
831 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | 833 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed |
832 | << " ms, mapping: " << t3needed << " ms" << oendl; | 834 | << " ms, mapping: " << t3needed << " ms" << oendl; |
833 | 835 | ||
834 | return nonCustomMap; | 836 | return nonCustomMap; |
835 | } | 837 | } |
836 | 838 | ||
837 | /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ | 839 | /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ |
838 | OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const | 840 | OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const |
839 | { | 841 | { |
840 | // We want to get all contacts with one query. | 842 | // We want to get all contacts with one query. |
841 | // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). | 843 | // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). |
842 | // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned | 844 | // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned |
843 | // by using the cache.. | 845 | // by using the cache.. |
844 | QArray<int> cachelist = uidlist; | 846 | QArray<int> cachelist = uidlist; |
845 | OPimContact retContact; | 847 | OPimContact retContact; |
846 | 848 | ||
847 | odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; | 849 | odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; |
848 | 850 | ||
849 | QTime t; | 851 | QTime t; |
850 | t.start(); | 852 | t.start(); |
851 | 853 | ||
852 | int t2needed = 0; | 854 | int t2needed = 0; |
853 | int t3needed = 0; | 855 | int t3needed = 0; |
854 | QTime t2; | 856 | QTime t2; |
855 | t2.start(); | 857 | t2.start(); |
856 | FindQuery query( cachelist ); | 858 | FindQuery query( cachelist ); |
857 | OSQLResult res_noncustom = m_driver->query( &query ); | 859 | OSQLResult res_noncustom = m_driver->query( &query ); |
858 | t2needed = t2.elapsed(); | 860 | t2needed = t2.elapsed(); |
859 | 861 | ||
860 | QMap<int, QString> nonCustomMap; | 862 | QMap<int, QString> nonCustomMap; |
861 | QTime t3; | 863 | QTime t3; |
862 | t3.start(); | 864 | t3.start(); |
863 | OSQLResultItem resItem = res_noncustom.first(); | 865 | OSQLResultItem resItem = res_noncustom.first(); |
864 | do { | 866 | do { |
865 | OPimContact contact( fillNonCustomMap( resItem ) ); | 867 | OPimContact contact( fillNonCustomMap( resItem ) ); |
866 | contact.setExtraMap( requestCustom( contact.uid() ) ); | 868 | contact.setExtraMap( requestCustom( contact.uid() ) ); |
867 | odebug << "Caching uid: " << contact.uid() << oendl; | 869 | odebug << "Caching uid: " << contact.uid() << oendl; |
868 | cache( contact ); | 870 | cache( contact ); |
869 | if ( contact.uid() == uid ) | 871 | if ( contact.uid() == uid ) |
870 | retContact = contact; | 872 | retContact = contact; |
871 | resItem = res_noncustom.next(); | 873 | resItem = res_noncustom.next(); |
872 | } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! | 874 | } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! |
873 | t3needed = t3.elapsed(); | 875 | t3needed = t3.elapsed(); |
874 | 876 | ||
875 | 877 | ||
876 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | 878 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; |
877 | odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | 879 | odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed |
878 | << " ms, mapping: " << t3needed << " ms" << oendl; | 880 | << " ms, mapping: " << t3needed << " ms" << oendl; |
879 | 881 | ||
880 | return retContact; | 882 | return retContact; |
881 | } | 883 | } |
882 | 884 | ||
883 | QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const | 885 | QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const |
884 | { | 886 | { |
885 | QMap<int, QString> nonCustomMap; | 887 | QMap<int, QString> nonCustomMap; |
886 | 888 | ||
887 | // Now loop through all columns | 889 | // Now loop through all columns |
888 | QStringList fieldList = OPimContactFields::untrfields( false ); | 890 | QStringList fieldList = OPimContactFields::untrfields( false ); |
889 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 891 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
890 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 892 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
891 | // Get data for the selected column and store it with the | 893 | // Get data for the selected column and store it with the |
892 | // corresponding id into the map.. | 894 | // corresponding id into the map.. |
893 | 895 | ||
894 | int id = translate[*it]; | 896 | int id = translate[*it]; |
895 | QString value = resultItem.data( (*it) ); | 897 | QString value = resultItem.data( (*it) ); |
896 | 898 | ||
897 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; | 899 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; |
898 | 900 | ||
899 | switch( id ){ | 901 | switch( id ){ |
900 | case Qtopia::Birthday: | 902 | case Qtopia::Birthday: |
901 | case Qtopia::Anniversary:{ | 903 | case Qtopia::Anniversary:{ |
902 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) | 904 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) |
903 | QStringList list = QStringList::split( '-', value ); | 905 | QStringList list = QStringList::split( '-', value ); |
904 | QStringList::Iterator lit = list.begin(); | 906 | QStringList::Iterator lit = list.begin(); |
905 | int year = (*lit).toInt(); | 907 | int year = (*lit).toInt(); |
906 | int month = (*(++lit)).toInt(); | 908 | int month = (*(++lit)).toInt(); |
907 | int day = (*(++lit)).toInt(); | 909 | int day = (*(++lit)).toInt(); |
908 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ | 910 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ |
909 | QDate date( year, month, day ); | 911 | QDate date( year, month, day ); |
910 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); | 912 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); |
911 | } | 913 | } |
912 | } | 914 | } |
913 | break; | 915 | break; |
914 | case Qtopia::AddressCategory: | 916 | case Qtopia::AddressCategory: |
915 | odebug << "Category is: " << value << "" << oendl; | 917 | odebug << "Category is: " << value << "" << oendl; |
916 | default: | 918 | default: |
917 | nonCustomMap.insert( id, value ); | 919 | nonCustomMap.insert( id, value ); |
918 | } | 920 | } |
919 | } | 921 | } |
920 | 922 | ||
921 | nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) ); | 923 | nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) ); |
922 | 924 | ||
923 | return nonCustomMap; | 925 | return nonCustomMap; |
924 | } | 926 | } |
925 | 927 | ||
926 | 928 | ||
927 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const | 929 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const |
928 | { | 930 | { |
929 | QTime t; | 931 | QTime t; |
930 | t.start(); | 932 | t.start(); |
931 | 933 | ||
932 | QMap<QString, QString> customMap; | 934 | QMap<QString, QString> customMap; |
933 | 935 | ||
934 | FindCustomQuery query( uid ); | 936 | FindCustomQuery query( uid ); |
935 | OSQLResult res_custom = m_driver->query( &query ); | 937 | OSQLResult res_custom = m_driver->query( &query ); |
936 | 938 | ||
937 | if ( res_custom.state() == OSQLResult::Failure ) { | 939 | if ( res_custom.state() == OSQLResult::Failure ) { |
938 | owarn << "OSQLResult::Failure in find query !!" << oendl; | 940 | owarn << "OSQLResult::Failure in find query !!" << oendl; |
939 | QMap<QString, QString> empty; | 941 | QMap<QString, QString> empty; |
940 | return empty; | 942 | return empty; |
941 | } | 943 | } |
942 | 944 | ||
943 | OSQLResultItem::ValueList list = res_custom.results(); | 945 | OSQLResultItem::ValueList list = res_custom.results(); |
944 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 946 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
945 | for ( ; it != list.end(); ++it ) { | 947 | for ( ; it != list.end(); ++it ) { |
946 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | 948 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); |
947 | } | 949 | } |
948 | 950 | ||
949 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; | 951 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; |
950 | return customMap; | 952 | return customMap; |
951 | } | 953 | } |
952 | 954 | ||
953 | } | 955 | } |