bool AnnotationObjectList::RemoveAnnotation(const std::string &name) { int index = IndexForName(name); if(index != -1) { RemoveAnnotation(index); return true; } return false; }
NS_IMETHODIMP nsAnnotationService::CopyAnnotations(nsIURI* aSourceURI, nsIURI* aDestURI, PRBool aOverwriteDest) { mozStorageTransaction transaction(mDBConn, PR_FALSE); // source nsTArray<nsCString> sourceNames; nsresult rv = GetPageAnnotationNamesTArray(aSourceURI, &sourceNames); NS_ENSURE_SUCCESS(rv, rv); if (sourceNames.Length() == 0) return NS_OK; // nothing to copy // dest nsTArray<nsCString> destNames; rv = GetPageAnnotationNamesTArray(aDestURI, &destNames); NS_ENSURE_SUCCESS(rv, rv); // we assume you will only have a couple annotations max per URI #ifdef DEBUG if (sourceNames.Length() > 10 || destNames.Length() > 10) { NS_WARNING("There are a lot of annotations, copying them may be inefficient."); } #endif if (aOverwriteDest) { // overwrite existing ones, remove dest dupes from DB and our list for (PRUint32 i = 0; i < sourceNames.Length(); i ++) { PRUint32 destIndex = destNames.IndexOf(sourceNames[i]); if (destIndex != destNames.NoIndex) { destNames.RemoveElementAt(destIndex); RemoveAnnotation(aDestURI, sourceNames[i]); } } } else { // don't overwrite existing ones, remove dupes from the list of source names for (PRUint32 i = 0; i < destNames.Length(); i ++) { PRUint32 sourceIndex = sourceNames.IndexOf(destNames[i]); if (sourceIndex != sourceNames.NoIndex) sourceNames.RemoveElementAt(sourceIndex); } } // given (sourceID, destID, name) this will insert a new annotation on // source with the same values of the annotation on dest. nsCOMPtr<mozIStorageStatement> statement; rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING( "INSERT INTO moz_anno (page, name_id, mime_type, content, flags, expiration) " "SELECT ?1, name_id, mime_type, content, flags, expiration " "FROM moz_anno WHERE page = ?2 AND name_id = " "(SELECT name_id FROM moz_anno_name WHERE name = ?3)"), getter_AddRefs(statement)); NS_ENSURE_SUCCESS(rv, rv); // Get the IDs of the pages in quesion. PERFORMANCE: This is the second time // we do this for each page, since GetPageAnnotationNamesTArray does it when // it gets the names. If this function requires optimization, we should only // do this once and get the names ourselves using the IDs. PRInt64 sourceID, destID; nsNavHistory* history = nsNavHistory::GetHistoryService(); NS_ENSURE_TRUE(history, NS_ERROR_FAILURE); rv = history->GetUrlIdFor(aSourceURI, &sourceID, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(sourceID, NS_ERROR_UNEXPECTED); // we should have caught this above rv = history->GetUrlIdFor(aSourceURI, &destID, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(destID, NS_ERROR_UNEXPECTED); // we should have caught this above // now we know to create annotations from all sources names and there won't // be any collisions for (PRUint32 i = 0; i < sourceNames.Length(); i ++) { statement->BindInt64Parameter(0, sourceID); statement->BindInt64Parameter(1, destID); statement->BindUTF8StringParameter(2, sourceNames[i]); rv = statement->Execute(); NS_ENSURE_SUCCESS(rv, rv); } transaction.Commit(); return NS_OK; }