NS_IMETHODIMP nsAbMDBDirectory::GetCardFromProperty(const char *aProperty, const nsACString &aValue, bool caseSensitive, nsIAbCard **result) { NS_ENSURE_ARG(aProperty); NS_ENSURE_ARG_POINTER(result); *result = nullptr; // If the value is empty, don't match. if (aValue.IsEmpty()) return NS_OK; nsresult rv; if (!mDatabase) { rv = GetAbDatabase(); // We can't find the database file, so we can't find the card at all. if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK; NS_ENSURE_SUCCESS(rv, rv); } // nsIAddrDatabase has aCaseInsensitive as its parameter return mDatabase->GetCardFromAttribute(this, aProperty, aValue, !caseSensitive, result); }
NS_IMETHODIMP nsAbMDBDirectory::GetChildCards(nsISimpleEnumerator* *result) { nsresult rv; if (mIsQueryURI) { rv = StartSearch(); NS_ENSURE_SUCCESS(rv, rv); // TODO // Search is synchronous so need to return // results after search is complete nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID)); for (auto iter = mSearchCache.Iter(); !iter.Done(); iter.Next()) { array->AppendElement(iter.Data(), false); } return NS_NewArrayEnumerator(result, array); } rv = GetAbDatabase(); if (NS_FAILED(rv) || !mDatabase) return rv; return m_IsMailList ? mDatabase->EnumerateListAddresses(this, result) : mDatabase->EnumerateCards(this, result); }
nsresult nsAbMDBDirectory::RemoveCardFromAddressList(nsIAbCard* card) { nsresult rv = NS_OK; uint32_t listTotal; int32_t i, j; // These checks ensure we don't run into null pointers // as we did when we caused bug 280463. if (!mDatabase) { rv = GetAbDatabase(); NS_ENSURE_SUCCESS(rv, rv); } if (!m_AddressList) { rv = mDatabase->GetMailingListsFromDB(this); NS_ENSURE_SUCCESS(rv, rv); // If the previous call didn't gives us an m_AddressList (and succeeded) // then we haven't got any mailing lists to try and remove the card from. // So just return without doing anything if (!m_AddressList) return NS_OK; } rv = m_AddressList->GetLength(&listTotal); NS_ENSURE_SUCCESS(rv,rv); for (i = listTotal - 1; i >= 0; i--) { nsCOMPtr<nsIAbDirectory> listDir(do_QueryElementAt(m_AddressList, i, &rv)); if (listDir) { // First remove the instance in the database mDatabase->DeleteCardFromMailList(listDir, card, false); // Now remove the instance in any lists we hold. nsCOMPtr<nsIMutableArray> pAddressLists; listDir->GetAddressLists(getter_AddRefs(pAddressLists)); if (pAddressLists) { uint32_t total; rv = pAddressLists->GetLength(&total); for (j = total - 1; j >= 0; j--) { nsCOMPtr<nsIAbCard> cardInList(do_QueryElementAt(pAddressLists, j, &rv)); bool equals; rv = cardInList->Equals(card, &equals); // should we checking email? if (NS_SUCCEEDED(rv) && equals) pAddressLists->RemoveElementAt(j); } } } } return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::AddMailList(nsIAbDirectory *list, nsIAbDirectory **addedList) { NS_ENSURE_ARG_POINTER(addedList); if (mIsQueryURI) return NS_ERROR_NOT_IMPLEMENTED; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (NS_FAILED(rv) || !mDatabase) return NS_ERROR_FAILURE; nsCOMPtr<nsIAbMDBDirectory> dblist(do_QueryInterface(list, &rv)); if (NS_FAILED(rv)) { nsCOMPtr<nsIAbDirectory> newlist(new nsAbMDBDirProperty); if (!newlist) return NS_ERROR_OUT_OF_MEMORY; rv = newlist->CopyMailList(list); NS_ENSURE_SUCCESS(rv, rv); dblist = do_QueryInterface(newlist, &rv); NS_ENSURE_SUCCESS(rv, rv); mDatabase->CreateMailListAndAddToDB(newlist, true, this); } else mDatabase->CreateMailListAndAddToDB(list, true, this); mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); uint32_t dbRowID; dblist->GetDbRowID(&dbRowID); nsAutoCString listUri(mURI); listUri.AppendLiteral("/MailList"); listUri.AppendInt(dbRowID); nsCOMPtr<nsIAbDirectory> newList; rv = AddDirectory(listUri.get(), getter_AddRefs(newList)); if (NS_SUCCEEDED(rv) && newList) { nsCOMPtr<nsIAbMDBDirectory> dbnewList(do_QueryInterface(newList, &rv)); NS_ENSURE_SUCCESS(rv, rv); dbnewList->CopyDBMailList(dblist); AddMailListToDirectory(newList); NotifyItemAdded(newList); } NS_IF_ADDREF(*addedList = newList); return rv; }
NS_IMETHODIMP nsAbMDBDirectory::DropCard(nsIAbCard* aCard, PRBool needToCopyCard) { NS_ENSURE_ARG_POINTER(aCard); if (mIsQueryURI) return NS_ERROR_NOT_IMPLEMENTED; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (NS_FAILED(rv) || !mDatabase) return NS_ERROR_FAILURE; nsCOMPtr<nsIAbCard> newCard; nsCOMPtr<nsIAbMDBCard> dbcard; if (needToCopyCard) { dbcard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); newCard = do_QueryInterface(dbcard, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = newCard->Copy(aCard); NS_ENSURE_SUCCESS(rv, rv); } else { dbcard = do_QueryInterface(aCard, &rv); NS_ENSURE_SUCCESS(rv,rv); newCard = aCard; } dbcard->SetAbDatabase(mDatabase); if (m_IsMailList) { if (needToCopyCard) { nsCOMPtr <nsIMdbRow> cardRow; // if card doesn't exist in db, add the card to the directory that // contains the mailing list. mDatabase->FindRowByCard(newCard, getter_AddRefs(cardRow)); if (!cardRow) mDatabase->CreateNewCardAndAddToDB(newCard, PR_TRUE /* notify */, this); else mDatabase->InitCardFromRow(newCard, cardRow); } // since we didn't copy the card, we don't have to notify that it was inserted mDatabase->CreateNewListCardAndAddToDB(this, m_dbRowID, newCard, PR_FALSE /* notify */); } else { mDatabase->CreateNewCardAndAddToDB(newCard, PR_TRUE /* notify */, this); } mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::ModifyCard(nsIAbCard *aModifiedCard) { NS_ENSURE_ARG_POINTER(aModifiedCard); nsresult rv; if (!mDatabase) { rv = GetAbDatabase(); NS_ENSURE_SUCCESS(rv, rv); } rv = mDatabase->EditCard(aModifiedCard, true, this); NS_ENSURE_SUCCESS(rv, rv); return mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); }
NS_IMETHODIMP nsAbMDBDirectory::EditMailListToDatabase(nsIAbCard *listCard) { if (mIsQueryURI) return NS_ERROR_NOT_IMPLEMENTED; if (!m_IsMailList) return NS_ERROR_UNEXPECTED; nsresult rv = GetAbDatabase(); NS_ENSURE_SUCCESS(rv, rv); mDatabase->EditMailList(this, listCard, true); mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::CardForEmailAddress(const nsACString &aEmailAddress, nsIAbCard ** aAbCard) { NS_ENSURE_ARG_POINTER(aAbCard); *aAbCard = nullptr; // Ensure that if we've not been given an email address we never match // so that we don't fail out unnecessarily and we don't match a blank email // address against random cards that the user hasn't supplied an email for. if (aEmailAddress.IsEmpty()) return NS_OK; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (rv == NS_ERROR_FILE_NOT_FOUND) { // If file wasn't found, the card cannot exist. return NS_OK; } NS_ENSURE_SUCCESS(rv, rv); // Convert Email to lower case in UTF-16 format. This correctly lower-cases // it and doing this change means that we can use a hash lookup in the // database rather than searching and comparing each line individually. NS_ConvertUTF8toUTF16 lowerEmail(aEmailAddress); ToLowerCase(lowerEmail); // If lower email is empty, something went wrong somewhere, e.g. the conversion. // Hence, don't go looking for a card with no email address. Something is wrong. if (lowerEmail.IsEmpty()) return NS_ERROR_FAILURE; mDatabase->GetCardFromAttribute(this, kLowerPriEmailColumn, NS_ConvertUTF16toUTF8(lowerEmail), false, aAbCard); if (!*aAbCard) { mDatabase->GetCardFromAttribute(this, kLower2ndEmailColumn, NS_ConvertUTF16toUTF8(lowerEmail), false, aAbCard); } return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::AddCard(nsIAbCard* card, nsIAbCard **addedCard) { if (mIsQueryURI) return NS_ERROR_NOT_IMPLEMENTED; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (NS_FAILED(rv) || !mDatabase) return NS_ERROR_FAILURE; nsCOMPtr<nsIAbCard> newCard; nsCOMPtr<nsIAbMDBCard> dbcard; dbcard = do_QueryInterface(card, &rv); if (NS_FAILED(rv) || !dbcard) { dbcard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); newCard = do_QueryInterface(dbcard, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = newCard->Copy(card); NS_ENSURE_SUCCESS(rv, rv); } else { newCard = card; } dbcard->SetAbDatabase (mDatabase); if (m_IsMailList) mDatabase->CreateNewListCardAndAddToDB(this, m_dbRowID, newCard, PR_TRUE /* notify */); else mDatabase->CreateNewCardAndAddToDB(newCard, PR_TRUE, this); mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); NS_IF_ADDREF(*addedCard = newCard); return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::HasCard(nsIAbCard *cards, bool *hasCard) { if(!hasCard) return NS_ERROR_NULL_POINTER; if (mIsQueryURI) { *hasCard = mSearchCache.Get(cards, nullptr); return NS_OK; } nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if(NS_SUCCEEDED(rv) && mDatabase) { if(NS_SUCCEEDED(rv)) rv = mDatabase->ContainsCard(cards, hasCard); } return rv; }
NS_IMETHODIMP nsAbMDBDirectory::AddCard(nsIAbCard* card, nsIAbCard **addedCard) { if (mIsQueryURI) return NS_ERROR_NOT_IMPLEMENTED; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (NS_FAILED(rv) || !mDatabase) return NS_ERROR_FAILURE; if (m_IsMailList) rv = mDatabase->CreateNewListCardAndAddToDB(this, m_dbRowID, card, true /* notify */); else rv = mDatabase->CreateNewCardAndAddToDB(card, true, this); NS_ENSURE_SUCCESS(rv, rv); mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); NS_IF_ADDREF(*addedCard = card); return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::GetCardsFromProperty(const char *aProperty, const nsACString &aValue, bool caseSensitive, nsISimpleEnumerator **result) { NS_ENSURE_ARG(aProperty); NS_ENSURE_ARG_POINTER(result); *result = nullptr; if (aValue.IsEmpty()) return NS_OK; if (!mDatabase) { nsresult rv = GetAbDatabase(); if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK; NS_ENSURE_SUCCESS(rv, rv); } return mDatabase->GetCardsFromAttribute(this, aProperty, aValue, !caseSensitive, result); }
NS_IMETHODIMP nsAbMDBDirectory::CardForEmailAddress(const nsACString &aEmailAddress, nsIAbCard ** aAbCard) { NS_ENSURE_ARG_POINTER(aAbCard); *aAbCard = NULL; // Ensure that if we've not been given an email address we never match // so that we don't fail out unnecessarily and we don't match a blank email // address against random cards that the user hasn't supplied an email for. if (aEmailAddress.IsEmpty()) return NS_OK; nsresult rv = NS_OK; if (!mDatabase) rv = GetAbDatabase(); if (rv == NS_ERROR_FILE_NOT_FOUND) { // If file wasn't found, the card cannot exist. return NS_OK; } NS_ENSURE_SUCCESS(rv, rv); mDatabase->GetCardFromAttribute(this, kLowerPriEmailColumn /* see #196777 */, aEmailAddress, PR_TRUE /* caseInsensitive, see bug #191798 */, aAbCard); if (!*aAbCard) { // fix for bug #187239 // didn't find it as the primary email? try again, with k2ndEmailColumn ("Additional Email") // // TODO bug #198731 // unlike the kPriEmailColumn, we don't have kLower2ndEmailColumn // so we will still suffer from bug #196777 for "additional emails" mDatabase->GetCardFromAttribute(this, k2ndEmailColumn, aEmailAddress, PR_TRUE /* caseInsensitive, see bug #191798 */, aAbCard); } return NS_OK; }
NS_IMETHODIMP nsAbMDBDirectory::DeleteCards(nsIArray *aCards) { NS_ENSURE_ARG_POINTER(aCards); nsresult rv = NS_OK; if (mIsQueryURI) { // if this is a query, delete the cards from the directory (without the query) // before we do the delete, make this directory (which represents the search) // a listener on the database, so that it will get notified when the cards are deleted // after delete, remove this query as a listener. nsCOMPtr<nsIAddrDatabase> database; rv = GetDatabase(getter_AddRefs(database)); NS_ENSURE_SUCCESS(rv,rv); rv = database->AddListener(this); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbDirectory> directory; rv = abManager->GetDirectory(mURINoQuery, getter_AddRefs(directory)); NS_ENSURE_SUCCESS(rv, rv); rv = directory->DeleteCards(aCards); NS_ENSURE_SUCCESS(rv, rv); rv = database->RemoveListener(this); NS_ENSURE_SUCCESS(rv, rv); return rv; } if (!mDatabase) rv = GetAbDatabase(); if (NS_SUCCEEDED(rv) && mDatabase) { uint32_t cardCount; uint32_t i; rv = aCards->GetLength(&cardCount); NS_ENSURE_SUCCESS(rv, rv); for (i = 0; i < cardCount; i++) { nsCOMPtr<nsIAbCard> card(do_QueryElementAt(aCards, i, &rv)); NS_ENSURE_SUCCESS(rv, rv); if (card) { uint32_t rowID; rv = card->GetPropertyAsUint32("DbRowID", &rowID); NS_ENSURE_SUCCESS(rv, rv); if (m_IsMailList) { mDatabase->DeleteCardFromMailList(this, card, true); uint32_t cardTotal = 0; int32_t i; if (m_AddressList) rv = m_AddressList->GetLength(&cardTotal); for (i = cardTotal - 1; i >= 0; i--) { nsCOMPtr<nsIAbCard> arrayCard(do_QueryElementAt(m_AddressList, i, &rv)); if (arrayCard) { // No card can have a row ID of 0 uint32_t arrayRowID = 0; arrayCard->GetPropertyAsUint32("DbRowID", &arrayRowID); if (rowID == arrayRowID) m_AddressList->RemoveElementAt(i); } } } else { mDatabase->DeleteCard(card, true, this); bool bIsMailList = false; card->GetIsMailList(&bIsMailList); if (bIsMailList) { //to do, get mailing list dir side uri and notify nsIAbManager to remove it nsAutoCString listUri(mURI); listUri.AppendLiteral("/MailList"); listUri.AppendInt(rowID); if (!listUri.IsEmpty()) { nsresult rv = NS_OK; nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbDirectory> listDir; rv = abManager->GetDirectory(listUri, getter_AddRefs(listDir)); NS_ENSURE_SUCCESS(rv, rv); uint32_t dirIndex; if (m_AddressList && NS_SUCCEEDED(m_AddressList->IndexOf(0, listDir, &dirIndex))) m_AddressList->RemoveElementAt(dirIndex); mSubDirectories.RemoveObject(listDir); if (listDir) NotifyItemDeleted(listDir); } } else { rv = RemoveCardFromAddressList(card); NS_ENSURE_SUCCESS(rv,rv); } } } } mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); } return rv; }
NS_IMETHODIMP nsAbMDBDirectory::DeleteCards(nsIArray *aCards) { nsresult rv = NS_OK; if (mIsQueryURI) { // if this is a query, delete the cards from the directory (without the query) // before we do the delete, make this directory (which represents the search) // a listener on the database, so that it will get notified when the cards are deleted // after delete, remove this query as a listener. nsCOMPtr<nsIAddrDatabase> database; rv = GetDatabase(getter_AddRefs(database)); NS_ENSURE_SUCCESS(rv,rv); rv = database->AddListener(this); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIRDFResource> resource; rv = gRDFService->GetResource(mURINoQuery, getter_AddRefs(resource)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbDirectory> directory = do_QueryInterface(resource, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = directory->DeleteCards(aCards); NS_ENSURE_SUCCESS(rv, rv); rv = database->RemoveListener(this); NS_ENSURE_SUCCESS(rv, rv); return rv; } if (!mDatabase) rv = GetAbDatabase(); if (NS_SUCCEEDED(rv) && mDatabase) { PRUint32 cardCount; PRUint32 i; rv = aCards->GetLength(&cardCount); NS_ENSURE_SUCCESS(rv, rv); for (i = 0; i < cardCount; i++) { nsCOMPtr<nsIAbCard> card(do_QueryElementAt(aCards, i, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbMDBCard> dbcard(do_QueryInterface(card, &rv)); NS_ENSURE_SUCCESS(rv, rv); if (card) { if (m_IsMailList) { mDatabase->DeleteCardFromMailList(this, card, PR_TRUE); PRUint32 cardTotal = 0; PRInt32 i; if (m_AddressList) rv = m_AddressList->GetLength(&cardTotal); for (i = cardTotal - 1; i >= 0; i--) { nsCOMPtr<nsIAbMDBCard> dbarrayCard(do_QueryElementAt(m_AddressList, i, &rv)); if (dbarrayCard) { PRUint32 tableID, rowID, cardTableID, cardRowID; dbarrayCard->GetDbTableID(&tableID); dbarrayCard->GetDbRowID(&rowID); dbcard->GetDbTableID(&cardTableID); dbcard->GetDbRowID(&cardRowID); if (tableID == cardTableID && rowID == cardRowID) m_AddressList->RemoveElementAt(i); } } } else { mDatabase->DeleteCard(card, PR_TRUE, this); PRBool bIsMailList = PR_FALSE; card->GetIsMailList(&bIsMailList); if (bIsMailList) { //to do, get mailing list dir side uri and notify rdf to remove it PRUint32 rowID; dbcard->GetDbRowID(&rowID); nsCAutoString listUri(mURI); listUri.AppendLiteral("/MailList"); listUri.AppendInt(rowID); if (!listUri.IsEmpty()) { nsresult rv = NS_OK; nsCOMPtr<nsIRDFService> rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIRDFResource> listResource; rv = rdfService->GetResource(listUri, getter_AddRefs(listResource)); nsCOMPtr<nsIAbDirectory> listDir = do_QueryInterface(listResource, &rv); if (NS_FAILED(rv)) return rv; PRUint32 dirIndex; if (m_AddressList && NS_SUCCEEDED(m_AddressList->IndexOf(0, listDir, &dirIndex))) m_AddressList->RemoveElementAt(dirIndex); mSubDirectories.RemoveObject(listDir); if (listDir) NotifyItemDeleted(listDir); } } else { rv = RemoveCardFromAddressList(card); NS_ENSURE_SUCCESS(rv,rv); } } } } mDatabase->Commit(nsAddrDBCommitType::kLargeCommit); } return rv; }