Skip to content

Commit

Permalink
[qtcontacts-sqlite] Allow enum property extensions to be stored. Cont…
Browse files Browse the repository at this point in the history
…ributes to MER#1368

Due to the schema originating to support the QtMobility.Contacts API
we store some properties in string form, when the qtpim API now uses
user-extensible enum values. Passing all values through a translation
step that only knows the predefined values causes extension values to
be lost.

To fix this problem, perform a schema upgrade in which all pre-existing
text values are converted to the equivalent enum value. In some cases
the column containing these values should be typed as INTEGER, when
in fact it is typed as TEXT. To avoid changing the columns, the read
and write routines for these columns manually translate between text
and integral form.
  • Loading branch information
matthewvogt committed Oct 13, 2015
1 parent bd16866 commit 4b06f2f
Show file tree
Hide file tree
Showing 5 changed files with 403 additions and 57 deletions.
58 changes: 28 additions & 30 deletions src/engine/contactreader.cpp
Expand Up @@ -31,7 +31,6 @@

#include "contactreader.h"
#include "contactsengine.h"
#include "conversion_p.h"
#include "trace_p.h"

#include "../extensions/qtcontacts-extensions.h"
Expand Down Expand Up @@ -79,8 +78,6 @@

#include <QtDebug>

using namespace Conversion;

static const int ReportBatchSize = 50;

static const QString aggregateSyncTarget(QString::fromLatin1("aggregate"));
Expand Down Expand Up @@ -203,6 +200,15 @@ static const FieldInfo addressFields[] =

};

static QList<int> subTypeList(const QStringList &subTypeValues)
{
QList<int> rv;
foreach (const QString &value, subTypeValues) {
rv.append(value.toInt());
}
return rv;
}

