author | eilers <eilers> | 2005-03-23 09:25:18 (UTC) |
---|---|---|
committer | eilers <eilers> | 2005-03-23 09:25:18 (UTC) |
commit | cd1e107bcc03cbe2ff5179d4367225e4b0e47005 (patch) (unidiff) | |
tree | 0d748542c77a491c68a610b2f611981278133d3b | |
parent | 7d82b94d669746cac36dcabf026428bdc9286c72 (diff) | |
download | opie-cd1e107bcc03cbe2ff5179d4367225e4b0e47005.zip opie-cd1e107bcc03cbe2ff5179d4367225e4b0e47005.tar.gz opie-cd1e107bcc03cbe2ff5179d4367225e4b0e47005.tar.bz2 |
Fixing last issues on QueryByExample on SQL databases. All tests passed successfully
-rw-r--r-- | libopie2/opiepim/ChangeLog | 2 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 62 |
2 files changed, 35 insertions, 29 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog index acb6cb1..ee063aa 100644 --- a/libopie2/opiepim/ChangeLog +++ b/libopie2/opiepim/ChangeLog | |||
@@ -1,36 +1,38 @@ | |||
1 | 2005-03-23 Stefan Eilers <stefan@eilers-online.net> | ||
2 | * #1608 Finishing work on SQL backend. Datediff and other queries for QueryByExample now working as exprected. All tests passed successfully | ||
1 | 2005-03-20 Stefan Eilers <stefan@eilers-online.net> | 3 | 2005-03-20 Stefan Eilers <stefan@eilers-online.net> |
2 | * #1608 Quickfix for problem with DateDiff on SQL backend. I have to rethink this solution, but due to the short time, this should work. | 4 | * #1608 Quickfix for problem with DateDiff on SQL backend. I have to rethink this solution, but due to the short time, this should work. |
3 | 2005-03-19 Stefan Eilers <stefan@eilers-online.net> | 5 | 2005-03-19 Stefan Eilers <stefan@eilers-online.net> |
4 | * Minor update for sorted(). Now ignoring any category search if "DoNotShowWithCategory" filter is activated. | 6 | * Minor update for sorted(). Now ignoring any category search if "DoNotShowWithCategory" filter is activated. |
5 | * Fixing uninitialized member variable, caused crash of backend | 7 | * Fixing uninitialized member variable, caused crash of backend |
6 | 2005-03-18 Stefan Eilers <stefan@eilers-online.net> | 8 | 2005-03-18 Stefan Eilers <stefan@eilers-online.net> |
7 | * Rewrote generic sorted filter and added filter for "DoNotShowWithCategory", needed by addressbook (other filters need to be added!) | 9 | * Rewrote generic sorted filter and added filter for "DoNotShowWithCategory", needed by addressbook (other filters need to be added!) |
8 | 2005-01-16 Stefan Eilers <stefan@eilers-online.net> | 10 | 2005-01-16 Stefan Eilers <stefan@eilers-online.net> |
9 | * Added new OPimEventSortVector class, improved OPimSortVector | 11 | * Added new OPimEventSortVector class, improved OPimSortVector |
10 | * OPimAccessBackend now supports generic sorting. | 12 | * OPimAccessBackend now supports generic sorting. |
11 | 2005-01-03 Stefan Eilers <stefan@eilers-online.net> | 13 | 2005-01-03 Stefan Eilers <stefan@eilers-online.net> |
12 | * Fixing bug in API documentation | 14 | * Fixing bug in API documentation |
13 | * Moving hasQuerySettings() and querySettings() to OPimAccessTemplate to be available for all frontends | 15 | * Moving hasQuerySettings() and querySettings() to OPimAccessTemplate to be available for all frontends |
14 | 2004-12-28 Stefan Eilers <stefan@eilers-online.net> | 16 | 2004-12-28 Stefan Eilers <stefan@eilers-online.net> |
15 | * Make improved query by example accessable via frontend | 17 | * Make improved query by example accessable via frontend |
16 | * Some API documentation improvement | 18 | * Some API documentation improvement |
17 | * Cleanup of backend api.. | 19 | * Cleanup of backend api.. |
18 | * Fixing bug #1501 | 20 | * Fixing bug #1501 |
19 | 2004-11-23 Stefan Eilers <stefan@eilers-online.net> | 21 | 2004-11-23 Stefan Eilers <stefan@eilers-online.net> |
20 | * Implement fast and full featured version of sorted() for addressbook | 22 | * Implement fast and full featured version of sorted() for addressbook |
21 | * Implement generic queryByExample for all Addressboook backends. It allows incremental search. | 23 | * Implement generic queryByExample for all Addressboook backends. It allows incremental search. |
22 | * Update of API Documentation | 24 | * Update of API Documentation |
23 | 2004-11-18 Holger Freyther <freyther@handhelds.org> | 25 | 2004-11-18 Holger Freyther <freyther@handhelds.org> |
24 | * Every Access can give a set of Occurrences for a period or a datetime | 26 | * Every Access can give a set of Occurrences for a period or a datetime |
25 | * QueryByExample, Find, Sort can be generically accessed by OPimBase | 27 | * QueryByExample, Find, Sort can be generically accessed by OPimBase |
26 | pointer interface | 28 | pointer interface |
27 | * OPimBackendOccurrence gets split up to OPimOccurrences by | 29 | * OPimBackendOccurrence gets split up to OPimOccurrences by |
28 | OPimTemplateBase | 30 | OPimTemplateBase |
29 | * Add safeCast to various OPimRecords | 31 | * Add safeCast to various OPimRecords |
30 | * Kill memleak in OPimTodo | 32 | * Kill memleak in OPimTodo |
31 | * Add SortVector implementations for OPimTodo and OPimContact | 33 | * Add SortVector implementations for OPimTodo and OPimContact |
32 | 34 | ||
33 | 2004-??-??The Opie Team <opie@handhelds.org> | 35 | 2004-??-??The Opie Team <opie@handhelds.org> |
34 | * Implemented some important modifications to allow to use OPimRecords as it is, without | 36 | * Implemented some important modifications to allow to use OPimRecords as it is, without |
35 | have to cast them. This makes it possible to write applications which handling pim | 37 | have to cast them. This makes it possible to write applications which handling pim |
36 | data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file | 38 | data in a generic manner (see opimconvertion tool) (eilers) \ No newline at end of file |
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 50421e2..175d62a 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | |||
@@ -1,1092 +1,1096 @@ | |||
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 UIDArray& ); | 130 | FindQuery(const UIDArray& ); |
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 | UIDArray m_uids; | 136 | UIDArray 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 UIDArray& ); | 146 | FindCustomQuery(const UIDArray& ); |
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 | UIDArray m_uids; | 152 | UIDArray 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 | 282 | ||
283 | RemoveQuery::~RemoveQuery() {} | 283 | RemoveQuery::~RemoveQuery() {} |
284 | 284 | ||
285 | QString RemoveQuery::query()const { | 285 | QString RemoveQuery::query()const { |
286 | QString qu = "DELETE from addressbook where uid = " | 286 | QString qu = "DELETE from addressbook where uid = " |
287 | + QString::number(m_uid) + ";"; | 287 | + QString::number(m_uid) + ";"; |
288 | qu += "DELETE from custom_data where uid = " | 288 | qu += "DELETE from custom_data where uid = " |
289 | + QString::number(m_uid) + ";"; | 289 | + QString::number(m_uid) + ";"; |
290 | return qu; | 290 | return qu; |
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 UIDArray& ints) | 297 | FindQuery::FindQuery(const UIDArray& 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 | 309 | ||
310 | 310 | ||
311 | QString FindQuery::multi()const { | 311 | QString FindQuery::multi()const { |
312 | QString qu = "select * from addressbook where"; | 312 | QString qu = "select * from addressbook where"; |
313 | for (uint i = 0; i < m_uids.count(); i++ ) { | 313 | for (uint i = 0; i < m_uids.count(); i++ ) { |
314 | qu += " uid = " + QString::number( m_uids[i] ) + " OR"; | 314 | qu += " uid = " + QString::number( m_uids[i] ) + " OR"; |
315 | } | 315 | } |
316 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 316 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. |
317 | 317 | ||
318 | odebug << "find query: " << qu << "" << oendl; | 318 | odebug << "find query: " << qu << "" << oendl; |
319 | return qu; | 319 | return qu; |
320 | } | 320 | } |
321 | 321 | ||
322 | QString FindQuery::single()const{ | 322 | QString FindQuery::single()const{ |
323 | QString qu = "select *"; | 323 | QString qu = "select *"; |
324 | qu += " from addressbook where uid = " + QString::number(m_uid); | 324 | qu += " from addressbook where uid = " + QString::number(m_uid); |
325 | 325 | ||
326 | // owarn << "find query: " << qu << "" << oendl; | 326 | // owarn << "find query: " << qu << "" << oendl; |
327 | return qu; | 327 | return qu; |
328 | } | 328 | } |
329 | 329 | ||
330 | 330 | ||
331 | FindCustomQuery::FindCustomQuery(int uid) | 331 | FindCustomQuery::FindCustomQuery(int uid) |
332 | : OSQLQuery(), m_uid( uid ) { | 332 | : OSQLQuery(), m_uid( uid ) { |
333 | } | 333 | } |
334 | FindCustomQuery::FindCustomQuery(const UIDArray& ints) | 334 | FindCustomQuery::FindCustomQuery(const UIDArray& ints) |
335 | : OSQLQuery(), m_uids( ints ){ | 335 | : OSQLQuery(), m_uids( ints ){ |
336 | } | 336 | } |
337 | FindCustomQuery::~FindCustomQuery() { | 337 | FindCustomQuery::~FindCustomQuery() { |
338 | } | 338 | } |
339 | QString FindCustomQuery::query()const{ | 339 | QString FindCustomQuery::query()const{ |
340 | // if ( m_uids.count() == 0 ) | 340 | // if ( m_uids.count() == 0 ) |
341 | return single(); | 341 | return single(); |
342 | } | 342 | } |
343 | QString FindCustomQuery::single()const{ | 343 | QString FindCustomQuery::single()const{ |
344 | QString qu = "select uid, type, value from custom_data where uid = "; | 344 | QString qu = "select uid, type, value from custom_data where uid = "; |
345 | qu += QString::number(m_uid); | 345 | qu += QString::number(m_uid); |
346 | return qu; | 346 | return qu; |
347 | } | 347 | } |
348 | 348 | ||
349 | }; | 349 | }; |
350 | 350 | ||
351 | 351 | ||
352 | /* --------------------------------------------------------------------------- */ | 352 | /* --------------------------------------------------------------------------- */ |
353 | 353 | ||
354 | namespace Opie { | 354 | namespace Opie { |
355 | 355 | ||
356 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, | 356 | OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, |
357 | const QString& filename ): | 357 | const QString& filename ): |
358 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) | 358 | OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) |
359 | { | 359 | { |
360 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; | 360 | odebug << "C'tor OPimContactAccessBackend_SQL starts" << oendl; |
361 | QTime t; | 361 | QTime t; |
362 | t.start(); | 362 | t.start(); |
363 | 363 | ||
364 | /* Expecting to access the default filename if nothing else is set */ | 364 | /* Expecting to access the default filename if nothing else is set */ |
365 | if ( filename.isEmpty() ){ | 365 | if ( filename.isEmpty() ){ |
366 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); | 366 | m_fileName = Global::applicationFileName( "addressbook","addressbook.db" ); |
367 | } else | 367 | } else |
368 | m_fileName = filename; | 368 | m_fileName = filename; |
369 | 369 | ||
370 | // Get the standart sql-driver from the OSQLManager.. | 370 | // Get the standart sql-driver from the OSQLManager.. |
371 | OSQLManager man; | 371 | OSQLManager man; |
372 | m_driver = man.standard(); | 372 | m_driver = man.standard(); |
373 | m_driver->setUrl( m_fileName ); | 373 | m_driver->setUrl( m_fileName ); |
374 | 374 | ||
375 | load(); | 375 | load(); |
376 | 376 | ||
377 | odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; | 377 | odebug << "C'tor OPimContactAccessBackend_SQL ends: " << t.elapsed() << " ms" << oendl; |
378 | } | 378 | } |
379 | 379 | ||
380 | OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () | 380 | OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () |
381 | { | 381 | { |
382 | if( m_driver ) | 382 | if( m_driver ) |
383 | delete m_driver; | 383 | delete m_driver; |
384 | } | 384 | } |
385 | 385 | ||
386 | bool OPimContactAccessBackend_SQL::load () | 386 | bool OPimContactAccessBackend_SQL::load () |
387 | { | 387 | { |
388 | if (!m_driver->open() ) | 388 | if (!m_driver->open() ) |
389 | return false; | 389 | return false; |
390 | 390 | ||
391 | // Don't expect that the database exists. | 391 | // Don't expect that the database exists. |
392 | // It is save here to create the table, even if it | 392 | // It is save here to create the table, even if it |
393 | // do exist. ( Is that correct for all databases ?? ) | 393 | // do exist. ( Is that correct for all databases ?? ) |
394 | CreateQuery creat; | 394 | CreateQuery creat; |
395 | OSQLResult res = m_driver->query( &creat ); | 395 | OSQLResult res = m_driver->query( &creat ); |
396 | 396 | ||
397 | update(); | 397 | update(); |
398 | 398 | ||
399 | return true; | 399 | return true; |
400 | 400 | ||
401 | } | 401 | } |
402 | 402 | ||
403 | bool OPimContactAccessBackend_SQL::reload() | 403 | bool OPimContactAccessBackend_SQL::reload() |
404 | { | 404 | { |
405 | return load(); | 405 | return load(); |
406 | } | 406 | } |
407 | 407 | ||
408 | bool OPimContactAccessBackend_SQL::save() | 408 | bool OPimContactAccessBackend_SQL::save() |
409 | { | 409 | { |
410 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) | 410 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) |
411 | } | 411 | } |
412 | 412 | ||
413 | 413 | ||
414 | void OPimContactAccessBackend_SQL::clear () | 414 | void OPimContactAccessBackend_SQL::clear () |
415 | { | 415 | { |
416 | ClearQuery cle; | 416 | ClearQuery cle; |
417 | OSQLResult res = m_driver->query( &cle ); | 417 | OSQLResult res = m_driver->query( &cle ); |
418 | 418 | ||
419 | reload(); | 419 | reload(); |
420 | } | 420 | } |
421 | 421 | ||
422 | bool OPimContactAccessBackend_SQL::wasChangedExternally() | 422 | bool OPimContactAccessBackend_SQL::wasChangedExternally() |
423 | { | 423 | { |
424 | return false; | 424 | return false; |
425 | } | 425 | } |
426 | 426 | ||
427 | UIDArray OPimContactAccessBackend_SQL::allRecords() const | 427 | UIDArray OPimContactAccessBackend_SQL::allRecords() const |
428 | { | 428 | { |
429 | 429 | ||
430 | // FIXME: Think about cute handling of changed tables.. | 430 | // FIXME: Think about cute handling of changed tables.. |
431 | // Thus, we don't have to call update here... | 431 | // Thus, we don't have to call update here... |
432 | if ( m_changed ) | 432 | if ( m_changed ) |
433 | ((OPimContactAccessBackend_SQL*)this)->update(); | 433 | ((OPimContactAccessBackend_SQL*)this)->update(); |
434 | 434 | ||
435 | return m_uids; | 435 | return m_uids; |
436 | } | 436 | } |
437 | 437 | ||
438 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) | 438 | bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) |
439 | { | 439 | { |
440 | odebug << "add in contact SQL-Backend" << oendl; | 440 | odebug << "add in contact SQL-Backend" << oendl; |
441 | InsertQuery ins( newcontact ); | 441 | InsertQuery ins( newcontact ); |
442 | OSQLResult res = m_driver->query( &ins ); | 442 | OSQLResult res = m_driver->query( &ins ); |
443 | 443 | ||
444 | if ( res.state() == OSQLResult::Failure ) | 444 | if ( res.state() == OSQLResult::Failure ) |
445 | return false; | 445 | return false; |
446 | 446 | ||
447 | int c = m_uids.count(); | 447 | int c = m_uids.count(); |
448 | m_uids.resize( c+1 ); | 448 | m_uids.resize( c+1 ); |
449 | m_uids[c] = newcontact.uid(); | 449 | m_uids[c] = newcontact.uid(); |
450 | 450 | ||
451 | return true; | 451 | return true; |
452 | } | 452 | } |
453 | 453 | ||
454 | 454 | ||
455 | bool OPimContactAccessBackend_SQL::remove ( int uid ) | 455 | bool OPimContactAccessBackend_SQL::remove ( int uid ) |
456 | { | 456 | { |
457 | RemoveQuery rem( uid ); | 457 | RemoveQuery rem( uid ); |
458 | OSQLResult res = m_driver->query(&rem ); | 458 | OSQLResult res = m_driver->query(&rem ); |
459 | 459 | ||
460 | if ( res.state() == OSQLResult::Failure ) | 460 | if ( res.state() == OSQLResult::Failure ) |
461 | return false; | 461 | return false; |
462 | 462 | ||
463 | m_changed = true; | 463 | m_changed = true; |
464 | 464 | ||
465 | return true; | 465 | return true; |
466 | } | 466 | } |
467 | 467 | ||
468 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) | 468 | bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) |
469 | { | 469 | { |
470 | if ( !remove( contact.uid() ) ) | 470 | if ( !remove( contact.uid() ) ) |
471 | return false; | 471 | return false; |
472 | 472 | ||
473 | return add( contact ); | 473 | return add( contact ); |
474 | } | 474 | } |
475 | 475 | ||
476 | 476 | ||
477 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const | 477 | OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const |
478 | { | 478 | { |
479 | odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; | 479 | odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; |
480 | QTime t; | 480 | QTime t; |
481 | t.start(); | 481 | t.start(); |
482 | 482 | ||
483 | OPimContact retContact( requestNonCustom( uid ) ); | 483 | OPimContact retContact( requestNonCustom( uid ) ); |
484 | retContact.setExtraMap( requestCustom( uid ) ); | 484 | retContact.setExtraMap( requestCustom( uid ) ); |
485 | 485 | ||
486 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; | 486 | odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; |
487 | return retContact; | 487 | return retContact; |
488 | } | 488 | } |
489 | 489 | ||
490 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const | 490 | OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const |
491 | { | 491 | { |
492 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; | 492 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; |
493 | odebug << "searching for " << uid << "" << oendl; | 493 | odebug << "searching for " << uid << "" << oendl; |
494 | 494 | ||
495 | QTime t; | 495 | QTime t; |
496 | t.start(); | 496 | t.start(); |
497 | 497 | ||
498 | uint numReadAhead = readAhead(); | 498 | uint numReadAhead = readAhead(); |
499 | QArray<int> searchList( numReadAhead ); | 499 | QArray<int> searchList( numReadAhead ); |
500 | 500 | ||
501 | uint size =0; | 501 | uint size =0; |
502 | 502 | ||
503 | // Build an array with all elements which should be requested and cached | 503 | // Build an array with all elements which should be requested and cached |
504 | // We will just request "numReadAhead" elements, starting from "current" position in | 504 | // We will just request "numReadAhead" elements, starting from "current" position in |
505 | // the list of many uids ! | 505 | // the list of many uids ! |
506 | switch( direction ) { | 506 | switch( direction ) { |
507 | /* forward */ | 507 | /* forward */ |
508 | case Frontend::Forward: | 508 | case Frontend::Forward: |
509 | for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { | 509 | for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) { |
510 | searchList[size] = queryUids[i]; | 510 | searchList[size] = queryUids[i]; |
511 | size++; | 511 | size++; |
512 | } | 512 | } |
513 | break; | 513 | break; |
514 | /* reverse */ | 514 | /* reverse */ |
515 | case Frontend::Reverse: | 515 | case Frontend::Reverse: |
516 | for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { | 516 | for ( uint i = current; i != 0 && size < numReadAhead; i-- ) { |
517 | searchList[size] = queryUids[i]; | 517 | searchList[size] = queryUids[i]; |
518 | size++; | 518 | size++; |
519 | } | 519 | } |
520 | break; | 520 | break; |
521 | } | 521 | } |
522 | 522 | ||
523 | //Shrink to real size.. | 523 | //Shrink to real size.. |
524 | searchList.resize( size ); | 524 | searchList.resize( size ); |
525 | 525 | ||
526 | OPimContact retContact( requestContactsAndCache( uid, searchList ) ); | 526 | OPimContact retContact( requestContactsAndCache( uid, searchList ) ); |
527 | 527 | ||
528 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; | 528 | odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; |
529 | return retContact; | 529 | return retContact; |
530 | } | 530 | } |
531 | 531 | ||
532 | 532 | ||
533 | UIDArray OPimContactAccessBackend_SQL::queryByExample ( const UIDArray& uidlist, const OPimContact &query, int settings, | 533 | UIDArray OPimContactAccessBackend_SQL::queryByExample ( const UIDArray& uidlist, const OPimContact &query, int settings, |
534 | const QDateTime& qd ) const | 534 | const QDateTime& qd ) const |
535 | { | 535 | { |
536 | QString qu = "SELECT uid FROM addressbook WHERE"; | 536 | QString searchQuery = ""; |
537 | QString datediff_query = ""; | ||
538 | QString uid_query = ""; | ||
537 | 539 | ||
538 | // Just add uid's selection if we really try to search in a subset of all uids! Otherwise this would | 540 | // Just add uid's selection if we really try to search in a subset of all uids! Otherwise this would |
539 | // just take time and memory! | 541 | // just take time and memory! |
540 | if ( uidlist.count() != m_uids.count() ) { | 542 | if ( uidlist.count() != m_uids.count() ) { |
541 | qu += " ("; | 543 | uid_query += " ("; |
542 | 544 | ||
543 | for ( uint i = 0; i < uidlist.count(); i++ ) { | 545 | for ( uint i = 0; i < uidlist.count(); i++ ) { |
544 | qu += " uid = " + QString::number( uidlist[i] ) + " OR"; | 546 | uid_query += " uid = " + QString::number( uidlist[i] ) + " OR"; |
545 | } | 547 | } |
546 | qu.remove( qu.length()-2, 2 ); // Hmmmm.. | 548 | uid_query.remove( uid_query.length()-2, 2 ); // Hmmmm.. |
547 | qu += " ) AND "; | 549 | uid_query += " ) AND "; |
548 | } | 550 | } |
549 | 551 | ||
550 | QString searchQuery = ""; | ||
551 | QString temp_searchQuery = ""; | ||
552 | 552 | ||
553 | QDate startDate; | 553 | QDate startDate; |
554 | 554 | ||
555 | if ( qd.isValid() ) | 555 | if ( qd.isValid() ) |
556 | startDate = qd.date(); | 556 | startDate = qd.date(); |
557 | else | 557 | else |
558 | startDate = QDate::currentDate(); | 558 | startDate = QDate::currentDate(); |
559 | 559 | ||
560 | 560 | ||
561 | QMap<int, QString> queryFields = query.toMap(); | 561 | QMap<int, QString> queryFields = query.toMap(); |
562 | QStringList fieldList = OPimContactFields::untrfields( false ); | 562 | QStringList fieldList = OPimContactFields::untrfields( false ); |
563 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 563 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
564 | 564 | ||
565 | // Convert every filled field to a SQL-Query | 565 | // Convert every filled field to a SQL-Query |
566 | // bool isAnyFieldSelected = false; | 566 | // bool isAnyFieldSelected = false; |
567 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 567 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
568 | 568 | ||
569 | int id = translate[*it]; | 569 | int id = translate[*it]; |
570 | QString queryStr = queryFields[id]; | 570 | QString queryStr = queryFields[id]; |
571 | QDate* endDate = 0l; | 571 | QDate* endDate = 0l; |
572 | 572 | ||
573 | if ( !queryStr.isEmpty() ){ | 573 | if ( !queryStr.isEmpty() ){ |
574 | // If something is alredy stored in the query, add an "AND" | 574 | // If something is alredy stored in the query, add an "AND" |
575 | // to the end of the string to prepare for the next .. | 575 | // to the end of the string to prepare for the next .. |
576 | if ( !searchQuery.isEmpty() ) | 576 | if ( !searchQuery.isEmpty() ) |
577 | searchQuery += " AND"; | 577 | searchQuery += " AND"; |
578 | 578 | ||
579 | // isAnyFieldSelected = true; | 579 | // isAnyFieldSelected = true; |
580 | switch( id ){ | 580 | switch( id ){ |
581 | case Qtopia::Birthday: | 581 | case Qtopia::Birthday: |
582 | endDate = new QDate( query.birthday() ); | 582 | endDate = new QDate( query.birthday() ); |
583 | // Fall through ! | 583 | // Fall through ! |
584 | case Qtopia::Anniversary: | 584 | case Qtopia::Anniversary: |
585 | if ( endDate == 0l ) | 585 | if ( endDate == 0l ) |
586 | endDate = new QDate( query.anniversary() ); | 586 | endDate = new QDate( query.anniversary() ); |
587 | 587 | ||
588 | if ( settings & OPimContactAccess::DateDiff ) { | 588 | if ( settings & OPimContactAccess::DateDiff ) { |
589 | // To handle datediffs correctly, we need to remove the year information from | 589 | // To handle datediffs correctly, we need to remove the year information from |
590 | // the birthday and anniversary. | 590 | // the birthday and anniversary. |
591 | // To do this efficiently, we will create a temporary table which contains the | 591 | // To do this efficiently, we will create a temporary table which contains the |
592 | // information we need and do the query on it. | 592 | // information we need and do the query on it. |
593 | // This table is just visible for this process and will be removed | 593 | // This table is just visible for this process and will be removed |
594 | // automatically after using. | 594 | // automatically after using. |
595 | temp_searchQuery = "CREATE TEMP TABLE bs ( uid, \"Birthday\", \"Anniversary\" );"; | 595 | datediff_query = "CREATE TEMP TABLE bs ( uid, \"Birthday\", \"Anniversary\" );"; |
596 | temp_searchQuery += "INSERT INTO bs SELECT uid,substr(\"Birthday\", 6, 10),substr(\"Anniversary\", 6, 10) FROM addressbook WHERE ( \"Birthday\" != '' OR \"Anniversary\" != '' );"; | 596 | datediff_query += "INSERT INTO bs SELECT uid,substr(\"Birthday\", 6, 10),substr(\"Anniversary\", 6, 10) FROM addressbook WHERE ( \"Birthday\" != '' OR \"Anniversary\" != '' );"; |
597 | 597 | datediff_query += QString( "SELECT uid FROM bs WHERE " ) + uid_query; | |
598 | temp_searchQuery += QString( "SELECT uid FROM bs WHERE (\"%1\" <= '%2-%3\' AND \"%4\" >= '%5-%6')" ) | 598 | datediff_query += QString( " (\"%1\" <= '%2-%3\' AND \"%4\" >= '%5-%6')" ) |
599 | .arg( *it ) | 599 | .arg( *it ) |
600 | //.arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) | 600 | //.arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) |
601 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) | 601 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) |
602 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) | 602 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) |
603 | .arg( *it ) | 603 | .arg( *it ) |
604 | //.arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) | 604 | //.arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) |
605 | .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) | 605 | .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) |
606 | .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; | 606 | .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; |
607 | } | 607 | } |
608 | 608 | ||
609 | if ( settings & OPimContactAccess::DateYear ){ | 609 | if ( settings & OPimContactAccess::DateYear ){ |
610 | // if ( settings & OPimContactAccess::DateDiff ) | ||
611 | // searchQuery += " AND"; | ||
612 | |||
613 | searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) | 610 | searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) |
614 | .arg( *it ) | 611 | .arg( *it ) |
615 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); | 612 | .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); |
616 | } | 613 | } |
617 | 614 | ||
618 | if ( settings & OPimContactAccess::DateMonth ){ | 615 | if ( settings & OPimContactAccess::DateMonth ){ |
619 | if ( ( settings & OPimContactAccess::DateDiff ) | 616 | if ( settings & OPimContactAccess::DateYear ) |
620 | || ( settings & OPimContactAccess::DateYear ) ) | ||
621 | searchQuery += " AND"; | 617 | searchQuery += " AND"; |
622 | 618 | ||
623 | searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) | 619 | searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) |
624 | .arg( *it ) | 620 | .arg( *it ) |
625 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); | 621 | .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); |
626 | } | 622 | } |
627 | 623 | ||
628 | if ( settings & OPimContactAccess::DateDay ){ | 624 | if ( settings & OPimContactAccess::DateDay ){ |
629 | if ( ( settings & OPimContactAccess::DateDiff ) | 625 | if ( ( settings & OPimContactAccess::DateYear ) |
630 | || ( settings & OPimContactAccess::DateYear ) | ||
631 | || ( settings & OPimContactAccess::DateMonth ) ) | 626 | || ( settings & OPimContactAccess::DateMonth ) ) |
632 | searchQuery += " AND"; | 627 | searchQuery += " AND"; |
633 | 628 | ||
634 | searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) | 629 | searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) |
635 | .arg( *it ) | 630 | .arg( *it ) |
636 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); | 631 | .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); |
637 | } | 632 | } |
638 | 633 | ||
639 | break; | 634 | break; |
640 | default: | 635 | default: |
641 | // Switching between case sensitive and insensitive... | 636 | // Switching between case sensitive and insensitive... |
642 | // LIKE is not case sensitive, GLOB is case sensitive | 637 | // LIKE is not case sensitive, GLOB is case sensitive |
643 | // Do exist a better solution to switch this ? | 638 | // Do exist a better solution to switch this ? |
644 | if ( settings & OPimContactAccess::IgnoreCase ) | 639 | if ( settings & OPimContactAccess::IgnoreCase ) |
645 | searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" | 640 | searchQuery += " (\"" + *it + "\"" + " LIKE " + "'" |
646 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; | 641 | + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; |
647 | else | 642 | else |
648 | searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" | 643 | searchQuery += " (\"" + *it + "\"" + " GLOB " + "'" |
649 | + queryStr + "'" + ")"; | 644 | + queryStr + "'" + ")"; |
650 | 645 | ||
651 | } | 646 | } |
652 | } | 647 | } |
653 | 648 | ||
654 | delete endDate; | 649 | delete endDate; |
650 | |||
651 | // The following if line is a replacement for | ||
652 | // if ( searchQuery.endsWith( "AND" ) ) | ||
653 | if ( searchQuery.findRev( "AND" ) == ( searchQuery.length() - 3 ) ){ | ||
654 | odebug << "remove AND" << oendl; | ||
655 | searchQuery.remove( searchQuery.length()-3, 3 ); // Hmmmm.. | ||
656 | } | ||
657 | |||
655 | } | 658 | } |
656 | 659 | ||
657 | // The following is very ugly! (eilers) | 660 | // Now compose the complete query |
658 | if ( !temp_searchQuery.isEmpty() && !searchQuery.isEmpty() ){ | 661 | QString qu = "SELECT uid FROM addressbook WHERE " + uid_query; |
662 | |||
663 | if ( !datediff_query.isEmpty() && !searchQuery.isEmpty() ){ | ||
659 | // If we use DateDiff, we have to intersect two queries. | 664 | // If we use DateDiff, we have to intersect two queries. |
660 | qu = temp_searchQuery + QString( " INTERSECT " ) + qu + searchQuery; | 665 | qu = datediff_query + QString( " INTERSECT " ) + qu + searchQuery; |
661 | } else if ( temp_searchQuery.isEmpty() && !searchQuery.isEmpty() ){ | 666 | } else if ( datediff_query.isEmpty() && !searchQuery.isEmpty() ){ |
662 | qu += searchQuery; | 667 | qu += searchQuery; |
663 | } else if ( !temp_searchQuery.isEmpty() && searchQuery.isEmpty() ){ | 668 | } else if ( !datediff_query.isEmpty() && searchQuery.isEmpty() ){ |
664 | // This will cause wrong results!! Uid filter is not used here! | 669 | qu = datediff_query; |
665 | qu = temp_searchQuery; | 670 | } else if ( datediff_query.isEmpty() && searchQuery.isEmpty() ){ |
666 | } else if ( temp_searchQuery.isEmpty() && searchQuery.isEmpty() ){ | ||
667 | UIDArray empty; | 671 | UIDArray empty; |
668 | return empty; | 672 | return empty; |
669 | } | 673 | } |
670 | 674 | ||
671 | odebug << "queryByExample query: " << qu << "" << oendl; | 675 | odebug << "queryByExample query: " << qu << "" << oendl; |
672 | 676 | ||
673 | // Execute query and return the received uid's | 677 | // Execute query and return the received uid's |
674 | OSQLRawQuery raw( qu ); | 678 | OSQLRawQuery raw( qu ); |
675 | OSQLResult res = m_driver->query( &raw ); | 679 | OSQLResult res = m_driver->query( &raw ); |
676 | if ( res.state() != OSQLResult::Success ){ | 680 | if ( res.state() != OSQLResult::Success ){ |
677 | UIDArray empty; | 681 | UIDArray empty; |
678 | return empty; | 682 | return empty; |
679 | } | 683 | } |
680 | 684 | ||
681 | UIDArray list = extractUids( res ); | 685 | UIDArray list = extractUids( res ); |
682 | 686 | ||
683 | // Remove temp table if created | 687 | // Remove temp table if created |
684 | if ( !temp_searchQuery.isEmpty( ) ){ | 688 | if ( !datediff_query.isEmpty( ) ){ |
685 | qu = "DROP TABLE bs"; | 689 | qu = "DROP TABLE bs"; |
686 | OSQLRawQuery raw( qu ); | 690 | OSQLRawQuery raw( qu ); |
687 | OSQLResult res = m_driver->query( &raw ); | 691 | OSQLResult res = m_driver->query( &raw ); |
688 | } | 692 | } |
689 | 693 | ||
690 | return list; | 694 | return list; |
691 | } | 695 | } |
692 | 696 | ||
693 | UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | 697 | UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const |
694 | { | 698 | { |
695 | #if 0 | 699 | #if 0 |
696 | QArray<int> nix(0); | 700 | QArray<int> nix(0); |
697 | return nix; | 701 | return nix; |
698 | 702 | ||
699 | #else | 703 | #else |
700 | QString qu = "SELECT uid FROM addressbook WHERE ("; | 704 | QString qu = "SELECT uid FROM addressbook WHERE ("; |
701 | QString searchlist; | 705 | QString searchlist; |
702 | 706 | ||
703 | QStringList fieldList = OPimContactFields::untrfields( false ); | 707 | QStringList fieldList = OPimContactFields::untrfields( false ); |
704 | // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 708 | // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
705 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 709 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
706 | if ( !searchlist.isEmpty() ) | 710 | if ( !searchlist.isEmpty() ) |
707 | searchlist += " OR "; | 711 | searchlist += " OR "; |
708 | searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; | 712 | searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; |
709 | } | 713 | } |
710 | 714 | ||
711 | qu = qu + searchlist + ")"; | 715 | qu = qu + searchlist + ")"; |
712 | 716 | ||
713 | odebug << "query: " << qu << "" << oendl; | 717 | odebug << "query: " << qu << "" << oendl; |
714 | 718 | ||
715 | OSQLRawQuery raw( qu ); | 719 | OSQLRawQuery raw( qu ); |
716 | OSQLResult res = m_driver->query( &raw ); | 720 | OSQLResult res = m_driver->query( &raw ); |
717 | 721 | ||
718 | return extractUids( res ); | 722 | return extractUids( res ); |
719 | 723 | ||
720 | 724 | ||
721 | #endif | 725 | #endif |
722 | } | 726 | } |
723 | 727 | ||
724 | const uint OPimContactAccessBackend_SQL::querySettings() const | 728 | const uint OPimContactAccessBackend_SQL::querySettings() const |
725 | { | 729 | { |
726 | return OPimContactAccess::IgnoreCase | 730 | return OPimContactAccess::IgnoreCase |
727 | | OPimContactAccess::WildCards | 731 | | OPimContactAccess::WildCards |
728 | | OPimContactAccess::DateDiff | 732 | | OPimContactAccess::DateDiff |
729 | | OPimContactAccess::DateYear | 733 | | OPimContactAccess::DateYear |
730 | | OPimContactAccess::DateMonth | 734 | | OPimContactAccess::DateMonth |
731 | | OPimContactAccess::DateDay | 735 | | OPimContactAccess::DateDay |
732 | ; | 736 | ; |
733 | } | 737 | } |
734 | 738 | ||
735 | bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const | 739 | bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const |
736 | { | 740 | { |
737 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay | 741 | /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay |
738 | * may be added with any of the other settings. IgnoreCase should never used alone. | 742 | * may be added with any of the other settings. IgnoreCase should never used alone. |
739 | * Wildcards, RegExp, ExactMatch should never used at the same time... | 743 | * Wildcards, RegExp, ExactMatch should never used at the same time... |
740 | */ | 744 | */ |
741 | 745 | ||
742 | // Step 1: Check whether the given settings are supported by this backend | 746 | // Step 1: Check whether the given settings are supported by this backend |
743 | if ( ( querySettings & ( | 747 | if ( ( querySettings & ( |
744 | OPimContactAccess::IgnoreCase | 748 | OPimContactAccess::IgnoreCase |
745 | | OPimContactAccess::WildCards | 749 | | OPimContactAccess::WildCards |
746 | | OPimContactAccess::DateDiff | 750 | | OPimContactAccess::DateDiff |
747 | | OPimContactAccess::DateYear | 751 | | OPimContactAccess::DateYear |
748 | | OPimContactAccess::DateMonth | 752 | | OPimContactAccess::DateMonth |
749 | | OPimContactAccess::DateDay | 753 | | OPimContactAccess::DateDay |
750 | // | OPimContactAccess::RegExp | 754 | // | OPimContactAccess::RegExp |
751 | // | OPimContactAccess::ExactMatch | 755 | // | OPimContactAccess::ExactMatch |
752 | ) ) != querySettings ) | 756 | ) ) != querySettings ) |
753 | return false; | 757 | return false; |
754 | 758 | ||
755 | // Step 2: Check whether the given combinations are ok.. | 759 | // Step 2: Check whether the given combinations are ok.. |
756 | 760 | ||
757 | // IngoreCase alone is invalid | 761 | // IngoreCase alone is invalid |
758 | if ( querySettings == OPimContactAccess::IgnoreCase ) | 762 | if ( querySettings == OPimContactAccess::IgnoreCase ) |
759 | return false; | 763 | return false; |
760 | 764 | ||
761 | // WildCards, RegExp and ExactMatch should never used at the same time | 765 | // WildCards, RegExp and ExactMatch should never used at the same time |
762 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase | 766 | switch ( querySettings & ~( OPimContactAccess::IgnoreCase |
763 | | OPimContactAccess::DateDiff | 767 | | OPimContactAccess::DateDiff |
764 | | OPimContactAccess::DateYear | 768 | | OPimContactAccess::DateYear |
765 | | OPimContactAccess::DateMonth | 769 | | OPimContactAccess::DateMonth |
766 | | OPimContactAccess::DateDay | 770 | | OPimContactAccess::DateDay |
767 | ) | 771 | ) |
768 | ){ | 772 | ){ |
769 | case OPimContactAccess::RegExp: | 773 | case OPimContactAccess::RegExp: |
770 | return ( true ); | 774 | return ( true ); |
771 | case OPimContactAccess::WildCards: | 775 | case OPimContactAccess::WildCards: |
772 | return ( true ); | 776 | return ( true ); |
773 | case OPimContactAccess::ExactMatch: | 777 | case OPimContactAccess::ExactMatch: |
774 | return ( true ); | 778 | return ( true ); |
775 | case 0: // one of the upper removed bits were set.. | 779 | case 0: // one of the upper removed bits were set.. |
776 | return ( true ); | 780 | return ( true ); |
777 | default: | 781 | default: |
778 | return ( false ); | 782 | return ( false ); |
779 | } | 783 | } |
780 | 784 | ||
781 | } | 785 | } |
782 | 786 | ||
783 | UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, | 787 | UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, |
784 | int filter, const QArray<int>& categories )const | 788 | int filter, const QArray<int>& categories )const |
785 | { | 789 | { |
786 | QTime t; | 790 | QTime t; |
787 | t.start(); | 791 | t.start(); |
788 | 792 | ||
789 | QString query = "SELECT uid FROM addressbook"; | 793 | QString query = "SELECT uid FROM addressbook"; |
790 | 794 | ||
791 | query += " WHERE ("; | 795 | query += " WHERE ("; |
792 | for ( uint i = 0; i < ar.count(); i++ ) { | 796 | for ( uint i = 0; i < ar.count(); i++ ) { |
793 | query += " uid = " + QString::number( ar[i] ) + " OR"; | 797 | query += " uid = " + QString::number( ar[i] ) + " OR"; |
794 | } | 798 | } |
795 | query.remove( query.length()-2, 2 ); // Hmmmm.. | 799 | query.remove( query.length()-2, 2 ); // Hmmmm.. |
796 | query += ")"; | 800 | query += ")"; |
797 | 801 | ||
798 | 802 | ||
799 | if ( filter != OPimBase::FilterOff ){ | 803 | if ( filter != OPimBase::FilterOff ){ |
800 | if ( filter & OPimContactAccess::DoNotShowWithCategory ){ | 804 | if ( filter & OPimContactAccess::DoNotShowWithCategory ){ |
801 | query += " AND ( \"Categories\" == '' )"; | 805 | query += " AND ( \"Categories\" == '' )"; |
802 | } else if ( filter & OPimBase::FilterCategory ){ | 806 | } else if ( filter & OPimBase::FilterCategory ){ |
803 | query += " AND ("; | 807 | query += " AND ("; |
804 | for ( uint i = 0; i < categories.count(); i++ ){ | 808 | for ( uint i = 0; i < categories.count(); i++ ){ |
805 | query += "\"Categories\" LIKE"; | 809 | query += "\"Categories\" LIKE"; |
806 | query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR"; | 810 | query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR"; |
807 | } | 811 | } |
808 | query.remove( query.length()-2, 2 ); // Hmmmm.. | 812 | query.remove( query.length()-2, 2 ); // Hmmmm.. |
809 | query += ")"; | 813 | query += ")"; |
810 | } | 814 | } |
811 | 815 | ||
812 | if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){ | 816 | if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){ |
813 | query += " AND ( \"Children\" != '' )"; | 817 | query += " AND ( \"Children\" != '' )"; |
814 | } | 818 | } |
815 | 819 | ||
816 | if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){ | 820 | if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){ |
817 | query += " AND ( \"Anniversary\" != '' )"; | 821 | query += " AND ( \"Anniversary\" != '' )"; |
818 | } | 822 | } |
819 | 823 | ||
820 | if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){ | 824 | if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){ |
821 | query += " AND ( \"Birthday\" != '' )"; | 825 | query += " AND ( \"Birthday\" != '' )"; |
822 | } | 826 | } |
823 | 827 | ||
824 | if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){ | 828 | if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){ |
825 | // Expect that no Street means no Address, too! (eilers) | 829 | // Expect that no Street means no Address, too! (eilers) |
826 | query += " AND ( \"Home Street\" != '' )"; | 830 | query += " AND ( \"Home Street\" != '' )"; |
827 | } | 831 | } |
828 | 832 | ||
829 | if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){ | 833 | if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){ |
830 | // Expect that no Street means no Address, too! (eilers) | 834 | // Expect that no Street means no Address, too! (eilers) |
831 | query += " AND ( \"Business Street\" != '' )"; | 835 | query += " AND ( \"Business Street\" != '' )"; |
832 | } | 836 | } |
833 | 837 | ||
834 | } | 838 | } |
835 | 839 | ||
836 | query += " ORDER BY"; | 840 | query += " ORDER BY"; |
837 | 841 | ||
838 | switch ( sortOrder ) { | 842 | switch ( sortOrder ) { |
839 | case OPimContactAccess::SortSummary: | 843 | case OPimContactAccess::SortSummary: |
840 | query += " \"Notes\""; | 844 | query += " \"Notes\""; |
841 | break; | 845 | break; |
842 | case OPimContactAccess::SortByCategory: | 846 | case OPimContactAccess::SortByCategory: |
843 | query += " \"Categories\""; | 847 | query += " \"Categories\""; |
844 | break; | 848 | break; |
845 | case OPimContactAccess::SortByDate: | 849 | case OPimContactAccess::SortByDate: |
846 | query += " \"\""; | 850 | query += " \"\""; |
847 | break; | 851 | break; |
848 | case OPimContactAccess::SortTitle: | 852 | case OPimContactAccess::SortTitle: |
849 | query += " \"Name Title\""; | 853 | query += " \"Name Title\""; |
850 | break; | 854 | break; |
851 | case OPimContactAccess::SortFirstName: | 855 | case OPimContactAccess::SortFirstName: |
852 | query += " \"First Name\""; | 856 | query += " \"First Name\""; |
853 | break; | 857 | break; |
854 | case OPimContactAccess::SortMiddleName: | 858 | case OPimContactAccess::SortMiddleName: |
855 | query += " \"Middle Name\""; | 859 | query += " \"Middle Name\""; |
856 | break; | 860 | break; |
857 | case OPimContactAccess::SortLastName: | 861 | case OPimContactAccess::SortLastName: |
858 | query += " \"Last Name\""; | 862 | query += " \"Last Name\""; |
859 | break; | 863 | break; |
860 | case OPimContactAccess::SortFileAsName: | 864 | case OPimContactAccess::SortFileAsName: |
861 | query += " \"File As\""; | 865 | query += " \"File As\""; |
862 | break; | 866 | break; |
863 | case OPimContactAccess::SortSuffix: | 867 | case OPimContactAccess::SortSuffix: |
864 | query += " \"Suffix\""; | 868 | query += " \"Suffix\""; |
865 | break; | 869 | break; |
866 | case OPimContactAccess::SortEmail: | 870 | case OPimContactAccess::SortEmail: |
867 | query += " \"Default Email\""; | 871 | query += " \"Default Email\""; |
868 | break; | 872 | break; |
869 | case OPimContactAccess::SortNickname: | 873 | case OPimContactAccess::SortNickname: |
870 | query += " \"Nickname\""; | 874 | query += " \"Nickname\""; |
871 | break; | 875 | break; |
872 | case OPimContactAccess::SortAnniversary: | 876 | case OPimContactAccess::SortAnniversary: |
873 | query += " \"Anniversary\""; | 877 | query += " \"Anniversary\""; |
874 | break; | 878 | break; |
875 | case OPimContactAccess::SortBirthday: | 879 | case OPimContactAccess::SortBirthday: |
876 | query += " \"Birthday\""; | 880 | query += " \"Birthday\""; |
877 | break; | 881 | break; |
878 | case OPimContactAccess::SortGender: | 882 | case OPimContactAccess::SortGender: |
879 | query += " \"Gender\""; | 883 | query += " \"Gender\""; |
880 | break; | 884 | break; |
881 | default: | 885 | default: |
882 | query += " \"Last Name\""; | 886 | query += " \"Last Name\""; |
883 | } | 887 | } |
884 | 888 | ||
885 | if ( !asc ) | 889 | if ( !asc ) |
886 | query += " DESC"; | 890 | query += " DESC"; |
887 | 891 | ||
888 | 892 | ||
889 | odebug << "sorted query is: " << query << "" << oendl; | 893 | odebug << "sorted query is: " << query << "" << oendl; |
890 | 894 | ||
891 | OSQLRawQuery raw( query ); | 895 | OSQLRawQuery raw( query ); |
892 | OSQLResult res = m_driver->query( &raw ); | 896 | OSQLResult res = m_driver->query( &raw ); |
893 | if ( res.state() != OSQLResult::Success ){ | 897 | if ( res.state() != OSQLResult::Success ){ |
894 | UIDArray empty; | 898 | UIDArray empty; |
895 | return empty; | 899 | return empty; |
896 | } | 900 | } |
897 | 901 | ||
898 | UIDArray list = extractUids( res ); | 902 | UIDArray list = extractUids( res ); |
899 | 903 | ||
900 | odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; | 904 | odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; |
901 | return list; | 905 | return list; |
902 | } | 906 | } |
903 | 907 | ||
904 | 908 | ||
905 | void OPimContactAccessBackend_SQL::update() | 909 | void OPimContactAccessBackend_SQL::update() |
906 | { | 910 | { |
907 | odebug << "Update starts" << oendl; | 911 | odebug << "Update starts" << oendl; |
908 | QTime t; | 912 | QTime t; |
909 | t.start(); | 913 | t.start(); |
910 | 914 | ||
911 | // Now load the database set and extract the uid's | 915 | // Now load the database set and extract the uid's |
912 | // which will be held locally | 916 | // which will be held locally |
913 | 917 | ||
914 | LoadQuery lo; | 918 | LoadQuery lo; |
915 | OSQLResult res = m_driver->query(&lo); | 919 | OSQLResult res = m_driver->query(&lo); |
916 | if ( res.state() != OSQLResult::Success ) | 920 | if ( res.state() != OSQLResult::Success ) |
917 | return; | 921 | return; |
918 | 922 | ||
919 | m_uids = extractUids( res ); | 923 | m_uids = extractUids( res ); |
920 | 924 | ||
921 | m_changed = false; | 925 | m_changed = false; |
922 | 926 | ||
923 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; | 927 | odebug << "Update ends " << t.elapsed() << " ms" << oendl; |
924 | } | 928 | } |
925 | 929 | ||
926 | UIDArray OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const | 930 | UIDArray OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const |
927 | { | 931 | { |
928 | odebug << "extractUids" << oendl; | 932 | odebug << "extractUids" << oendl; |
929 | QTime t; | 933 | QTime t; |
930 | t.start(); | 934 | t.start(); |
931 | OSQLResultItem::ValueList list = res.results(); | 935 | OSQLResultItem::ValueList list = res.results(); |
932 | OSQLResultItem::ValueList::Iterator it; | 936 | OSQLResultItem::ValueList::Iterator it; |
933 | UIDArray ints(list.count() ); | 937 | UIDArray ints(list.count() ); |
934 | odebug << " count = " << list.count() << "" << oendl; | 938 | odebug << " count = " << list.count() << "" << oendl; |
935 | 939 | ||
936 | int i = 0; | 940 | int i = 0; |
937 | for (it = list.begin(); it != list.end(); ++it ) { | 941 | for (it = list.begin(); it != list.end(); ++it ) { |
938 | ints[i] = (*it).data("uid").toInt(); | 942 | ints[i] = (*it).data("uid").toInt(); |
939 | i++; | 943 | i++; |
940 | } | 944 | } |
941 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; | 945 | odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; |
942 | 946 | ||
943 | return ints; | 947 | return ints; |
944 | 948 | ||
945 | } | 949 | } |
946 | 950 | ||
947 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const | 951 | QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const |
948 | { | 952 | { |
949 | QTime t; | 953 | QTime t; |
950 | t.start(); | 954 | t.start(); |
951 | 955 | ||
952 | int t2needed = 0; | 956 | int t2needed = 0; |
953 | int t3needed = 0; | 957 | int t3needed = 0; |
954 | QTime t2; | 958 | QTime t2; |
955 | t2.start(); | 959 | t2.start(); |
956 | FindQuery query( uid ); | 960 | FindQuery query( uid ); |
957 | OSQLResult res_noncustom = m_driver->query( &query ); | 961 | OSQLResult res_noncustom = m_driver->query( &query ); |
958 | t2needed = t2.elapsed(); | 962 | t2needed = t2.elapsed(); |
959 | 963 | ||
960 | OSQLResultItem resItem = res_noncustom.first(); | 964 | OSQLResultItem resItem = res_noncustom.first(); |
961 | 965 | ||
962 | QMap<int, QString> nonCustomMap; | 966 | QMap<int, QString> nonCustomMap; |
963 | QTime t3; | 967 | QTime t3; |
964 | t3.start(); | 968 | t3.start(); |
965 | nonCustomMap = fillNonCustomMap( resItem ); | 969 | nonCustomMap = fillNonCustomMap( resItem ); |
966 | t3needed = t3.elapsed(); | 970 | t3needed = t3.elapsed(); |
967 | 971 | ||
968 | 972 | ||
969 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | 973 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; |
970 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | 974 | odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed |
971 | << " ms, mapping: " << t3needed << " ms" << oendl; | 975 | << " ms, mapping: " << t3needed << " ms" << oendl; |
972 | 976 | ||
973 | return nonCustomMap; | 977 | return nonCustomMap; |
974 | } | 978 | } |
975 | 979 | ||
976 | /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ | 980 | /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ |
977 | OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const UIDArray& uidlist )const | 981 | OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const UIDArray& uidlist )const |
978 | { | 982 | { |
979 | // We want to get all contacts with one query. | 983 | // We want to get all contacts with one query. |
980 | // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). | 984 | // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). |
981 | // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned | 985 | // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned |
982 | // by using the cache.. | 986 | // by using the cache.. |
983 | UIDArray cachelist = uidlist; | 987 | UIDArray cachelist = uidlist; |
984 | OPimContact retContact; | 988 | OPimContact retContact; |
985 | 989 | ||
986 | odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; | 990 | odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; |
987 | 991 | ||
988 | QTime t; | 992 | QTime t; |
989 | t.start(); | 993 | t.start(); |
990 | 994 | ||
991 | int t2needed = 0; | 995 | int t2needed = 0; |
992 | int t3needed = 0; | 996 | int t3needed = 0; |
993 | QTime t2; | 997 | QTime t2; |
994 | t2.start(); | 998 | t2.start(); |
995 | FindQuery query( cachelist ); | 999 | FindQuery query( cachelist ); |
996 | OSQLResult res_noncustom = m_driver->query( &query ); | 1000 | OSQLResult res_noncustom = m_driver->query( &query ); |
997 | t2needed = t2.elapsed(); | 1001 | t2needed = t2.elapsed(); |
998 | 1002 | ||
999 | QMap<int, QString> nonCustomMap; | 1003 | QMap<int, QString> nonCustomMap; |
1000 | QTime t3; | 1004 | QTime t3; |
1001 | t3.start(); | 1005 | t3.start(); |
1002 | OSQLResultItem resItem = res_noncustom.first(); | 1006 | OSQLResultItem resItem = res_noncustom.first(); |
1003 | do { | 1007 | do { |
1004 | OPimContact contact( fillNonCustomMap( resItem ) ); | 1008 | OPimContact contact( fillNonCustomMap( resItem ) ); |
1005 | contact.setExtraMap( requestCustom( contact.uid() ) ); | 1009 | contact.setExtraMap( requestCustom( contact.uid() ) ); |
1006 | odebug << "Caching uid: " << contact.uid() << oendl; | 1010 | odebug << "Caching uid: " << contact.uid() << oendl; |
1007 | cache( contact ); | 1011 | cache( contact ); |
1008 | if ( contact.uid() == uid ) | 1012 | if ( contact.uid() == uid ) |
1009 | retContact = contact; | 1013 | retContact = contact; |
1010 | resItem = res_noncustom.next(); | 1014 | resItem = res_noncustom.next(); |
1011 | } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! | 1015 | } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !! |
1012 | t3needed = t3.elapsed(); | 1016 | t3needed = t3.elapsed(); |
1013 | 1017 | ||
1014 | 1018 | ||
1015 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; | 1019 | // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; |
1016 | odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed | 1020 | odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed |
1017 | << " ms, mapping: " << t3needed << " ms" << oendl; | 1021 | << " ms, mapping: " << t3needed << " ms" << oendl; |
1018 | 1022 | ||
1019 | return retContact; | 1023 | return retContact; |
1020 | } | 1024 | } |
1021 | 1025 | ||
1022 | QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const | 1026 | QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const |
1023 | { | 1027 | { |
1024 | QMap<int, QString> nonCustomMap; | 1028 | QMap<int, QString> nonCustomMap; |
1025 | 1029 | ||
1026 | // Now loop through all columns | 1030 | // Now loop through all columns |
1027 | QStringList fieldList = OPimContactFields::untrfields( false ); | 1031 | QStringList fieldList = OPimContactFields::untrfields( false ); |
1028 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); | 1032 | QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); |
1029 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ | 1033 | for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ |
1030 | // Get data for the selected column and store it with the | 1034 | // Get data for the selected column and store it with the |
1031 | // corresponding id into the map.. | 1035 | // corresponding id into the map.. |
1032 | 1036 | ||
1033 | int id = translate[*it]; | 1037 | int id = translate[*it]; |
1034 | QString value = resultItem.data( (*it) ); | 1038 | QString value = resultItem.data( (*it) ); |
1035 | 1039 | ||
1036 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; | 1040 | // odebug << "Reading " << (*it) << "... found: " << value << "" << oendl; |
1037 | 1041 | ||
1038 | switch( id ){ | 1042 | switch( id ){ |
1039 | case Qtopia::Birthday: | 1043 | case Qtopia::Birthday: |
1040 | case Qtopia::Anniversary:{ | 1044 | case Qtopia::Anniversary:{ |
1041 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) | 1045 | // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) |
1042 | QStringList list = QStringList::split( '-', value ); | 1046 | QStringList list = QStringList::split( '-', value ); |
1043 | QStringList::Iterator lit = list.begin(); | 1047 | QStringList::Iterator lit = list.begin(); |
1044 | int year = (*lit).toInt(); | 1048 | int year = (*lit).toInt(); |
1045 | int month = (*(++lit)).toInt(); | 1049 | int month = (*(++lit)).toInt(); |
1046 | int day = (*(++lit)).toInt(); | 1050 | int day = (*(++lit)).toInt(); |
1047 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ | 1051 | if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ |
1048 | QDate date( year, month, day ); | 1052 | QDate date( year, month, day ); |
1049 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); | 1053 | nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); |
1050 | } | 1054 | } |
1051 | } | 1055 | } |
1052 | break; | 1056 | break; |
1053 | case Qtopia::AddressCategory: | 1057 | case Qtopia::AddressCategory: |
1054 | odebug << "Category is: " << value << "" << oendl; | 1058 | odebug << "Category is: " << value << "" << oendl; |
1055 | default: | 1059 | default: |
1056 | nonCustomMap.insert( id, value ); | 1060 | nonCustomMap.insert( id, value ); |
1057 | } | 1061 | } |
1058 | } | 1062 | } |
1059 | 1063 | ||
1060 | nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) ); | 1064 | nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) ); |
1061 | 1065 | ||
1062 | return nonCustomMap; | 1066 | return nonCustomMap; |
1063 | } | 1067 | } |
1064 | 1068 | ||
1065 | 1069 | ||
1066 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const | 1070 | QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const |
1067 | { | 1071 | { |
1068 | QTime t; | 1072 | QTime t; |
1069 | t.start(); | 1073 | t.start(); |
1070 | 1074 | ||
1071 | QMap<QString, QString> customMap; | 1075 | QMap<QString, QString> customMap; |
1072 | 1076 | ||
1073 | FindCustomQuery query( uid ); | 1077 | FindCustomQuery query( uid ); |
1074 | OSQLResult res_custom = m_driver->query( &query ); | 1078 | OSQLResult res_custom = m_driver->query( &query ); |
1075 | 1079 | ||
1076 | if ( res_custom.state() == OSQLResult::Failure ) { | 1080 | if ( res_custom.state() == OSQLResult::Failure ) { |
1077 | owarn << "OSQLResult::Failure in find query !!" << oendl; | 1081 | owarn << "OSQLResult::Failure in find query !!" << oendl; |
1078 | QMap<QString, QString> empty; | 1082 | QMap<QString, QString> empty; |
1079 | return empty; | 1083 | return empty; |
1080 | } | 1084 | } |
1081 | 1085 | ||
1082 | OSQLResultItem::ValueList list = res_custom.results(); | 1086 | OSQLResultItem::ValueList list = res_custom.results(); |
1083 | OSQLResultItem::ValueList::Iterator it = list.begin(); | 1087 | OSQLResultItem::ValueList::Iterator it = list.begin(); |
1084 | for ( ; it != list.end(); ++it ) { | 1088 | for ( ; it != list.end(); ++it ) { |
1085 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); | 1089 | customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); |
1086 | } | 1090 | } |
1087 | 1091 | ||
1088 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; | 1092 | odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl; |
1089 | return customMap; | 1093 | return customMap; |
1090 | } | 1094 | } |
1091 | 1095 | ||
1092 | } | 1096 | } |