author | eilers <eilers> | 2004-04-05 07:03:09 (UTC) |
---|---|---|
committer | eilers <eilers> | 2004-04-05 07:03:09 (UTC) |
commit | e6e31e93aa55bb967a044fe3660201000a6e59b0 (patch) (side-by-side diff) | |
tree | 1071fa4b22698fd56dde283bbb7375478b7e1ddf | |
parent | 6be3d148fc1d610ebfa193012657b3b77d9368e3 (diff) | |
download | opie-e6e31e93aa55bb967a044fe3660201000a6e59b0.zip opie-e6e31e93aa55bb967a044fe3660201000a6e59b0.tar.gz opie-e6e31e93aa55bb967a044fe3660201000a6e59b0.tar.bz2 |
SQL-Backends are almost finished !
Works: Loading/Storing data, Most important search queries for Address/todo
Unfinished: Search-Queries for Datebook, regexp search
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 180 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | 1 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp | 70 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_sql.h | 2 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccesssql.cpp | 173 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccesssql.h | 5 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimcontact.h | 2 |
7 files changed, 339 insertions, 94 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 1ea35a8..3142f75 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp @@ -34,35 +34,36 @@ #include <qarray.h> #include <qdatetime.h> #include <qstringlist.h> #include <qpe/global.h> #include <qpe/recordfields.h> +#include <opie2/opimcontact.h> #include <opie2/opimcontactfields.h> #include <opie2/opimdateconversion.h> #include <opie2/osqldriver.h> #include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> +using namespace Opie; using namespace Opie::DB; /* - * Implementation of used query types - * CREATE query + * Implementation of used query types * CREATE query * LOAD query * INSERT * REMOVE * CLEAR */ -namespace Opie { +namespace { /** * CreateQuery for the Todolist Table */ class CreateQuery : public OSQLQuery { public: CreateQuery(); ~CreateQuery(); QString query()const; @@ -145,17 +146,17 @@ namespace Opie { QString single()const; QString multi()const; QArray<int> m_uids; int m_uid; }; - // We using three tables to store the information: + // We using two tables to store the information: // 1. addressbook : It contains General information about the contact (non custom) // 2. custom_data : Not official supported entries // All tables are connected by the uid of the contact. // Maybe I should add a table for meta-information ? CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; @@ -163,17 +164,17 @@ namespace Opie { qu += "create table addressbook( uid PRIMARY KEY "; QStringList fieldList = OPimContactFields::untrfields( false ); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ qu += QString( ",\"%1\" VARCHAR(10)" ).arg( *it ); } qu += " );"; - qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; return qu; } ClearQuery::ClearQuery() : OSQLQuery() {} ClearQuery::~ClearQuery() {} QString ClearQuery::query()const { @@ -216,45 +217,36 @@ namespace Opie { QStringList fieldList = OPimContactFields::untrfields( false ); QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ // Convert Column-String to Id and get value for this id.. // Hmmm.. Maybe not very cute solution.. int id = translate[*it]; switch ( id ){ - case Qtopia::Birthday:{ - // These entries should stored in a special format - // year-month-day - QDate day = m_contact.birthday(); - if ( day.isValid() ){ - qu += QString(",\"%1-%2-%3\"") - .arg( day.year() ) - .arg( day.month() ) - .arg( day.day() ); + case Qtopia::Birthday: + case Qtopia::Anniversary:{ + QDate day; + if ( id == Qtopia::Birthday ){ + day = m_contact.birthday(); } else { - qu += ",\"\""; + day = m_contact.anniversary(); } - } - break; - case Qtopia::Anniversary:{ // These entries should stored in a special format // year-month-day - QDate day = m_contact.anniversary(); if ( day.isValid() ){ qu += QString(",\"%1-%2-%3\"") - .arg( day.year() ) - .arg( day.month() ) - .arg( day.day() ); + .arg( QString::number( day.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( day.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( day.day() ).rightJustify( 2, '0' ) ); } else { qu += ",\"\""; } } break; - default: qu += QString( ",\"%1\"" ).arg( contactMap[id] ); } } qu += " );"; // Now add custom data.. @@ -263,25 +255,25 @@ namespace Opie { QMap<QString, QString> customMap = m_contact.toExtraMap(); for( QMap<QString, QString>::Iterator it = customMap.begin(); it != customMap.end(); ++it ){ qu += "insert into custom_data VALUES(" + QString::number( m_contact.uid() ) + "," + QString::number( id++ ) + ",'" - + it.key() //.latin1() + + it.key() + "'," + "0" // Priority for future enhancements + ",'" - + it.data() //.latin1() + + it.data() + "');"; } // qu += "commit;"; - qWarning("add %s", qu.latin1() ); + qDebug("add %s", qu.latin1() ); return qu; } RemoveQuery::RemoveQuery(int uid ) : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { @@ -353,34 +345,34 @@ namespace Opie { /* --------------------------------------------------------------------------- */ namespace Opie { OPimContactAccessBackend_SQL::OPimContactAccessBackend_SQL ( const QString& /* appname */, const QString& filename ): OPimContactAccessBackend(), m_changed(false), m_driver( NULL ) { - qWarning("C'tor OPimContactAccessBackend_SQL starts"); + qDebug("C'tor OPimContactAccessBackend_SQL starts"); QTime t; 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 OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() ); + qDebug("C'tor OPimContactAccessBackend_SQL ends: %d ms", t.elapsed() ); } OPimContactAccessBackend_SQL::~OPimContactAccessBackend_SQL () { if( m_driver ) delete m_driver; } @@ -471,64 +463,133 @@ bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) return false; return add( contact ); } OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const { - qWarning("OPimContactAccessBackend_SQL::find()"); + qDebug("OPimContactAccessBackend_SQL::find()"); QTime t; t.start(); OPimContact retContact( requestNonCustom( uid ) ); retContact.setExtraMap( requestCustom( uid ) ); - qWarning("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); + qDebug("OPimContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() ); return retContact; } -QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& d = QDateTime() ) +QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) { QString qu = "SELECT uid FROM addressbook WHERE"; + QString searchQuery =""; + + QDate startDate; + + if ( qd.isValid() ) + startDate = qd.date(); + else + startDate = QDate::currentDate(); + QMap<int, QString> queryFields = query.toMap(); QStringList fieldList = OPimContactFields::untrfields( false ); QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); // Convert every filled field to a SQL-Query - bool isAnyFieldSelected = false; +// bool isAnyFieldSelected = false; for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ + int id = translate[*it]; QString queryStr = queryFields[id]; + QDate* endDate = 0l; + if ( !queryStr.isEmpty() ){ - isAnyFieldSelected = true; + // If something is alredy stored in the query, add an "AND" + // to the end of the string to prepare for the next .. + if ( !searchQuery.isEmpty() ) + searchQuery += " AND"; + +// isAnyFieldSelected = true; switch( id ){ + case Qtopia::Birthday: + endDate = new QDate( query.birthday() ); + // Fall through ! + case Qtopia::Anniversary: + if ( endDate == 0l ) + endDate = new QDate( query.anniversary() ); + + if ( settings & OPimContactAccess::DateDiff ) { + searchQuery += QString( " (\"%1\" <= '%2-%3-%4\' AND \"%5\" >= '%6-%7-%8')" ) + .arg( *it ) + .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ) + .arg( *it ) + .arg( QString::number( startDate.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( startDate.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( startDate.day() ).rightJustify( 2, '0' ) ) ; + } + + if ( settings & OPimContactAccess::DateYear ){ + if ( settings & OPimContactAccess::DateDiff ) + searchQuery += " AND"; + + searchQuery += QString( " (\"%1\" LIKE '%2-%')" ) + .arg( *it ) + .arg( QString::number( endDate->year() ).rightJustify( 4, '0' ) ); + } + + if ( settings & OPimContactAccess::DateMonth ){ + if ( ( settings & OPimContactAccess::DateDiff ) + || ( settings & OPimContactAccess::DateYear ) ) + searchQuery += " AND"; + + searchQuery += QString( " (\"%1\" LIKE '%-%2-%')" ) + .arg( *it ) + .arg( QString::number( endDate->month() ).rightJustify( 2, '0' ) ); + } + + if ( settings & OPimContactAccess::DateDay ){ + if ( ( settings & OPimContactAccess::DateDiff ) + || ( settings & OPimContactAccess::DateYear ) + || ( settings & OPimContactAccess::DateMonth ) ) + searchQuery += " AND"; + + searchQuery += QString( " (\"%1\" LIKE '%-%-%2')" ) + .arg( *it ) + .arg( QString::number( endDate->day() ).rightJustify( 2, '0' ) ); + } + + break; default: // Switching between case sensitive and insensitive... // LIKE is not case sensitive, GLOB is case sensitive // Do exist a better solution to switch this ? if ( settings & OPimContactAccess::IgnoreCase ) - qu += "(\"" + *it + "\"" + " LIKE " + "'" - + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND "; + searchQuery += "(\"" + *it + "\"" + " LIKE " + "'" + + queryStr.replace(QRegExp("\\*"),"%") + "'" + ")"; else - qu += "(\"" + *it + "\"" + " GLOB " + "'" - + queryStr + "'" + ") AND "; + searchQuery += "(\"" + *it + "\"" + " GLOB " + "'" + + queryStr + "'" + ")"; } } } // Skip trailing "AND" - if ( isAnyFieldSelected ) - qu = qu.left( qu.length() - 4 ); +// if ( isAnyFieldSelected ) +// qu = qu.left( qu.length() - 4 ); + + qu += searchQuery; - qWarning( "queryByExample query: %s", qu.latin1() ); + qDebug( "queryByExample query: %s", qu.latin1() ); // Execute query and return the received uid's OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> empty; return empty; } @@ -542,34 +603,39 @@ QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { QArray<int> nix(0); return nix; } const uint OPimContactAccessBackend_SQL::querySettings() { return OPimContactAccess::IgnoreCase - || OPimContactAccess::WildCards; + || OPimContactAccess::WildCards + || OPimContactAccess::DateDiff + || OPimContactAccess::DateYear + || OPimContactAccess::DateMonth + || OPimContactAccess::DateDay + ; } bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const { /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards -// | OPimContactAccess::DateDiff -// | OPimContactAccess::DateYear -// | OPimContactAccess::DateMonth -// | OPimContactAccess::DateDay + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay // | OPimContactAccess::RegExp // | OPimContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid @@ -604,69 +670,69 @@ QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) t.start(); QString query = "SELECT uid FROM addressbook "; query += "ORDER BY \"Last Name\" "; if ( !asc ) query += "DESC"; - // qWarning("sorted query is: %s", query.latin1() ); + // qDebug("sorted query is: %s", query.latin1() ); OSQLRawQuery raw( query ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ QArray<int> empty; return empty; } QArray<int> list = extractUids( res ); - qWarning("sorted needed %d ms!", t.elapsed() ); + qDebug("sorted needed %d ms!", t.elapsed() ); return list; } void OPimContactAccessBackend_SQL::update() { - qWarning("Update starts"); + qDebug("Update starts"); QTime t; t.start(); // Now load the database set and extract the uid's // which will be held locally LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; m_uids = extractUids( res ); m_changed = false; - qWarning("Update ends %d ms", t.elapsed() ); + qDebug("Update ends %d ms", t.elapsed() ); } QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const { - qWarning("extractUids"); + qDebug("extractUids"); QTime t; t.start(); OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); - qWarning(" count = %d", list.count() ); + qDebug(" 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() ); + qDebug("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); return ints; } QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const { QTime t; @@ -691,17 +757,17 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ // Get data for the selected column and store it with the // corresponding id into the map.. int id = translate[*it]; QString value = resItem.data( (*it) ); - // qWarning("Reading %s... found: %s", (*it).latin1(), value.latin1() ); + // qDebug("Reading %s... found: %s", (*it).latin1(), value.latin1() ); switch( id ){ case Qtopia::Birthday: case Qtopia::Anniversary:{ // Birthday and Anniversary are encoded special ( yyyy-mm-dd ) QStringList list = QStringList::split( '-', value ); QStringList::Iterator lit = list.begin(); int year = (*lit).toInt(); @@ -709,28 +775,28 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co int day = (*(++lit)).toInt(); if ( ( day != 0 ) && ( month != 0 ) && ( year != 0 ) ){ QDate date( year, month, day ); nonCustomMap.insert( id, OPimDateConversion::dateToString( date ) ); } } break; case Qtopia::AddressCategory: - qWarning("Category is: %s", value.latin1() ); + qDebug("Category is: %s", value.latin1() ); default: nonCustomMap.insert( id, value ); } } // First insert uid nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) ); t3needed = t3.elapsed(); - // qWarning("Adding UID: %s", resItem.data( "uid" ).latin1() ); - qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", + // qDebug("Adding UID: %s", resItem.data( "uid" ).latin1() ); + qDebug("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed ); return nonCustomMap; } QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const { QTime t; @@ -748,13 +814,13 @@ QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) c } OSQLResultItem::ValueList list = res_custom.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); for ( ; it != list.end(); ++it ) { customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); } - qWarning("RequestCustom needed: %d ms", t.elapsed() ); + qDebug("RequestCustom needed: %d ms", t.elapsed() ); return customMap; } } diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 2b467c3..7b4d81f 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -225,16 +225,17 @@ QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &qu bool allcorrect = true; for ( int i = 0; i < Qtopia::Groups; i++ ) { // Birthday and anniversary are special nonstring fields and should // be handled specially switch ( i ){ case Qtopia::Birthday: queryDate = new QDate( query.birthday() ); checkDate = new QDate( (*it)->birthday() ); + // fall through case Qtopia::Anniversary: if ( queryDate == 0l ){ queryDate = new QDate( query.anniversary() ); checkDate = new QDate( (*it)->anniversary() ); } if ( queryDate->isValid() ){ if( checkDate->isValid() ){ diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp index a779dc1..8a8cb0b 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.cpp @@ -43,16 +43,53 @@ #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> #include <opie2/opimrecurrence.h> #include <opie2/odatebookaccessbackend_sql.h> using namespace Opie::DB; +namespace { + /** + * a find query for custom elements + */ + class FindCustomQuery : public OSQLQuery { + public: + FindCustomQuery(int uid); + FindCustomQuery(const QArray<int>& ); + ~FindCustomQuery(); + QString query()const; + private: + QString single()const; + QString multi()const; + QArray<int> m_uids; + int m_uid; + }; + + FindCustomQuery::FindCustomQuery(int uid) + : OSQLQuery(), m_uid( uid ) { + } + FindCustomQuery::FindCustomQuery(const QArray<int>& ints) + : OSQLQuery(), m_uids( ints ){ + } + FindCustomQuery::~FindCustomQuery() { + } + QString FindCustomQuery::query()const{ +// if ( m_uids.count() == 0 ) + return single(); + } + QString FindCustomQuery::single()const{ + QString qu = "select uid, type, value from custom_data where uid = "; + qu += QString::number(m_uid); + return qu; + } +} + + namespace Opie { ODateBookAccessBackend_SQL::ODateBookAccessBackend_SQL( const QString& , const QString& fileName ) : ODateBookAccessBackend(), m_driver( NULL ) { m_fileName = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.db" ) : fileName; @@ -118,17 +155,17 @@ 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 += " );"; - qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );"; + qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), 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; @@ -197,19 +234,19 @@ OPimEvent ODateBookAccessBackend_SQL::find( int uid ) const{ dateEventMap.insert( OPimEvent::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 + // Last step: Put map into date event, add custom map and return it OPimEvent retDate( dateEventMap ); - + retDate.setExtraMap( requestCustom( uid ) ); return retDate; } // FIXME: Speed up update of uid's.. bool ODateBookAccessBackend_SQL::add( const OPimEvent& ev ) { QMap<int,QString> eventMap = ev.toMap(); @@ -360,9 +397,36 @@ QArray<int> ODateBookAccessBackend_SQL::extractUids( OSQLResult& res ) const i++; } qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() ); return ints; } +QMap<QString, QString> ODateBookAccessBackend_SQL::requestCustom( int uid ) const +{ + QTime t; + t.start(); + + QMap<QString, QString> customMap; + + FindCustomQuery query( uid ); + OSQLResult res_custom = m_driver->query( &query ); + + if ( res_custom.state() == OSQLResult::Failure ) { + qWarning("OSQLResult::Failure in find query !!"); + QMap<QString, QString> empty; + return empty; + } + + OSQLResultItem::ValueList list = res_custom.results(); + OSQLResultItem::ValueList::Iterator it = list.begin(); + for ( ; it != list.end(); ++it ) { + customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); + } + + qDebug("RequestCustom needed: %d ms", t.elapsed() ); + return customMap; +} + + } diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h index 60d7f21..b624159 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_sql.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_sql.h @@ -83,15 +83,17 @@ private: Opie::DB::OSQLDriver* m_driver; class Private; Private *d; void initFields(); void update(); + QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; + QMap<QString, QString> requestCustom( int uid ) const; }; } #endif diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp index d218090..b4170fc 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.cpp +++ b/libopie2/opiepim/backend/otodoaccesssql.cpp @@ -1,11 +1,12 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) + Copyright (C) Holger Freyther (zecke@handhelds.org) =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, @@ -23,16 +24,18 @@ -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> +#include <qmap.h> +#include <qstring.h> #include <qpe/global.h> #include <opie2/osqldriver.h> #include <opie2/osqlresult.h> #include <opie2/osqlmanager.h> #include <opie2/osqlquery.h> @@ -143,26 +146,44 @@ namespace { QString with()const; QString out()const; QDate m_start; QDate m_end; bool m_inc :1; }; + /** + * a find query for custom elements + */ + class FindCustomQuery : public OSQLQuery { + public: + FindCustomQuery(int uid); + FindCustomQuery(const QArray<int>& ); + ~FindCustomQuery(); + QString query()const; + private: + QString single()const; + QString multi()const; + QArray<int> m_uids; + int m_uid; + }; + + + CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; qu += "description, summary, priority, DueDate, progress , state, "; // This is the recurrance-stuff .. Exceptions are currently not supported (see OPimRecurrence.cpp) ! (eilers) qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, "; qu += "reminders, alarms, maintainer, startdate, completeddate);"; - qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; + qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), priority INTEGER, value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; return qu; } LoadQuery::LoadQuery() : OSQLQuery() {} LoadQuery::~LoadQuery() {} QString LoadQuery::query()const { QString qu; // We do not need "distinct" here. The primary key is always unique.. @@ -174,17 +195,19 @@ namespace { InsertQuery::InsertQuery( const OPimTodo& todo ) : OSQLQuery(), m_todo( todo ) { } InsertQuery::~InsertQuery() { } /* * converts from a OPimTodo to a query - * we leave out X-Ref + Alarms + * we leave out X-Ref + Maintainer + * FIXME: Implement/Finish toMap()/fromMap() into OpimTodo to move the encoding + * decoding stuff there.. (eilers) */ QString InsertQuery::query()const{ int year, month, day; year = month = day = 0; if (m_todo.hasDueDate() ) { QDate date = m_todo.dueDate(); year = date.year(); @@ -210,19 +233,19 @@ namespace { QMap<int, QString> recMap = m_todo.recurrence().toMap(); qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + "," + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," + QString::number( m_todo.isCompleted() ) + "," + "'" + m_todo.description() + "'" + "," + "'" + m_todo.summary() + "'" + "," + QString::number(m_todo.priority() ) + "," - + "'" + QString::number(year) + "-" - + QString::number(month) - + "-" + QString::number( day ) + "'" + "," + + "'" + QString::number(year).rightJustify( 4, '0' ) + "-" + + QString::number(month).rightJustify( 2, '0' ) + + "-" + QString::number( day ).rightJustify( 2, '0' )+ "'" + "," + QString::number( m_todo.progress() ) + "," + QString::number( m_todo.state().state() ) + "," + "'" + recMap[ OPimRecurrence::RType ] + "'" + "," + "'" + recMap[ OPimRecurrence::RWeekdays ] + "'" + "," + "'" + recMap[ OPimRecurrence::RPosition ] + "'" + "," + "'" + recMap[ OPimRecurrence::RFreq ] + "'" + "," + "'" + recMap[ OPimRecurrence::RHasEndDate ] + "'" + "," + "'" + recMap[ OPimRecurrence::EndDate ] + "'" + "," @@ -235,25 +258,45 @@ namespace { + "'" + manager.alarmsToString() + "'" + ","; } else{ qu += QString( "''" ) + "," + "''" + ","; } qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) - + "'" + QString::number(sYear) + "-" - + QString::number(sMonth) - + "-" + QString::number(sDay) + "'" + "," - + "'" + QString::number(eYear) + "-" - + QString::number(eMonth) - + "-"+QString::number(eDay) + "'" + + "'" + QString::number(sYear).rightJustify( 4, '0' ) + "-" + + QString::number(sMonth).rightJustify( 2, '0' ) + + "-" + QString::number(sDay).rightJustify( 2, '0' )+ "'" + "," + + "'" + QString::number(eYear).rightJustify( 4, '0' ) + "-" + + QString::number(eMonth).rightJustify( 2, '0' ) + + "-"+QString::number(eDay).rightJustify( 2, '0' ) + "'" + ")"; - qWarning("add %s", qu.latin1() ); + // Save custom Entries: + int id = 0; + id = 0; + QMap<QString, QString> customMap = m_todo.toExtraMap(); + for( QMap<QString, QString>::Iterator it = customMap.begin(); + it != customMap.end(); ++it ){ + qu += "insert into custom_data VALUES(" + + QString::number( m_todo.uid() ) + + "," + + QString::number( id++ ) + + ",'" + + it.key() + + "'," + + "0" // Priority for future enhancements + + ",'" + + it.data() + + "');"; + } + + + qDebug("add %s", qu.latin1() ); return qu; } RemoveQuery::RemoveQuery(int uid ) : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); @@ -295,49 +338,78 @@ namespace { return qu; } OverDueQuery::OverDueQuery(): OSQLQuery() {} OverDueQuery::~OverDueQuery() {} QString OverDueQuery::query()const { QDate date = QDate::currentDate(); QString str; - str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); + str = QString("select uid from todolist where DueDate ='%1-%2-%3'") + .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( date.day() ) .rightJustify( 2, '0' ) ); return str; } EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} EffQuery::~EffQuery() {} QString EffQuery::query()const { return m_inc ? with() : out(); } QString EffQuery::with()const { 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() ); + .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); 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() ); + .arg( QString::number( m_start.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( m_start.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_start.day() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_end.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( m_end.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( m_end.day() ).rightJustify( 2, '0' ) ); return str; } + + FindCustomQuery::FindCustomQuery(int uid) + : OSQLQuery(), m_uid( uid ) { + } + FindCustomQuery::FindCustomQuery(const QArray<int>& ints) + : OSQLQuery(), m_uids( ints ){ + } + FindCustomQuery::~FindCustomQuery() { + } + QString FindCustomQuery::query()const{ + return single(); // Multiple requests not supported ! + } + QString FindCustomQuery::single()const{ + QString qu = "select uid, type, value from custom_data where uid = "; + qu += QString::number(m_uid); + return qu; + } + }; namespace Opie { OPimTodoAccessBackendSQL::OPimTodoAccessBackendSQL( const QString& file ) - : OPimTodoAccessBackend(), m_dict(15), m_driver(NULL), m_dirty(true) + : OPimTodoAccessBackend(),/* 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(); @@ -378,27 +450,27 @@ QArray<int> OPimTodoAccessBackendSQL::queryByExample( const OPimTodo& , int, con OPimTodo OPimTodoAccessBackendSQL::find(int uid ) const{ FindQuery query( uid ); return todo( m_driver->query(&query) ); } OPimTodo OPimTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, uint cur, Frontend::CacheDirection dir ) const{ uint CACHE = readAhead(); - qWarning("searching for %d", uid ); + qDebug("searching for %d", uid ); QArray<int> search( CACHE ); uint size =0; OPimTodo 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] ); + qDebug("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]; @@ -463,17 +535,17 @@ QArray<int> OPimTodoAccessBackendSQL::effectiveToDos( const QDate& s, EffQuery ef(s, t, u ); return uids (m_driver->query(&ef) ); } /* * */ QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, int sortFilter, int cat ) { - qWarning("sorted %d, %d", asc, sortOrder ); + qDebug("sorted %d, %d", asc, sortOrder ); QString query; query = "select uid from todolist WHERE "; /* * Sort Filter stuff * not that straight forward * FIXME: Replace magic numbers * @@ -484,26 +556,29 @@ QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, if (cat != 0 ) str = QString::number( cat ); query += " categories like '%" +str+"%' AND"; } /* Show only overdue */ if ( sortFilter & 2 ) { QDate date = QDate::currentDate(); QString due; QString base; - base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); + base = QString("DueDate <= '%1-%2-%3' AND completed = 0") + .arg( QString::number( date.year() ).rightJustify( 4, '0' ) ) + .arg( QString::number( date.month() ).rightJustify( 2, '0' ) ) + .arg( QString::number( date.day() ).rightJustify( 2, '0' ) ); query += " " + base + " AND"; } /* not show completed */ if ( sortFilter & 4 ) { query += " completed = 0 AND"; }else{ query += " ( completed = 1 OR completed = 0) AND"; } - /* srtip the end */ + /* strip the end */ query = query.remove( query.length()-3, 3 ); /* * sort order stuff * quite straight forward */ query += "ORDER BY "; @@ -519,63 +594,66 @@ QArray<int> OPimTodoAccessBackendSQL::sorted( bool asc, int sortOrder, query += "summary"; break; case 3: query += "DueDate"; break; } if ( !asc ) { - qWarning("not ascending!"); + qDebug("not ascending!"); query += " DESC"; } - qWarning( query ); + qDebug( query ); OSQLRawQuery raw(query ); return uids( m_driver->query(&raw) ); } bool OPimTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ if ( str == "0-0-0" ) return false; else{ int day, year, month; QStringList list = QStringList::split("-", str ); year = list[0].toInt(); month = list[1].toInt(); day = list[2].toInt(); da.setYMD( year, month, day ); return true; } } -OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res) const{ +OPimTodo OPimTodoAccessBackendSQL::todo( const OSQLResult& res ) const{ if ( res.state() == OSQLResult::Failure ) { OPimTodo to; return to; } OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it = list.begin(); - qWarning("todo1"); + qDebug("todo1"); OPimTodo to = todo( (*it) ); cache( to ); ++it; for ( ; it != list.end(); ++it ) { - qWarning("caching"); + qDebug("caching"); cache( todo( (*it) ) ); } return to; } OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { - qWarning("todo"); + qDebug("todo(ResultItem)"); + + // Request information from addressbook table and create the OPimTodo-object. + bool hasDueDate = false; QDate dueDate = QDate::currentDate(); hasDueDate = date( dueDate, item.data("DueDate") ); QStringList cats = QStringList::split(";", item.data("categories") ); - qWarning("Item is completed: %d", item.data("completed").toInt() ); + qDebug("Item is completed: %d", item.data("completed").toInt() ); OPimTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), cats, item.data("summary"), item.data("description"), item.data("progress").toUShort(), hasDueDate, dueDate, item.data("uid").toInt() ); bool isOk; int prioInt = QString( item.data("priority") ).toInt( &isOk ); @@ -609,26 +687,31 @@ OPimTodo OPimTodoAccessBackendSQL::todo( OSQLResultItem& item )const { recMap.insert( OPimRecurrence::EndDate , item.data("EndDate") ); recMap.insert( OPimRecurrence::Created , item.data("Created") ); recMap.insert( OPimRecurrence::Exceptions , item.data("Exceptions") ); OPimRecurrence recur; recur.fromMap( recMap ); to.setRecurrence( recur ); + // Finally load the custom-entries for this UID and put it into the created object + to.setExtraMap( requestCustom( to.uid() ) ); + return to; } OPimTodo OPimTodoAccessBackendSQL::todo( int uid )const { FindQuery find( uid ); return todo( m_driver->query(&find) ); } /* * update the dict */ void OPimTodoAccessBackendSQL::fillDict() { + +#if 0 /* initialize dict */ /* * UPDATE dict if you change anything!!! * FIXME: Isn't this dict obsolete ? (eilers) */ m_dict.setAutoDelete( TRUE ); m_dict.insert("Categories" , new int(OPimTodo::Category) ); m_dict.insert("Uid" , new int(OPimTodo::Uid) ); @@ -640,16 +723,18 @@ void OPimTodoAccessBackendSQL::fillDict() { m_dict.insert("DateDay" , new int(OPimTodo::DateDay) ); m_dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); m_dict.insert("DateYear" , new int(OPimTodo::DateYear) ); m_dict.insert("Progress" , new int(OPimTodo::Progress) ); m_dict.insert("Completed", new int(OPimTodo::Completed) ); // Why twice ? (eilers) m_dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); // m_dict.insert("HasAlarmDateTime",new int(OPimTodo::HasAlarmDateTime) ); // old stuff (eilers) // m_dict.insert("AlarmDateTime", new int(OPimTodo::AlarmDateTime) ); // old stuff (eilers) + +#endif } /* * need to be const so let's fool the * compiler :( */ void OPimTodoAccessBackendSQL::update()const { ((OPimTodoAccessBackendSQL*)this)->m_dirty = false; LoadQuery lo; @@ -659,17 +744,17 @@ void OPimTodoAccessBackendSQL::update()const { ((OPimTodoAccessBackendSQL*)this)->m_uids = uids( res ); } QArray<int> OPimTodoAccessBackendSQL::uids( const OSQLResult& res) const{ OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; QArray<int> ints(list.count() ); - qWarning(" count = %d", list.count() ); + qDebug(" count = %d", list.count() ); int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } return ints; } @@ -720,9 +805,35 @@ QBitArray OPimTodoAccessBackendSQL::sup() const{ return ar; } void OPimTodoAccessBackendSQL::removeAllCompleted(){ #warning OPimTodoAccessBackendSQL::removeAllCompleted() not implemented !! } + +QMap<QString, QString> OPimTodoAccessBackendSQL::requestCustom( int uid ) const +{ + QMap<QString, QString> customMap; + + FindCustomQuery query( uid ); + OSQLResult res_custom = m_driver->query( &query ); + + if ( res_custom.state() == OSQLResult::Failure ) { + qWarning("OSQLResult::Failure in find query !!"); + QMap<QString, QString> empty; + return empty; + } + + OSQLResultItem::ValueList list = res_custom.results(); + OSQLResultItem::ValueList::Iterator it = list.begin(); + for ( ; it != list.end(); ++it ) { + customMap.insert( (*it).data( "type" ), (*it).data( "value" ) ); + } + + return customMap; +} + + + + } diff --git a/libopie2/opiepim/backend/otodoaccesssql.h b/libopie2/opiepim/backend/otodoaccesssql.h index 0ae2591..0cc7722 100644 --- a/libopie2/opiepim/backend/otodoaccesssql.h +++ b/libopie2/opiepim/backend/otodoaccesssql.h @@ -24,17 +24,17 @@ -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPIE_PIM_ACCESS_SQL_H #define OPIE_PIM_ACCESS_SQL_H -#include <qasciidict.h> +/* #include <qasciidict.h> */ #include <opie2/otodoaccessbackend.h> namespace Opie { namespace DB { class OSQLDriver; class OSQLResult; class OSQLResultItem; @@ -75,18 +75,19 @@ private: void update()const; void fillDict(); inline bool date( QDate& date, const QString& )const; inline OPimTodo todo( const Opie::DB::OSQLResult& )const; inline OPimTodo todo( Opie::DB::OSQLResultItem& )const; inline QArray<int> uids( const Opie::DB::OSQLResult& )const; OPimTodo todo( int uid )const; QBitArray sup() const; + QMap<QString, QString> requestCustom( int uid ) const; - QAsciiDict<int> m_dict; + // QAsciiDict<int> m_dict; Opie::DB::OSQLDriver* m_driver; QArray<int> m_uids; bool m_dirty : 1; }; } #endif diff --git a/libopie2/opiepim/core/opimcontact.h b/libopie2/opiepim/core/opimcontact.h index c08f7ed..9d3cacc 100644 --- a/libopie2/opiepim/core/opimcontact.h +++ b/libopie2/opiepim/core/opimcontact.h @@ -1,11 +1,11 @@ /* This file is part of the Opie Project - Copyright (C) The Main Author <main-author@whereever.org> + Copyright (C) Stefan Eilers <eilers.stefan@handhelds.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, |