summaryrefslogtreecommitdiff
path: root/noncore/unsupported/libopie/pim/odatebookaccessbackend_sql.cpp
Unidiff
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.cpp374
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
59using namespace Opie::DB;
60
61
62ODateBookAccessBackend_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
78ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
79 if( m_driver )
80 delete m_driver;
81}
82
83void 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
118bool 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
148void 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
163bool ODateBookAccessBackend_SQL::reload()
164{
165 return load();
166}
167
168bool ODateBookAccessBackend_SQL::save()
169{
170 return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers)
171}
172
173QArray<int> ODateBookAccessBackend_SQL::allRecords()const
174{
175 return m_uids;
176}
177
178QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) {
179 return QArray<int>();
180}
181
182void 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
194OEvent 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..
220bool 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..
266bool 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
285bool ODateBookAccessBackend_SQL::replace( const OEvent& ev )
286{
287 remove( ev.uid() );
288 return add( ev );
289}
290
291QArray<int> ODateBookAccessBackend_SQL::rawEvents()const
292{
293 return allRecords();
294}
295
296QArray<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
309QArray<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
322OEvent::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}
334OEvent::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
347QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
348{
349 QArray<int> null;
350 return null;
351}
352
353/* ===== Private Functions ========================================== */
354
355QArray<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}