diff -r e4ebb16b39ea -r 603d3f8b6302 plugins/contacts/symbian/plugin/src/cntrelationship.cpp --- a/plugins/contacts/symbian/plugin/src/cntrelationship.cpp Fri Sep 17 08:34:34 2010 +0300 +++ b/plugins/contacts/symbian/plugin/src/cntrelationship.cpp Mon Oct 04 01:37:06 2010 +0300 @@ -211,24 +211,43 @@ { QContactManager::Error singleError; bool returnValue(true); + bool hasManyRelationshipTypes(false); *error = QContactManager::NoError; - // loop through the relationships - for (int i = 0; i < relationships->count(); i++) - { - // save the relationship - saveRelationship(affectedContactIds, &(relationships->operator[](i)), &singleError); - if (errorMap && singleError != QContactManager::NoError) { - errorMap->insert(i, singleError); +#ifdef SYMBIAN_BACKEND_USE_SQLITE + TInt symbianError = KErrNone; + QString relationshipType; + + // validate relationships + returnValue = validateRelationships(*relationships, relationshipType, error); + hasManyRelationshipTypes = relationshipType.isEmpty(); + + // if all relationships are valid and of the same type, we can try to use the batch save, which is much faster + if (returnValue && !hasManyRelationshipTypes) { + if (!relationships->isEmpty()) { + CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationshipType); + TRAP(symbianError, returnValue = abstractRelationship->saveRelationshipsL(affectedContactIds, relationships, &singleError)); + returnValue = returnValue && singleError == QContactManager::NoError && symbianError == KErrNone; } - - // update the total error - if (singleError != QContactManager::NoError) { - *error = singleError; - returnValue = false; + } +#endif + // if validation or batch save failed, or if there are many different relationship types, + // the relationships need to be added one by one + if (!returnValue || hasManyRelationshipTypes) { + for (int i = 0; i < relationships->count(); ++i) { + // save the relationship + saveRelationship(affectedContactIds, &(relationships->operator[](i)), &singleError); + if (errorMap && singleError != QContactManager::NoError) { + errorMap->insert(i, singleError); + } + + // update the total error + if (singleError != QContactManager::NoError) { + *error = singleError; + returnValue = false; + } } - } return returnValue; @@ -272,24 +291,47 @@ */ bool CntRelationship::removeRelationships(QSet *affectedContactIds, const QList& relationships, QMap* errorMap, QContactManager::Error* error) { + QContactManager::Error singleError; bool returnValue(true); + bool hasManyRelationshipTypes(false); + *error = QContactManager::NoError; - QContactManager::Error qtError(QContactManager::NoError); + +#ifdef SYMBIAN_BACKEND_USE_SQLITE + TInt symbianError = KErrNone; + QString relationshipType; - //loop through the relationships - for(int i = 0; i < relationships.count(); i++) - { - //remove the relationships - removeRelationship(affectedContactIds, relationships.at(i), &qtError); - if (errorMap && qtError != QContactManager::NoError) - errorMap->insert(i, qtError); - - // update the total error - if (qtError != QContactManager::NoError) { - returnValue = false; - *error = qtError; + // validate relationships + returnValue = validateRelationships(relationships, relationshipType, error); + hasManyRelationshipTypes = relationshipType.isEmpty(); + + // if all relationships are valid and of the same type, we can try to use the batch remove, which is much faster + if (returnValue && !hasManyRelationshipTypes) { + if (!relationships.isEmpty()) { + CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationshipType); + TRAP(symbianError, returnValue = abstractRelationship->removeRelationshipsL(affectedContactIds, relationships, &singleError)); + returnValue = returnValue && singleError == QContactManager::NoError && symbianError == KErrNone; } } +#endif + // if validation or batch remove failed, or if there are many relationship types, + // the relationships need to be removed one by one + if (!returnValue || hasManyRelationshipTypes) { + for (int i = 0; i < relationships.count(); ++i) { + //remove the relationships + removeRelationship(affectedContactIds, relationships.at(i), &singleError); + if (errorMap && singleError != QContactManager::NoError) { + errorMap->insert(i, singleError); + } + + // update the total error + if (singleError != QContactManager::NoError) { + returnValue = false; + *error = singleError; + } + } + } + return returnValue; } @@ -350,3 +392,45 @@ CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationship.relationshipType()); return abstractRelationship->validateRelationship(relationship, error); } + +#ifdef SYMBIAN_BACKEND_USE_SQLITE +/* + * Validates the relationships. If all valid relationships are of the same type, + * the type will be passed back in relationshipType. Otherwise it will be empty. + */ +bool CntRelationship::validateRelationships(const QList &relationships, QString &relationshipType, QContactManager::Error *error) +{ + QContactManager::Error validationError; + bool hasManyRelationshipTypes = false; + bool returnValue = true; + + foreach (QContactRelationship relationship, relationships) { + if (validateRelationship(relationship, &validationError)) { + // Update manager uri to this manager if it is empty + if (relationship.second().managerUri().isEmpty()) { + QContactId second = relationship.second(); + second.setManagerUri(m_managerUri); + relationship.setSecond(second); + } + + // get the relationship type + if (relationship.relationshipType() != relationshipType && !relationshipType.isEmpty()) { + hasManyRelationshipTypes = true; + } + else if (relationshipType.isEmpty()) { + relationshipType = relationship.relationshipType(); + } + } + else { + *error = validationError; + returnValue = false; + } + } + + if (hasManyRelationshipTypes) { + relationshipType.clear(); + } + + return returnValue; +} +#endif