00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <opie2/osqldriver.h>
00036 #include <opie2/osqlmanager.h>
00037 #include <opie2/osqlquery.h>
00038
00039 #include <opie2/opimrecurrence.h>
00040 #include <opie2/odatebookaccessbackend_sql.h>
00041 #include <opie2/odebug.h>
00042
00043 #include <qpe/global.h>
00044
00045
00046 #include <qarray.h>
00047 #include <qstringlist.h>
00048
00049
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052
00053
00054 using namespace Opie::DB;
00055
00056 namespace {
00060 class FindCustomQuery : public OSQLQuery {
00061 public:
00062 FindCustomQuery(int uid);
00063 FindCustomQuery(const QArray<int>& );
00064 ~FindCustomQuery();
00065 QString query()const;
00066 private:
00067 QString single()const;
00068 QString multi()const;
00069 QArray<int> m_uids;
00070 int m_uid;
00071 };
00072
00073 FindCustomQuery::FindCustomQuery(int uid)
00074 : OSQLQuery(), m_uid( uid ) {
00075 }
00076 FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
00077 : OSQLQuery(), m_uids( ints ){
00078 }
00079 FindCustomQuery::~FindCustomQuery() {
00080 }
00081 QString FindCustomQuery::query()const{
00082
00083 return single();
00084 }
00085 QString FindCustomQuery::single()const{
00086 QString qu = "select uid, type, value from custom_data where uid = ";
00087 qu += QString::number(m_uid);
00088 return qu;
00089 }
00090 }
00091
00092
00093 namespace Opie {
00094
00095
00096 ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& ,
00097 const QString& fileName )
00098 : ODateBookAccessBackend(), m_driver( NULL )
00099 {
00100 m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
00101
00102
00103 OSQLManager man;
00104 m_driver = man.standard();
00105 m_driver->setUrl( m_fileName );
00106
00107 initFields();
00108
00109 load();
00110 }
00111
00112 ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
00113 if( m_driver )
00114 delete m_driver;
00115 }
00116
00117 void ODateBookAccessBackend_SQL::initFields()
00118 {
00119
00120
00121
00122 m_fieldMap.insert( OPimEvent::FUid, "uid" );
00123 m_fieldMap.insert( OPimEvent::FCategories, "Categories" );
00124 m_fieldMap.insert( OPimEvent::FDescription, "Description" );
00125 m_fieldMap.insert( OPimEvent::FLocation, "Location" );
00126 m_fieldMap.insert( OPimEvent::FType, "Type" );
00127 m_fieldMap.insert( OPimEvent::FAlarm, "Alarm" );
00128 m_fieldMap.insert( OPimEvent::FSound, "Sound" );
00129 m_fieldMap.insert( OPimEvent::FRType, "RType" );
00130 m_fieldMap.insert( OPimEvent::FRWeekdays, "RWeekdays" );
00131 m_fieldMap.insert( OPimEvent::FRPosition, "RPosition" );
00132 m_fieldMap.insert( OPimEvent::FRFreq, "RFreq" );
00133 m_fieldMap.insert( OPimEvent::FRHasEndDate, "RHasEndDate" );
00134 m_fieldMap.insert( OPimEvent::FREndDate, "REndDate" );
00135 m_fieldMap.insert( OPimEvent::FRCreated, "RCreated" );
00136 m_fieldMap.insert( OPimEvent::FRExceptions, "RExceptions" );
00137 m_fieldMap.insert( OPimEvent::FStart, "Start" );
00138 m_fieldMap.insert( OPimEvent::FEnd, "End" );
00139 m_fieldMap.insert( OPimEvent::FNote, "Note" );
00140 m_fieldMap.insert( OPimEvent::FTimeZone, "TimeZone" );
00141 m_fieldMap.insert( OPimEvent::FRecParent, "RecParent" );
00142 m_fieldMap.insert( OPimEvent::FRecChildren, "Recchildren" );
00143
00144
00145 QMapConstIterator<int, QString> it;
00146 for ( it = m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
00147 m_reverseFieldMap.insert( it.data(), it.key() );
00148 }
00149
00150 }
00151
00152 bool ODateBookAccessBackend_SQL::load()
00153 {
00154 if (!m_driver->open() )
00155 return false;
00156
00157
00158
00159
00160 QString qu = "create table datebook( uid INTEGER PRIMARY KEY ";
00161
00162 QMap<int, QString>::Iterator it;
00163 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
00164 qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() );
00165 }
00166 qu += " );";
00167
00168 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
00169
00170 OSQLRawQuery raw( qu );
00171 OSQLResult res = m_driver->query( &raw );
00172 if ( res.state() != OSQLResult::Success )
00173 return false;
00174
00175 update();
00176
00177 return true;
00178 }
00179
00180 void ODateBookAccessBackend_SQL::update()
00181 {
00182
00183 QString qu = "select uid from datebook";
00184 OSQLRawQuery raw( qu );
00185 OSQLResult res = m_driver->query( &raw );
00186 if ( res.state() != OSQLResult::Success ){
00187
00188 return;
00189 }
00190
00191 m_uids = extractUids( res );
00192
00193 }
00194
00195 bool ODateBookAccessBackend_SQL::reload()
00196 {
00197 return load();
00198 }
00199
00200 bool ODateBookAccessBackend_SQL::save()
00201 {
00202 return m_driver->close();
00203 }
00204
00205 QArray<int> ODateBookAccessBackend_SQL::allRecords()const
00206 {
00207 return m_uids;
00208 }
00209
00210 QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OPimEvent&, int, const QDateTime& ) {
00211 qDebug( "Accessing ODateBookAccessBackend_SQL::queryByExample() which is not implemented!" );
00212 return QArray<int>();
00213 }
00214
00215 void ODateBookAccessBackend_SQL::clear()
00216 {
00217 QString qu = "drop table datebook;";
00218 qu += "drop table custom_data;";
00219
00220 OSQLRawQuery raw( qu );
00221 OSQLResult res = m_driver->query( &raw );
00222
00223 reload();
00224 }
00225
00226
00227 OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{
00228 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " )" << oendl;
00229
00230 QString qu = "select *";
00231 qu += "from datebook where uid = " + QString::number(uid);
00232
00233 odebug << "Query: " << qu << "" << oendl;
00234
00235 OSQLRawQuery raw( qu );
00236 OSQLResult res = m_driver->query( &raw );
00237
00238 OSQLResultItem resItem = res.first();
00239
00240
00241 QMap<int,QString> dateEventMap;
00242 dateEventMap.insert( OPimEvent::FUid, QString::number( uid ) );
00243
00244
00245 QMapConstIterator<int, QString> it;
00246 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
00247 dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) );
00248 }
00249
00250
00251 OPimEvent retDate( dateEventMap );
00252 retDate.setExtraMap( requestCustom( uid ) );
00253
00254 odebug << "ODateBookAccessBackend_SQL::find( " << uid << " ) end" << oendl;
00255 return retDate;
00256 }
00257
00258
00259 bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev )
00260 {
00261 QMap<int,QString> eventMap = ev.toMap();
00262
00263 QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() );
00264 QMap<int, QString>::Iterator it;
00265 for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){
00266 if ( !eventMap[it.key()].isEmpty() )
00267 qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] );
00268 else
00269 qu += QString( ",\"\"" );
00270 }
00271 qu += " );";
00272
00273
00274 int id = 0;
00275 QMap<QString, QString> customMap = ev.toExtraMap();
00276 for( QMap<QString, QString>::Iterator it = customMap.begin();
00277 it != customMap.end(); ++it ){
00278 qu += "insert into custom_data VALUES("
00279 + QString::number( ev.uid() )
00280 + ","
00281 + QString::number( id++ )
00282 + ",'"
00283 + it.key()
00284 + "',"
00285 + "0"
00286 + ",'"
00287 + it.data()
00288 + "');";
00289 }
00290
00291 OSQLRawQuery raw( qu );
00292 OSQLResult res = m_driver->query( &raw );
00293 if ( res.state() != OSQLResult::Success ){
00294 return false;
00295 }
00296
00297
00298 update();
00299
00300 return true;
00301 }
00302
00303
00304 bool ODateBookAccessBackend_SQL::remove( int uid )
00305 {
00306 QString qu = "DELETE from datebook where uid = "
00307 + QString::number( uid ) + ";";
00308 qu += "DELETE from custom_data where uid = "
00309 + QString::number( uid ) + ";";
00310
00311 OSQLRawQuery raw( qu );
00312 OSQLResult res = m_driver->query( &raw );
00313 if ( res.state() != OSQLResult::Success ){
00314 return false;
00315 }
00316
00317
00318 update();
00319
00320 return true;
00321 }
00322
00323 bool ODateBookAccessBackend_SQL::replace( const OPimEvent& ev )
00324 {
00325 remove( ev.uid() );
00326 return add( ev );
00327 }
00328
00329
00330 QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const
00331 {
00332 QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\"";
00333 OSQLRawQuery raw( qu );
00334 OSQLResult res = m_driver->query( &raw );
00335 if ( res.state() != OSQLResult::Success ){
00336 QArray<int> nix;
00337 return nix;
00338 }
00339
00340 return extractUids( res );
00341 }
00342
00343 QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const
00344 {
00345 QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\"";
00346 OSQLRawQuery raw( qu );
00347 OSQLResult res = m_driver->query( &raw );
00348 if ( res.state() != OSQLResult::Success ){
00349 QArray<int> nix;
00350 return nix;
00351 }
00352
00353 return extractUids( res );
00354 }
00355
00356 OPimEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats()const
00357 {
00358 QArray<int> nonRepUids = nonRepeats();
00359 OPimEvent::ValueList list;
00360
00361 for (uint i = 0; i < nonRepUids.count(); ++i ){
00362 list.append( find( nonRepUids[i] ) );
00363 }
00364
00365 return list;
00366
00367 }
00368 OPimEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()const
00369 {
00370 QArray<int> rawRepUids = rawRepeats();
00371 OPimEvent::ValueList list;
00372
00373 for (uint i = 0; i < rawRepUids.count(); ++i ){
00374 list.append( find( rawRepUids[i] ) );
00375 }
00376
00377 return list;
00378 }
00379
00380
00381 QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
00382 {
00383
00384 QString qu = "SELECT uid FROM datebook WHERE (";
00385
00386
00387 qu += " rlike(\""+ r.pattern() + "\", Location ) OR";
00388 qu += " rlike(\""+ r.pattern() + "\", Note )";
00389
00390 qu += " )";
00391
00392 odebug << "query: " << qu << "" << oendl;
00393
00394 OSQLRawQuery raw( qu );
00395 OSQLResult res = m_driver->query( &raw );
00396
00397 return extractUids( res );
00398
00399
00400
00401 }
00402
00403
00404
00405 QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const
00406 {
00407 QTime t;
00408 t.start();
00409 OSQLResultItem::ValueList list = res.results();
00410 OSQLResultItem::ValueList::Iterator it;
00411 QArray<int> ints(list.count() );
00412
00413 int i = 0;
00414 for (it = list.begin(); it != list.end(); ++it ) {
00415 ints[i] = (*it).data("uid").toInt();
00416 i++;
00417 }
00418
00419 return ints;
00420
00421 }
00422
00423 QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const
00424 {
00425 QTime t;
00426 t.start();
00427
00428 QMap<QString, QString> customMap;
00429
00430 FindCustomQuery query( uid );
00431 OSQLResult res_custom = m_driver->query( &query );
00432
00433 if ( res_custom.state() == OSQLResult::Failure ) {
00434 QMap<QString, QString> empty;
00435 return empty;
00436 }
00437
00438 OSQLResultItem::ValueList list = res_custom.results();
00439 OSQLResultItem::ValueList::Iterator it = list.begin();
00440 for ( ; it != list.end(); ++it ) {
00441 customMap.insert( (*it).data( "type" ), (*it).data( "value" ) );
00442 }
00443
00444 odebug << "RequestCustom needed: " << t.elapsed() << " ms" << oendl;
00445 return customMap;
00446 }
00447
00448
00449 }