30 files changed, 711 insertions, 126 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro index 8682e84..a3d01ab 100644 --- a/libopie/libopie.pro +++ b/libopie/libopie.pro @@ -100,10 +100,10 @@ CONFTEST = $$system( echo $CONFIG_SQL_PIM_BACKEND ) contains( CONFTEST, y ){ DEFINES += __USE_SQL LIBS += -lopiedb2 -HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h -SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp +HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h pim/odatebookaccessbackend_sql.h +SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp pim/odatebookaccessbackend_sql.cpp } INTERFACES = otimepickerbase.ui orecurrancebase.ui diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h index 3567687..761ab9a 100644 --- a/libopie/pim/obackendfactory.h +++ b/libopie/pim/obackendfactory.h @@ -15,8 +15,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.9 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.8 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. * A lot of changes fill follow... @@ -79,8 +91,9 @@ #ifdef __USE_SQL #include "otodoaccesssql.h" #include "ocontactaccessbackend_sql.h" +#include "odatebookaccessbackend_sql.h" #endif class OBackendPrivate; @@ -142,9 +155,9 @@ class OBackendFactory if ( backend == "sql" ) return (T*) new OTodoAccessBackendSQL(""); #else if ( backend == "sql" ) - qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); #endif return (T*) new OTodoAccessXML( appName ); case CONTACT: @@ -152,15 +165,20 @@ class OBackendFactory if ( backend == "sql" ) return (T*) new OContactAccessBackend_SQL(""); #else if ( backend == "sql" ) - qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); #endif return (T*) new OContactAccessBackend_XML( appName ); case DATE: +#ifdef __USE_SQL if ( backend == "sql" ) - qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + return (T*) new ODateBookAccessBackend_SQL(""); +#else + if ( backend == "sql" ) + qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); +#endif return (T*) new ODateBookAccessBackend_XML( appName ); default: return NULL; diff --git a/libopie/pim/ocontactaccess.h b/libopie/pim/ocontactaccess.h index 9b0a719..bd6da40 100644 --- a/libopie/pim/ocontactaccess.h +++ b/libopie/pim/ocontactaccess.h @@ -16,8 +16,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.10 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.9 2003/08/01 12:30:16 eilers * Merging changes from BRANCH_1_0 to HEAD * * Revision 1.8.2.1 2003/06/30 14:34:19 eilers @@ -77,9 +89,9 @@ * This is just a frontend for the real database handling which is * done by the backend. * This class is used to access the Contacts on a system. This class as any OPIE PIM * class is backend independent. - + * @author Stefan Eilers, Holger Freyther * @see OPimAccessTemplate */ class OContactAccess: public QObject, public OPimAccessTemplate<OContact> { diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp index dd9dbde..a5be4c8 100644 --- a/libopie/pim/ocontactaccessbackend_sql.cpp +++ b/libopie/pim/ocontactaccessbackend_sql.cpp @@ -13,8 +13,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.4 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.3 2003/12/08 15:18:10 eilers * Committing unfinished sql implementation before merging to libopie2 starts.. * * Revision 1.2 2003/09/29 07:44:26 eilers @@ -509,18 +521,18 @@ bool OContactAccessBackend_SQL::reload() } bool OContactAccessBackend_SQL::save() { - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } void OContactAccessBackend_SQL::clear () { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); - CreateQuery qu; - res = m_driver->query(&qu); + + reload(); } bool OContactAccessBackend_SQL::wasChangedExternally() { diff --git a/libopie/pim/odatebookaccess.cpp b/libopie/pim/odatebookaccess.cpp index a3661a3..82934f9 100644 --- a/libopie/pim/odatebookaccess.cpp +++ b/libopie/pim/odatebookaccess.cpp @@ -55,12 +55,27 @@ ODateBookAccess::List ODateBookAccess::nonRepeats()const { * @param from Include all events from... * @param to Include all events to... */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) { - return m_backEnd->effecticeEvents( from, to ); + return m_backEnd->effectiveEvents( from, to ); } /** * @return all events at a given datetime */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) { - return m_backEnd->effecticeEvents( start ); + return m_backEnd->effectiveEvents( start ); +} + +/** + * @return non repeating dates in the time span between from and to + * @param from Include all events from... + * @param to Include all events to... + */ +OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) { + return m_backEnd->effectiveNonRepeatingEvents( from, to ); +} +/** + * @return all non repeating events at a given datetime + */ +OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDateTime& start ) { + return m_backEnd->effectiveNonRepeatingEvents( start ); } diff --git a/libopie/pim/odatebookaccess.h b/libopie/pim/odatebookaccess.h index 7c7a63f..62196da 100644 --- a/libopie/pim/odatebookaccess.h +++ b/libopie/pim/odatebookaccess.h @@ -12,9 +12,9 @@ * All access to the datebook should be done via this class. * Make sure to load and save the datebook this is not part of * destructing and creating the object * - * @author Holger Freyther + * @author Holger Freyther, Stefan Eilers */ class ODateBookAccess : public OPimAccessTemplate<OEvent> { public: ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); @@ -28,10 +28,13 @@ public: /* return non repeating events */ List nonRepeats()const; - OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); - OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); + /* return non repeating events (from,to) */ + OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ) const; + OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ) const; + OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const; + OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ) const; private: ODateBookAccessBackend* m_backEnd; class Private; diff --git a/libopie/pim/odatebookaccessbackend.cpp b/libopie/pim/odatebookaccessbackend.cpp index 8fa1a68..f0c5d65 100644 --- a/libopie/pim/odatebookaccessbackend.cpp +++ b/libopie/pim/odatebookaccessbackend.cpp @@ -126,23 +126,49 @@ ODateBookAccessBackend::ODateBookAccessBackend() } ODateBookAccessBackend::~ODateBookAccessBackend() { } -OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDate& from, +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, const QDate& to ) { OEffectiveEvent::ValueList tmpList; OEvent::ValueList list = directNonRepeats(); events( tmpList, list, from, to ); repeat( tmpList, directRawRepeats(),from,to ); - list = directRawRepeats(); + list = directRawRepeats(); // Useless, isn't it ? (eilers) qHeapSort( tmpList ); return tmpList; } -OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDateTime& dt ) { - OEffectiveEvent::ValueList day = effecticeEvents( dt.date(), dt.date() ); +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { + OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); + OEffectiveEvent::ValueList::Iterator it; + + OEffectiveEvent::ValueList tmpList; + QDateTime dtTmp; + for ( it = day.begin(); it != day.end(); ++it ) { + dtTmp = QDateTime( (*it).date(), (*it).startTime() ); + if ( QABS(dt.secsTo(dtTmp) ) < 60 ) + tmpList.append( (*it) ); + } + + return tmpList; +} + +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, + const QDate& to ) { + OEffectiveEvent::ValueList tmpList; + OEvent::ValueList list = directNonRepeats(); + + events( tmpList, list, from, to ); + + qHeapSort( tmpList ); + return tmpList; +} + +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { + OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); OEffectiveEvent::ValueList::Iterator it; OEffectiveEvent::ValueList tmpList; QDateTime dtTmp; diff --git a/libopie/pim/odatebookaccessbackend.h b/libopie/pim/odatebookaccessbackend.h index 3c02c42..3472ab3 100644 --- a/libopie/pim/odatebookaccessbackend.h +++ b/libopie/pim/odatebookaccessbackend.h @@ -59,15 +59,28 @@ public: * Effective Events are special event occuring during a time frame. This method does calcualte * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method * yourself */ - virtual OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to ); + virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); /** * this is an overloaded member function - * @see effecticeEvents + * @see effectiveEvents( const QDate& from, const QDate& to ) */ - virtual OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start ); + virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); + + /** + * Effective Events are special event occuring during a time frame. This method does calcualte + * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method + * yourself + */ + virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); + + /** + * this is an overloaded member function + * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) + */ + virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); private: class Private; Private *d; diff --git a/libopie/pim/odatebookaccessbackend_sql.cpp b/libopie/pim/odatebookaccessbackend_sql.cpp index 9769bf7..e893b38 100644 --- a/libopie/pim/odatebookaccessbackend_sql.cpp +++ b/libopie/pim/odatebookaccessbackend_sql.cpp @@ -13,8 +13,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.2 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.1 2003/12/08 15:18:12 eilers * Committing unfinished sql implementation before merging to libopie2 starts.. * * @@ -25,21 +37,18 @@ #include <qarray.h> #include <qstringlist.h> -#include "orecur.h" -#include "odatebookaccessbackend_sql.h" +#include <qpe/global.h> #include <opie2/osqldriver.h> -#include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> -namespace { - +#include "orecur.h" +#include "odatebookaccessbackend_sql.h" -}; ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , const QString& fileName ) : ODateBookAccessBackend(), m_driver( NULL ) @@ -56,8 +65,10 @@ ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , load(); } ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { + if( m_driver ) + delete m_driver; } void ODateBookAccessBackend_SQL::initFields() { @@ -77,15 +88,22 @@ void ODateBookAccessBackend_SQL::initFields() m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); - m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); + m_fieldMap.insert( OEvent::FRExceptions, "RExceptions" ); m_fieldMap.insert( OEvent::FStart, "Start" ); m_fieldMap.insert( OEvent::FEnd, "End" ); m_fieldMap.insert( OEvent::FNote, "Note" ); m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); + + // Create a map that maps the column name to the id + QMapConstIterator<int, QString> it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + m_reverseFieldMap.insert( it.data(), it.key() ); + } + } bool ODateBookAccessBackend_SQL::load() { @@ -98,14 +116,16 @@ bool ODateBookAccessBackend_SQL::load() QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; QMap<int, QString>::Iterator it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ - qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); + qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); } qu += " );"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + qWarning( "command: %s", qu.latin1() ); + OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ) return false; @@ -121,43 +141,24 @@ void ODateBookAccessBackend_SQL::update() QString qu = "select uid from datebook"; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - m_uids.clear(); + // m_uids.clear(); return; } m_uids = extractUids( res ); } -QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const -{ - qWarning("extractUids"); - - OSQLResultItem::ValueList list = res.results(); - OSQLResultItem::ValueList::Iterator it; - QArray<int> ints(list.count() ); - qWarning(" count = %d", list.count() ); - - int i = 0; - for (it = list.begin(); it != list.end(); ++it ) { - ints[i] = (*it).data("uid").toInt(); - i++; - } - - return ints; - -} - bool ODateBookAccessBackend_SQL::reload() { return load(); } bool ODateBookAccessBackend_SQL::save() { - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> ODateBookAccessBackend_SQL::allRecords()const { @@ -175,47 +176,181 @@ void ODateBookAccessBackend_SQL::clear() OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); + reload(); } OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ + QString qu = "select *"; + qu += "from datebook where uid = " + QString::number(uid); + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + + OSQLResultItem resItem = res.first(); + + // Create Map for date event and insert UID + QMap<int,QString> dateEventMap; + dateEventMap.insert( OEvent::FUid, QString::number( uid ) ); + + // Now insert the data out of the columns into the map. + QMapConstIterator<int, QString> it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); + } + + // Last step: Put map into date event and return it + OEvent retDate( dateEventMap ); + + return retDate; +} + +bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) +{ + QMap<int,QString> eventMap = ev.toMap(); + + QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); + QMap<int, QString>::Iterator it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + if ( !eventMap[it.key()].isEmpty() ) + qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); + else + qu += QString( ",\"\"" ); + } + qu += " );"; + + // Add custom entries + int id = 0; + QMap<QString, QString> customMap = ev.toExtraMap(); + for( QMap<QString, QString>::Iterator it = customMap.begin(); + it != customMap.end(); ++it ){ + qu += "insert into custom_data VALUES(" + + QString::number( ev.uid() ) + + "," + + QString::number( id++ ) + + ",'" + + it.key() //.latin1() + + "'," + + "0" // Priority for future enhancements + + ",'" + + it.data() //.latin1() + + "');"; + } + qWarning("add %s", qu.latin1() ); + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + return false; } -bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { return true; } -bool ODateBookAccessBackend_SQL::remove( int uid ) { + +bool ODateBookAccessBackend_SQL::remove( int uid ) +{ + QString qu = "DELETE from datebook where uid = " + + QString::number( uid ) + ";"; + qu += "DELETE from custom_data where uid = " + + QString::number( uid ) + ";"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + return false; + } return true; } -bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { + +bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) +{ remove( ev.uid() ); return add( ev ); } -QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { + +QArray<int> ODateBookAccessBackend_SQL::rawEvents()const +{ return allRecords(); } -QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { - return ints; +QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const +{ + QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + QArray<int> nix; + return nix; } -QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { - return ints; + return extractUids( res ); +} + +QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const +{ + QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + QArray<int> nix; + return nix; + } + + return extractUids( res ); +} + +OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() +{ + QArray<int> nonRepUids = nonRepeats(); + OEvent::ValueList list; + + for (uint i = 0; i < nonRepUids.count(); ++i ){ + list.append( find( nonRepUids[i] ) ); } -OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { return list; + +} +OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() +{ + QArray<int> rawRepUids = rawRepeats(); + OEvent::ValueList list; + + for (uint i = 0; i < rawRepUids.count(); ++i ){ + list.append( find( rawRepUids[i] ) ); } -OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { return list; } QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { + QArray<int> null; + return null; +} + +/* ===== Private Functions ========================================== */ + +QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const +{ + qWarning("extractUids"); + QTime t; + t.start(); + OSQLResultItem::ValueList list = res.results(); + OSQLResultItem::ValueList::Iterator it; + QArray<int> ints(list.count() ); + qWarning(" count = %d", list.count() ); + + int i = 0; + for (it = list.begin(); it != list.end(); ++it ) { + ints[i] = (*it).data("uid").toInt(); + i++; + } + qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); + + return ints; - return m_currentQuery; } diff --git a/libopie/pim/odatebookaccessbackend_sql.h b/libopie/pim/odatebookaccessbackend_sql.h index 85e0d4f..f39e154 100644 --- a/libopie/pim/odatebookaccessbackend_sql.h +++ b/libopie/pim/odatebookaccessbackend_sql.h @@ -1,8 +1,9 @@ #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #include <qmap.h> +#include <opie2/osqlresult.h> #include "odatebookaccessbackend.h" class OSQLDriver; @@ -44,8 +45,9 @@ private: QString m_fileName; QArray<int> m_uids; QMap<int, QString> m_fieldMap; + QMap<QString, int> m_reverseFieldMap; OSQLDriver* m_driver; class Private; diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp index ec05e77..9b31957 100644 --- a/libopie/pim/oevent.cpp +++ b/libopie/pim/oevent.cpp @@ -76,8 +76,17 @@ OEvent::OEvent( const OEvent& ev) : OPimRecord( ev ), data( ev.data ) { data->ref(); } + +OEvent::OEvent( const QMap<int, QString> map ) + : OPimRecord( 0 ) +{ + data = new Data; + + fromMap( map ); +} + OEvent::~OEvent() { if ( data->deref() ) { delete data; data = 0; @@ -402,8 +411,12 @@ QMap<int, QString> OEvent::toMap()const { retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); + } else { + ORecur recur = recurrence(); + QMap<int, QString> recFields = recur.toMap(); + retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); } return retMap; } diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h index 9218c97..9eb948f 100644 --- a/libopie/pim/oevent.h +++ b/libopie/pim/oevent.h @@ -75,8 +75,14 @@ public: /** * copy c'tor */ OEvent( const OEvent& ); + + /** + * Create OEvent, initialized by map + * @see enum RecordFields + */ + OEvent( const QMap<int, QString> map ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; diff --git a/libopie/pim/otimezone.cpp b/libopie/pim/otimezone.cpp index b2bd3aa..34659c3 100644 --- a/libopie/pim/otimezone.cpp +++ b/libopie/pim/otimezone.cpp @@ -15,13 +15,18 @@ namespace { return ret; } QDateTime utcTime( time_t t, const QString& zone) { QCString org = ::getenv( "TZ" ); +#ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", zone.latin1(), true ); ::tzset(); tm* broken = ::localtime( &t ); ::setenv( "TZ", org, true ); +#else +#warning "Need a replacement for MacOSX!!" + tm* broken = ::localtime( &t ); +#endif QDateTime ret; ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); @@ -40,14 +45,18 @@ namespace { broken.tm_min = t.minute(); broken.tm_sec = t.second(); QCString org = ::getenv( "TZ" ); +#ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", str.latin1(), true ); ::tzset(); time_t ti = ::mktime( &broken ); ::setenv( "TZ", org, true ); - +#else +#warning "Need a replacement for MacOSX!!" + time_t ti = ::mktime( &broken ); +#endif return ti; } } OTimeZone::OTimeZone( const ZoneName& zone ) diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp index 75a0860..3764c7e 100644 --- a/libopie/pim/otodoaccesssql.cpp +++ b/libopie/pim/otodoaccesssql.cpp @@ -329,9 +329,9 @@ bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); diff --git a/libopie/pim/test/converter.cpp b/libopie/pim/test/converter.cpp index 650d119..bfdb605 100644 --- a/libopie/pim/test/converter.cpp +++ b/libopie/pim/test/converter.cpp @@ -8,15 +8,23 @@ #include <opie/ocontactaccess.h> #include <opie/ocontactaccessbackend_xml.h> #include <opie/ocontactaccessbackend_sql.h> +#include <opie/odatebookaccess.h> +#include <opie/odatebookaccessbackend_xml.h> +#include <opie/odatebookaccessbackend_sql.h> + +// #define _ADDRESSBOOK_ACCESS + Converter::Converter(){ } void Converter::start_conversion(){ qWarning("Converting Contacts from XML to SQL.."); // Creating backends to the requested databases.. + +#ifdef _ADDRESSBOOK_ACCESS OContactAccessBackend* xmlBackend = new OContactAccessBackend_XML( "Converter", QString::null ); OContactAccessBackend* sqlBackend = new OContactAccessBackend_SQL( QString::null, @@ -25,16 +33,32 @@ void Converter::start_conversion(){ OContactAccess* xmlAccess = new OContactAccess ( "addressbook_xml", QString::null , xmlBackend, true ); OContactAccess* sqlAccess = new OContactAccess ( "addressbook_sql", - QString::null , sqlBackend, true ); + QString::null ); + +#else + ODateBookAccessBackend* xmlBackend = new ODateBookAccessBackend_XML( "Converter", + QString::null ); + + ODateBookAccessBackend* sqlBackend = new ODateBookAccessBackend_SQL( QString::null, + QString::null ); + // Put the created backends into frontends to access them + ODateBookAccess* xmlAccess = new ODateBookAccess ( xmlBackend ); + + ODateBookAccess* sqlAccess = new ODateBookAccess ( sqlBackend ); + + xmlAccess->load(); + +#endif QTime t; t.start(); // Clean the sql-database.. sqlAccess->clear(); +#ifdef _ADDRESSBOOK_ACCESS // Now trasmit every contact from the xml database to the sql-database OContactAccess::List contactList = xmlAccess->allRecords(); m_progressBar->setTotalSteps( contactList.count() ); int count = 0; @@ -44,9 +68,24 @@ void Converter::start_conversion(){ sqlAccess->add( *it ); m_progressBar->setProgress( ++count ); } } +#else + // Now transmit every contact from the xml database to the sql-database + ODateBookAccess::List dateList = xmlAccess->allRecords(); + m_progressBar->setTotalSteps( dateList.count() ); + qWarning( "Number of elements to copy: %d", dateList.count() ); + + int count = 0; + if ( sqlAccess && xmlAccess ){ + ODateBookAccess::List::Iterator it; + for ( it = dateList.begin(); it != dateList.end(); ++it ){ + sqlAccess->add( *it ); + m_progressBar->setProgress( ++count ); + } + } +#endif // Delete the frontends. Backends will be deleted automatically, too ! delete sqlAccess; qWarning("Conversion is finished and needed %d ms !", t.elapsed()); diff --git a/libopie/pim/test/converter.h b/libopie/pim/test/converter.h new file mode 100755 index 0000000..1cc2a7c --- a/dev/null +++ b/libopie/pim/test/converter.h @@ -0,0 +1,18 @@ +#ifndef _CONVERTER_H_ +#define _CONVERTER_H_ + + +#include "converter_base.h" + + +class Converter: public converter_base { +public: + Converter(); + + void start_conversion(); +private: + +}; + + +#endif diff --git a/libopie/pim/test/converter.pro b/libopie/pim/test/converter.pro index aa74bff..bd9c7a3 100644 --- a/libopie/pim/test/converter.pro +++ b/libopie/pim/test/converter.pro @@ -1,5 +1,5 @@ -TEMPLATE = app +# TEMPLATE = app CONFIG = qt warn_on debug # CONFIG = qt warn_on release #HEADERS = SOURCES = converter.cpp diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h index 3567687..761ab9a 100644 --- a/libopie2/opiepim/backend/obackendfactory.h +++ b/libopie2/opiepim/backend/obackendfactory.h @@ -15,8 +15,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.9 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.8 2003/09/22 14:31:16 eilers * Added first experimental incarnation of sql-backend for addressbook. * Some modifications to be able to compile the todo sql-backend. * A lot of changes fill follow... @@ -79,8 +91,9 @@ #ifdef __USE_SQL #include "otodoaccesssql.h" #include "ocontactaccessbackend_sql.h" +#include "odatebookaccessbackend_sql.h" #endif class OBackendPrivate; @@ -142,9 +155,9 @@ class OBackendFactory if ( backend == "sql" ) return (T*) new OTodoAccessBackendSQL(""); #else if ( backend == "sql" ) - qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); #endif return (T*) new OTodoAccessXML( appName ); case CONTACT: @@ -152,15 +165,20 @@ class OBackendFactory if ( backend == "sql" ) return (T*) new OContactAccessBackend_SQL(""); #else if ( backend == "sql" ) - qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); #endif return (T*) new OContactAccessBackend_XML( appName ); case DATE: +#ifdef __USE_SQL if ( backend == "sql" ) - qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!"); + return (T*) new ODateBookAccessBackend_SQL(""); +#else + if ( backend == "sql" ) + qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); +#endif return (T*) new ODateBookAccessBackend_XML( appName ); default: return NULL; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index dd9dbde..a5be4c8 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp @@ -13,8 +13,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.4 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.3 2003/12/08 15:18:10 eilers * Committing unfinished sql implementation before merging to libopie2 starts.. * * Revision 1.2 2003/09/29 07:44:26 eilers @@ -509,18 +521,18 @@ bool OContactAccessBackend_SQL::reload() } bool OContactAccessBackend_SQL::save() { - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } void OContactAccessBackend_SQL::clear () { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); - CreateQuery qu; - res = m_driver->query(&qu); + + reload(); } bool OContactAccessBackend_SQL::wasChangedExternally() { diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp index 8fa1a68..f0c5d65 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp @@ -126,23 +126,49 @@ ODateBookAccessBackend::ODateBookAccessBackend() } ODateBookAccessBackend::~ODateBookAccessBackend() { } -OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDate& from, +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDate& from, const QDate& to ) { OEffectiveEvent::ValueList tmpList; OEvent::ValueList list = directNonRepeats(); events( tmpList, list, from, to ); repeat( tmpList, directRawRepeats(),from,to ); - list = directRawRepeats(); + list = directRawRepeats(); // Useless, isn't it ? (eilers) qHeapSort( tmpList ); return tmpList; } -OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDateTime& dt ) { - OEffectiveEvent::ValueList day = effecticeEvents( dt.date(), dt.date() ); +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveEvents( const QDateTime& dt ) { + OEffectiveEvent::ValueList day = effectiveEvents( dt.date(), dt.date() ); + OEffectiveEvent::ValueList::Iterator it; + + OEffectiveEvent::ValueList tmpList; + QDateTime dtTmp; + for ( it = day.begin(); it != day.end(); ++it ) { + dtTmp = QDateTime( (*it).date(), (*it).startTime() ); + if ( QABS(dt.secsTo(dtTmp) ) < 60 ) + tmpList.append( (*it) ); + } + + return tmpList; +} + +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, + const QDate& to ) { + OEffectiveEvent::ValueList tmpList; + OEvent::ValueList list = directNonRepeats(); + + events( tmpList, list, from, to ); + + qHeapSort( tmpList ); + return tmpList; +} + +OEffectiveEvent::ValueList ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt ) { + OEffectiveEvent::ValueList day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); OEffectiveEvent::ValueList::Iterator it; OEffectiveEvent::ValueList tmpList; QDateTime dtTmp; diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.h b/libopie2/opiepim/backend/odatebookaccessbackend.h index 3c02c42..3472ab3 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend.h @@ -59,15 +59,28 @@ public: * Effective Events are special event occuring during a time frame. This method does calcualte * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method * yourself */ - virtual OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to ); + virtual OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); /** * this is an overloaded member function - * @see effecticeEvents + * @see effectiveEvents( const QDate& from, const QDate& to ) */ - virtual OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start ); + virtual OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); + + /** + * Effective Events are special event occuring during a time frame. This method does calcualte + * EffectiveEvents bases on the directNonRepeats and directRawRepeats. You may implement this method + * yourself + */ + virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ); + + /** + * this is an overloaded member function + * @see effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) + */ + virtual OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ); private: class Private; Private *d; diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp index 9769bf7..e893b38 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp @@ -13,8 +13,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.2 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.1 2003/12/08 15:18:12 eilers * Committing unfinished sql implementation before merging to libopie2 starts.. * * @@ -25,21 +37,18 @@ #include <qarray.h> #include <qstringlist.h> -#include "orecur.h" -#include "odatebookaccessbackend_sql.h" +#include <qpe/global.h> #include <opie2/osqldriver.h> -#include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> -namespace { - +#include "orecur.h" +#include "odatebookaccessbackend_sql.h" -}; ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , const QString& fileName ) : ODateBookAccessBackend(), m_driver( NULL ) @@ -56,8 +65,10 @@ ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , load(); } ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() { + if( m_driver ) + delete m_driver; } void ODateBookAccessBackend_SQL::initFields() { @@ -77,15 +88,22 @@ void ODateBookAccessBackend_SQL::initFields() m_fieldMap.insert( OEvent::FRFreq, "RFreq" ); m_fieldMap.insert( OEvent::FRHasEndDate, "RHasEndDate" ); m_fieldMap.insert( OEvent::FREndDate, "REndDate" ); m_fieldMap.insert( OEvent::FRCreated, "RCreated" ); - m_fieldMap.insert( OEvent::FRExeptions, "RExceptions" ); + m_fieldMap.insert( OEvent::FRExceptions, "RExceptions" ); m_fieldMap.insert( OEvent::FStart, "Start" ); m_fieldMap.insert( OEvent::FEnd, "End" ); m_fieldMap.insert( OEvent::FNote, "Note" ); m_fieldMap.insert( OEvent::FTimeZone, "TimeZone" ); m_fieldMap.insert( OEvent::FRecParent, "RecParent" ); m_fieldMap.insert( OEvent::FRecChildren, "Recchildren" ); + + // Create a map that maps the column name to the id + QMapConstIterator<int, QString> it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + m_reverseFieldMap.insert( it.data(), it.key() ); + } + } bool ODateBookAccessBackend_SQL::load() { @@ -98,14 +116,16 @@ bool ODateBookAccessBackend_SQL::load() QString qu = "create table datebook( uid INTEGER PRIMARY KEY "; QMap<int, QString>::Iterator it; for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ - qu += QString( ",\"%1\" VARCHAR(10)" ).arg( it.data() ); + qu += QString( ",%1 VARCHAR(10)" ).arg( it.data() ); } qu += " );"; qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + qWarning( "command: %s", qu.latin1() ); + OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ) return false; @@ -121,43 +141,24 @@ void ODateBookAccessBackend_SQL::update() QString qu = "select uid from datebook"; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - m_uids.clear(); + // m_uids.clear(); return; } m_uids = extractUids( res ); } -QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const -{ - qWarning("extractUids"); - - OSQLResultItem::ValueList list = res.results(); - OSQLResultItem::ValueList::Iterator it; - QArray<int> ints(list.count() ); - qWarning(" count = %d", list.count() ); - - int i = 0; - for (it = list.begin(); it != list.end(); ++it ) { - ints[i] = (*it).data("uid").toInt(); - i++; - } - - return ints; - -} - bool ODateBookAccessBackend_SQL::reload() { return load(); } bool ODateBookAccessBackend_SQL::save() { - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> ODateBookAccessBackend_SQL::allRecords()const { @@ -175,47 +176,181 @@ void ODateBookAccessBackend_SQL::clear() OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); + reload(); } OEvent ODateBookAccessBackend_SQL::find( int uid ) const{ + QString qu = "select *"; + qu += "from datebook where uid = " + QString::number(uid); + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + + OSQLResultItem resItem = res.first(); + + // Create Map for date event and insert UID + QMap<int,QString> dateEventMap; + dateEventMap.insert( OEvent::FUid, QString::number( uid ) ); + + // Now insert the data out of the columns into the map. + QMapConstIterator<int, QString> it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + dateEventMap.insert( m_reverseFieldMap[*it], resItem.data( *it ) ); + } + + // Last step: Put map into date event and return it + OEvent retDate( dateEventMap ); + + return retDate; +} + +bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) +{ + QMap<int,QString> eventMap = ev.toMap(); + + QString qu = "insert into datebook VALUES( " + QString::number( ev.uid() ); + QMap<int, QString>::Iterator it; + for ( it = ++m_fieldMap.begin(); it != m_fieldMap.end(); ++it ){ + if ( !eventMap[it.key()].isEmpty() ) + qu += QString( ",\"%1\"" ).arg( eventMap[it.key()] ); + else + qu += QString( ",\"\"" ); + } + qu += " );"; + + // Add custom entries + int id = 0; + QMap<QString, QString> customMap = ev.toExtraMap(); + for( QMap<QString, QString>::Iterator it = customMap.begin(); + it != customMap.end(); ++it ){ + qu += "insert into custom_data VALUES(" + + QString::number( ev.uid() ) + + "," + + QString::number( id++ ) + + ",'" + + it.key() //.latin1() + + "'," + + "0" // Priority for future enhancements + + ",'" + + it.data() //.latin1() + + "');"; + } + qWarning("add %s", qu.latin1() ); + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + return false; } -bool ODateBookAccessBackend_SQL::add( const OEvent& ev ) { return true; } -bool ODateBookAccessBackend_SQL::remove( int uid ) { + +bool ODateBookAccessBackend_SQL::remove( int uid ) +{ + QString qu = "DELETE from datebook where uid = " + + QString::number( uid ) + ";"; + qu += "DELETE from custom_data where uid = " + + QString::number( uid ) + ";"; + + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + return false; + } return true; } -bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) { + +bool ODateBookAccessBackend_SQL::replace( const OEvent& ev ) +{ remove( ev.uid() ); return add( ev ); } -QArray<int> ODateBookAccessBackend_SQL::rawEvents()const { + +QArray<int> ODateBookAccessBackend_SQL::rawEvents()const +{ return allRecords(); } -QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const { - return ints; +QArray<int> ODateBookAccessBackend_SQL::rawRepeats()const +{ + QString qu = "select uid from datebook where RType!=\"\" AND RType!=\"NoRepeat\""; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + QArray<int> nix; + return nix; } -QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const { - return ints; + return extractUids( res ); +} + +QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const +{ + QString qu = "select uid from datebook where RType=\"\" or RType=\"NoRepeat\""; + OSQLRawQuery raw( qu ); + OSQLResult res = m_driver->query( &raw ); + if ( res.state() != OSQLResult::Success ){ + QArray<int> nix; + return nix; + } + + return extractUids( res ); +} + +OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() +{ + QArray<int> nonRepUids = nonRepeats(); + OEvent::ValueList list; + + for (uint i = 0; i < nonRepUids.count(); ++i ){ + list.append( find( nonRepUids[i] ) ); } -OEvent::ValueList ODateBookAccessBackend_SQL::directNonRepeats() { return list; + +} +OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() +{ + QArray<int> rawRepUids = rawRepeats(); + OEvent::ValueList list; + + for (uint i = 0; i < rawRepUids.count(); ++i ){ + list.append( find( rawRepUids[i] ) ); } -OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() { return list; } QArray<int> ODateBookAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { + QArray<int> null; + return null; +} + +/* ===== Private Functions ========================================== */ + +QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const +{ + qWarning("extractUids"); + QTime t; + t.start(); + OSQLResultItem::ValueList list = res.results(); + OSQLResultItem::ValueList::Iterator it; + QArray<int> ints(list.count() ); + qWarning(" count = %d", list.count() ); + + int i = 0; + for (it = list.begin(); it != list.end(); ++it ) { + ints[i] = (*it).data("uid").toInt(); + i++; + } + qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); + + return ints; - return m_currentQuery; } diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h index 85e0d4f..f39e154 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h @@ -1,8 +1,9 @@ #ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #define OPIE_DATE_BOOK_ACCESS_BACKEND_SQL__H #include <qmap.h> +#include <opie2/osqlresult.h> #include "odatebookaccessbackend.h" class OSQLDriver; @@ -44,8 +45,9 @@ private: QString m_fileName; QArray<int> m_uids; QMap<int, QString> m_fieldMap; + QMap<QString, int> m_reverseFieldMap; OSQLDriver* m_driver; class Private; diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index 75a0860..3764c7e 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp @@ -329,9 +329,9 @@ bool OTodoAccessBackendSQL::reload(){ return load(); } bool OTodoAccessBackendSQL::save(){ - return m_driver->close(); + return m_driver->close(); // Shouldn't m_driver->sync be better than close ? (eilers) } QArray<int> OTodoAccessBackendSQL::allRecords()const { if (m_dirty ) update(); diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h index 9b0a719..bd6da40 100644 --- a/libopie2/opiepim/core/ocontactaccess.h +++ b/libopie2/opiepim/core/ocontactaccess.h @@ -16,8 +16,20 @@ * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.10 2003/12/22 10:19:26 eilers + * Finishing implementation of sql-backend for datebook. But I have to + * port the PIM datebook application to use it, before I could debug the + * whole stuff. + * Thus, PIM-Database backend is finished, but highly experimental. And some + * parts are still generic. For instance, the "queryByExample()" methods are + * not (or not fully) implemented. Todo: custom-entries not stored. + * The big show stopper: matchRegExp() (needed by OpieSearch) needs regular + * expression search in the database, which is not supported by sqlite ! + * Therefore we need either an extended sqlite or a workaround which would + * be very slow and memory consuming.. + * * Revision 1.9 2003/08/01 12:30:16 eilers * Merging changes from BRANCH_1_0 to HEAD * * Revision 1.8.2.1 2003/06/30 14:34:19 eilers @@ -77,9 +89,9 @@ * This is just a frontend for the real database handling which is * done by the backend. * This class is used to access the Contacts on a system. This class as any OPIE PIM * class is backend independent. - + * @author Stefan Eilers, Holger Freyther * @see OPimAccessTemplate */ class OContactAccess: public QObject, public OPimAccessTemplate<OContact> { diff --git a/libopie2/opiepim/core/odatebookaccess.cpp b/libopie2/opiepim/core/odatebookaccess.cpp index a3661a3..82934f9 100644 --- a/libopie2/opiepim/core/odatebookaccess.cpp +++ b/libopie2/opiepim/core/odatebookaccess.cpp @@ -55,12 +55,27 @@ ODateBookAccess::List ODateBookAccess::nonRepeats()const { * @param from Include all events from... * @param to Include all events to... */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) { - return m_backEnd->effecticeEvents( from, to ); + return m_backEnd->effectiveEvents( from, to ); } /** * @return all events at a given datetime */ OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) { - return m_backEnd->effecticeEvents( start ); + return m_backEnd->effectiveEvents( start ); +} + +/** + * @return non repeating dates in the time span between from and to + * @param from Include all events from... + * @param to Include all events to... + */ +OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) { + return m_backEnd->effectiveNonRepeatingEvents( from, to ); +} +/** + * @return all non repeating events at a given datetime + */ +OEffectiveEvent::ValueList ODateBookAccess::effectiveNonRepeatingEvents( const QDateTime& start ) { + return m_backEnd->effectiveNonRepeatingEvents( start ); } diff --git a/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h index 7c7a63f..62196da 100644 --- a/libopie2/opiepim/core/odatebookaccess.h +++ b/libopie2/opiepim/core/odatebookaccess.h @@ -12,9 +12,9 @@ * All access to the datebook should be done via this class. * Make sure to load and save the datebook this is not part of * destructing and creating the object * - * @author Holger Freyther + * @author Holger Freyther, Stefan Eilers */ class ODateBookAccess : public OPimAccessTemplate<OEvent> { public: ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); @@ -28,10 +28,13 @@ public: /* return non repeating events */ List nonRepeats()const; - OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ); - OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ); + /* return non repeating events (from,to) */ + OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to ) const; + OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start ) const; + OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const; + OEffectiveEvent::ValueList effectiveNonRepeatingEvents( const QDateTime& start ) const; private: ODateBookAccessBackend* m_backEnd; class Private; diff --git a/libopie2/opiepim/core/otimezone.cpp b/libopie2/opiepim/core/otimezone.cpp index b2bd3aa..34659c3 100644 --- a/libopie2/opiepim/core/otimezone.cpp +++ b/libopie2/opiepim/core/otimezone.cpp @@ -15,13 +15,18 @@ namespace { return ret; } QDateTime utcTime( time_t t, const QString& zone) { QCString org = ::getenv( "TZ" ); +#ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", zone.latin1(), true ); ::tzset(); tm* broken = ::localtime( &t ); ::setenv( "TZ", org, true ); +#else +#warning "Need a replacement for MacOSX!!" + tm* broken = ::localtime( &t ); +#endif QDateTime ret; ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) ); ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); @@ -40,14 +45,18 @@ namespace { broken.tm_min = t.minute(); broken.tm_sec = t.second(); QCString org = ::getenv( "TZ" ); +#ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", str.latin1(), true ); ::tzset(); time_t ti = ::mktime( &broken ); ::setenv( "TZ", org, true ); - +#else +#warning "Need a replacement for MacOSX!!" + time_t ti = ::mktime( &broken ); +#endif return ti; } } OTimeZone::OTimeZone( const ZoneName& zone ) diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp index ec05e77..9b31957 100644 --- a/libopie2/opiepim/oevent.cpp +++ b/libopie2/opiepim/oevent.cpp @@ -76,8 +76,17 @@ OEvent::OEvent( const OEvent& ev) : OPimRecord( ev ), data( ev.data ) { data->ref(); } + +OEvent::OEvent( const QMap<int, QString> map ) + : OPimRecord( 0 ) +{ + data = new Data; + + fromMap( map ); +} + OEvent::~OEvent() { if ( data->deref() ) { delete data; data = 0; @@ -402,8 +411,12 @@ QMap<int, QString> OEvent::toMap()const { retMap.insert( OEvent::FRHasEndDate, recFields[ORecur::RHasEndDate] ); retMap.insert( OEvent::FREndDate, recFields[ORecur::EndDate] ); retMap.insert( OEvent::FRCreated, recFields[ORecur::Created] ); retMap.insert( OEvent::FRExceptions, recFields[ORecur::Exceptions] ); + } else { + ORecur recur = recurrence(); + QMap<int, QString> recFields = recur.toMap(); + retMap.insert( OEvent::FRType, recFields[ORecur::RType] ); } return retMap; } diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h index 9218c97..9eb948f 100644 --- a/libopie2/opiepim/oevent.h +++ b/libopie2/opiepim/oevent.h @@ -75,8 +75,14 @@ public: /** * copy c'tor */ OEvent( const OEvent& ); + + /** + * Create OEvent, initialized by map + * @see enum RecordFields + */ + OEvent( const QMap<int, QString> map ); ~OEvent(); OEvent &operator=( const OEvent& ); QString description()const; |