qtmobility/src/contacts/engines/qcontactmemorybackend.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    51 #include "qcontactmemorybackend_p.h"
    51 #include "qcontactmemorybackend_p.h"
    52 
    52 
    53 #include <QTimer>
    53 #include <QTimer>
    54 #include <QUuid>
    54 #include <QUuid>
    55 #include <QSharedData>
    55 #include <QSharedData>
       
    56 #include <QDebug>
       
    57 
    56 QTM_BEGIN_NAMESPACE
    58 QTM_BEGIN_NAMESPACE
    57 
    59 
    58 /*!
    60 /*!
    59   \class QContactMemoryEngine
    61   \class QContactMemoryEngine
    60   \brief The QContactMemoryEngine class provides an in-memory implementation
    62   \brief The QContactMemoryEngine class provides an in-memory implementation
    72   whenever a manager uses this backend, and is decreased when the manager
    74   whenever a manager uses this backend, and is decreased when the manager
    73   no longer requires this engine.
    75   no longer requires this engine.
    74  */
    76  */
    75 
    77 
    76 /* static data for manager class */
    78 /* static data for manager class */
    77 QMap<QString, QContactMemoryEngine*> QContactMemoryEngine::engines;
    79 QMap<QString, QContactMemoryEngineData*> QContactMemoryEngine::engineDatas;
    78 
    80 
    79 /*!
    81 /*!
    80  * Factory function for creating a new in-memory backend, based
    82  * Factory function for creating a new in-memory backend, based
    81  * on the given \a parameters.
    83  * on the given \a parameters.
    82  *
    84  *
    91         // no store given?  new, anonymous store.
    93         // no store given?  new, anonymous store.
    92         idValue = QUuid::createUuid().toString();
    94         idValue = QUuid::createUuid().toString();
    93         anonymous = true;
    95         anonymous = true;
    94     }
    96     }
    95 
    97 
    96     if (engines.contains(idValue)) {
    98     QContactMemoryEngineData* data = engineDatas.value(idValue);
    97         QContactMemoryEngine *engine = engines.value(idValue);
    99     if (data) {
    98         engine->d->m_refCount.ref();
   100         data->m_refCount.ref();
    99         engine->d->m_anonymous = anonymous;
       
   100         return engine;
       
   101     } else {
   101     } else {
   102         QContactMemoryEngine *engine = new QContactMemoryEngine(parameters);
   102         data = new QContactMemoryEngineData();
   103         engine->d->m_engineName = QString(QLatin1String("memory"));
   103         data->m_id = idValue;
   104         engine->d->m_engineVersion = 1;
   104         data->m_anonymous = anonymous;
   105         engine->d->m_id = idValue;
   105         engineDatas.insert(idValue, data);
   106         engine->d->m_anonymous = anonymous;
   106     }
   107         engines.insert(idValue, engine);
   107     return new QContactMemoryEngine(data);
   108         return engine;
       
   109     }
       
   110 }
   108 }
   111 
   109 
   112 /*!
   110 /*!
   113  * Constructs a new in-memory backend.
   111  * Constructs a new in-memory backend which shares the given \a data with
   114  *
   112  * other shared memory engines.
   115  * Loads the in-memory data associated with the memory store identified by the "id" parameter
       
   116  * from the given \a parameters if it exists, or a new, anonymous store if it does not.
       
   117  */
   113  */
   118 QContactMemoryEngine::QContactMemoryEngine(const QMap<QString, QString>& parameters)
   114 QContactMemoryEngine::QContactMemoryEngine(QContactMemoryEngineData* data)
   119     : d(new QContactMemoryEngineData)
   115     : d(data)
   120 {
   116 {
   121     Q_UNUSED(parameters);
   117     d->m_sharedEngines.append(this);
   122 }
   118 }
   123 
   119 
   124 /*! \reimp */
   120 /*! Frees any memory used by this engine */
   125 void QContactMemoryEngine::deref()
   121 QContactMemoryEngine::~QContactMemoryEngine()
   126 {
   122 {
       
   123     d->m_sharedEngines.removeAll(this);
   127     if (!d->m_refCount.deref()) {
   124     if (!d->m_refCount.deref()) {
   128         engines.remove(d->m_id);
   125         engineDatas.remove(d->m_id);
   129         delete d;
   126         delete d;
   130         delete this;
       
   131     }
   127     }
   132 }
   128 }
   133 
   129 
   134 /*! \reimp */
   130 /*! \reimp */
   135 QString QContactMemoryEngine::managerName() const
   131 QString QContactMemoryEngine::managerName() const
   136 {
   132 {
   137     return d->m_engineName;
   133     return QLatin1String("memory");
   138 }
       
   139 
       
   140 /*! This function is deprecated and should not be used.  Use QContactMemoryEngine::managerVersion() instead! */
       
   141 int QContactMemoryEngine::implementationVersion() const
       
   142 {
       
   143     return d->m_engineVersion;
       
   144 }
   134 }
   145 
   135 
   146 /*! \reimp */
   136 /*! \reimp */
   147 QMap<QString, QString> QContactMemoryEngine::managerParameters() const
   137 QMap<QString, QString> QContactMemoryEngine::managerParameters() const
   148 {
   138 {
   150     params.insert(QLatin1String("id"), d->m_id);
   140     params.insert(QLatin1String("id"), d->m_id);
   151     return params;
   141     return params;
   152 }
   142 }
   153 
   143 
   154 /*! \reimp */
   144 /*! \reimp */
   155 bool QContactMemoryEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error& error)
   145 bool QContactMemoryEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error* error)
   156 {
   146 {
   157     if (contactId == QContactLocalId(0) || d->m_contactIds.contains(contactId)) {
   147     if (contactId == QContactLocalId(0) || d->m_contactIds.contains(contactId)) {
   158         error = QContactManager::NoError;
   148         *error = QContactManager::NoError;
   159         QContactLocalId oldId = d->m_selfContactId;
   149         QContactLocalId oldId = d->m_selfContactId;
   160         d->m_selfContactId = contactId;
   150         d->m_selfContactId = contactId;
   161 
   151 
   162         QContactChangeSet cs;
   152         QContactChangeSet changeSet;
   163         cs.oldAndNewSelfContactId() = QPair<QContactLocalId, QContactLocalId>(oldId, contactId);
   153         changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(oldId, contactId));
   164         cs.emitSignals(this);
   154         d->emitSharedSignals(&changeSet);
   165         return true;
   155         return true;
   166     }
   156     }
   167 
   157 
   168     error = QContactManager::DoesNotExistError;
   158     *error = QContactManager::DoesNotExistError;
   169     return false;
   159     return false;
   170 }
   160 }
   171 
   161 
   172 /*! \reimp */
   162 /*! \reimp */
   173 QContactLocalId QContactMemoryEngine::selfContactId(QContactManager::Error& error) const
   163 QContactLocalId QContactMemoryEngine::selfContactId(QContactManager::Error* error) const
   174 {
   164 {
   175     error = QContactManager::DoesNotExistError;
   165     *error = QContactManager::DoesNotExistError;
   176     if (d->m_selfContactId != QContactLocalId(0))
   166     if (d->m_selfContactId != QContactLocalId(0))
   177         error = QContactManager::NoError;
   167         *error = QContactManager::NoError;
   178     return d->m_selfContactId;
   168     return d->m_selfContactId;
   179 }
   169 }
   180 
   170 
   181 /*! \reimp */
   171 /*! \reimp */
   182 QList<QContactLocalId> QContactMemoryEngine::contacts(const QList<QContactSortOrder>& sortOrders, QContactManager::Error& error) const
   172 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
   183 {
   173 {
   184     return contactIds(sortOrders, error);
   174     Q_UNUSED(fetchHint); // no optimisations are possible in the memory backend; ignore the fetch hint.
   185 }
       
   186 
       
   187 /*! \reimp */
       
   188 QList<QContactLocalId> QContactMemoryEngine::contactIds(const QList<QContactSortOrder> &sortOrders, QContactManager::Error &error) const
       
   189 {
       
   190     // TODO: this needs to be done properly...
       
   191     error = QContactManager::NoError;
       
   192     QList<QContactLocalId> sortedIds;
       
   193     QList<QContact> sortedContacts;
       
   194     for (int i = 0; i < d->m_contacts.size(); i++)
       
   195         QContactManagerEngine::addSorted(&sortedContacts, d->m_contacts.at(i), sortOrders);
       
   196     for (int i = 0; i < sortedContacts.size(); i++)
       
   197         sortedIds.append(sortedContacts.at(i).id().localId());
       
   198     return sortedIds;
       
   199 }
       
   200 
       
   201 /*! \reimp */
       
   202 QList<QContact> QContactMemoryEngine::contacts(const QList<QContactSortOrder> &sortOrders, const QStringList& definitionRestrictions, QContactManager::Error &error) const
       
   203 {
       
   204     Q_UNUSED(definitionRestrictions);
       
   205     error = QContactManager::NoError;
       
   206     QList<QContact> sortedContacts;
       
   207     for (int i = 0; i < d->m_contacts.size(); i++)
       
   208         QContactManagerEngine::addSorted(&sortedContacts, contact(d->m_contacts.at(i).localId(), QStringList(), error), sortOrders);
       
   209     // we ignore the restrictions - we don't want to do extra work to remove them.
       
   210     // note that the restriction is "optional" - it defines the minimum set of detail types which _must_ be returned
       
   211     // but doesn't require that they are the _only_ detail types which are returned.
       
   212     return sortedContacts;
       
   213 }
       
   214 
       
   215 /*! \reimp */
       
   216 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, QContactManager::Error& error) const
       
   217 {
       
   218     int index = d->m_contactIds.indexOf(contactId);
   175     int index = d->m_contactIds.indexOf(contactId);
   219     if (index != -1) {
   176     if (index != -1) {
   220         // found the contact successfully.
   177         // found the contact successfully.
   221         error = QContactManager::NoError;
   178         *error = QContactManager::NoError;
   222         QContact retn = d->m_contacts.at(index);
   179         return d->m_contacts.at(index);
   223 
   180     }
   224         // synthesize the display label if we need to.
   181 
   225         QContactDisplayLabel dl = retn.detail(QContactDisplayLabel::DefinitionName);
   182     *error = QContactManager::DoesNotExistError;
   226         if (dl.label().isEmpty()) {
       
   227             QContactManager::Error synthError;
       
   228             retn = setContactDisplayLabel(synthesizedDisplayLabel(retn, synthError), retn);
       
   229         }
       
   230 
       
   231         // also, retrieve the current relationships the contact is involved with.
       
   232         QList<QContactRelationship> relationshipCache = d->m_orderedRelationships.value(contactId);
       
   233         QContactManagerEngine::setContactRelationships(&retn, relationshipCache);
       
   234 
       
   235         // and return the contact
       
   236         return retn;
       
   237     }
       
   238 
       
   239     error = QContactManager::DoesNotExistError;
       
   240     return QContact();
   183     return QContact();
   241 }
   184 }
   242 
   185 
   243 /*! \reimp */
   186 /*! \reimp */
   244 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions, QContactManager::Error& error) const
   187 QList<QContactLocalId> QContactMemoryEngine::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const
   245 {
   188 {
   246     Q_UNUSED(definitionRestrictions); // return the entire contact (meets contract, no optimisations possible for memory engine).
   189     /* Special case the fast case */
   247     int index = d->m_contactIds.indexOf(contactId);
   190     if (filter.type() == QContactFilter::DefaultFilter && sortOrders.count() == 0) {
   248     if (index != -1) {
   191         return d->m_contactIds;
   249         // found the contact successfully.
   192     } else {
   250         error = QContactManager::NoError;
   193         QList<QContact> clist = contacts(filter, sortOrders, QContactFetchHint(), error);
   251         QContact retn = d->m_contacts.at(index);
   194 
   252 
   195         /* Extract the ids */
   253         // synthesize the display label if we need to.
   196         QList<QContactLocalId> ids;
   254         QContactDisplayLabel dl = retn.detail(QContactDisplayLabel::DefinitionName);
   197         foreach(const QContact& c, clist)
   255         if (dl.label().isEmpty()) {
   198             ids.append(c.localId());
   256             QContactManager::Error synthError;
   199 
   257             retn = setContactDisplayLabel(synthesizedDisplayLabel(retn, synthError), retn);
   200         return ids;
   258         }
   201     }
   259 
   202 }
   260         // also, retrieve the current relationships the contact is involved with.
   203 
   261         QList<QContactRelationship> relationshipCache = d->m_orderedRelationships.value(contactId);
   204 /*! \reimp */
   262         QContactManagerEngine::setContactRelationships(&retn, relationshipCache);
   205 QList<QContact> QContactMemoryEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
   263 
   206 {
   264         // and return the contact
   207     Q_UNUSED(fetchHint); // no optimisations are possible in the memory backend; ignore the fetch hint.
   265         return retn;
   208     Q_UNUSED(error);
   266     }
   209 
   267 
   210     QList<QContact> sorted;
   268     error = QContactManager::DoesNotExistError;
   211 
   269     return QContact();
   212     /* First filter out contacts - check for default filter first */
   270 }
   213     if (filter.type() == QContactFilter::DefaultFilter) {
   271 
   214         foreach(const QContact&c, d->m_contacts) {
   272 bool QContactMemoryEngine::saveContact(QContact* theContact, QContactChangeSet& changeSet, QContactManager::Error& error)
   215             QContactManagerEngine::addSorted(&sorted,c, sortOrders);
       
   216         }
       
   217     } else {
       
   218         foreach(const QContact&c, d->m_contacts) {
       
   219             if (QContactManagerEngine::testFilter(filter, c))
       
   220                 QContactManagerEngine::addSorted(&sorted,c, sortOrders);
       
   221         }
       
   222     }
       
   223 
       
   224     return sorted;
       
   225 }
       
   226 
       
   227 /*! Saves the given contact \a theContact, storing any error to \a error and
       
   228     filling the \a changeSet with ids of changed contacts as required */
       
   229 bool QContactMemoryEngine::saveContact(QContact* theContact, QContactChangeSet& changeSet, QContactManager::Error* error)
   273 {
   230 {
   274     // ensure that the contact's details conform to their definitions
   231     // ensure that the contact's details conform to their definitions
   275     if (!validateContact(*theContact, error)) {
   232     if (!validateContact(*theContact, error)) {
   276         return false;
   233         return false;
   277     }
   234     }
   281     if (index != -1) {
   238     if (index != -1) {
   282         /* We also need to check that there are no modified create only details */
   239         /* We also need to check that there are no modified create only details */
   283         QContact oldContact = d->m_contacts.at(index);
   240         QContact oldContact = d->m_contacts.at(index);
   284 
   241 
   285         if (oldContact.type() != theContact->type()) {
   242         if (oldContact.type() != theContact->type()) {
   286             error = QContactManager::AlreadyExistsError;
   243             *error = QContactManager::AlreadyExistsError;
   287             return false;
   244             return false;
   288         }
   245         }
   289 
   246 
   290         QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName);
   247         QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName);
   291         ts.setLastModified(QDateTime::currentDateTime());
   248         ts.setLastModified(QDateTime::currentDateTime());
   292         QContactManagerEngine::setDetailAccessConstraints(&ts, QContactDetail::ReadOnly | QContactDetail::Irremovable);
   249         QContactManagerEngine::setDetailAccessConstraints(&ts, QContactDetail::ReadOnly | QContactDetail::Irremovable);
   293         theContact->saveDetail(&ts);
   250         theContact->saveDetail(&ts);
   294 
   251 
   295         /* And we need to check that the relationships are up-to-date or not modified */
       
   296         QList<QContactRelationship> orderedList = theContact->relationshipOrder();
       
   297         QList<QContactRelationship> upToDateList = d->m_orderedRelationships.value(theContact->localId());
       
   298         if (theContact->relationships() != orderedList) {
       
   299             // the user has modified the order of relationships; we may need to update the lists etc.
       
   300             if (upToDateList.size() != orderedList.size()) {
       
   301                 // the cache was stale; relationships have been added or removed in the meantime.
       
   302                 error = QContactManager::InvalidRelationshipError;
       
   303                 return false;
       
   304             }
       
   305             
       
   306             // size is the same, need to ensure that no invalid relationships are in the list.
       
   307             for (int i = 0; i < orderedList.size(); i++) {
       
   308                 QContactRelationship currOrderedRel = orderedList.at(i);
       
   309                 if (!upToDateList.contains(currOrderedRel)) {
       
   310                     // the cache was stale; relationships have been added and removed in the meantime.
       
   311                     error = QContactManager::InvalidRelationshipError;
       
   312                     return false;
       
   313                 }
       
   314             }
       
   315 
       
   316             // everything is fine.  update the up-to-date list
       
   317             d->m_orderedRelationships.insert(theContact->localId(), orderedList);
       
   318         }
       
   319 
       
   320         // synthesize the display label for the contact.
   252         // synthesize the display label for the contact.
   321         QContact saveContact = setContactDisplayLabel(synthesizedDisplayLabel(*theContact, error), *theContact);
   253         setContactDisplayLabel(theContact, synthesizedDisplayLabel(*theContact, error));
   322         *theContact = saveContact;
       
   323 
   254 
   324         // Looks ok, so continue
   255         // Looks ok, so continue
   325         d->m_contacts.replace(index, *theContact);
   256         d->m_contacts.replace(index, *theContact);
   326         changeSet.changedContacts().insert(theContact->localId());
   257         changeSet.insertChangedContact(theContact->localId());
   327     } else {
   258     } else {
   328         // id does not exist; if not zero, fail.
   259         // id does not exist; if not zero, fail.
   329         QContactId newId;
   260         QContactId newId;
   330         newId.setManagerUri(managerUri());
   261         newId.setManagerUri(managerUri());
   331         if (theContact->id() != QContactId() && theContact->id() != newId) {
   262         if (theContact->id() != QContactId() && theContact->id() != newId) {
   332             // the ID is not empty, and it doesn't identify an existing contact in our database either.
   263             // the ID is not empty, and it doesn't identify an existing contact in our database either.
   333             error = QContactManager::DoesNotExistError;
   264             *error = QContactManager::DoesNotExistError;
   334             return false;
   265             return false;
   335         }
   266         }
   336 
   267 
   337         /* New contact */
   268         /* New contact */
   338         QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName);
   269         QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName);
   344         // update the contact item - set its ID
   275         // update the contact item - set its ID
   345         newId.setLocalId(++d->m_nextContactId);
   276         newId.setLocalId(++d->m_nextContactId);
   346         theContact->setId(newId);
   277         theContact->setId(newId);
   347 
   278 
   348         // synthesize the display label for the contact.
   279         // synthesize the display label for the contact.
   349         QContact saveContact = setContactDisplayLabel(synthesizedDisplayLabel(*theContact, error), *theContact);
   280         setContactDisplayLabel(theContact, synthesizedDisplayLabel(*theContact, error));
   350         *theContact = saveContact;
       
   351 
   281 
   352         // finally, add the contact to our internal lists and return
   282         // finally, add the contact to our internal lists and return
   353         d->m_contacts.append(*theContact);                   // add contact to list
   283         d->m_contacts.append(*theContact);                   // add contact to list
   354         d->m_contactIds.append(theContact->localId());  // track the contact id.
   284         d->m_contactIds.append(theContact->localId());  // track the contact id.
   355 
   285 
   356         changeSet.addedContacts().insert(theContact->localId());
   286         changeSet.insertAddedContact(theContact->localId());
   357     }
   287     }
   358 
   288 
   359     error = QContactManager::NoError;     // successful.
   289     *error = QContactManager::NoError;     // successful.
   360     return true;
   290     return true;
   361 }
   291 }
   362 
   292 
   363 /*! \reimp */
   293 /*! \reimp */
   364 bool QContactMemoryEngine::saveContact(QContact* contact, QContactManager::Error& error)
   294 bool QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   365 {
       
   366     QContactChangeSet changeSet;
       
   367     bool retn = saveContact(contact, changeSet, error);
       
   368     changeSet.emitSignals(this);
       
   369     return retn;
       
   370 }
       
   371 
       
   372 /*! \reimp */
       
   373 QList<QContactManager::Error> QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QContactManager::Error& error)
       
   374 {
       
   375     QList<QContactManager::Error> ret;
       
   376     if (!contacts) {
       
   377         error = QContactManager::BadArgumentError;
       
   378         return ret;
       
   379     } else {
       
   380         // for batch processing, we store up the changes and emit at the end.
       
   381         QContactChangeSet changeSet;
       
   382         QContactManager::Error functionError = QContactManager::NoError;
       
   383         for (int i = 0; i < contacts->count(); i++) {
       
   384             QContact current = contacts->at(i);
       
   385             if (!saveContact(&current, changeSet, error)) {
       
   386                 functionError = error;
       
   387                 ret.append(functionError);
       
   388             } else {
       
   389                 (*contacts)[i] = current;
       
   390                 ret.append(QContactManager::NoError);
       
   391             }
       
   392         }
       
   393 
       
   394         error = functionError;
       
   395         changeSet.emitSignals(this);
       
   396         return ret;
       
   397     }
       
   398 }
       
   399 
       
   400 /*! \reimp */
       
   401 bool QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error)
       
   402 {
   295 {
   403     if(errorMap) {
   296     if(errorMap) {
   404         errorMap->clear();
   297         errorMap->clear();
   405     }
   298     }
   406 
   299 
   407     if (!contacts) {
   300     if (!contacts) {
   408         error = QContactManager::BadArgumentError;
   301         *error = QContactManager::BadArgumentError;
   409         return false;
   302         return false;
   410     }
   303     }
   411 
   304 
   412     QContactChangeSet changeSet;
   305     QContactChangeSet changeSet;
   413     QContact current;
   306     QContact current;
   414     QContactManager::Error operationError = QContactManager::NoError;
   307     QContactManager::Error operationError = QContactManager::NoError;
   415     for (int i = 0; i < contacts->count(); i++) {
   308     for (int i = 0; i < contacts->count(); i++) {
   416         current = contacts->at(i);
   309         current = contacts->at(i);
   417         if (!saveContact(&current, changeSet, error)) {
   310         if (!saveContact(&current, changeSet, error)) {
   418             operationError = error;
   311             operationError = *error;
   419             errorMap->insert(i, operationError);
   312             errorMap->insert(i, operationError);
   420         } else {
   313         } else {
   421             (*contacts)[i] = current;
   314             (*contacts)[i] = current;
   422         }
   315         }
   423     }
   316     }
   424 
   317 
   425     error = operationError;
   318     *error = operationError;
   426     changeSet.emitSignals(this);
   319     d->emitSharedSignals(&changeSet);
   427     // return false if some error occurred
   320     // return false if some error occurred
   428     return error == QContactManager::NoError;
   321     return (*error == QContactManager::NoError);
   429 }
   322 }
   430 
   323 
   431 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactChangeSet& changeSet, QContactManager::Error& error)
   324 /*! Removes the contact identified by the given \a contactId, storing any error to \a error and
       
   325     filling the \a changeSet with ids of changed contacts and relationships as required */
       
   326 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactChangeSet& changeSet, QContactManager::Error* error)
   432 {
   327 {
   433     int index = d->m_contactIds.indexOf(contactId);
   328     int index = d->m_contactIds.indexOf(contactId);
   434 
   329 
   435     if (index == -1) {
   330     if (index == -1) {
   436         error = QContactManager::DoesNotExistError;
   331         *error = QContactManager::DoesNotExistError;
   437         return false;
   332         return false;
   438     }
   333     }
   439 
   334 
   440     // remove the contact from any relationships it was in.
   335     // remove the contact from any relationships it was in.
   441     QContactId thisContact;
   336     QContactId thisContact;
   442     thisContact.setManagerUri(managerUri());
   337     thisContact.setManagerUri(managerUri());
   443     thisContact.setLocalId(contactId);
   338     thisContact.setLocalId(contactId);
   444     QList<QContactRelationship> allRelationships = relationships(QString(), thisContact, QContactRelationshipFilter::Either, error);
   339     QList<QContactRelationship> allRelationships = relationships(QString(), thisContact, QContactRelationship::Either, error);
   445     if (error != QContactManager::NoError && error != QContactManager::DoesNotExistError) {
   340     if (*error != QContactManager::NoError && *error != QContactManager::DoesNotExistError) {
   446         error = QContactManager::UnspecifiedError; // failed to clean up relationships
   341         *error = QContactManager::UnspecifiedError; // failed to clean up relationships
   447         return false;
   342         return false;
   448     }
   343     }
   449 
   344 
   450     // this is meant to be a transaction, so if any of these fail, we're in BIG TROUBLE.
   345     // this is meant to be a transaction, so if any of these fail, we're in BIG TROUBLE.
   451     // a real backend will use DBMS transactions to ensure database integrity.
   346     // a real backend will use DBMS transactions to ensure database integrity.
   452     for (int i = 0; i < allRelationships.size(); i++) {
   347     removeRelationships(allRelationships, 0, error);
   453         QContactRelationship currRel = allRelationships.at(i);
       
   454         removeRelationship(currRel, error);
       
   455     }
       
   456 
   348 
   457     // having cleaned up the relationships, remove the contact from the lists.
   349     // having cleaned up the relationships, remove the contact from the lists.
   458     d->m_contacts.removeAt(index);
   350     d->m_contacts.removeAt(index);
   459     d->m_contactIds.removeAt(index);
   351     d->m_contactIds.removeAt(index);
   460     error = QContactManager::NoError;
   352     *error = QContactManager::NoError;
   461 
   353 
   462     // and if it was the self contact, reset the self contact id
   354     // and if it was the self contact, reset the self contact id
   463     if (contactId == d->m_selfContactId) {
   355     if (contactId == d->m_selfContactId) {
   464         d->m_selfContactId = QContactLocalId(0);
   356         d->m_selfContactId = QContactLocalId(0);
   465         changeSet.oldAndNewSelfContactId() = QPair<QContactLocalId, QContactLocalId>(contactId, QContactLocalId(0));
   357         changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(contactId, QContactLocalId(0)));
   466     }
   358     }
   467 
   359 
   468     changeSet.removedContacts().insert(contactId);
   360     changeSet.insertRemovedContact(contactId);
   469     return true;
   361     return true;
   470 }
   362 }
   471 
   363 
   472 /*! \reimp */
   364 /*! \reimp */
   473 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error& error)
   365 bool QContactMemoryEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   474 {
   366 {
   475     QContactChangeSet changeSet;
   367     if (contactIds.count() == 0) {
   476     bool retn = removeContact(contactId, changeSet, error);
   368         *error = QContactManager::BadArgumentError;
   477     changeSet.emitSignals(this);
   369         return false;
   478     return retn;
   370     }
   479 }
   371     
   480 
       
   481 /*! \reimp */
       
   482 QList<QContactManager::Error> QContactMemoryEngine::removeContacts(QList<QContactLocalId>* contactIds, QContactManager::Error& error)
       
   483 {
       
   484     QList<QContactManager::Error> ret;
       
   485     if (!contactIds) {
       
   486         error = QContactManager::BadArgumentError;
       
   487         return ret;
       
   488     }
       
   489 
       
   490     // for batch processing, we store up the changes and emit at the end.
       
   491     QContactChangeSet changeSet;
       
   492     QContactManager::Error functionError = QContactManager::NoError;
       
   493     for (int i = 0; i < contactIds->count(); i++) {
       
   494         QContactLocalId current = contactIds->at(i);
       
   495         if (!removeContact(current, changeSet, error)) {
       
   496             functionError = error;
       
   497             ret.append(functionError);
       
   498         } else {
       
   499             (*contactIds)[i] = 0;
       
   500             ret.append(QContactManager::NoError);
       
   501         }
       
   502     }
       
   503 
       
   504     error = functionError;
       
   505     changeSet.emitSignals(this);
       
   506     return ret;
       
   507 }
       
   508 
       
   509 /*! \reimp */
       
   510 bool QContactMemoryEngine::removeContacts(QList<QContactLocalId>* contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error)
       
   511 {
       
   512     if (!contactIds) {
       
   513         error = QContactManager::BadArgumentError;
       
   514         return false;
       
   515     }
       
   516 
       
   517     QContactChangeSet changeSet;
   372     QContactChangeSet changeSet;
   518     QContactLocalId current;
   373     QContactLocalId current;
   519     QContactManager::Error operationError = QContactManager::NoError;
   374     QContactManager::Error operationError = QContactManager::NoError;
   520     for (int i = 0; i < contactIds->count(); i++) {
   375     for (int i = 0; i < contactIds.count(); i++) {
   521         current = contactIds->at(i);
   376         current = contactIds.at(i);
   522         if (!removeContact(current, changeSet, error)) {
   377         if (!removeContact(current, changeSet, error)) {
   523             operationError = error;
   378             operationError = *error;
   524             errorMap->insert(i, operationError);
   379             errorMap->insert(i, operationError);
   525         } else {
   380         }
   526             (*contactIds)[i] = 0;
   381     }
   527         }
   382 
   528     }
   383     *error = operationError;
   529 
   384     d->emitSharedSignals(&changeSet);
   530     error = operationError;
       
   531     changeSet.emitSignals(this);
       
   532     // return false if some errors occurred
   385     // return false if some errors occurred
   533     return error == QContactManager::NoError;
   386     return (*error == QContactManager::NoError);
   534 }
   387 }
   535 
   388 
   536 /*! \reimp */
   389 /*! \reimp */
   537 QList<QContactRelationship> QContactMemoryEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationshipFilter::Role role, QContactManager::Error& error) const
   390 QList<QContactRelationship> QContactMemoryEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const
   538 {
   391 {
   539     QContactId defaultId;
   392     QContactId defaultId;
   540     QList<QContactRelationship> retn;
   393     QList<QContactRelationship> retn;
   541     for (int i = 0; i < d->m_relationships.size(); i++) {
   394     for (int i = 0; i < d->m_relationships.size(); i++) {
   542         QContactRelationship curr = d->m_relationships.at(i);
   395         QContactRelationship curr = d->m_relationships.at(i);
   550             retn.append(curr);
   403             retn.append(curr);
   551             continue;
   404             continue;
   552         }
   405         }
   553 
   406 
   554         // otherwise, check that the participant exists and plays the required role in the relationship.
   407         // otherwise, check that the participant exists and plays the required role in the relationship.
   555         if (role == QContactRelationshipFilter::First && curr.first() == participantId) {
   408         if (role == QContactRelationship::First && curr.first() == participantId) {
   556             retn.append(curr);
   409             retn.append(curr);
   557         } else if (role == QContactRelationshipFilter::Second && curr.second() == participantId) {
   410         } else if (role == QContactRelationship::Second && curr.second() == participantId) {
   558             retn.append(curr);
   411             retn.append(curr);
   559         } else if (role == QContactRelationshipFilter::Either && (curr.first() == participantId || curr.second() == participantId)) {
   412         } else if (role == QContactRelationship::Either && (curr.first() == participantId || curr.second() == participantId)) {
   560             retn.append(curr);
   413             retn.append(curr);
   561         }
   414         }
   562     }
   415     }
   563 
   416 
   564     error = QContactManager::NoError;
   417     *error = QContactManager::NoError;
   565     if (retn.isEmpty())
   418     if (retn.isEmpty())
   566         error = QContactManager::DoesNotExistError;
   419         *error = QContactManager::DoesNotExistError;
   567     return retn;
   420     return retn;
   568 }
   421 }
   569 
   422 
   570 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactChangeSet& changeSet, QContactManager::Error& error)
   423 /*! Saves the given relationship \a relationship, storing any error to \a error and
       
   424     filling the \a changeSet with ids of changed contacts and relationships as required */
       
   425 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactChangeSet& changeSet, QContactManager::Error* error)
   571 {
   426 {
   572     // Attempt to validate the relationship.
   427     // Attempt to validate the relationship.
   573     // first, check that the source contact exists and is in this manager.
   428     // first, check that the source contact exists and is in this manager.
   574     QString myUri = managerUri();
   429     QString myUri = managerUri();
       
   430     int firstContactIndex = d->m_contactIds.indexOf(relationship->first().localId());
   575     if ((!relationship->first().managerUri().isEmpty() && relationship->first().managerUri() != myUri)
   431     if ((!relationship->first().managerUri().isEmpty() && relationship->first().managerUri() != myUri)
   576             ||!d->m_contactIds.contains(relationship->first().localId())) {
   432             ||firstContactIndex == -1) {
   577         error = QContactManager::InvalidRelationshipError;
   433         *error = QContactManager::InvalidRelationshipError;
   578         return false;
   434         return false;
   579     }
   435     }
   580 
   436 
   581     // second, check that the second contact exists (if it's local); we cannot check other managers' contacts.
   437     // second, check that the second contact exists (if it's local); we cannot check other managers' contacts.
   582     QContactId dest = relationship->second();
   438     QContactId dest = relationship->second();
       
   439     int secondContactIndex = d->m_contactIds.indexOf(dest.localId());
   583 
   440 
   584     if (dest.managerUri().isEmpty() || dest.managerUri() == myUri) {
   441     if (dest.managerUri().isEmpty() || dest.managerUri() == myUri) {
   585         // this entry in the destination list is supposedly stored in this manager.
   442         // this entry in the destination list is supposedly stored in this manager.
   586         // check that it exists, and that it isn't the source contact (circular)
   443         // check that it exists, and that it isn't the source contact (circular)
   587         if (!d->m_contactIds.contains(dest.localId()) || dest.localId() == relationship->first().localId()) {
   444         if (secondContactIndex == -1 || dest.localId() == relationship->first().localId()) {
   588             error = QContactManager::InvalidRelationshipError;
   445             *error = QContactManager::InvalidRelationshipError;
   589             return false;
   446             return false;
   590         }
   447         }
   591     }
   448     }
   592 
   449 
   593     // the relationship is valid.  We need to update the manager URIs in the second contact if it is empty to our URI.
   450     // the relationship is valid.  We need to update the manager URIs in the second contact if it is empty to our URI.
   597         relationship->setSecond(dest);
   454         relationship->setSecond(dest);
   598     }
   455     }
   599 
   456 
   600     // check to see if the relationship already exists in the database.  If so, replace.
   457     // check to see if the relationship already exists in the database.  If so, replace.
   601     // We do this because we don't want duplicates in our lists / maps of relationships.
   458     // We do this because we don't want duplicates in our lists / maps of relationships.
   602     error = QContactManager::NoError;
   459     *error = QContactManager::NoError;
   603     QList<QContactRelationship> allRelationships = d->m_relationships;
   460     QList<QContactRelationship> allRelationships = d->m_relationships;
   604     for (int i = 0; i < allRelationships.size(); i++) {
   461     for (int i = 0; i < allRelationships.size(); i++) {
   605         QContactRelationship curr = allRelationships.at(i);
   462         QContactRelationship curr = allRelationships.at(i);
   606         if (curr == *relationship) {
   463         if (curr == *relationship) {
   607             d->m_relationships.removeAt(i);
       
   608             d->m_relationships.insert(i, *relationship);
       
   609             return true;
   464             return true;
   610             // TODO: set error to AlreadyExistsError and return false?
   465             // TODO: set error to AlreadyExistsError and return false?
   611         }
   466         }
   612     }
   467     }
   613 
   468 
   616     QList<QContactRelationship> secondRelationships = d->m_orderedRelationships.value(relationship->second().localId());
   471     QList<QContactRelationship> secondRelationships = d->m_orderedRelationships.value(relationship->second().localId());
   617     firstRelationships.append(*relationship);
   472     firstRelationships.append(*relationship);
   618     secondRelationships.append(*relationship);
   473     secondRelationships.append(*relationship);
   619     d->m_orderedRelationships.insert(relationship->first().localId(), firstRelationships);
   474     d->m_orderedRelationships.insert(relationship->first().localId(), firstRelationships);
   620     d->m_orderedRelationships.insert(relationship->second().localId(), secondRelationships);
   475     d->m_orderedRelationships.insert(relationship->second().localId(), secondRelationships);
   621     changeSet.addedRelationshipsContacts().insert(relationship->first().localId());
   476     changeSet.insertAddedRelationshipsContact(relationship->first().localId());
   622     changeSet.addedRelationshipsContacts().insert(relationship->second().localId());
   477     changeSet.insertAddedRelationshipsContact(relationship->second().localId());
       
   478 
       
   479     // update the contacts involved
       
   480     QContactManagerEngine::setContactRelationships(&d->m_contacts[firstContactIndex], firstRelationships);
       
   481     QContactManagerEngine::setContactRelationships(&d->m_contacts[secondContactIndex], secondRelationships);
   623 
   482 
   624     // finally, insert into our list of all relationships, and return.
   483     // finally, insert into our list of all relationships, and return.
   625     d->m_relationships.append(*relationship);
   484     d->m_relationships.append(*relationship);
   626     return true;
   485     return true;
   627 }
   486 }
   628 
   487 
   629 /*! \reimp */
   488 /*! \reimp */
   630 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error& error)
   489 bool QContactMemoryEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   631 {
   490 {
   632     QContactChangeSet changeSet;
   491     *error = QContactManager::NoError;
   633     bool retn = saveRelationship(relationship, changeSet, error);
       
   634     changeSet.emitSignals(this);
       
   635     return retn;
       
   636 }
       
   637 
       
   638 /*! \reimp */
       
   639 QList<QContactManager::Error> QContactMemoryEngine::saveRelationships(QList<QContactRelationship>* relationships, QContactManager::Error& error)
       
   640 {
       
   641     error = QContactManager::NoError;
       
   642     QContactManager::Error functionError;
   492     QContactManager::Error functionError;
   643     QContactChangeSet changeSet;
   493     QContactChangeSet changeSet;
   644     QList<QContactManager::Error> retn;
   494 
   645     for (int i = 0; i < relationships->size(); i++) {
   495     for (int i = 0; i < relationships->size(); i++) {
   646         QContactRelationship curr = relationships->at(i);
   496         QContactRelationship curr = relationships->at(i);
   647         saveRelationship(&curr, changeSet, functionError);
   497         saveRelationship(&curr, changeSet, &functionError);
   648         retn.append(functionError);
   498         if (functionError != QContactManager::NoError && errorMap)
       
   499             errorMap->insert(i, functionError);
   649 
   500 
   650         // and replace the current relationship with the updated version.
   501         // and replace the current relationship with the updated version.
   651         relationships->replace(i, curr);
   502         relationships->replace(i, curr);
   652 
   503 
   653         // also, update the total error if it did not succeed.
   504         // also, update the total error if it did not succeed.
   654         if (functionError != QContactManager::NoError)
   505         if (functionError != QContactManager::NoError)
   655             error = functionError;
   506             *error = functionError;
   656     }
   507     }
   657 
   508 
   658     changeSet.emitSignals(this);
   509     d->emitSharedSignals(&changeSet);
   659     return retn;
   510     return (*error == QContactManager::NoError);
   660 }
   511 }
   661 
   512 
   662 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactChangeSet& changeSet, QContactManager::Error& error)
   513 /*! Removes the given relationship \a relationship, storing any error to \a error and
       
   514     filling the \a changeSet with ids of changed contacts and relationships as required */
       
   515 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactChangeSet& changeSet, QContactManager::Error* error)
   663 {
   516 {
   664     // attempt to remove it from our list of relationships.
   517     // attempt to remove it from our list of relationships.
   665     if (!d->m_relationships.removeOne(relationship)) {
   518     if (!d->m_relationships.removeOne(relationship)) {
   666         error = QContactManager::DoesNotExistError;
   519         *error = QContactManager::DoesNotExistError;
   667         return false;
   520         return false;
   668     }
   521     }
   669 
   522 
   670     // if that worked, then we need to remove it from the two locations in our map, also.
   523     // if that worked, then we need to remove it from the two locations in our map, also.
   671     QList<QContactRelationship> firstRelationships = d->m_orderedRelationships.value(relationship.first().localId());
   524     QList<QContactRelationship> firstRelationships = d->m_orderedRelationships.value(relationship.first().localId());
   673     firstRelationships.removeOne(relationship);
   526     firstRelationships.removeOne(relationship);
   674     secondRelationships.removeOne(relationship);
   527     secondRelationships.removeOne(relationship);
   675     d->m_orderedRelationships.insert(relationship.first().localId(), firstRelationships);
   528     d->m_orderedRelationships.insert(relationship.first().localId(), firstRelationships);
   676     d->m_orderedRelationships.insert(relationship.second().localId(), secondRelationships);
   529     d->m_orderedRelationships.insert(relationship.second().localId(), secondRelationships);
   677 
   530 
       
   531     // Update the contacts as well
       
   532     int firstContactIndex = d->m_contactIds.indexOf(relationship.first().localId());
       
   533     int secondContactIndex = relationship.second().managerUri() == managerUri() ? d->m_contactIds.indexOf(relationship.second().localId()) : -1;
       
   534     if (firstContactIndex != -1)
       
   535         QContactMemoryEngine::setContactRelationships(&d->m_contacts[firstContactIndex], firstRelationships);
       
   536     if (secondContactIndex != -1)
       
   537         QContactMemoryEngine::setContactRelationships(&d->m_contacts[secondContactIndex], secondRelationships);
       
   538 
   678     // set our changes, and return.
   539     // set our changes, and return.
   679     changeSet.removedRelationshipsContacts().insert(relationship.first().localId());
   540     changeSet.insertRemovedRelationshipsContact(relationship.first().localId());
   680     changeSet.removedRelationshipsContacts().insert(relationship.second().localId());
   541     changeSet.insertRemovedRelationshipsContact(relationship.second().localId());
   681     error = QContactManager::NoError;
   542     *error = QContactManager::NoError;
   682     return true;
   543     return true;
   683 }
   544 }
   684 
   545 
   685 /*! \reimp */
   546 /*! \reimp */
   686 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error& error)
   547 bool QContactMemoryEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
   687 {
   548 {
   688     QContactChangeSet changeSet;
       
   689     bool retn = removeRelationship(relationship, changeSet, error);
       
   690     changeSet.emitSignals(this);
       
   691     return retn;
       
   692 }
       
   693 
       
   694 /*! \reimp */
       
   695 QList<QContactManager::Error> QContactMemoryEngine::removeRelationships(const QList<QContactRelationship>& relationships, QContactManager::Error& error)
       
   696 {
       
   697     QList<QContactManager::Error> retn;
       
   698     QContactManager::Error functionError;
   549     QContactManager::Error functionError;
       
   550     QContactChangeSet cs;
   699     for (int i = 0; i < relationships.size(); i++) {
   551     for (int i = 0; i < relationships.size(); i++) {
   700         removeRelationship(relationships.at(i), functionError);
   552         removeRelationship(relationships.at(i), cs, &functionError);
   701         retn.append(functionError);
       
   702 
   553 
   703         // update the total error if it did not succeed.
   554         // update the total error if it did not succeed.
   704         if (functionError != QContactManager::NoError) {
   555         if (functionError != QContactManager::NoError) {
   705             error = functionError;
   556             if (errorMap)
   706         }
   557                 errorMap->insert(i, functionError);
   707     }
   558             *error = functionError;
   708 
   559         }
   709     return retn;
   560     }
   710 }
   561 
   711 
   562     d->emitSharedSignals(&cs);
   712 /*! \reimp */
   563     return (*error == QContactManager::NoError);
   713 QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(const QString& contactType, QContactManager::Error& error) const
   564 }
       
   565 
       
   566 /*! \reimp */
       
   567 QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const
   714 {
   568 {
   715     // lazy initialisation of schema definitions.
   569     // lazy initialisation of schema definitions.
   716     if (d->m_definitions.isEmpty()) {
   570     if (d->m_definitions.isEmpty()) {
   717         d->m_definitions = QContactManagerEngine::schemaDefinitions();
   571         d->m_definitions = QContactManagerEngine::schemaDefinitions();
   718     }
   572     }
   719 
   573 
   720     error = QContactManager::NoError;
   574     *error = QContactManager::NoError;
   721     return d->m_definitions.value(contactType);
   575     return d->m_definitions.value(contactType);
   722 }
   576 }
   723 
   577 
   724 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error& error)
   578 /*! Saves the given detail definition \a def, storing any error to \a error and
       
   579     filling the \a changeSet with ids of changed contacts as required */
       
   580 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error* error)
   725 {
   581 {
   726     // we should check for changes to the database in this function, and add ids of changed data to changeSet. TODO.
   582     // we should check for changes to the database in this function, and add ids of changed data to changeSet. TODO.
   727     Q_UNUSED(changeSet);
   583     Q_UNUSED(changeSet);
   728 
   584 
   729     if (!validateDefinition(def, error)) {
   585     if (!validateDefinition(def, error)) {
   733     detailDefinitions(contactType, error); // just to populate the definitions if we haven't already.
   589     detailDefinitions(contactType, error); // just to populate the definitions if we haven't already.
   734     QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType);
   590     QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType);
   735     defsForThisType.insert(def.name(), def);
   591     defsForThisType.insert(def.name(), def);
   736     d->m_definitions.insert(contactType, defsForThisType);
   592     d->m_definitions.insert(contactType, defsForThisType);
   737 
   593 
   738     error = QContactManager::NoError;
   594     *error = QContactManager::NoError;
   739     return true;
   595     return true;
   740 }
   596 }
   741 
   597 
   742 /*! \reimp */
   598 /*! \reimp */
   743 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error& error)
   599 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error* error)
   744 {
   600 {
   745     QContactChangeSet changeSet;
   601     QContactChangeSet changeSet;
   746     bool retn = saveDetailDefinition(def, contactType, changeSet, error);
   602     bool retn = saveDetailDefinition(def, contactType, changeSet, error);
   747     changeSet.emitSignals(this);
   603     d->emitSharedSignals(&changeSet);
   748     return retn;
   604     return retn;
   749 }
   605 }
   750 
   606 
   751 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error& error)
   607 /*! Removes the detail definition identified by \a definitionId, storing any error to \a error and
       
   608     filling the \a changeSet with ids of changed contacts as required */
       
   609 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error* error)
   752 {
   610 {
   753     // we should check for changes to the database in this function, and add ids of changed data to changeSet...
   611     // we should check for changes to the database in this function, and add ids of changed data to changeSet...
   754     // we should also check to see if the changes have invalidated any contact data, and add the ids of those contacts
   612     // we should also check to see if the changes have invalidated any contact data, and add the ids of those contacts
   755     // to the change set.  TODO!
   613     // to the change set.  TODO!
   756     Q_UNUSED(changeSet);
   614     Q_UNUSED(changeSet);
   757 
   615 
   758     if (definitionId.isEmpty()) {
   616     if (definitionId.isEmpty()) {
   759         error = QContactManager::BadArgumentError;
   617         *error = QContactManager::BadArgumentError;
   760         return false;
   618         return false;
   761     }
   619     }
   762 
   620 
   763     detailDefinitions(contactType, error); // just to populate the definitions if we haven't already.
   621     detailDefinitions(contactType, error); // just to populate the definitions if we haven't already.
   764     QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType);
   622     QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType);
   765     bool success = defsForThisType.remove(definitionId);
   623     bool success = defsForThisType.remove(definitionId);
   766     d->m_definitions.insert(contactType, defsForThisType);
   624     d->m_definitions.insert(contactType, defsForThisType);
   767     if (success)
   625     if (success)
   768         error = QContactManager::NoError;
   626         *error = QContactManager::NoError;
   769     else
   627     else
   770         error = QContactManager::DoesNotExistError;
   628         *error = QContactManager::DoesNotExistError;
   771     return success;
   629     return success;
   772 }
   630 }
   773 
   631 
   774 /*! \reimp */
   632 /*! \reimp */
   775 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactManager::Error& error)
   633 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactManager::Error* error)
   776 {
   634 {
   777     QContactChangeSet changeSet;
   635     QContactChangeSet changeSet;
   778     bool retn = removeDetailDefinition(definitionId, contactType, changeSet, error);
   636     bool retn = removeDetailDefinition(definitionId, contactType, changeSet, error);
   779     changeSet.emitSignals(this);
   637     d->emitSharedSignals(&changeSet);
   780     return retn;
   638     return retn;
   781 }
   639 }
   782 
   640 
   783 /*! \reimp */
   641 /*! \reimp */
   784 void QContactMemoryEngine::requestDestroyed(QContactAbstractRequest* req)
   642 void QContactMemoryEngine::requestDestroyed(QContactAbstractRequest* req)
   785 {
   643 {
   786     d->m_asynchronousOperations.removeOne(req);
   644     Q_UNUSED(req);
   787 }
   645 }
   788 
   646 
   789 /*! \reimp */
   647 /*! \reimp */
   790 bool QContactMemoryEngine::startRequest(QContactAbstractRequest* req)
   648 bool QContactMemoryEngine::startRequest(QContactAbstractRequest* req)
   791 {
   649 {
   792     if (!d->m_asynchronousOperations.contains(req))
   650     if (!req)
   793         d->m_asynchronousOperations.enqueue(req);
   651         return false;
   794     updateRequestState(req, QContactAbstractRequest::ActiveState);
   652     updateRequestState(req, QContactAbstractRequest::ActiveState);
   795     QTimer::singleShot(0, this, SLOT(performAsynchronousOperation()));
   653     performAsynchronousOperation(req);
   796     return true;
   654     return true;
   797 }
   655 }
   798 
   656 
   799 /*! \reimp */
   657 /*! \reimp */
   800 bool QContactMemoryEngine::cancelRequest(QContactAbstractRequest* req)
   658 bool QContactMemoryEngine::cancelRequest(QContactAbstractRequest* req)
   801 {
   659 {
   802     updateRequestState(req, QContactAbstractRequest::CanceledState);
   660     Q_UNUSED(req); // we can't cancel since we complete immediately
       
   661     return false;
       
   662 }
       
   663 
       
   664 /*! \reimp */
       
   665 bool QContactMemoryEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs)
       
   666 {
       
   667     // in our implementation, we always complete any operation we start.
       
   668     Q_UNUSED(msecs);
       
   669     Q_UNUSED(req);
       
   670 
   803     return true;
   671     return true;
   804 }
       
   805 
       
   806 /*! This function is deprecated!  Use QContactMemoryEngine::waitForRequestFinished() instead!
       
   807     Waits up to \a msecs milliseconds for the request \a req to emit the progress() signal.
       
   808     Returns true if the progress() signal was emitted during the period, otherwise false.
       
   809 */
       
   810 bool QContactMemoryEngine::waitForRequestProgress(QContactAbstractRequest* req, int msecs)
       
   811 {
       
   812     Q_UNUSED(msecs);
       
   813 
       
   814     if (!d->m_asynchronousOperations.removeOne(req))
       
   815         return false; // didn't exist.
       
   816 
       
   817     // replace at head of queue
       
   818     d->m_asynchronousOperations.insert(0, req);
       
   819 
       
   820     // and perform the operation.
       
   821     performAsynchronousOperation();
       
   822 
       
   823     return true;
       
   824 }
       
   825 
       
   826 /*! \reimp */
       
   827 bool QContactMemoryEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs)
       
   828 {
       
   829     // in our implementation, we always complete any operation we start.
       
   830     // so, waitForRequestFinished is equivalent to waitForRequestProgress.
       
   831     return waitForRequestProgress(req, msecs);
       
   832 }
   672 }
   833 
   673 
   834 /*!
   674 /*!
   835  * This slot is called some time after an asynchronous request is started.
   675  * This slot is called some time after an asynchronous request is started.
   836  * It performs the required operation, sets the result and returns.
   676  * It performs the required operation, sets the result and returns.
   837  */
   677  */
   838 void QContactMemoryEngine::performAsynchronousOperation()
   678 void QContactMemoryEngine::performAsynchronousOperation(QContactAbstractRequest *currentRequest)
   839 {
   679 {
   840     QContactAbstractRequest *currentRequest;
       
   841 
       
   842     // take the first pending request and finish it
       
   843     if (d->m_asynchronousOperations.isEmpty())
       
   844         return;
       
   845     currentRequest = d->m_asynchronousOperations.dequeue();
       
   846 
       
   847     // check to see if it is cancelling; if so, remove it from the queue and return.
       
   848     if (currentRequest->state() == QContactAbstractRequest::CanceledState) {
       
   849         return;
       
   850     }
       
   851 
       
   852     // store up changes, and emit signals once at the end of the (possibly batch) operation.
   680     // store up changes, and emit signals once at the end of the (possibly batch) operation.
   853     QContactChangeSet changeSet;
   681     QContactChangeSet changeSet;
   854 
   682 
   855     // Now perform the active request and emit required signals.
   683     // Now perform the active request and emit required signals.
   856     Q_ASSERT(currentRequest->state() == QContactAbstractRequest::ActiveState);
   684     Q_ASSERT(currentRequest->state() == QContactAbstractRequest::ActiveState);
   858         case QContactAbstractRequest::ContactFetchRequest:
   686         case QContactAbstractRequest::ContactFetchRequest:
   859         {
   687         {
   860             QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest);
   688             QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest);
   861             QContactFilter filter = r->filter();
   689             QContactFilter filter = r->filter();
   862             QList<QContactSortOrder> sorting = r->sorting();
   690             QList<QContactSortOrder> sorting = r->sorting();
   863             QStringList defs = r->definitionRestrictions();
   691             QContactFetchHint fetchHint = r->fetchHint();
   864 
   692 
   865             QContactManager::Error operationError;
   693             QContactManager::Error operationError;
   866             QList<QContact> requestedContacts = QContactManagerEngine::contacts(filter, sorting, defs, operationError);
   694             QList<QContact> requestedContacts = contacts(filter, sorting, fetchHint, &operationError);
   867 
   695 
   868             // update the request with the results.
   696             // update the request with the results.
   869             if (!requestedContacts.isEmpty() || operationError != QContactManager::NoError)
   697             if (!requestedContacts.isEmpty() || operationError != QContactManager::NoError)
   870                 updateContactFetchRequest(r, requestedContacts, operationError); // emit resultsAvailable()
   698                 updateContactFetchRequest(r, requestedContacts, operationError, QContactAbstractRequest::FinishedState);
   871             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   699             else
       
   700                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   872         }
   701         }
   873         break;
   702         break;
   874 
   703 
   875         case QContactAbstractRequest::ContactLocalIdFetchRequest:
   704         case QContactAbstractRequest::ContactLocalIdFetchRequest:
   876         {
   705         {
   877             QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest);
   706             QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest);
   878             QContactFilter filter = r->filter();
   707             QContactFilter filter = r->filter();
   879             QList<QContactSortOrder> sorting = r->sorting();
   708             QList<QContactSortOrder> sorting = r->sorting();
   880 
   709 
   881             QContactManager::Error operationError = QContactManager::NoError;
   710             QContactManager::Error operationError = QContactManager::NoError;
   882             QList<QContactLocalId> requestedContactIds = QContactManagerEngine::contactIds(filter, sorting, operationError);
   711             QList<QContactLocalId> requestedContactIds = contactIds(filter, sorting, &operationError);
   883 
   712 
   884             if (!requestedContactIds.isEmpty() || operationError != QContactManager::NoError)
   713             if (!requestedContactIds.isEmpty() || operationError != QContactManager::NoError)
   885                 updateContactLocalIdFetchRequest(r, requestedContactIds, operationError); // emit resultsAvailable()
   714                 updateContactLocalIdFetchRequest(r, requestedContactIds, operationError, QContactAbstractRequest::FinishedState);
   886             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   715             else
       
   716                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   887         }
   717         }
   888         break;
   718         break;
   889 
   719 
   890         case QContactAbstractRequest::ContactSaveRequest:
   720         case QContactAbstractRequest::ContactSaveRequest:
   891         {
   721         {
   892             QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest);
   722             QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest);
   893             QList<QContact> contacts = r->contacts();
   723             QList<QContact> contacts = r->contacts();
   894 
   724 
   895             QContactManager::Error operationError = QContactManager::NoError;
   725             QContactManager::Error operationError = QContactManager::NoError;
   896             QMap<int, QContactManager::Error> errorMap;
   726             QMap<int, QContactManager::Error> errorMap;
   897             saveContacts(&contacts, &errorMap, operationError);
   727             saveContacts(&contacts, &errorMap, &operationError);
   898 
   728 
   899             updateContactSaveRequest(r, contacts, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
   729             updateContactSaveRequest(r, contacts, operationError, errorMap, QContactAbstractRequest::FinishedState);
   900             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
   901         }
   730         }
   902         break;
   731         break;
   903 
   732 
   904         case QContactAbstractRequest::ContactRemoveRequest:
   733         case QContactAbstractRequest::ContactRemoveRequest:
   905         {
   734         {
   913             QList<QContactLocalId> contactsToRemove = r->contactIds();
   742             QList<QContactLocalId> contactsToRemove = r->contactIds();
   914             QMap<int, QContactManager::Error> errorMap;
   743             QMap<int, QContactManager::Error> errorMap;
   915 
   744 
   916             for (int i = 0; i < contactsToRemove.size(); i++) {
   745             for (int i = 0; i < contactsToRemove.size(); i++) {
   917                 QContactManager::Error tempError;
   746                 QContactManager::Error tempError;
   918                 removeContact(contactsToRemove.at(i), changeSet, tempError);
   747                 removeContact(contactsToRemove.at(i), changeSet, &tempError);
   919 
   748 
   920                 if (tempError != QContactManager::NoError) {
   749                 if (tempError != QContactManager::NoError) {
   921                     errorMap.insert(i, tempError);
   750                     errorMap.insert(i, tempError);
   922                     operationError = tempError;
   751                     operationError = tempError;
   923                 }
   752                 }
   924             }
   753             }
   925 
   754 
   926             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
   755             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
   927                 updateContactRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
   756                 updateContactRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState);
   928             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   757             else
       
   758                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   929         }
   759         }
   930         break;
   760         break;
   931 
   761 
   932         case QContactAbstractRequest::DetailDefinitionFetchRequest:
   762         case QContactAbstractRequest::DetailDefinitionFetchRequest:
   933         {
   763         {
   935             QContactManager::Error operationError = QContactManager::NoError;
   765             QContactManager::Error operationError = QContactManager::NoError;
   936             QMap<int, QContactManager::Error> errorMap;
   766             QMap<int, QContactManager::Error> errorMap;
   937             QMap<QString, QContactDetailDefinition> requestedDefinitions;
   767             QMap<QString, QContactDetailDefinition> requestedDefinitions;
   938             QStringList names = r->definitionNames();
   768             QStringList names = r->definitionNames();
   939             if (names.isEmpty())
   769             if (names.isEmpty())
   940                 names = detailDefinitions(r->contactType(), operationError).keys(); // all definitions.
   770                 names = detailDefinitions(r->contactType(), &operationError).keys(); // all definitions.
   941 
   771 
   942             QContactManager::Error tempError;
   772             QContactManager::Error tempError;
   943             for (int i = 0; i < names.size(); i++) {
   773             for (int i = 0; i < names.size(); i++) {
   944                 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), tempError);
   774                 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), &tempError);
   945                 requestedDefinitions.insert(names.at(i), current);
   775                 requestedDefinitions.insert(names.at(i), current);
   946 
   776 
   947                 if (tempError != QContactManager::NoError) {
   777                 if (tempError != QContactManager::NoError) {
   948                     errorMap.insert(i, tempError);
   778                     errorMap.insert(i, tempError);
   949                     operationError = tempError;
   779                     operationError = tempError;
   950                 }
   780                 }
   951             }
   781             }
   952 
   782 
   953             if (!errorMap.isEmpty() || !requestedDefinitions.isEmpty() || operationError != QContactManager::NoError)
   783             if (!errorMap.isEmpty() || !requestedDefinitions.isEmpty() || operationError != QContactManager::NoError)
   954                 updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap); // emit resultsAvailable()
   784                 updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap, QContactAbstractRequest::FinishedState);
   955             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   785             else
       
   786                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   956         }
   787         }
   957         break;
   788         break;
   958 
   789 
   959         case QContactAbstractRequest::DetailDefinitionSaveRequest:
   790         case QContactAbstractRequest::DetailDefinitionSaveRequest:
   960         {
   791         {
   965             QList<QContactDetailDefinition> savedDefinitions;
   796             QList<QContactDetailDefinition> savedDefinitions;
   966 
   797 
   967             QContactManager::Error tempError;
   798             QContactManager::Error tempError;
   968             for (int i = 0; i < definitions.size(); i++) {
   799             for (int i = 0; i < definitions.size(); i++) {
   969                 QContactDetailDefinition current = definitions.at(i);
   800                 QContactDetailDefinition current = definitions.at(i);
   970                 saveDetailDefinition(current, r->contactType(), changeSet, tempError);
   801                 saveDetailDefinition(current, r->contactType(), changeSet, &tempError);
   971                 savedDefinitions.append(current);
   802                 savedDefinitions.append(current);
   972 
   803 
   973                 if (tempError != QContactManager::NoError) {
   804                 if (tempError != QContactManager::NoError) {
   974                     errorMap.insert(i, tempError);
   805                     errorMap.insert(i, tempError);
   975                     operationError = tempError;
   806                     operationError = tempError;
   976                 }
   807                 }
   977             }
   808             }
   978 
   809 
   979             // update the request with the results.
   810             // update the request with the results.
   980             updateDefinitionSaveRequest(r, savedDefinitions, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
   811             updateDefinitionSaveRequest(r, savedDefinitions, operationError, errorMap, QContactAbstractRequest::FinishedState);
   981             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
   982         }
   812         }
   983         break;
   813         break;
   984 
   814 
   985         case QContactAbstractRequest::DetailDefinitionRemoveRequest:
   815         case QContactAbstractRequest::DetailDefinitionRemoveRequest:
   986         {
   816         {
   990             QContactManager::Error operationError = QContactManager::NoError;
   820             QContactManager::Error operationError = QContactManager::NoError;
   991             QMap<int, QContactManager::Error> errorMap;
   821             QMap<int, QContactManager::Error> errorMap;
   992 
   822 
   993             for (int i = 0; i < names.size(); i++) {
   823             for (int i = 0; i < names.size(); i++) {
   994                 QContactManager::Error tempError;
   824                 QContactManager::Error tempError;
   995                 removeDetailDefinition(names.at(i), r->contactType(), changeSet, tempError);
   825                 removeDetailDefinition(names.at(i), r->contactType(), changeSet, &tempError);
   996 
   826 
   997                 if (tempError != QContactManager::NoError) {
   827                 if (tempError != QContactManager::NoError) {
   998                     errorMap.insert(i, tempError);
   828                     errorMap.insert(i, tempError);
   999                     operationError = tempError;
   829                     operationError = tempError;
  1000                 }
   830                 }
  1001             }
   831             }
  1002 
   832 
  1003             // there are no results, so just update the status with the error.
   833             // there are no results, so just update the status with the error.
  1004             updateDefinitionRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
   834             updateDefinitionRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1005             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1006         }
   835         }
  1007         break;
   836         break;
  1008 
   837 
  1009         case QContactAbstractRequest::RelationshipFetchRequest:
   838         case QContactAbstractRequest::RelationshipFetchRequest:
  1010         {
   839         {
  1011             QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest);
   840             QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest);
  1012             QContactManager::Error operationError = QContactManager::NoError;
   841             QContactManager::Error operationError = QContactManager::NoError;
  1013             QList<QContactManager::Error> operationErrors;
   842             QList<QContactManager::Error> operationErrors;
  1014             QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationshipFilter::Either, operationError);
   843             QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationship::Either, &operationError);
  1015             QList<QContactRelationship> requestedRelationships;
   844             QList<QContactRelationship> requestedRelationships;
  1016 
   845 
  1017             // select the requested relationships.
   846             // select the requested relationships.
  1018             for (int i = 0; i < allRelationships.size(); i++) {
   847             for (int i = 0; i < allRelationships.size(); i++) {
  1019                 QContactRelationship currRel = allRelationships.at(i);
   848                 QContactRelationship currRel = allRelationships.at(i);
  1026                 requestedRelationships.append(currRel);
   855                 requestedRelationships.append(currRel);
  1027             }
   856             }
  1028 
   857 
  1029             // update the request with the results.
   858             // update the request with the results.
  1030             if (!requestedRelationships.isEmpty() || operationError != QContactManager::NoError)
   859             if (!requestedRelationships.isEmpty() || operationError != QContactManager::NoError)
  1031                 updateRelationshipFetchRequest(r, requestedRelationships, operationError); // emit resultsAvailable()
   860                 updateRelationshipFetchRequest(r, requestedRelationships, operationError, QContactAbstractRequest::FinishedState);
  1032             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   861             else
       
   862                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
  1033         }
   863         }
  1034         break;
   864         break;
  1035 
   865 
  1036         case QContactAbstractRequest::RelationshipRemoveRequest:
   866         case QContactAbstractRequest::RelationshipRemoveRequest:
  1037         {
   867         {
  1038             QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest);
   868             QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest);
  1039             QContactManager::Error operationError = QContactManager::NoError;
   869             QContactManager::Error operationError = QContactManager::NoError;
  1040             QList<QContactRelationship> relationshipsToRemove = r->relationships();
   870             QList<QContactRelationship> relationshipsToRemove = r->relationships();
  1041             QMap<int, QContactManager::Error> errorMap;
   871             QMap<int, QContactManager::Error> errorMap;
  1042 
   872 
  1043             bool foundMatch = false;
   873             removeRelationships(r->relationships(), &errorMap, &operationError);
  1044             for (int i = 0; i < relationshipsToRemove.size(); i++) {
       
  1045                 QContactManager::Error tempError;
       
  1046                 removeRelationship(relationshipsToRemove.at(i), tempError);
       
  1047 
       
  1048                 if (tempError != QContactManager::NoError) {
       
  1049                     errorMap.insert(i, tempError);
       
  1050                     operationError = tempError;
       
  1051                 }
       
  1052             }
       
  1053             
       
  1054             if (foundMatch == false && operationError == QContactManager::NoError)
       
  1055                 operationError = QContactManager::DoesNotExistError;
       
  1056 
   874 
  1057             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
   875             if (!errorMap.isEmpty() || operationError != QContactManager::NoError)
  1058                 updateRelationshipRemoveRequest(r, operationError, errorMap); // emit resultsAvailable()
   876                 updateRelationshipRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1059             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
   877             else
       
   878                 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
  1060         }
   879         }
  1061         break;
   880         break;
  1062 
   881 
  1063         case QContactAbstractRequest::RelationshipSaveRequest:
   882         case QContactAbstractRequest::RelationshipSaveRequest:
  1064         {
   883         {
  1065             QContactRelationshipSaveRequest* r = static_cast<QContactRelationshipSaveRequest*>(currentRequest);
   884             QContactRelationshipSaveRequest* r = static_cast<QContactRelationshipSaveRequest*>(currentRequest);
  1066             QContactManager::Error operationError = QContactManager::NoError;
   885             QContactManager::Error operationError = QContactManager::NoError;
  1067             QMap<int, QContactManager::Error> errorMap;
   886             QMap<int, QContactManager::Error> errorMap;
  1068             QList<QContactRelationship> requestRelationships = r->relationships();
   887             QList<QContactRelationship> requestRelationships = r->relationships();
  1069             QList<QContactRelationship> savedRelationships;
   888 
  1070 
   889             saveRelationships(&requestRelationships, &errorMap, &operationError);
  1071             QContactManager::Error tempError;
       
  1072             for (int i = 0; i < requestRelationships.size(); i++) {
       
  1073                 QContactRelationship current = requestRelationships.at(i);
       
  1074                 saveRelationship(&current, tempError);
       
  1075                 savedRelationships.append(current);
       
  1076 
       
  1077                 if (tempError != QContactManager::NoError) {
       
  1078                     errorMap.insert(i, tempError);
       
  1079                     operationError = tempError;
       
  1080                 }
       
  1081             }
       
  1082 
   890 
  1083             // update the request with the results.
   891             // update the request with the results.
  1084             updateRelationshipSaveRequest(r, savedRelationships, operationError, errorMap); // there will always be results of some form.  emit resultsAvailable().
   892             updateRelationshipSaveRequest(r, requestRelationships, operationError, errorMap, QContactAbstractRequest::FinishedState);
  1085             updateRequestState(currentRequest, QContactAbstractRequest::FinishedState);
       
  1086         }
   893         }
  1087         break;
   894         break;
  1088 
   895 
  1089         default: // unknown request type.
   896         default: // unknown request type.
  1090         break;
   897         break;
  1091     }
   898     }
  1092 
   899 
  1093     // now emit any signals we have to emit
   900     // now emit any signals we have to emit
  1094     changeSet.emitSignals(this);
   901     d->emitSharedSignals(&changeSet);
  1095 }
   902 }
  1096 
   903 
  1097 /*!
   904 /*!
  1098  * \reimp
   905  * \reimp
  1099  */
   906  */
  1105     switch (feature) {
   912     switch (feature) {
  1106         case QContactManager::Groups:
   913         case QContactManager::Groups:
  1107         case QContactManager::ActionPreferences:
   914         case QContactManager::ActionPreferences:
  1108         case QContactManager::Relationships:
   915         case QContactManager::Relationships:
  1109         case QContactManager::ArbitraryRelationshipTypes:
   916         case QContactManager::ArbitraryRelationshipTypes:
  1110         case QContactManager::RelationshipOrdering:
       
  1111         case QContactManager::MutableDefinitions:
   917         case QContactManager::MutableDefinitions:
  1112             return true;
   918             return true;
  1113         case QContactManager::Anonymous:
   919         case QContactManager::Anonymous:
  1114             return d->m_anonymous;
   920             return d->m_anonymous;
  1115         case QContactManager::SelfContact:
   921         case QContactManager::SelfContact:
  1121 }
   927 }
  1122 
   928 
  1123 /*!
   929 /*!
  1124  * \reimp
   930  * \reimp
  1125  */
   931  */
  1126 QStringList QContactMemoryEngine::supportedRelationshipTypes(const QString& contactType) const
   932 bool QContactMemoryEngine::isRelationshipTypeSupported(const QString& relationshipType, const QString& contactType) const
  1127 {
   933 {
  1128     Q_UNUSED(contactType);
   934     // the memory backend supports arbitrary relationship types
  1129     return QStringList()
   935     // but some relationship types don't make sense for groups.
  1130         << QContactRelationship::HasMember
   936     if (contactType == QContactType::TypeGroup) {
  1131         << QContactRelationship::Aggregates
   937         if (relationshipType == QContactRelationship::HasSpouse || relationshipType == QContactRelationship::HasAssistant) {
  1132         << QContactRelationship::IsSameAs
   938             return false;
  1133         << QContactRelationship::HasAssistant
   939         }
  1134         << QContactRelationship::HasManager
   940     }
  1135         << QContactRelationship::HasSpouse;
   941 
       
   942     // all other relationship types for all contact types are supported.
       
   943     return true;
  1136 }
   944 }
  1137 
   945 
  1138 /*!
   946 /*!
  1139  * \reimp
   947  * \reimp
  1140  */
   948  */
  1155 
   963 
  1156     return st;
   964     return st;
  1157 }
   965 }
  1158 
   966 
  1159 /*!
   967 /*!
  1160  * This function is deprecated.  Use QContactManagerEngine::isFilterSupported() instead!
       
  1161  * The function returns true if the backend natively supports the given filter \a filter, otherwise false.
   968  * The function returns true if the backend natively supports the given filter \a filter, otherwise false.
  1162  */
   969  */
  1163 bool QContactMemoryEngine::filterSupported(const QContactFilter& filter) const
   970 bool QContactMemoryEngine::isFilterSupported(const QContactFilter& filter) const
  1164 {
   971 {
  1165     Q_UNUSED(filter);
   972     Q_UNUSED(filter);
  1166     // Until we add hashes for common stuff, fall back to slow code
   973     // Until we add hashes for common stuff, fall back to slow code
  1167     return false;
   974     return false;
  1168 }
   975 }