static void setValues(QContactAddress *detail, QSqlQuery *query, const int offset)
{
typedef QContactAddress T;
Expand All @@ -213,9 +219,8 @@ static void setValues(QContactAddress *detail, QSqlQuery *query, const int offse
setValue(detail, T::FieldLocality , query->value(offset + 3));
setValue(detail, T::FieldPostcode , query->value(offset + 4));
setValue(detail, T::FieldCountry , query->value(offset + 5));
QStringList subTypeNames(query->value(offset + 6).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes , QVariant::fromValue<QList<int> >(Address::subTypeList(subTypeNames)));

const QStringList subTypeValues(query->value(offset + 6).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes , QVariant::fromValue<QList<int> >(subTypeList(subTypeValues)));
}

static const FieldInfo anniversaryFields[] =
Expand All @@ -232,7 +237,7 @@ static void setValues(QContactAnniversary *detail, QSqlQuery *query, const int o

setValue(detail, T::FieldOriginalDate, dateValue(query->value(offset + 0)));
setValue(detail, T::FieldCalendarId , query->value(offset + 1));
setValue(detail, T::FieldSubType , QVariant::fromValue<int>(Anniversary::subType(query->value(offset + 2).toString())));
setValue(detail, T::FieldSubType , QVariant::fromValue<int>(query->value(offset + 2).toString().toInt()));
setValue(detail, T::FieldEvent , query->value(offset + 3));
}

Expand Down Expand Up @@ -394,12 +399,12 @@ static void setValues(QContactOnlineAccount *detail, QSqlQuery *query, const int

setValue(detail, T::FieldAccountUri , query->value(offset + 0));
// ignore lowerAccountUri
setValue(detail, T::FieldProtocol , QVariant::fromValue<int>(OnlineAccount::protocol(query->value(offset + 2).toString())));
setValue(detail, T::FieldProtocol , QVariant::fromValue<int>(query->value(offset + 2).toString().toInt()));
setValue(detail, T::FieldServiceProvider, query->value(offset + 3));
setValue(detail, T::FieldCapabilities , stringListValue(query->value(offset + 4)));

QStringList subTypeNames(query->value(offset + 5).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes, QVariant::fromValue<QList<int> >(OnlineAccount::subTypeList(subTypeNames)));
const QStringList subTypeValues(query->value(offset + 5).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes, QVariant::fromValue<QList<int> >(subTypeList(subTypeValues)));

setValue(detail, QContactOnlineAccount__FieldAccountPath, query->value(offset + 6));
setValue(detail, QContactOnlineAccount__FieldAccountIconPath, query->value(offset + 7));
Expand Down Expand Up @@ -445,8 +450,8 @@ static void setValues(QContactPhoneNumber *detail, QSqlQuery *query, const int o

setValue(detail, T::FieldNumber , query->value(offset + 0));

QStringList subTypeNames(query->value(offset + 1).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes, QVariant::fromValue<QList<int> >(PhoneNumber::subTypeList(subTypeNames)));
const QStringList subTypeValues(query->value(offset + 1).toString().split(QLatin1Char(';'), QString::SkipEmptyParts));
setValue(detail, T::FieldSubTypes, QVariant::fromValue<QList<int> >(subTypeList(subTypeValues)));

setValue(detail, QContactPhoneNumber__FieldNormalizedNumber, query->value(offset + 2));
}
Expand Down Expand Up @@ -516,15 +521,15 @@ static void setValues(QContactTag *detail, QSqlQuery *query, const int offset)
static const FieldInfo urlFields[] =
{
{ QContactUrl::FieldUrl, "url", StringField },
{ QContactUrl::FieldSubType, "subTypes", StringListField }
{ QContactUrl::FieldSubType, "subTypes", StringField }
};

static void setValues(QContactUrl *detail, QSqlQuery *query, const int offset)
{
typedef QContactUrl T;

setValue(detail, T::FieldUrl , urlValue(query->value(offset + 0)));
setValue(detail, T::FieldSubType, QVariant::fromValue<int>(Url::subType(query->value(offset + 1).toString())));
setValue(detail, T::FieldSubType, QVariant::fromValue<int>(query->value(offset + 1).toString().toInt()));
}

static const FieldInfo originMetadataFields[] =
Expand Down Expand Up @@ -833,30 +838,30 @@ static bool validFilterField(F filter)

static QString convertFilterValueToString(const QContactDetailFilter &filter, const QString &defaultValue)
{
// Some enum types are stored in textual form
// Some enum values are stored in textual columns
if (filter.detailType() == QContactOnlineAccount::Type) {
if (filter.detailField() == QContactOnlineAccount::FieldProtocol) {
return OnlineAccount::protocol(filter.value().toInt());
return QString::number(filter.value().toInt());
} else if (filter.detailField() == QContactOnlineAccount::FieldSubTypes) {
// TODO: what if the value is a list?
return OnlineAccount::subTypeList(QList<int>() << filter.value().toInt()).first();
return QString::number(filter.value().toInt());
}
} else if (filter.detailType() == QContactPhoneNumber::Type) {
if (filter.detailField() == QContactPhoneNumber::FieldSubTypes) {
// TODO: what if the value is a list?
return PhoneNumber::subTypeList(QList<int>() << filter.value().toInt()).first();
return QString::number(filter.value().toInt());
}
} else if (filter.detailType() == QContactAnniversary::Type) {
if (filter.detailField() == QContactAnniversary::FieldSubType) {
return Anniversary::subType(filter.value().toInt());
return QString::number(filter.value().toInt());
}
} else if (filter.detailType() == QContactUrl::Type) {
if (filter.detailField() == QContactUrl::FieldSubType) {
return Url::subType(filter.value().toInt());
return QString::number(filter.value().toInt());
}
} else if (filter.detailType() == QContactGender::Type) {
if (filter.detailField() == QContactGender::FieldGender) {
return Gender::gender(filter.value().toInt());
return QString::number(filter.value().toInt());
}
}

Expand Down Expand Up @@ -2139,15 +2144,8 @@ QContactManager::Error ContactReader::queryContacts(
QContactGender gender;
// Gender is an enum in qtpim
QString genderText = contactQuery.value(13).toString();
if (genderText.startsWith(QChar::fromLatin1('f'), Qt::CaseInsensitive)) {
gender.setGender(QContactGender::GenderFemale);
} else if (genderText.startsWith(QChar::fromLatin1('m'), Qt::CaseInsensitive)) {
gender.setGender(QContactGender::GenderMale);
} else {
gender.setGender(QContactGender::GenderUnspecified);
}
if (!gender.isEmpty())
contact.saveDetail(&gender);
gender.setGender(static_cast<QContactGender::GenderField>(genderText.toInt()));
contact.saveDetail(&gender);

QContactFavorite favorite;
setValue(&favorite, QContactFavorite::FieldFavorite, contactQuery.value(14).toBool());
Expand Down

0 comments on commit 4b06f2f

Please sign in to comment.