Diffstat (limited to 'libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 180 |
1 files changed, 123 insertions, 57 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 @@ -30,43 +30,44 @@ * SQL Backend for the OPIE-Contact Database. */ #include "ocontactaccessbackend_sql.h" #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; }; /** * Clears (delete) a Table @@ -141,43 +142,43 @@ namespace Opie { FindCustomQuery(const QArray<int>& ); ~FindCustomQuery(); QString query()const; private: 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; 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 { QString qu = "drop table addressbook;"; qu += "drop table custom_data;"; // qu += "drop table dates;"; return qu; @@ -212,80 +213,71 @@ namespace Opie { // Get all information out of the contact-class // Remember: The category is stored in contactMap, too ! QMap<int, QString> contactMap = m_contact.toMap(); 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.. int id = 0; id = 0; 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 { QString qu = "DELETE from addressbook where uid = " + QString::number(m_uid) + ";"; qu += "DELETE from custom_data where uid = " + QString::number(m_uid) + ";"; @@ -349,42 +341,42 @@ 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; } bool OPimContactAccessBackend_SQL::load () { if (!m_driver->open() ) return false; @@ -467,113 +459,187 @@ bool OPimContactAccessBackend_SQL::remove ( int uid ) bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) { if ( !remove( contact.uid() ) ) 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; } QArray<int> list = extractUids( res ); return list; } 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 if ( querySettings == OPimContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time @@ -600,77 +666,77 @@ bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) { QTime t; 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; t.start(); QMap<int, QString> nonCustomMap; @@ -687,54 +753,54 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co QTime t3; t3.start(); // Now loop through all columns QStringList fieldList = OPimContactFields::untrfields( false ); 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(); int month = (*(++lit)).toInt(); 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; t.start(); QMap<QString, QString> customMap; @@ -744,17 +810,17 @@ QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) c 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" ) ); } - qWarning("RequestCustom needed: %d ms", t.elapsed() ); + qDebug("RequestCustom needed: %d ms", t.elapsed() ); return customMap; } } |