summaryrefslogtreecommitdiff
authoreilers <eilers>2003-09-29 07:44:26 (UTC)
committer eilers <eilers>2003-09-29 07:44:26 (UTC)
commit36d6b0096c41b01e69bb0d12e6c29648cbbf8290 (patch) (side-by-side diff)
treec87f4f92c4a1fbdf57e502a9c5e3e44fd9e98540
parentb2e22408970ef548e23e9bbdcd87302f35fc6d4d (diff)
downloadopie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.zip
opie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.tar.gz
opie-36d6b0096c41b01e69bb0d12e6c29648cbbf8290.tar.bz2
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.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_sql.cpp307
-rw-r--r--libopie/pim/ocontactfields.cpp10
-rw-r--r--libopie/pim/otodoaccesssql.cpp90
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp307
-rw-r--r--libopie2/opiepim/backend/otodoaccesssql.cpp90
-rw-r--r--libopie2/opiepim/ocontactfields.cpp10
6 files changed, 732 insertions, 82 deletions
diff --git a/libopie/pim/ocontactaccessbackend_sql.cpp b/libopie/pim/ocontactaccessbackend_sql.cpp
index 4afa5f3..132c9fc 100644
--- a/libopie/pim/ocontactaccessbackend_sql.cpp
+++ b/libopie/pim/ocontactaccessbackend_sql.cpp
@@ -11,12 +11,17 @@
* =====================================================================
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * 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...
*
*/
@@ -34,12 +39,28 @@
#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
+
+
/*
* Implementation of used query types
* CREATE query
* LOAD query
* INSERT
* REMOVE
@@ -137,52 +158,65 @@ namespace {
};
// We using three tables to store the information:
// 1. addressbook : It contains General information about the contact (non custom)
- // 2. dates : Stuff like birthdays, anniversaries, etc.
- // 3. custom_data : Not official supported entries
+ // 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;
+#ifdef __STORE_HORIZONTAL_
+
+ qu += "create table addressbook( uid PRIMARY KEY ";
+
+ QStringList fieldList = OContactFields::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) );";
+
+#else
+
qu += "create table addressbook( 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, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
// qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
+
+#endif // __STORE_HORIZONTAL_
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;";
+// qu += "drop table dates;";
return qu;
}
-// 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
LoadQuery::LoadQuery() : OSQLQuery() {}
LoadQuery::~LoadQuery() {}
QString LoadQuery::query()const {
QString qu;
+#ifdef __STORE_HORIZONTAL_
+ qu += "select uid from addressbook";
+#else
#ifndef __USE_SUPERFAST_LOADQUERY
qu += "select distinct uid from addressbook";
#else
qu += "select uid from addressbook where type = 'Last Name'";
-#endif
+# endif // __USE_SUPERFAST_LOADQUERY
+#endif // __STORE_HORIZONTAL_
return qu;
}
InsertQuery::InsertQuery( const OContact& contact )
@@ -194,16 +228,68 @@ namespace {
/*
* converts from a OContact to a query
*/
QString InsertQuery::query()const{
+#ifdef __STORE_HORIZONTAL_
+ QString qu;
+ qu += "insert into addressbook VALUES( " +
+ QString::number( m_contact.uid() );
+
+ // 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 = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::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() );
+ } else {
+ qu += ",\"\"";
+ }
+ }
+ 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() );
+ } else {
+ qu += ",\"\"";
+ }
+ }
+ break;
+
+ default:
+ qu += QString( ",\"%1\"" ).arg( contactMap[id] );
+ }
+ }
+ qu += " );";
+
+
+#else
// Get all information out of the contact-class
// Remember: The category is stored in contactMap, too !
QMap<int, QString> contactMap = m_contact.toMap();
- QMap<QString, QString> customMap = m_contact.toExtraMap();
QMap<QString, QString> addressbook_db;
// Get the translation from the ID to the String
QMap<int, QString> transMap = OContactFields::idToUntrFields();
@@ -258,14 +344,19 @@ namespace {
+ "0" // Priority for future enhancements
+ ",'"
+ it.data() //.latin1()
+ "');";
}
+#endif //__STORE_HORIZONTAL_
// Now add custom data..
+#ifdef __STORE_HORIZONTAL_
+ int id = 0;
+#endif
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++ )
@@ -274,27 +365,24 @@ namespace {
+ "',"
+ "0" // Priority for future enhancements
+ ",'"
+ it.data() //.latin1()
+ "');";
}
-
// qu += "commit;";
qWarning("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 dates where uid = "
- + QString::number(m_uid) + ";";
qu += "DELETE from custom_data where uid = "
+ QString::number(m_uid) + ";";
return qu;
}
@@ -322,17 +410,27 @@ namespace {
qu += " UID = " + QString::number( m_uids[i] ) + " OR";
}
qu.remove( qu.length()-2, 2 ); // Hmmmm..
return qu;
}
*/
+#ifdef __STORE_HORIZONTAL_
+ QString FindQuery::single()const{
+ QString qu = "select *";
+ qu += " from addressbook where uid = " + QString::number(m_uid);
+
+ // qWarning("find query: %s", qu.latin1() );
+ return qu;
+ }
+#else
QString FindQuery::single()const{
QString qu = "select uid, type, value from addressbook where uid = ";
qu += QString::number(m_uid);
return qu;
}
+#endif
FindCustomQuery::FindCustomQuery(int uid)
: OSQLQuery(), m_uid( uid ) {
}
FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
@@ -372,13 +470,13 @@ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl( m_fileName );
load();
- qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
+ qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
}
bool OContactAccessBackend_SQL::load ()
{
if (!m_driver->open() )
@@ -475,53 +573,144 @@ OContact OContactAccessBackend_SQL::find ( int uid ) const
QTime t;
t.start();
OContact retContact( requestNonCustom( uid ) );
retContact.setExtraMap( requestCustom( uid ) );
- qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
+ qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
return retContact;
}
QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
{
- QArray<int> nix(0);
- return nix;
+ QString qu = "SELECT uid FROM addressbook WHERE";
+
+ QMap<int, QString> queryFields = query.toMap();
+ QStringList fieldList = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::untrFieldsToId();
+
+ // Convert every filled field to a SQL-Query
+ bool isAnyFieldSelected = false;
+ for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
+ int id = translate[*it];
+ QString queryStr = queryFields[id];
+ if ( !queryStr.isEmpty() ){
+ isAnyFieldSelected = true;
+ switch( id ){
+ 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 & OContactAccess::IgnoreCase )
+ qu += "(\"" + *it + "\"" + " LIKE " + "'"
+ + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND ";
+ else
+ qu += "(\"" + *it + "\"" + " GLOB " + "'"
+ + queryStr + "'" + ") AND ";
+
+ }
+ }
+ }
+ // Skip trailing "AND"
+ if ( isAnyFieldSelected )
+ qu = qu.left( qu.length() - 4 );
+
+ qWarning( "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> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
{
QArray<int> nix(0);
return nix;
}
const uint OContactAccessBackend_SQL::querySettings()
{
- return 0;
+ return OContactAccess::IgnoreCase
+ || OContactAccess::WildCards;
}
bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
{
+ /* OContactAccess::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 & (
+ OContactAccess::IgnoreCase
+ | OContactAccess::WildCards
+// | OContactAccess::DateDiff
+// | OContactAccess::DateYear
+// | OContactAccess::DateMonth
+// | OContactAccess::DateDay
+// | OContactAccess::RegExp
+// | OContactAccess::ExactMatch
+ ) ) != querySettings )
return false;
+
+ // Step 2: Check whether the given combinations are ok..
+
+ // IngoreCase alone is invalid
+ if ( querySettings == OContactAccess::IgnoreCase )
+ return false;
+
+ // WildCards, RegExp and ExactMatch should never used at the same time
+ switch ( querySettings & ~( OContactAccess::IgnoreCase
+ | OContactAccess::DateDiff
+ | OContactAccess::DateYear
+ | OContactAccess::DateMonth
+ | OContactAccess::DateDay
+ )
+ ){
+ case OContactAccess::RegExp:
+ return ( true );
+ case OContactAccess::WildCards:
+ return ( true );
+ case OContactAccess::ExactMatch:
+ return ( true );
+ case 0: // one of the upper removed bits were set..
+ return ( true );
+ default:
+ return ( false );
+ }
+
}
QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
{
QTime t;
t.start();
- // Not implemented..
+#ifdef __STORE_HORIZONTAL_
+ QString query = "SELECT uid FROM addressbook ";
+ query += "ORDER BY \"Last Name\" ";
+#else
QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
+ query += "ORDER BY upper( value )";
+#endif
- query += "ORDER BY value ";
if ( !asc )
query += "DESC";
- qWarning("sorted query is: %s", query.latin1() );
+ // qWarning("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;
@@ -549,13 +738,13 @@ void OContactAccessBackend_SQL::update()
return;
m_uids = extractUids( res );
m_changed = false;
- qWarning("Update ends %d", t.elapsed() );
+ qWarning("Update ends %d ms", t.elapsed() );
}
QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
{
qWarning("extractUids");
QTime t;
@@ -573,12 +762,78 @@ QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
return ints;
}
+#ifdef __STORE_HORIZONTAL_
+QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
+{
+ QTime t;
+ t.start();
+
+ QMap<int, QString> nonCustomMap;
+
+ int t2needed = 0;
+ int t3needed = 0;
+ QTime t2;
+ t2.start();
+ FindQuery query( uid );
+ OSQLResult res_noncustom = m_driver->query( &query );
+ t2needed = t2.elapsed();
+
+ OSQLResultItem resItem = res_noncustom.first();
+
+ QTime t3;
+ t3.start();
+ // Now loop through all columns
+ QStringList fieldList = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::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() );
+
+ 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, OConversion::dateToString( date ) );
+ }
+ }
+ break;
+ case Qtopia::AddressCategory:
+ qWarning("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",
+ t.elapsed(), t2needed, t3needed );
+
+ return nonCustomMap;
+}
+#else
+
QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
{
QTime t;
t.start();
QMap<int, QString> nonCustomMap;
@@ -630,16 +885,18 @@ QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
}
}
// Add UID to Map..
nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
t3needed = t3.elapsed();
- qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
+ qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed );
return nonCustomMap;
}
+#endif // __STORE_HORIZONTAL_
+
QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
{
QTime t;
t.start();
QMap<QString, QString> customMap;
@@ -656,9 +913,9 @@ QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) cons
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", t.elapsed() );
+ qWarning("RequestCustom needed: %d ms", t.elapsed() );
return customMap;
}
diff --git a/libopie/pim/ocontactfields.cpp b/libopie/pim/ocontactfields.cpp
index 831a596..7206f0d 100644
--- a/libopie/pim/ocontactfields.cpp
+++ b/libopie/pim/ocontactfields.cpp
@@ -170,12 +170,15 @@ QStringList OContactFields::trfields( bool sorted )
*/
QStringList OContactFields::untrfields( bool sorted )
{
QStringList list;
QMap<int, QString> mapIdToStr = idToUntrFields();
+ list.append( mapIdToStr[ Qtopia::AddressUid ] );
+ list.append( mapIdToStr[ Qtopia::AddressCategory ] );
+
list.append( mapIdToStr[ Qtopia::Title ] );
list.append( mapIdToStr[ Qtopia::FirstName ] );
list.append( mapIdToStr[ Qtopia::MiddleName ] );
list.append( mapIdToStr[ Qtopia::LastName ] );
list.append( mapIdToStr[ Qtopia::Suffix ] );
list.append( mapIdToStr[ Qtopia::FileAs ] );
@@ -208,12 +211,15 @@ QStringList OContactFields::untrfields( bool sorted )
return list;
}
QMap<int, QString> OContactFields::idToTrFields()
{
QMap<int, QString> ret_map;
+ ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) );
+ ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) );
+
ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
@@ -271,12 +277,15 @@ QMap<int, QString> OContactFields::idToTrFields()
}
QMap<int, QString> OContactFields::idToUntrFields()
{
QMap<int, QString> ret_map;
+ ret_map.insert( Qtopia::AddressUid, "User Id" );
+ ret_map.insert( Qtopia::AddressCategory, "Categories" );
+
ret_map.insert( Qtopia::Title, "Name Title" );
ret_map.insert( Qtopia::FirstName, "First Name" );
ret_map.insert( Qtopia::MiddleName, "Middle Name" );
ret_map.insert( Qtopia::LastName, "Last Name" );
ret_map.insert( Qtopia::Suffix, "Suffix" );
ret_map.insert( Qtopia::FileAs, "File As" );
@@ -325,12 +334,13 @@ QMap<int, QString> OContactFields::idToUntrFields()
ret_map.insert( Qtopia::Anniversary, "Anniversary" );
ret_map.insert( Qtopia::Nickname, "Nickname" );
ret_map.insert( Qtopia::Children, "Children" );
// other
ret_map.insert( Qtopia::Notes, "Notes" );
+ ret_map.insert( Qtopia::Groups, "Groups" );
return ret_map;
}
QMap<QString, int> OContactFields::trFieldsToId()
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index 23e0c3e..d255c66 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -115,22 +115,25 @@ namespace {
CreateQuery::CreateQuery() : OSQLQuery() {}
CreateQuery::~CreateQuery() {}
QString CreateQuery::query()const {
QString qu;
- qu += "create table todolist( uid, categories, completed, progress, ";
- qu += "summary, DueDate, priority, description )";
+ qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
+ qu += "description, summary, priority, DueDate, progress , state, ";
+ qu += "Recurrence, notifiers, maintainer, startdate, completeddate)";
return qu;
}
LoadQuery::LoadQuery() : OSQLQuery() {}
LoadQuery::~LoadQuery() {}
QString LoadQuery::query()const {
QString qu;
- qu += "select distinct uid from todolist";
+ // We do not need "distinct" here. The primary key is always unique..
+ //qu += "select distinct uid from todolist";
+ qu += "select uid from todolist";
return qu;
}
InsertQuery::InsertQuery( const OTodo& todo )
: OSQLQuery(), m_todo( todo ) {
@@ -148,17 +151,51 @@ namespace {
if (m_todo.hasDueDate() ) {
QDate date = m_todo.dueDate();
year = date.year();
month = date.month();
day = date.day();
}
+ int sYear = 0, sMonth = 0, sDay = 0;
+ if( m_todo.hasStartDate() ){
+ QDate sDate = m_todo.startDate();
+ sYear = sDate.year();
+ sMonth= sDate.month();
+ sDay = sDate.day();
+ }
+
+ int eYear = 0, eMonth = 0, eDay = 0;
+ if( m_todo.hasCompletedDate() ){
+ QDate eDate = m_todo.completedDate();
+ eYear = eDate.year();
+ eMonth= eDate.month();
+ eDay = eDate.day();
+ }
QString qu;
- qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',";
- qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ",";
- qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',";
- qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')";
+ 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( m_todo.progress() ) + ","
+ + "''" + "," // state (conversion needed)
+// + QString::number( m_todo.state() ) + ","
+ + "''" + "," // Recurrence (conversion needed)
+ + "''" + "," // Notifiers (conversion needed)
+ + "''" + "," // Maintainers (conversion needed)
+ + "'" + QString::number(sYear) + "-"
+ + QString::number(sMonth)
+ + "-" + QString::number(sDay) + "'" + ","
+ + "'" + QString::number(eYear) + "-"
+ + QString::number(eMonth)
+ + "-"+QString::number(eDay) + "'"
+ + ")";
qWarning("add %s", qu.latin1() );
return qu;
}
RemoveQuery::RemoveQuery(int uid )
@@ -189,19 +226,17 @@ namespace {
if (m_uids.count() == 0 )
return single();
else
return multi();
}
QString FindQuery::single()const{
- QString qu = "select uid, categories, completed, progress, summary, ";
- qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
+ QString qu = "select * from todolist where uid = " + QString::number(m_uid);
return qu;
}
QString FindQuery::multi()const {
- QString qu = "select uid, categories, completed, progress, summary, ";
- qu += "DueDate, priority, description from todolist where ";
+ QString qu = "select * from todolist where ";
for (uint i = 0; i < m_uids.count(); i++ ) {
qu += " UID = " + QString::number( m_uids[i] ) + " OR";
}
qu.remove( qu.length()-2, 2 );
return qu;
}
@@ -285,13 +320,13 @@ 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{
- int CACHE = readAhead();
+ uint CACHE = readAhead();
qWarning("searching for %d", uid );
QArray<int> search( CACHE );
uint size =0;
OTodo to;
// we try to cache CACHE items
@@ -469,20 +504,36 @@ OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
cache( todo( (*it) ) );
}
return to;
}
OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
qWarning("todo");
- bool has = false; QDate da = QDate::currentDate();
- has = date( da, item.data("DueDate") );
+ bool hasDueDate = false; QDate dueDate = QDate::currentDate();
+ hasDueDate = date( dueDate, item.data("DueDate") );
QStringList cats = QStringList::split(";", item.data("categories") );
OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
cats, item.data("summary"), item.data("description"),
- item.data("progress").toUShort(), has, da,
+ item.data("progress").toUShort(), hasDueDate, dueDate,
item.data("uid").toInt() );
+
+ bool isOk;
+ int prioInt = QString( item.data("priority") ).toInt( &isOk );
+ if ( isOk )
+ to.setPriority( prioInt );
+
+ bool hasStartDate = false; QDate startDate = QDate::currentDate();
+ hasStartDate = date( startDate, item.data("startdate") );
+ bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
+ hasCompletedDate = date( completedDate, item.data("completeddate") );
+
+ if ( hasStartDate )
+ to.setStartDate( startDate );
+ if ( hasCompletedDate )
+ to.setCompletedDate( completedDate );
+
return to;
}
OTodo OTodoAccessBackendSQL::todo( int uid )const {
FindQuery find( uid );
return todo( m_driver->query(&find) );
}
@@ -567,13 +618,20 @@ QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
#endif
QArray<int> empty;
return empty;
}
QBitArray OTodoAccessBackendSQL::supports()const {
- static QBitArray ar = sup();
+ QBitArray ar( OTodo::CompletedDate + 1 );
+ ar.fill( true );
+ ar[OTodo::CrossReference] = false;
+ ar[OTodo::State ] = false;
+ ar[OTodo::Reminders] = false;
+ ar[OTodo::Notifiers] = false;
+ ar[OTodo::Maintainer] = false;
+
return ar;
}
QBitArray OTodoAccessBackendSQL::sup() {
QBitArray ar( OTodo::CompletedDate + 1 );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index 4afa5f3..132c9fc 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -11,12 +11,17 @@
* =====================================================================
* =====================================================================
* Version: $Id$
* =====================================================================
* History:
* $Log$
+ * 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...
*
*/
@@ -34,12 +39,28 @@
#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
+
+
/*
* Implementation of used query types
* CREATE query
* LOAD query
* INSERT
* REMOVE
@@ -137,52 +158,65 @@ namespace {
};
// We using three tables to store the information:
// 1. addressbook : It contains General information about the contact (non custom)
- // 2. dates : Stuff like birthdays, anniversaries, etc.
- // 3. custom_data : Not official supported entries
+ // 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;
+#ifdef __STORE_HORIZONTAL_
+
+ qu += "create table addressbook( uid PRIMARY KEY ";
+
+ QStringList fieldList = OContactFields::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) );";
+
+#else
+
qu += "create table addressbook( 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, priority INTEGER, value VARCHAR, PRIMARY KEY /* identifier */ (uid, id) );";
// qu += "create table dates( uid PRIMARY KEY, type, day, month, year, hour, minute, second );";
+
+#endif // __STORE_HORIZONTAL_
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;";
+// qu += "drop table dates;";
return qu;
}
-// 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
LoadQuery::LoadQuery() : OSQLQuery() {}
LoadQuery::~LoadQuery() {}
QString LoadQuery::query()const {
QString qu;
+#ifdef __STORE_HORIZONTAL_
+ qu += "select uid from addressbook";
+#else
#ifndef __USE_SUPERFAST_LOADQUERY
qu += "select distinct uid from addressbook";
#else
qu += "select uid from addressbook where type = 'Last Name'";
-#endif
+# endif // __USE_SUPERFAST_LOADQUERY
+#endif // __STORE_HORIZONTAL_
return qu;
}
InsertQuery::InsertQuery( const OContact& contact )
@@ -194,16 +228,68 @@ namespace {
/*
* converts from a OContact to a query
*/
QString InsertQuery::query()const{
+#ifdef __STORE_HORIZONTAL_
+ QString qu;
+ qu += "insert into addressbook VALUES( " +
+ QString::number( m_contact.uid() );
+
+ // 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 = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::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() );
+ } else {
+ qu += ",\"\"";
+ }
+ }
+ 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() );
+ } else {
+ qu += ",\"\"";
+ }
+ }
+ break;
+
+ default:
+ qu += QString( ",\"%1\"" ).arg( contactMap[id] );
+ }
+ }
+ qu += " );";
+
+
+#else
// Get all information out of the contact-class
// Remember: The category is stored in contactMap, too !
QMap<int, QString> contactMap = m_contact.toMap();
- QMap<QString, QString> customMap = m_contact.toExtraMap();
QMap<QString, QString> addressbook_db;
// Get the translation from the ID to the String
QMap<int, QString> transMap = OContactFields::idToUntrFields();
@@ -258,14 +344,19 @@ namespace {
+ "0" // Priority for future enhancements
+ ",'"
+ it.data() //.latin1()
+ "');";
}
+#endif //__STORE_HORIZONTAL_
// Now add custom data..
+#ifdef __STORE_HORIZONTAL_
+ int id = 0;
+#endif
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++ )
@@ -274,27 +365,24 @@ namespace {
+ "',"
+ "0" // Priority for future enhancements
+ ",'"
+ it.data() //.latin1()
+ "');";
}
-
// qu += "commit;";
qWarning("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 dates where uid = "
- + QString::number(m_uid) + ";";
qu += "DELETE from custom_data where uid = "
+ QString::number(m_uid) + ";";
return qu;
}
@@ -322,17 +410,27 @@ namespace {
qu += " UID = " + QString::number( m_uids[i] ) + " OR";
}
qu.remove( qu.length()-2, 2 ); // Hmmmm..
return qu;
}
*/
+#ifdef __STORE_HORIZONTAL_
+ QString FindQuery::single()const{
+ QString qu = "select *";
+ qu += " from addressbook where uid = " + QString::number(m_uid);
+
+ // qWarning("find query: %s", qu.latin1() );
+ return qu;
+ }
+#else
QString FindQuery::single()const{
QString qu = "select uid, type, value from addressbook where uid = ";
qu += QString::number(m_uid);
return qu;
}
+#endif
FindCustomQuery::FindCustomQuery(int uid)
: OSQLQuery(), m_uid( uid ) {
}
FindCustomQuery::FindCustomQuery(const QArray<int>& ints)
@@ -372,13 +470,13 @@ OContactAccessBackend_SQL::OContactAccessBackend_SQL ( const QString& /* appname
OSQLManager man;
m_driver = man.standard();
m_driver->setUrl( m_fileName );
load();
- qWarning("C'tor OContactAccessBackend_SQL ends: %d", t.elapsed() );
+ qWarning("C'tor OContactAccessBackend_SQL ends: %d ms", t.elapsed() );
}
bool OContactAccessBackend_SQL::load ()
{
if (!m_driver->open() )
@@ -475,53 +573,144 @@ OContact OContactAccessBackend_SQL::find ( int uid ) const
QTime t;
t.start();
OContact retContact( requestNonCustom( uid ) );
retContact.setExtraMap( requestCustom( uid ) );
- qWarning("OContactAccessBackend_SQL::find() needed: %d", t.elapsed() );
+ qWarning("OContactAccessBackend_SQL::find() needed: %d ms", t.elapsed() );
return retContact;
}
QArray<int> OContactAccessBackend_SQL::queryByExample ( const OContact &query, int settings, const QDateTime& d = QDateTime() )
{
- QArray<int> nix(0);
- return nix;
+ QString qu = "SELECT uid FROM addressbook WHERE";
+
+ QMap<int, QString> queryFields = query.toMap();
+ QStringList fieldList = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::untrFieldsToId();
+
+ // Convert every filled field to a SQL-Query
+ bool isAnyFieldSelected = false;
+ for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){
+ int id = translate[*it];
+ QString queryStr = queryFields[id];
+ if ( !queryStr.isEmpty() ){
+ isAnyFieldSelected = true;
+ switch( id ){
+ 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 & OContactAccess::IgnoreCase )
+ qu += "(\"" + *it + "\"" + " LIKE " + "'"
+ + queryStr.replace(QRegExp("\\*"),"%") + "'" + ") AND ";
+ else
+ qu += "(\"" + *it + "\"" + " GLOB " + "'"
+ + queryStr + "'" + ") AND ";
+
+ }
+ }
+ }
+ // Skip trailing "AND"
+ if ( isAnyFieldSelected )
+ qu = qu.left( qu.length() - 4 );
+
+ qWarning( "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> OContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const
{
QArray<int> nix(0);
return nix;
}
const uint OContactAccessBackend_SQL::querySettings()
{
- return 0;
+ return OContactAccess::IgnoreCase
+ || OContactAccess::WildCards;
}
bool OContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const
{
+ /* OContactAccess::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 & (
+ OContactAccess::IgnoreCase
+ | OContactAccess::WildCards
+// | OContactAccess::DateDiff
+// | OContactAccess::DateYear
+// | OContactAccess::DateMonth
+// | OContactAccess::DateDay
+// | OContactAccess::RegExp
+// | OContactAccess::ExactMatch
+ ) ) != querySettings )
return false;
+
+ // Step 2: Check whether the given combinations are ok..
+
+ // IngoreCase alone is invalid
+ if ( querySettings == OContactAccess::IgnoreCase )
+ return false;
+
+ // WildCards, RegExp and ExactMatch should never used at the same time
+ switch ( querySettings & ~( OContactAccess::IgnoreCase
+ | OContactAccess::DateDiff
+ | OContactAccess::DateYear
+ | OContactAccess::DateMonth
+ | OContactAccess::DateDay
+ )
+ ){
+ case OContactAccess::RegExp:
+ return ( true );
+ case OContactAccess::WildCards:
+ return ( true );
+ case OContactAccess::ExactMatch:
+ return ( true );
+ case 0: // one of the upper removed bits were set..
+ return ( true );
+ default:
+ return ( false );
+ }
+
}
QArray<int> OContactAccessBackend_SQL::sorted( bool asc, int , int , int )
{
QTime t;
t.start();
- // Not implemented..
+#ifdef __STORE_HORIZONTAL_
+ QString query = "SELECT uid FROM addressbook ";
+ query += "ORDER BY \"Last Name\" ";
+#else
QString query = "SELECT uid FROM addressbook WHERE type = 'Last Name' ";
+ query += "ORDER BY upper( value )";
+#endif
- query += "ORDER BY value ";
if ( !asc )
query += "DESC";
- qWarning("sorted query is: %s", query.latin1() );
+ // qWarning("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;
@@ -549,13 +738,13 @@ void OContactAccessBackend_SQL::update()
return;
m_uids = extractUids( res );
m_changed = false;
- qWarning("Update ends %d", t.elapsed() );
+ qWarning("Update ends %d ms", t.elapsed() );
}
QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
{
qWarning("extractUids");
QTime t;
@@ -573,12 +762,78 @@ QArray<int> OContactAccessBackend_SQL::extractUids( OSQLResult& res ) const
qWarning("extractUids ready: count2 = %d needs %d ms", i, t.elapsed() );
return ints;
}
+#ifdef __STORE_HORIZONTAL_
+QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
+{
+ QTime t;
+ t.start();
+
+ QMap<int, QString> nonCustomMap;
+
+ int t2needed = 0;
+ int t3needed = 0;
+ QTime t2;
+ t2.start();
+ FindQuery query( uid );
+ OSQLResult res_noncustom = m_driver->query( &query );
+ t2needed = t2.elapsed();
+
+ OSQLResultItem resItem = res_noncustom.first();
+
+ QTime t3;
+ t3.start();
+ // Now loop through all columns
+ QStringList fieldList = OContactFields::untrfields( false );
+ QMap<QString, int> translate = OContactFields::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() );
+
+ 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, OConversion::dateToString( date ) );
+ }
+ }
+ break;
+ case Qtopia::AddressCategory:
+ qWarning("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",
+ t.elapsed(), t2needed, t3needed );
+
+ return nonCustomMap;
+}
+#else
+
QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
{
QTime t;
t.start();
QMap<int, QString> nonCustomMap;
@@ -630,16 +885,18 @@ QMap<int, QString> OContactAccessBackend_SQL::requestNonCustom( int uid ) const
}
}
// Add UID to Map..
nonCustomMap.insert( Qtopia::AddressUid, QString::number( uid ) );
t3needed = t3.elapsed();
- qWarning("RequestNonCustom needed: ins:%d, query: %d, mapping: %d", t.elapsed(), t2needed, t3needed );
+ qWarning("RequestNonCustom needed: insg.:%d ms, query: %d ms, mapping: %d ms", t.elapsed(), t2needed, t3needed );
return nonCustomMap;
}
+#endif // __STORE_HORIZONTAL_
+
QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) const
{
QTime t;
t.start();
QMap<QString, QString> customMap;
@@ -656,9 +913,9 @@ QMap<QString, QString> OContactAccessBackend_SQL::requestCustom( int uid ) cons
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", t.elapsed() );
+ qWarning("RequestCustom needed: %d ms", t.elapsed() );
return customMap;
}
diff --git a/libopie2/opiepim/backend/otodoaccesssql.cpp b/libopie2/opiepim/backend/otodoaccesssql.cpp
index 23e0c3e..d255c66 100644
--- a/libopie2/opiepim/backend/otodoaccesssql.cpp
+++ b/libopie2/opiepim/backend/otodoaccesssql.cpp
@@ -115,22 +115,25 @@ namespace {
CreateQuery::CreateQuery() : OSQLQuery() {}
CreateQuery::~CreateQuery() {}
QString CreateQuery::query()const {
QString qu;
- qu += "create table todolist( uid, categories, completed, progress, ";
- qu += "summary, DueDate, priority, description )";
+ qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
+ qu += "description, summary, priority, DueDate, progress , state, ";
+ qu += "Recurrence, notifiers, maintainer, startdate, completeddate)";
return qu;
}
LoadQuery::LoadQuery() : OSQLQuery() {}
LoadQuery::~LoadQuery() {}
QString LoadQuery::query()const {
QString qu;
- qu += "select distinct uid from todolist";
+ // We do not need "distinct" here. The primary key is always unique..
+ //qu += "select distinct uid from todolist";
+ qu += "select uid from todolist";
return qu;
}
InsertQuery::InsertQuery( const OTodo& todo )
: OSQLQuery(), m_todo( todo ) {
@@ -148,17 +151,51 @@ namespace {
if (m_todo.hasDueDate() ) {
QDate date = m_todo.dueDate();
year = date.year();
month = date.month();
day = date.day();
}
+ int sYear = 0, sMonth = 0, sDay = 0;
+ if( m_todo.hasStartDate() ){
+ QDate sDate = m_todo.startDate();
+ sYear = sDate.year();
+ sMonth= sDate.month();
+ sDay = sDate.day();
+ }
+
+ int eYear = 0, eMonth = 0, eDay = 0;
+ if( m_todo.hasCompletedDate() ){
+ QDate eDate = m_todo.completedDate();
+ eYear = eDate.year();
+ eMonth= eDate.month();
+ eDay = eDate.day();
+ }
QString qu;
- qu = "insert into todolist VALUES(" + QString::number( m_todo.uid() ) + ",'" + m_todo.idsToString( m_todo.categories() ) + "',";
- qu += QString::number( m_todo.isCompleted() ) + "," + QString::number( m_todo.progress() ) + ",";
- qu += "'"+m_todo.summary()+"','"+QString::number(year)+"-"+QString::number(month)+"-"+QString::number(day)+"',";
- qu += QString::number(m_todo.priority() ) +",'" + m_todo.description() + "')";
+ 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( m_todo.progress() ) + ","
+ + "''" + "," // state (conversion needed)
+// + QString::number( m_todo.state() ) + ","
+ + "''" + "," // Recurrence (conversion needed)
+ + "''" + "," // Notifiers (conversion needed)
+ + "''" + "," // Maintainers (conversion needed)
+ + "'" + QString::number(sYear) + "-"
+ + QString::number(sMonth)
+ + "-" + QString::number(sDay) + "'" + ","
+ + "'" + QString::number(eYear) + "-"
+ + QString::number(eMonth)
+ + "-"+QString::number(eDay) + "'"
+ + ")";
qWarning("add %s", qu.latin1() );
return qu;
}
RemoveQuery::RemoveQuery(int uid )
@@ -189,19 +226,17 @@ namespace {
if (m_uids.count() == 0 )
return single();
else
return multi();
}
QString FindQuery::single()const{
- QString qu = "select uid, categories, completed, progress, summary, ";
- qu += "DueDate, priority, description from todolist where uid = " + QString::number(m_uid);
+ QString qu = "select * from todolist where uid = " + QString::number(m_uid);
return qu;
}
QString FindQuery::multi()const {
- QString qu = "select uid, categories, completed, progress, summary, ";
- qu += "DueDate, priority, description from todolist where ";
+ QString qu = "select * from todolist where ";
for (uint i = 0; i < m_uids.count(); i++ ) {
qu += " UID = " + QString::number( m_uids[i] ) + " OR";
}
qu.remove( qu.length()-2, 2 );
return qu;
}
@@ -285,13 +320,13 @@ 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{
- int CACHE = readAhead();
+ uint CACHE = readAhead();
qWarning("searching for %d", uid );
QArray<int> search( CACHE );
uint size =0;
OTodo to;
// we try to cache CACHE items
@@ -469,20 +504,36 @@ OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
cache( todo( (*it) ) );
}
return to;
}
OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
qWarning("todo");
- bool has = false; QDate da = QDate::currentDate();
- has = date( da, item.data("DueDate") );
+ bool hasDueDate = false; QDate dueDate = QDate::currentDate();
+ hasDueDate = date( dueDate, item.data("DueDate") );
QStringList cats = QStringList::split(";", item.data("categories") );
OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
cats, item.data("summary"), item.data("description"),
- item.data("progress").toUShort(), has, da,
+ item.data("progress").toUShort(), hasDueDate, dueDate,
item.data("uid").toInt() );
+
+ bool isOk;
+ int prioInt = QString( item.data("priority") ).toInt( &isOk );
+ if ( isOk )
+ to.setPriority( prioInt );
+
+ bool hasStartDate = false; QDate startDate = QDate::currentDate();
+ hasStartDate = date( startDate, item.data("startdate") );
+ bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
+ hasCompletedDate = date( completedDate, item.data("completeddate") );
+
+ if ( hasStartDate )
+ to.setStartDate( startDate );
+ if ( hasCompletedDate )
+ to.setCompletedDate( completedDate );
+
return to;
}
OTodo OTodoAccessBackendSQL::todo( int uid )const {
FindQuery find( uid );
return todo( m_driver->query(&find) );
}
@@ -567,13 +618,20 @@ QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
#endif
QArray<int> empty;
return empty;
}
QBitArray OTodoAccessBackendSQL::supports()const {
- static QBitArray ar = sup();
+ QBitArray ar( OTodo::CompletedDate + 1 );
+ ar.fill( true );
+ ar[OTodo::CrossReference] = false;
+ ar[OTodo::State ] = false;
+ ar[OTodo::Reminders] = false;
+ ar[OTodo::Notifiers] = false;
+ ar[OTodo::Maintainer] = false;
+
return ar;
}
QBitArray OTodoAccessBackendSQL::sup() {
QBitArray ar( OTodo::CompletedDate + 1 );
diff --git a/libopie2/opiepim/ocontactfields.cpp b/libopie2/opiepim/ocontactfields.cpp
index 831a596..7206f0d 100644
--- a/libopie2/opiepim/ocontactfields.cpp
+++ b/libopie2/opiepim/ocontactfields.cpp
@@ -170,12 +170,15 @@ QStringList OContactFields::trfields( bool sorted )
*/
QStringList OContactFields::untrfields( bool sorted )
{
QStringList list;
QMap<int, QString> mapIdToStr = idToUntrFields();
+ list.append( mapIdToStr[ Qtopia::AddressUid ] );
+ list.append( mapIdToStr[ Qtopia::AddressCategory ] );
+
list.append( mapIdToStr[ Qtopia::Title ] );
list.append( mapIdToStr[ Qtopia::FirstName ] );
list.append( mapIdToStr[ Qtopia::MiddleName ] );
list.append( mapIdToStr[ Qtopia::LastName ] );
list.append( mapIdToStr[ Qtopia::Suffix ] );
list.append( mapIdToStr[ Qtopia::FileAs ] );
@@ -208,12 +211,15 @@ QStringList OContactFields::untrfields( bool sorted )
return list;
}
QMap<int, QString> OContactFields::idToTrFields()
{
QMap<int, QString> ret_map;
+ ret_map.insert( Qtopia::AddressUid, QObject::tr( "User Id" ) );
+ ret_map.insert( Qtopia::AddressCategory, QObject::tr( "Categories" ) );
+
ret_map.insert( Qtopia::Title, QObject::tr( "Name Title") );
ret_map.insert( Qtopia::FirstName, QObject::tr( "First Name" ) );
ret_map.insert( Qtopia::MiddleName, QObject::tr( "Middle Name" ) );
ret_map.insert( Qtopia::LastName, QObject::tr( "Last Name" ) );
ret_map.insert( Qtopia::Suffix, QObject::tr( "Suffix" ));
ret_map.insert( Qtopia::FileAs, QObject::tr( "File As" ) );
@@ -271,12 +277,15 @@ QMap<int, QString> OContactFields::idToTrFields()
}
QMap<int, QString> OContactFields::idToUntrFields()
{
QMap<int, QString> ret_map;
+ ret_map.insert( Qtopia::AddressUid, "User Id" );
+ ret_map.insert( Qtopia::AddressCategory, "Categories" );
+
ret_map.insert( Qtopia::Title, "Name Title" );
ret_map.insert( Qtopia::FirstName, "First Name" );
ret_map.insert( Qtopia::MiddleName, "Middle Name" );
ret_map.insert( Qtopia::LastName, "Last Name" );
ret_map.insert( Qtopia::Suffix, "Suffix" );
ret_map.insert( Qtopia::FileAs, "File As" );
@@ -325,12 +334,13 @@ QMap<int, QString> OContactFields::idToUntrFields()
ret_map.insert( Qtopia::Anniversary, "Anniversary" );
ret_map.insert( Qtopia::Nickname, "Nickname" );
ret_map.insert( Qtopia::Children, "Children" );
// other
ret_map.insert( Qtopia::Notes, "Notes" );
+ ret_map.insert( Qtopia::Groups, "Groups" );
return ret_map;
}
QMap<QString, int> OContactFields::trFieldsToId()