summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend
authoreilers <eilers>2003-12-22 10:19:25 (UTC)
committer eilers <eilers>2003-12-22 10:19:25 (UTC)
commitae70312b1613e26b4ef89a2c9821d9531b82e987 (patch) (side-by-side diff)
tree7eb70bc45ee29e94da27a18b0136eb4a14e59fa6 /libopie2/opiepim/backend
parent9e7aafdb7c76d29fee742d53131a73dd60aded2b (diff)
downloadopie-ae70312b1613e26b4ef89a2c9821d9531b82e987.zip
opie-ae70312b1613e26b4ef89a2c9821d9531b82e987.tar.gz
opie-ae70312b1613e26b4ef89a2c9821d9531b82e987.tar.bz2
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..
Diffstat (limited to 'libopie2/opiepim/backend') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h24
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp18
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.cpp34
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.h19
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp231
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_sql.h2
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp2
7 files changed, 268 insertions, 62 deletions
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
@@ -1,176 +1,194 @@
/*
* Class to manage Backends.
*
* Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation;
* either version 2 of the License, or (at your option) any later
* version.
* =====================================================================
* ToDo: Use plugins
* =====================================================================
* 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...
*
* Revision 1.7 2003/08/01 12:30:16 eilers
* Merging changes from BRANCH_1_0 to HEAD
*
* Revision 1.6.4.1 2003/06/30 14:34:19 eilers
* Patches from Zecke:
* Fixing and cleaning up extraMap handling
* Adding d_ptr for binary compatibility in the future
*
* Revision 1.6 2003/04/13 18:07:10 zecke
* More API doc
* QString -> const QString&
* QString = 0l -> QString::null
*
* Revision 1.5 2003/02/21 23:31:52 zecke
* Add XML datebookresource
* -clean up todoaccessxml header
* -implement some more stuff in the oeven tester
* -extend DefaultFactory to not crash and to use datebook
*
* -reading of OEvents is working nicely.. saving will be added
* tomorrow
* -fix spelling in ODateBookAcces
*
* Revision 1.4 2002/10/14 15:55:18 eilers
* Redeactivate SQL.. ;)
*
* Revision 1.3 2002/10/10 17:08:58 zecke
* The Cache is finally in place
* I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
* The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster....
* I still have to fully implement read ahead
* This change is bic but sc
*
* Revision 1.2 2002/10/08 09:27:36 eilers
* Fixed libopie.pro to include the new pim-API.
* The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
* compile itself would need to install libsqlite, libopiesql...
* Therefore, the backend currently uses XML only..
*
* Revision 1.1 2002/10/07 17:35:01 eilers
* added OBackendFactory for advanced backend access
*
*
* =====================================================================
*/
#ifndef OPIE_BACKENDFACTORY_H_
#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
#include <qasciidict.h>
#include <qpe/config.h>
#include "otodoaccessxml.h"
#include "ocontactaccessbackend_xml.h"
#include "odatebookaccessbackend_xml.h"
#ifdef __USE_SQL
#include "otodoaccesssql.h"
#include "ocontactaccessbackend_sql.h"
+#include "odatebookaccessbackend_sql.h"
#endif
class OBackendPrivate;
/**
* This class is our factory. It will give us the default implementations
* of at least Todolist, Contacts and Datebook. In the future this class will
* allow users to switch the backend with ( XML->SQLite ) without the need
* to recompile.#
* This class as the whole PIM Api is making use of templates
*
* <pre>
* OTodoAccessBackend* backend = OBackEndFactory<OTodoAccessBackend>::Default("todo", QString::null );
* backend->load();
* </pre>
*
* @author Stefan Eilers
* @version 0.1
*/
template<class T>
class OBackendFactory
{
public:
OBackendFactory() {};
enum BACKENDS {
TODO,
CONTACT,
DATE
};
/**
* Returns a backend implementation for backendName
* @param backendName the type of the backend
* @param appName will be passed on to the backend
*/
static T* Default( const QString backendName, const QString& appName ){
// __asm__("int3");
Config config( "pimaccess" );
config.setGroup ( backendName );
QString backend = config.readEntry( "usebackend" );
qWarning("Selected backend for %s is: %s", backendName.latin1(), backend.latin1() );
QAsciiDict<int> dict ( 3 );
dict.setAutoDelete ( TRUE );
dict.insert( "todo", new int (TODO) );
dict.insert( "contact", new int (CONTACT) );
dict.insert( "datebook", new int(DATE) );
int *find = dict[ backendName ];
if (!find ) return 0;
switch ( *find ){
case TODO:
#ifdef __USE_SQL
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:
#ifdef __USE_SQL
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;
}
}
private:
OBackendPrivate* d;
};
#endif
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
@@ -1,64 +1,76 @@
/*
* SQL Backend for the OPIE-Contact Database.
*
* Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* =====================================================================
* =====================================================================
* 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
* Improvement of PIM-SQL Databases, but search queries are still limited.
* Addressbook: Changed table layout. Now, we just need 1/3 of disk-space.
* Todo: Started to add new attributes. Some type conversions missing.
*
* Revision 1.1 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...
*
*/
#include "ocontactaccessbackend_sql.h"
#include <qarray.h>
#include <qdatetime.h>
#include <qstringlist.h>
#include <qpe/global.h>
#include <qpe/recordfields.h>
#include <opie/ocontactfields.h>
#include <opie/oconversion.h>
#include <opie2/osqldriver.h>
#include <opie2/osqlresult.h>
#include <opie2/osqlmanager.h>
#include <opie2/osqlquery.h>
// If defined, we use a horizontal table ( uid, attr1, attr2, attr3, ..., attrn ) instead
// vertical like "uid, type, value".
// DON'T DEACTIVATE THIS DEFINE IN PRODUCTIVE ENVIRONMENTS !!
#define __STORE_HORIZONTAL_
// Distinct loading is not very fast. If I expect that every person has just
// one (and always one) 'Last Name', I can request all uid's for existing lastnames,
// which is faster..
// But this may not be true for all entries, like company contacts..
// The current AddressBook application handles this problem, but other may not.. (eilers)
#define __USE_SUPERFAST_LOADQUERY
/*
@@ -465,106 +477,106 @@ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname
t.start();
/* Expecting to access the default filename if nothing else is set */
if ( filename.isEmpty() ){
m_fileName = Global::applicationFileName( "addressbook","addressbook.db" );
} else
m_fileName = filename;
// Get the standart sql-driver from the OSQLManager..
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl( m_fileName );
load();
qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
}
OContactAccessBackend_SQL::~OContactAccessBackend_SQL ()
{
if( m_driver )
delete m_driver;
}
bool OContactAccessBackend_SQL::load ()
{
if (!m_driver->open() )
return false;
// Don't expect that the database exists.
// It is save here to create the table, even if it
// do exist. ( Is that correct for all databases ?? )
CreateQuery creat;
OSQLResult res = m_driver->query( &creat );
update();
return true;
}
bool OContactAccessBackend_SQL::reload()
{
return load();
}
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()
{
return false;
}
QArray<int> OContactAccessBackend_SQL::allRecords() const
{
// FIXME: Think about cute handling of changed tables..
// Thus, we don't have to call update here...
if ( m_changed )
((OContactAccessBackend_SQL*)this)->update();
return m_uids;
}
bool OContactAccessBackend_SQL::add ( const OContact &newcontact )
{
InsertQuery ins( newcontact );
OSQLResult res = m_driver->query( &ins );
if ( res.state() == OSQLResult::Failure )
return false;
int c = m_uids.count();
m_uids.resize( c+1 );
m_uids[c] = newcontact.uid();
return true;
}
bool OContactAccessBackend_SQL::remove ( int uid )
{
RemoveQuery rem( uid );
OSQLResult res = m_driver->query(&rem );
if ( res.state() == OSQLResult::Failure )
return false;
m_changed = true;
return true;
}
bool OContactAccessBackend_SQL::replace ( const OContact &contact )
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
@@ -82,75 +82,101 @@ namespace {
}else {
/* we only occur by days, not hours/minutes/seconds. Hence
* the actual end and start times will be the same for
* every repeated event. For multi day events this is
* fixed up later if on wronge day span
*/
eff.setStartTime( (*it).startDateTime().time() );
eff.setEndTime( (*it).endDateTime().time() );
}
if ( dur != 0 ) {
// multi-day repeating events
QDate sub_it = QMAX( repeat, from );
QDate startDate = repeat;
QDate endDate = startDate.addDays( dur );
while ( sub_it <= endDate && sub_it <= to ) {
OEffectiveEvent tmpEff = eff;
tmpEff.setEvent( (*it) );
if ( sub_it != startDate )
tmpEff.setStartTime( QTime(0, 0, 0 ) );
if ( sub_it != endDate )
tmpEff.setEndTime( QTime( 23, 59, 59 ) );
tmpEff.setDate( sub_it );
tmpEff.setEffectiveDates( startDate, endDate );
tmpList.append( tmpEff );
sub_it = sub_it.addDays( 1 );
}
itDate = endDate;
}else {
eff.setEvent( (*it) );
tmpList.append( eff );
itDate = repeat.addDays( 1 );
}
}
}
}
}
ODateBookAccessBackend::ODateBookAccessBackend()
: OPimAccessBackend<OEvent>()
{
}
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;
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;
}
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
@@ -15,63 +15,76 @@ class ODateBookAccessBackend : public OPimAccessBackend<OEvent> {
public:
typedef int UID;
/**
* c'tor without parameter
*/
ODateBookAccessBackend();
~ODateBookAccessBackend();
/**
* This method should return a list of UIDs containing
* all events. No filter should be applied
* @return list of events
*/
virtual QArray<UID> rawEvents()const = 0;
/**
* This method should return a list of UIDs containing
* all repeating events. No filter should be applied
* @return list of repeating events
*/
virtual QArray<UID> rawRepeats()const = 0;
/**
* This mthod should return a list of UIDs containing all non
* repeating events. No filter should be applied
* @return list of nonrepeating events
*/
virtual QArray<UID> nonRepeats() const = 0;
/**
* If you do not want to implement the effectiveEvents methods below
* you need to supply it with directNonRepeats.
* This method can return empty lists if effectiveEvents is implememted
*/
virtual OEvent::ValueList directNonRepeats() = 0;
/**
* Same as above but return raw repeats!
*/
virtual OEvent::ValueList directRawRepeats() = 0;
/* is implemented by default but you can reimplement it*/
/**
* 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;
};
#endif
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
@@ -1,221 +1,356 @@
/*
* SQL Backend for the OPIE-Calender Database.
*
* Copyright (c) 2003 by Stefan Eilers (Eilers.Stefan@epost.de)
*
* =====================================================================
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* =====================================================================
* =====================================================================
* 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..
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#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 )
{
- m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
+ m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName;
// Get the standart sql-driver from the OSQLManager..
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl( m_fileName );
initFields();
load();
}
ODateBookAccessBackend_SQL::~ODateBookAccessBackend_SQL() {
+ if( m_driver )
+ delete m_driver;
}
void ODateBookAccessBackend_SQL::initFields()
{
// This map contains the translation of the fieldtype id's to
// the names of the table columns
m_fieldMap.insert( OEvent::FUid, "uid" );
m_fieldMap.insert( OEvent::FCategories, "Categories" );
m_fieldMap.insert( OEvent::FDescription, "Description" );
m_fieldMap.insert( OEvent::FLocation, "Location" );
m_fieldMap.insert( OEvent::FType, "Type" );
m_fieldMap.insert( OEvent::FAlarm, "Alarm" );
m_fieldMap.insert( OEvent::FSound, "Sound" );
m_fieldMap.insert( OEvent::FRType, "RType" );
m_fieldMap.insert( OEvent::FRWeekdays, "RWeekdays" );
m_fieldMap.insert( OEvent::FRPosition, "RPosition" );
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()
{
if (!m_driver->open() )
return false;
// Don't expect that the database exists.
// It is save here to create the table, even if it
// do exist. ( Is that correct for all databases ?? )
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;
update();
return true;
}
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();
+ 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
{
- return m_uids;
+ return m_uids;
}
QArray<int> ODateBookAccessBackend_SQL::queryByExample(const OEvent&, int, const QDateTime& ) {
- return QArray<int>();
+ return QArray<int>();
}
void ODateBookAccessBackend_SQL::clear()
{
QString qu = "drop table datebook;";
qu += "drop table custom_data;";
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 ) {
- return true;
+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;
+ }
+
+ return true;
}
-bool ODateBookAccessBackend_SQL::remove( int uid ) {
- return true;
+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;
+ }
+
+ return extractUids( res );
}
-QArray<int> ODateBookAccessBackend_SQL::nonRepeats()const {
- return ints;
+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() {
- return list;
+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] ) );
+ }
+
+ return list;
+
}
-OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats() {
+OEvent::ValueList ODateBookAccessBackend_SQL::directRawRepeats()
+{
+ QArray<int> rawRepUids = rawRepeats();
+ OEvent::ValueList list;
- return list;
+ for (uint i = 0; i < rawRepUids.count(); ++i ){
+ list.append( find( rawRepUids[i] ) );
+ }
+
+ 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,60 +1,62 @@
#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;
/**
* This is the default SQL implementation for DateBoook SQL storage
* It fully implements the interface
* @see ODateBookAccessBackend
* @see OPimAccessBackend
*/
class ODateBookAccessBackend_SQL : public ODateBookAccessBackend {
public:
ODateBookAccessBackend_SQL( const QString& appName,
const QString& fileName = QString::null);
~ODateBookAccessBackend_SQL();
bool load();
bool reload();
bool save();
QArray<int> allRecords()const;
QArray<int> matchRegexp(const QRegExp &r) const;
QArray<int> queryByExample( const OEvent&, int, const QDateTime& d = QDateTime() );
OEvent find( int uid )const;
void clear();
bool add( const OEvent& ev );
bool remove( int uid );
bool replace( const OEvent& ev );
QArray<UID> rawEvents()const;
QArray<UID> rawRepeats()const;
QArray<UID> nonRepeats()const;
OEvent::ValueList directNonRepeats();
OEvent::ValueList directRawRepeats();
private:
bool loadFile();
QString m_fileName;
QArray<int> m_uids;
QMap<int, QString> m_fieldMap;
+ QMap<QString, int> m_reverseFieldMap;
OSQLDriver* m_driver;
class Private;
Private *d;
void initFields();
void update();
QArray<int> extractUids( OSQLResult& res ) const;
};
#endif
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
@@ -285,97 +285,97 @@ namespace {
QString str;
str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
.arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
.arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
return str;
}
QString EffQuery::out()const {
QString str;
str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
.arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
.arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
return str;
}
};
OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
: OTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true)
{
QString fi = file;
if ( fi.isEmpty() )
fi = Global::applicationFileName( "todolist", "todolist.db" );
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl(fi);
// fillDict();
}
OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
if( m_driver )
delete m_driver;
}
bool OTodoAccessBackendSQL::load(){
if (!m_driver->open() )
return false;
CreateQuery creat;
OSQLResult res = m_driver->query(&creat );
m_dirty = true;
return true;
}
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();
return m_uids;
}
QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
QArray<int> ints(0);
return ints;
}
OTodo OTodoAccessBackendSQL::find(int uid ) const{
FindQuery query( uid );
return todo( m_driver->query(&query) );
}
OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
uint cur, Frontend::CacheDirection dir ) const{
uint CACHE = readAhead();
qWarning("searching for %d", uid );
QArray<int> search( CACHE );
uint size =0;
OTodo to;
// we try to cache CACHE items
switch( dir ) {
/* forward */
case 0: // FIXME: Not a good style to use magic numbers here (eilers)
for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
qWarning("size %d %d", size, ints[i] );
search[size] = ints[i];
size++;
}
break;
/* reverse */
case 1: // FIXME: Not a good style to use magic numbers here (eilers)
for (uint i = cur; i != 0 && size < CACHE; i-- ) {
search[size] = ints[i];
size++;
}
break;
}
search.resize( size );
FindQuery query( search );
OSQLResult res = m_driver->query( &query );
if ( res.state() != OSQLResult::Success )
return to;