author | mickeyl <mickeyl> | 2004-11-16 19:14:18 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2004-11-16 19:14:18 (UTC) |
commit | ea3945a9bd8f9830f70b1efa133f9df13b19362f (patch) (unidiff) | |
tree | f2ea22cc50e9aa8aa73ee7dea148f41c563c9666 /noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp | |
parent | 1c6f490e8541626f68422e0a3a7c7281d7f5b7d3 (diff) | |
download | opie-ea3945a9bd8f9830f70b1efa133f9df13b19362f.zip opie-ea3945a9bd8f9830f70b1efa133f9df13b19362f.tar.gz opie-ea3945a9bd8f9830f70b1efa133f9df13b19362f.tar.bz2 |
libopie1 goes into unsupported
Diffstat (limited to 'noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp b/noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp new file mode 100644 index 0000000..5f87afe --- a/dev/null +++ b/noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | * SQL Backend for the OPIE-Calender Database. | ||
3 | * | ||
4 | * Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ===================================================================== | ||
13 | * Version: $Id$ | ||
14 | * ===================================================================== | ||
15 | * History: | ||
16 | * $Log$ | ||
17 | * Revision 1.1 2004/11/16 21:46:08 mickeyl | ||
18 | * libopie1 goes into unsupported | ||
19 | * | ||
20 | * Revision 1.4 2004/03/14 13:50:35 alwin | ||
21 | * namespace correction | ||
22 | * | ||
23 | * Revision 1.3 2003/12/22 11:41:39 eilers | ||
24 | * Fixing stupid bug, found by sourcode review.. | ||
25 | * | ||
26 | * Revision 1.2 2003/12/22 10:19:26 eilers | ||
27 | * Finishing implementation of sql-backend for datebook. But I have to | ||
28 | * port the PIM datebook application to use it, before I could debug the | ||
29 | * whole stuff. | ||
30 | * Thus, PIM-Database backend is finished, but highly experimental. And some | ||
31 | * parts are still generic. For instance, the "queryByExample()" methods are | ||
32 | * not (or not fully) implemented. Todo: custom-entries not stored. | ||
33 | * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular | ||
34 | * expression search in the database, which is not supported by sqlite ! | ||
35 | * Therefore we need either an extended sqlite or a workaround which would | ||
36 | * be very slow and memory consuming.. | ||
37 | * | ||
38 | * Revision 1.1 2003/12/08 15:18:12 eilers | ||
39 | * Committing unfinished sql implementation before merging to libopie2 starts.. | ||
40 | * | ||
41 | * | ||
42 | */ | ||
43 | |||
44 | #include <stdio.h> | ||
45 | #include <stdlib.h> | ||
46 | |||
47 | #include <qarray.h> | ||
48 | #include <qstringlist.h> | ||
49 | |||
50 | #include <qpe/global.h> | ||
51 | |||
52 | #include <opie2/osqldriver.h> | ||
53 | #include <opie2/osqlmanager.h> | ||
54 | #include <opie2/osqlquery.h> | ||
55 | |||
56 | #include "orecur.h" | ||
57 | #include "odatebookaccessbackend_sql.h" | ||
58 | |||
59 | using namespace Opie::DB; | ||
60 | |||
61 | |||
62 | ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , | ||
63 | const QString& fileName ) | ||
64 | : ODateBookAccessBackend(), m_driver( NULL ) | ||
65 | { | ||
66 | m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; | ||
67 | |||
68 | // Get the standart sql-driver from the OSQLManager.. | ||
69 | OSQLManager man; | ||
70 | m_driver = man.standard(); | ||
71 | m_driver->setUrl( m_fileName ); | ||
72 | |||
73 | initFields(); | ||
74 | |||
75 | load(); | ||
76 | } | ||
77 | |||
78 | ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { | ||
79 | if( m_driver ) | ||
80 | delete m_driver; | ||
81 | } | ||
82 | |||
83 | void ODateBookAccessBackend_SQL::initFields() | ||
84 | { | ||
85 | |||
86 | // This map contains the translation of the fieldtype id's to | ||
87 | // the names of the table columns | ||
88 | m_fieldMap.insert( OEvent::FUid, "uid" ); | ||
89 | m_fieldMap.insert( OEvent::FCategories, "Categories" ); | ||
90 | m_fieldMap.insert( OEvent::FDescription, "Description" ); | ||
91 | m_fieldMap.insert( OEvent::FLocation, "Location" ); | ||
92 | m_fieldMap.insert( OEvent::FType, "Type" ); | ||
93 | m_fieldMap.insert( OEvent::FAlarm, "Alarm" ); | ||
94 | m_fieldMap.insert( OEvent::FSound, "Sound" ); | ||
95 | m_fieldMap.insert( OEvent::FRType, "RType" ); | ||
96 | m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" ); | ||
97 | m_fieldMap.insert( OEvent::FRPosition, "RPosition" ); | ||
98 | m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); | ||
99 | m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); | ||
100 | m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); | ||
101 | m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); | ||
102 | m_fieldMap.insert( OEvent::FRExceptions, "RExceptions" ); | ||
103 | m_fieldMap.insert( OEvent::FStart, "Start" ); | ||
104 | m_fieldMap.insert( OEvent::FEnd, "End" ); | ||
105 | m_fieldMap.insert( OEvent::FNote, "Note" ); | ||
106 | m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); | ||
107 | m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); | ||
108 | m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); | ||
109 | |||
110 | // Create a map that maps the column name to the id | ||
111 | QMapConstIterator<int, QString> it; | ||
112 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
113 | m_reverseFieldMap.insert( it.data(), it.key() ); | ||
114 | } | ||
115 | |||
116 | } | ||
117 | |||
118 | bool ODateBookAccessBackend_SQL::load() | ||
119 | { | ||
120 | if (!m_driver->open() ) | ||
121 | return false; | ||
122 | |||
123 | // Don't expect that the database exists. | ||
124 | // It is save here to create the table, even if it | ||
125 | // do exist. ( Is that correct for all databases ?? ) | ||
126 | QStringqu = "create table datebook( uid INTEGER PRIMARY KEY "; | ||
127 | |||
128 | QMap<int, QString>::Iterator it; | ||
129 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
130 | qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); | ||
131 | } | ||
132 | qu += " );"; | ||
133 | |||
134 | qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; | ||
135 | |||
136 | qWarning( "command: %s", qu.latin1() ); | ||
137 | |||
138 | OSQLRawQuery raw( qu ); | ||
139 | OSQLResult res = m_driver->query( &raw ); | ||
140 | if ( res.state() != OSQLResult::Success ) | ||
141 | return false; | ||
142 | |||
143 | update(); | ||
144 | |||
145 | return true; | ||
146 | } | ||
147 | |||
148 | void ODateBookAccessBackend_SQL::update() | ||
149 | { | ||
150 | |||
151 | QString qu = "select uid from datebook"; | ||
152 | OSQLRawQuery raw( qu ); | ||
153 | OSQLResult res = m_driver->query( &raw ); | ||
154 | if ( res.state() != OSQLResult::Success ){ | ||
155 | // m_uids.clear(); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | m_uids = extractUids( res ); | ||
160 | |||
161 | } | ||
162 | |||
163 | bool ODateBookAccessBackend_SQL::reload() | ||
164 | { | ||
165 | return load(); | ||
166 | } | ||
167 | |||
168 | bool ODateBookAccessBackend_SQL::save() | ||
169 | { | ||
170 | return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) | ||
171 | } | ||
172 | |||
173 | QArray<int> ODateBookAccessBackend_SQL::allRecords()const | ||
174 | { | ||
175 | return m_uids; | ||
176 | } | ||
177 | |||
178 | QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) { | ||
179 | return QArray<int>(); | ||
180 | } | ||
181 | |||
182 | void ODateBookAccessBackend_SQL::clear() | ||
183 | { | ||
184 | QString qu = "drop table datebook;"; | ||
185 | qu += "drop table custom_data;"; | ||
186 | |||
187 | OSQLRawQuery raw( qu ); | ||
188 | OSQLResult res = m_driver->query( &raw ); | ||
189 | |||
190 | reload(); | ||
191 | } | ||
192 | |||
193 | |||
194 | OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ | ||
195 | QString qu = "select *"; | ||
196 | qu += "from datebook where uid = " + QString::number(uid); | ||
197 | |||
198 | OSQLRawQuery raw( qu ); | ||
199 | OSQLResult res = m_driver->query( &raw ); | ||
200 | |||
201 | OSQLResultItem resItem = res.first(); | ||
202 | |||
203 | // Create Map for date event and insert UID | ||
204 | QMap<int,QString> dateEventMap; | ||
205 | dateEventMap.insert( OEvent::FUid, QString::number( uid ) ); | ||
206 | |||
207 | // Now insert the data out of the columns into the map. | ||
208 | QMapConstIterator<int, QString> it; | ||
209 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
210 | dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); | ||
211 | } | ||
212 | |||
213 | // Last step: Put map into date event and return it | ||
214 | OEvent retDate( dateEventMap ); | ||
215 | |||
216 | return retDate; | ||
217 | } | ||
218 | |||
219 | // FIXME: Speed up update of uid's.. | ||
220 | bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) | ||
221 | { | ||
222 | QMap<int,QString> eventMap = ev.toMap(); | ||
223 | |||
224 | QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); | ||
225 | QMap<int, QString>::Iterator it; | ||
226 | for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ | ||
227 | if ( !eventMap[it.key()].isEmpty() ) | ||
228 | qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); | ||
229 | else | ||
230 | qu += QString( ",\"\"" ); | ||
231 | } | ||
232 | qu += " );"; | ||
233 | |||
234 | // Add custom entries | ||
235 | int id = 0; | ||
236 | QMap<QString, QString> customMap = ev.toExtraMap(); | ||
237 | for( QMap<QString, QString>::Iterator it = customMap.begin(); | ||
238 | it != customMap.end(); ++it ){ | ||
239 | qu += "insert into custom_data VALUES(" | ||
240 | + QString::number( ev.uid() ) | ||
241 | + "," | ||
242 | + QString::number( id++ ) | ||
243 | + ",'" | ||
244 | + it.key() //.latin1() | ||
245 | + "'," | ||
246 | + "0" // Priority for future enhancements | ||
247 | + ",'" | ||
248 | + it.data() //.latin1() | ||
249 | + "');"; | ||
250 | } | ||
251 | qWarning("add %s", qu.latin1() ); | ||
252 | |||
253 | OSQLRawQuery raw( qu ); | ||
254 | OSQLResult res = m_driver->query( &raw ); | ||
255 | if ( res.state() != OSQLResult::Success ){ | ||
256 | return false; | ||
257 | } | ||
258 | |||
259 | // Update list of uid's | ||
260 | update(); | ||
261 | |||
262 | return true; | ||
263 | } | ||
264 | |||
265 | // FIXME: Speed up update of uid's.. | ||
266 | bool ODateBookAccessBackend_SQL::remove( int uid ) | ||
267 | { | ||
268 | QString qu = "DELETE from datebook where uid = " | ||
269 | + QString::number( uid ) + ";"; | ||
270 | qu += "DELETE from custom_data where uid = " | ||
271 | + QString::number( uid ) + ";"; | ||
272 | |||
273 | OSQLRawQuery raw( qu ); | ||
274 | OSQLResult res = m_driver->query( &raw ); | ||
275 | if ( res.state() != OSQLResult::Success ){ | ||
276 | return false; | ||
277 | } | ||
278 | |||
279 | // Update list of uid's | ||
280 | update(); | ||
281 | |||
282 | return true; | ||
283 | } | ||
284 | |||
285 | bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) | ||
286 | { | ||
287 | remove( ev.uid() ); | ||
288 | return add( ev ); | ||
289 | } | ||
290 | |||
291 | QArray<int> ODateBookAccessBackend_SQL::rawEvents()const | ||
292 | { | ||
293 | return allRecords(); | ||
294 | } | ||
295 | |||
296 | QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const | ||
297 | { | ||
298 | QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; | ||
299 | OSQLRawQuery raw( qu ); | ||
300 | OSQLResult res = m_driver->query( &raw ); | ||
301 | if ( res.state() != OSQLResult::Success ){ | ||
302 | QArray<int> nix; | ||
303 | return nix; | ||
304 | } | ||
305 | |||
306 | return extractUids( res ); | ||
307 | } | ||
308 | |||
309 | QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const | ||
310 | { | ||
311 | QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; | ||
312 | OSQLRawQuery raw( qu ); | ||
313 | OSQLResult res = m_driver->query( &raw ); | ||
314 | if ( res.state() != OSQLResult::Success ){ | ||
315 | QArray<int> nix; | ||
316 | return nix; | ||
317 | } | ||
318 | |||
319 | return extractUids( res ); | ||
320 | } | ||
321 | |||
322 | OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() | ||
323 | { | ||
324 | QArray<int> nonRepUids = nonRepeats(); | ||
325 | OEvent::ValueList list; | ||
326 | |||
327 | for (uint i = 0; i < nonRepUids.count(); ++i ){ | ||
328 | list.append( find( nonRepUids[i] ) ); | ||
329 | } | ||
330 | |||
331 | return list; | ||
332 | |||
333 | } | ||
334 | OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() | ||
335 | { | ||
336 | QArray<int> rawRepUids = rawRepeats(); | ||
337 | OEvent::ValueList list; | ||
338 | |||
339 | for (uint i = 0; i < rawRepUids.count(); ++i ){ | ||
340 | list.append( find( rawRepUids[i] ) ); | ||
341 | } | ||
342 | |||
343 | return list; | ||
344 | } | ||
345 | |||
346 | |||
347 | QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const | ||
348 | { | ||
349 | QArray<int> null; | ||
350 | return null; | ||
351 | } | ||
352 | |||
353 | /* ===== Private Functions ========================================== */ | ||
354 | |||
355 | QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const | ||
356 | { | ||
357 | qWarning("extractUids"); | ||
358 | QTime t; | ||
359 | t.start(); | ||
360 | OSQLResultItem::ValueList list = res.results(); | ||
361 | OSQLResultItem::ValueList::Iterator it; | ||
362 | QArray<int> ints(list.count() ); | ||
363 | qWarning(" count = %d", list.count() ); | ||
364 | |||
365 | int i = 0; | ||
366 | for (it = list.begin(); it != list.end(); ++it ) { | ||
367 | ints[i] = (*it).data("uid").toInt(); | ||
368 | i++; | ||
369 | } | ||
370 | qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); | ||
371 | |||
372 | return ints; | ||
373 | |||
374 | } | ||