LCOV - code coverage report
Current view: top level - toolkit/components/places - nsAnnotationService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 19 912 2.1 %
Date: 2017-07-14 16:53:18 Functions: 7 69 10.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/ArrayUtils.h"
       7             : 
       8             : #include "nsAnnotationService.h"
       9             : #include "nsNavHistory.h"
      10             : #include "nsPlacesTables.h"
      11             : #include "nsPlacesIndexes.h"
      12             : #include "nsPlacesMacros.h"
      13             : #include "Helpers.h"
      14             : 
      15             : #include "nsNetUtil.h"
      16             : #include "nsIVariant.h"
      17             : #include "nsString.h"
      18             : #include "nsVariant.h"
      19             : #include "mozilla/storage.h"
      20             : 
      21             : #include "GeckoProfiler.h"
      22             : 
      23             : #include "nsNetCID.h"
      24             : 
      25             : using namespace mozilla;
      26             : using namespace mozilla::places;
      27             : 
      28             : #define ENSURE_ANNO_TYPE(_type, _statement)                                    \
      29             :   PR_BEGIN_MACRO                                                               \
      30             :   int32_t type = _statement->AsInt32(kAnnoIndex_Type);                         \
      31             :   NS_ENSURE_TRUE(type == nsIAnnotationService::_type, NS_ERROR_INVALID_ARG);   \
      32             :   PR_END_MACRO
      33             : 
      34             : #define NOTIFY_ANNOS_OBSERVERS(_notification)                                  \
      35             :   PR_BEGIN_MACRO                                                               \
      36             :   for (int32_t i = 0; i < mObservers.Count(); i++)                             \
      37             :     mObservers[i]->_notification;                                              \
      38             :   PR_END_MACRO
      39             : 
      40             : const int32_t nsAnnotationService::kAnnoIndex_ID = 0;
      41             : const int32_t nsAnnotationService::kAnnoIndex_PageOrItem = 1;
      42             : const int32_t nsAnnotationService::kAnnoIndex_NameID = 2;
      43             : const int32_t nsAnnotationService::kAnnoIndex_Content = 3;
      44             : const int32_t nsAnnotationService::kAnnoIndex_Flags = 4;
      45             : const int32_t nsAnnotationService::kAnnoIndex_Expiration = 5;
      46             : const int32_t nsAnnotationService::kAnnoIndex_Type = 6;
      47             : const int32_t nsAnnotationService::kAnnoIndex_DateAdded = 7;
      48             : const int32_t nsAnnotationService::kAnnoIndex_LastModified = 8;
      49             : 
      50             : namespace mozilla {
      51             : namespace places {
      52             : 
      53             : ////////////////////////////////////////////////////////////////////////////////
      54             : //// AnnotatedResult
      55             : 
      56           0 : AnnotatedResult::AnnotatedResult(const nsCString& aGUID,
      57             :                                  nsIURI* aURI,
      58             :                                  int64_t aItemId,
      59             :                                  const nsACString& aAnnotationName,
      60           0 :                                  nsIVariant* aAnnotationValue)
      61             : : mGUID(aGUID)
      62             : , mURI(aURI)
      63             : , mItemId(aItemId)
      64             : , mAnnotationName(aAnnotationName)
      65           0 : , mAnnotationValue(aAnnotationValue)
      66             : {
      67           0 : }
      68             : 
      69           0 : AnnotatedResult::~AnnotatedResult()
      70             : {
      71           0 : }
      72             : 
      73             : NS_IMETHODIMP
      74           0 : AnnotatedResult::GetGuid(nsACString& _guid)
      75             : {
      76           0 :   _guid = mGUID;
      77           0 :   return NS_OK;
      78             : }
      79             : 
      80             : NS_IMETHODIMP
      81           0 : AnnotatedResult::GetUri(nsIURI** _uri)
      82             : {
      83           0 :   NS_IF_ADDREF(*_uri = mURI);
      84           0 :   return NS_OK;
      85             : }
      86             : 
      87             : NS_IMETHODIMP
      88           0 : AnnotatedResult::GetItemId(int64_t* _itemId)
      89             : {
      90           0 :   *_itemId = mItemId;
      91           0 :   return NS_OK;
      92             : }
      93             : 
      94             : NS_IMETHODIMP
      95           0 : AnnotatedResult::GetAnnotationName(nsACString& _annotationName)
      96             : {
      97           0 :   _annotationName = mAnnotationName;
      98           0 :   return NS_OK;
      99             : }
     100             : 
     101             : NS_IMETHODIMP
     102           0 : AnnotatedResult::GetAnnotationValue(nsIVariant** _annotationValue)
     103             : {
     104           0 :   NS_IF_ADDREF(*_annotationValue = mAnnotationValue);
     105           0 :   return NS_OK;
     106             : }
     107             : 
     108           0 : NS_IMPL_ISUPPORTS(AnnotatedResult, mozIAnnotatedResult)
     109             : 
     110             : } // namespace places
     111             : } // namespace mozilla
     112             : 
     113           2 : PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsAnnotationService, gAnnotationService)
     114             : 
     115           9 : NS_IMPL_ISUPPORTS(nsAnnotationService
     116             : , nsIAnnotationService
     117             : , nsIObserver
     118             : , nsISupportsWeakReference
     119             : )
     120             : 
     121             : 
     122           1 : nsAnnotationService::nsAnnotationService()
     123           1 :   : mHasSessionAnnotations(false)
     124             : {
     125           1 :   NS_ASSERTION(!gAnnotationService,
     126             :                "Attempting to create two instances of the service!");
     127           1 :   gAnnotationService = this;
     128           1 : }
     129             : 
     130             : 
     131           0 : nsAnnotationService::~nsAnnotationService()
     132             : {
     133           0 :   NS_ASSERTION(gAnnotationService == this,
     134             :                "Deleting a non-singleton instance of the service");
     135           0 :   if (gAnnotationService == this)
     136           0 :     gAnnotationService = nullptr;
     137           0 : }
     138             : 
     139             : 
     140             : nsresult
     141           1 : nsAnnotationService::Init()
     142             : {
     143           1 :   mDB = Database::GetDatabase();
     144           1 :   NS_ENSURE_STATE(mDB);
     145             : 
     146           2 :   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
     147           1 :   if (obsSvc) {
     148           1 :     (void)obsSvc->AddObserver(this, TOPIC_PLACES_SHUTDOWN, true);
     149             :   }
     150             : 
     151           1 :   return NS_OK;
     152             : }
     153             : 
     154             : nsresult
     155           0 : nsAnnotationService::SetAnnotationStringInternal(nsIURI* aURI,
     156             :                                                  int64_t aItemId,
     157             :                                                  const nsACString& aName,
     158             :                                                  const nsAString& aValue,
     159             :                                                  int32_t aFlags,
     160             :                                                  uint16_t aExpiration)
     161             : {
     162           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
     163           0 :   nsCOMPtr<mozIStorageStatement> statement;
     164           0 :   nsresult rv = StartSetAnnotation(aURI, aItemId, aName, aFlags, aExpiration,
     165             :                                    nsIAnnotationService::TYPE_STRING,
     166           0 :                                    statement);
     167           0 :   NS_ENSURE_SUCCESS(rv, rv);
     168           0 :   mozStorageStatementScoper scoper(statement);
     169             : 
     170           0 :   rv = statement->BindStringByName(NS_LITERAL_CSTRING("content"), aValue);
     171           0 :   NS_ENSURE_SUCCESS(rv, rv);
     172             : 
     173           0 :   rv = statement->Execute();
     174           0 :   NS_ENSURE_SUCCESS(rv, rv);
     175             : 
     176           0 :   rv = transaction.Commit();
     177           0 :   NS_ENSURE_SUCCESS(rv, rv);
     178             : 
     179           0 :   return NS_OK;
     180             : }
     181             : 
     182             : 
     183             : NS_IMETHODIMP
     184           0 : nsAnnotationService::SetPageAnnotation(nsIURI* aURI,
     185             :                                        const nsACString& aName,
     186             :                                        nsIVariant* aValue,
     187             :                                        int32_t aFlags,
     188             :                                        uint16_t aExpiration)
     189             : {
     190           0 :   NS_ENSURE_ARG(aURI);
     191           0 :   NS_ENSURE_ARG(aValue);
     192             : 
     193             :   uint16_t dataType;
     194           0 :   nsresult rv = aValue->GetDataType(&dataType);
     195           0 :   NS_ENSURE_SUCCESS(rv, rv);
     196             : 
     197           0 :   switch (dataType) {
     198             :     case nsIDataType::VTYPE_INT8:
     199             :     case nsIDataType::VTYPE_UINT8:
     200             :     case nsIDataType::VTYPE_INT16:
     201             :     case nsIDataType::VTYPE_UINT16:
     202             :     case nsIDataType::VTYPE_INT32:
     203             :     case nsIDataType::VTYPE_UINT32:
     204             :     case nsIDataType::VTYPE_BOOL: {
     205             :       int32_t valueInt;
     206           0 :       rv = aValue->GetAsInt32(&valueInt);
     207           0 :       if (NS_SUCCEEDED(rv)) {
     208           0 :         NS_ENSURE_SUCCESS(rv, rv);
     209           0 :         rv = SetPageAnnotationInt32(aURI, aName, valueInt, aFlags, aExpiration);
     210           0 :         NS_ENSURE_SUCCESS(rv, rv);
     211           0 :         return NS_OK;
     212             :       }
     213             :       // Fall through int64_t case otherwise.
     214             :       MOZ_FALLTHROUGH;
     215             :     }
     216             :     case nsIDataType::VTYPE_INT64:
     217             :     case nsIDataType::VTYPE_UINT64: {
     218             :       int64_t valueLong;
     219           0 :       rv = aValue->GetAsInt64(&valueLong);
     220           0 :       if (NS_SUCCEEDED(rv)) {
     221           0 :         NS_ENSURE_SUCCESS(rv, rv);
     222           0 :         rv = SetPageAnnotationInt64(aURI, aName, valueLong, aFlags, aExpiration);
     223           0 :         NS_ENSURE_SUCCESS(rv, rv);
     224           0 :         return NS_OK;
     225             :       }
     226             :       // Fall through double case otherwise.
     227             :       MOZ_FALLTHROUGH;
     228             :     }
     229             :     case nsIDataType::VTYPE_FLOAT:
     230             :     case nsIDataType::VTYPE_DOUBLE: {
     231             :       double valueDouble;
     232           0 :       rv = aValue->GetAsDouble(&valueDouble);
     233           0 :       NS_ENSURE_SUCCESS(rv, rv);
     234           0 :       rv = SetPageAnnotationDouble(aURI, aName, valueDouble, aFlags, aExpiration);
     235           0 :       NS_ENSURE_SUCCESS(rv, rv);
     236           0 :       return NS_OK;
     237             :     }
     238             :     case nsIDataType::VTYPE_CHAR:
     239             :     case nsIDataType::VTYPE_WCHAR:
     240             :     case nsIDataType::VTYPE_DOMSTRING:
     241             :     case nsIDataType::VTYPE_CHAR_STR:
     242             :     case nsIDataType::VTYPE_WCHAR_STR:
     243             :     case nsIDataType::VTYPE_STRING_SIZE_IS:
     244             :     case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     245             :     case nsIDataType::VTYPE_UTF8STRING:
     246             :     case nsIDataType::VTYPE_CSTRING:
     247             :     case nsIDataType::VTYPE_ASTRING: {
     248           0 :       nsAutoString stringValue;
     249           0 :       rv = aValue->GetAsAString(stringValue);
     250           0 :       NS_ENSURE_SUCCESS(rv, rv);
     251           0 :       rv = SetPageAnnotationString(aURI, aName, stringValue, aFlags, aExpiration);
     252           0 :       NS_ENSURE_SUCCESS(rv, rv);
     253           0 :       return NS_OK;
     254             :     }
     255             :   }
     256             : 
     257           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     258             : }
     259             : 
     260             : 
     261             : NS_IMETHODIMP
     262           0 : nsAnnotationService::SetItemAnnotation(int64_t aItemId,
     263             :                                        const nsACString& aName,
     264             :                                        nsIVariant* aValue,
     265             :                                        int32_t aFlags,
     266             :                                        uint16_t aExpiration,
     267             :                                        uint16_t aSource)
     268             : {
     269           0 :   AUTO_PROFILER_LABEL("nsAnnotationService::SetItemAnnotation", OTHER);
     270             : 
     271           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     272           0 :   NS_ENSURE_ARG(aValue);
     273             : 
     274           0 :   if (aExpiration == EXPIRE_WITH_HISTORY)
     275           0 :     return NS_ERROR_INVALID_ARG;
     276             : 
     277             :   uint16_t dataType;
     278           0 :   nsresult rv = aValue->GetDataType(&dataType);
     279           0 :   NS_ENSURE_SUCCESS(rv, rv);
     280             : 
     281           0 :   switch (dataType) {
     282             :     case nsIDataType::VTYPE_INT8:
     283             :     case nsIDataType::VTYPE_UINT8:
     284             :     case nsIDataType::VTYPE_INT16:
     285             :     case nsIDataType::VTYPE_UINT16:
     286             :     case nsIDataType::VTYPE_INT32:
     287             :     case nsIDataType::VTYPE_UINT32:
     288             :     case nsIDataType::VTYPE_BOOL: {
     289             :       int32_t valueInt;
     290           0 :       rv = aValue->GetAsInt32(&valueInt);
     291           0 :       if (NS_SUCCEEDED(rv)) {
     292           0 :         NS_ENSURE_SUCCESS(rv, rv);
     293           0 :         rv = SetItemAnnotationInt32(aItemId, aName, valueInt, aFlags, aExpiration, aSource);
     294           0 :         NS_ENSURE_SUCCESS(rv, rv);
     295           0 :         return NS_OK;
     296             :       }
     297             :       // Fall through int64_t case otherwise.
     298             :       MOZ_FALLTHROUGH;
     299             :     }
     300             :     case nsIDataType::VTYPE_INT64:
     301             :     case nsIDataType::VTYPE_UINT64: {
     302             :       int64_t valueLong;
     303           0 :       rv = aValue->GetAsInt64(&valueLong);
     304           0 :       if (NS_SUCCEEDED(rv)) {
     305           0 :         NS_ENSURE_SUCCESS(rv, rv);
     306           0 :         rv = SetItemAnnotationInt64(aItemId, aName, valueLong, aFlags, aExpiration, aSource);
     307           0 :         NS_ENSURE_SUCCESS(rv, rv);
     308           0 :         return NS_OK;
     309             :       }
     310             :       // Fall through double case otherwise.
     311             :       MOZ_FALLTHROUGH;
     312             :     }
     313             :     case nsIDataType::VTYPE_FLOAT:
     314             :     case nsIDataType::VTYPE_DOUBLE: {
     315             :       double valueDouble;
     316           0 :       rv = aValue->GetAsDouble(&valueDouble);
     317           0 :       NS_ENSURE_SUCCESS(rv, rv);
     318           0 :       rv = SetItemAnnotationDouble(aItemId, aName, valueDouble, aFlags, aExpiration, aSource);
     319           0 :       NS_ENSURE_SUCCESS(rv, rv);
     320           0 :       return NS_OK;
     321             :     }
     322             :     case nsIDataType::VTYPE_CHAR:
     323             :     case nsIDataType::VTYPE_WCHAR:
     324             :     case nsIDataType::VTYPE_DOMSTRING:
     325             :     case nsIDataType::VTYPE_CHAR_STR:
     326             :     case nsIDataType::VTYPE_WCHAR_STR:
     327             :     case nsIDataType::VTYPE_STRING_SIZE_IS:
     328             :     case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     329             :     case nsIDataType::VTYPE_UTF8STRING:
     330             :     case nsIDataType::VTYPE_CSTRING:
     331             :     case nsIDataType::VTYPE_ASTRING: {
     332           0 :       nsAutoString stringValue;
     333           0 :       rv = aValue->GetAsAString(stringValue);
     334           0 :       NS_ENSURE_SUCCESS(rv, rv);
     335           0 :       rv = SetItemAnnotationString(aItemId, aName, stringValue, aFlags, aExpiration, aSource);
     336           0 :       NS_ENSURE_SUCCESS(rv, rv);
     337           0 :       return NS_OK;
     338             :     }
     339             :   }
     340             : 
     341           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     342             : }
     343             : 
     344             : 
     345             : NS_IMETHODIMP
     346           0 : nsAnnotationService::SetPageAnnotationString(nsIURI* aURI,
     347             :                                              const nsACString& aName,
     348             :                                              const nsAString& aValue,
     349             :                                              int32_t aFlags,
     350             :                                              uint16_t aExpiration)
     351             : {
     352           0 :   NS_ENSURE_ARG(aURI);
     353             : 
     354           0 :   nsresult rv = SetAnnotationStringInternal(aURI, 0, aName, aValue,
     355           0 :                                             aFlags, aExpiration);
     356           0 :   NS_ENSURE_SUCCESS(rv, rv);
     357             : 
     358           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationSet(aURI, aName));
     359             : 
     360           0 :   return NS_OK;
     361             : }
     362             : 
     363             : 
     364             : NS_IMETHODIMP
     365           0 : nsAnnotationService::SetItemAnnotationString(int64_t aItemId,
     366             :                                              const nsACString& aName,
     367             :                                              const nsAString& aValue,
     368             :                                              int32_t aFlags,
     369             :                                              uint16_t aExpiration,
     370             :                                              uint16_t aSource)
     371             : {
     372           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     373             : 
     374           0 :   if (aExpiration == EXPIRE_WITH_HISTORY)
     375           0 :     return NS_ERROR_INVALID_ARG;
     376             : 
     377           0 :   nsresult rv = SetAnnotationStringInternal(nullptr, aItemId, aName, aValue,
     378           0 :                                             aFlags, aExpiration);
     379           0 :   NS_ENSURE_SUCCESS(rv, rv);
     380             : 
     381           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationSet(aItemId, aName, aSource));
     382             : 
     383           0 :   return NS_OK;
     384             : }
     385             : 
     386             : 
     387             : nsresult
     388           0 : nsAnnotationService::SetAnnotationInt32Internal(nsIURI* aURI,
     389             :                                                 int64_t aItemId,
     390             :                                                 const nsACString& aName,
     391             :                                                 int32_t aValue,
     392             :                                                 int32_t aFlags,
     393             :                                                 uint16_t aExpiration)
     394             : {
     395           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
     396           0 :   nsCOMPtr<mozIStorageStatement> statement;
     397           0 :   nsresult rv = StartSetAnnotation(aURI, aItemId, aName, aFlags, aExpiration,
     398             :                                    nsIAnnotationService::TYPE_INT32,
     399           0 :                                    statement);
     400           0 :   NS_ENSURE_SUCCESS(rv, rv);
     401           0 :   mozStorageStatementScoper scoper(statement);
     402             : 
     403           0 :   rv = statement->BindInt32ByName(NS_LITERAL_CSTRING("content"), aValue);
     404           0 :   NS_ENSURE_SUCCESS(rv, rv);
     405             : 
     406           0 :   rv = statement->Execute();
     407           0 :   NS_ENSURE_SUCCESS(rv, rv);
     408             : 
     409           0 :   rv = transaction.Commit();
     410           0 :   NS_ENSURE_SUCCESS(rv, rv);
     411             : 
     412           0 :   return NS_OK;
     413             : }
     414             : 
     415             : 
     416             : NS_IMETHODIMP
     417           0 : nsAnnotationService::SetPageAnnotationInt32(nsIURI* aURI,
     418             :                                             const nsACString& aName,
     419             :                                             int32_t aValue,
     420             :                                             int32_t aFlags,
     421             :                                             uint16_t aExpiration)
     422             : {
     423           0 :   NS_ENSURE_ARG(aURI);
     424             : 
     425           0 :   nsresult rv = SetAnnotationInt32Internal(aURI, 0, aName, aValue,
     426           0 :                                            aFlags, aExpiration);
     427           0 :   NS_ENSURE_SUCCESS(rv, rv);
     428             : 
     429           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationSet(aURI, aName));
     430             : 
     431           0 :   return NS_OK;
     432             : }
     433             : 
     434             : 
     435             : NS_IMETHODIMP
     436           0 : nsAnnotationService::SetItemAnnotationInt32(int64_t aItemId,
     437             :                                             const nsACString& aName,
     438             :                                             int32_t aValue,
     439             :                                             int32_t aFlags,
     440             :                                             uint16_t aExpiration,
     441             :                                             uint16_t aSource)
     442             : {
     443           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     444             : 
     445           0 :   if (aExpiration == EXPIRE_WITH_HISTORY)
     446           0 :     return NS_ERROR_INVALID_ARG;
     447             : 
     448           0 :   nsresult rv = SetAnnotationInt32Internal(nullptr, aItemId, aName, aValue,
     449           0 :                                            aFlags, aExpiration);
     450           0 :   NS_ENSURE_SUCCESS(rv, rv);
     451             : 
     452           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationSet(aItemId, aName, aSource));
     453             : 
     454           0 :   return NS_OK;
     455             : }
     456             : 
     457             : 
     458             : nsresult
     459           0 : nsAnnotationService::SetAnnotationInt64Internal(nsIURI* aURI,
     460             :                                                 int64_t aItemId,
     461             :                                                 const nsACString& aName,
     462             :                                                 int64_t aValue,
     463             :                                                 int32_t aFlags,
     464             :                                                 uint16_t aExpiration)
     465             : {
     466           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
     467           0 :   nsCOMPtr<mozIStorageStatement> statement;
     468           0 :   nsresult rv = StartSetAnnotation(aURI, aItemId, aName, aFlags, aExpiration,
     469             :                                    nsIAnnotationService::TYPE_INT64,
     470           0 :                                    statement);
     471           0 :   NS_ENSURE_SUCCESS(rv, rv);
     472           0 :   mozStorageStatementScoper scoper(statement);
     473             : 
     474           0 :   rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("content"), aValue);
     475           0 :   NS_ENSURE_SUCCESS(rv, rv);
     476             : 
     477           0 :   rv = statement->Execute();
     478           0 :   NS_ENSURE_SUCCESS(rv, rv);
     479             : 
     480           0 :   rv = transaction.Commit();
     481           0 :   NS_ENSURE_SUCCESS(rv, rv);
     482             : 
     483           0 :   return NS_OK;
     484             : }
     485             : 
     486             : 
     487             : NS_IMETHODIMP
     488           0 : nsAnnotationService::SetPageAnnotationInt64(nsIURI* aURI,
     489             :                                             const nsACString& aName,
     490             :                                             int64_t aValue,
     491             :                                             int32_t aFlags,
     492             :                                             uint16_t aExpiration)
     493             : {
     494           0 :   NS_ENSURE_ARG(aURI);
     495             : 
     496           0 :   nsresult rv = SetAnnotationInt64Internal(aURI, 0, aName, aValue,
     497           0 :                                            aFlags, aExpiration);
     498           0 :   NS_ENSURE_SUCCESS(rv, rv);
     499             : 
     500           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationSet(aURI, aName));
     501             : 
     502           0 :   return NS_OK;
     503             : }
     504             : 
     505             : 
     506             : NS_IMETHODIMP
     507           0 : nsAnnotationService::SetItemAnnotationInt64(int64_t aItemId,
     508             :                                             const nsACString& aName,
     509             :                                             int64_t aValue,
     510             :                                             int32_t aFlags,
     511             :                                             uint16_t aExpiration,
     512             :                                             uint16_t aSource)
     513             : {
     514           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     515             : 
     516           0 :   if (aExpiration == EXPIRE_WITH_HISTORY)
     517           0 :     return NS_ERROR_INVALID_ARG;
     518             : 
     519           0 :   nsresult rv = SetAnnotationInt64Internal(nullptr, aItemId, aName, aValue,
     520           0 :                                            aFlags, aExpiration);
     521           0 :   NS_ENSURE_SUCCESS(rv, rv);
     522             : 
     523           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationSet(aItemId, aName, aSource));
     524             : 
     525           0 :   return NS_OK;
     526             : }
     527             : 
     528             : 
     529             : nsresult
     530           0 : nsAnnotationService::SetAnnotationDoubleInternal(nsIURI* aURI,
     531             :                                                  int64_t aItemId,
     532             :                                                  const nsACString& aName,
     533             :                                                  double aValue,
     534             :                                                  int32_t aFlags,
     535             :                                                  uint16_t aExpiration)
     536             : {
     537           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
     538           0 :   nsCOMPtr<mozIStorageStatement> statement;
     539           0 :   nsresult rv = StartSetAnnotation(aURI, aItemId, aName, aFlags, aExpiration,
     540             :                                    nsIAnnotationService::TYPE_DOUBLE,
     541           0 :                                    statement);
     542           0 :   NS_ENSURE_SUCCESS(rv, rv);
     543           0 :   mozStorageStatementScoper scoper(statement);
     544             : 
     545           0 :   rv = statement->BindDoubleByName(NS_LITERAL_CSTRING("content"), aValue);
     546           0 :   NS_ENSURE_SUCCESS(rv, rv);
     547             : 
     548           0 :   rv = statement->Execute();
     549           0 :   NS_ENSURE_SUCCESS(rv, rv);
     550             : 
     551           0 :   rv = transaction.Commit();
     552           0 :   NS_ENSURE_SUCCESS(rv, rv);
     553             : 
     554           0 :   return NS_OK;
     555             : }
     556             : 
     557             : 
     558             : NS_IMETHODIMP
     559           0 : nsAnnotationService::SetPageAnnotationDouble(nsIURI* aURI,
     560             :                                              const nsACString& aName,
     561             :                                              double aValue,
     562             :                                              int32_t aFlags,
     563             :                                              uint16_t aExpiration)
     564             : {
     565           0 :   NS_ENSURE_ARG(aURI);
     566             : 
     567           0 :   nsresult rv = SetAnnotationDoubleInternal(aURI, 0, aName, aValue,
     568           0 :                                             aFlags, aExpiration);
     569           0 :   NS_ENSURE_SUCCESS(rv, rv);
     570             : 
     571           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationSet(aURI, aName));
     572             : 
     573           0 :   return NS_OK;
     574             : }
     575             : 
     576             : 
     577             : NS_IMETHODIMP
     578           0 : nsAnnotationService::SetItemAnnotationDouble(int64_t aItemId,
     579             :                                              const nsACString& aName,
     580             :                                              double aValue,
     581             :                                              int32_t aFlags,
     582             :                                              uint16_t aExpiration,
     583             :                                              uint16_t aSource)
     584             : {
     585           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     586             : 
     587           0 :   if (aExpiration == EXPIRE_WITH_HISTORY)
     588           0 :     return NS_ERROR_INVALID_ARG;
     589             : 
     590           0 :   nsresult rv = SetAnnotationDoubleInternal(nullptr, aItemId, aName, aValue,
     591           0 :                                             aFlags, aExpiration);
     592           0 :   NS_ENSURE_SUCCESS(rv, rv);
     593             : 
     594           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationSet(aItemId, aName, aSource));
     595             : 
     596           0 :   return NS_OK;
     597             : }
     598             : 
     599             : NS_IMETHODIMP
     600           0 : nsAnnotationService::GetPageAnnotationString(nsIURI* aURI,
     601             :                                              const nsACString& aName,
     602             :                                              nsAString& _retval)
     603             : {
     604           0 :   NS_ENSURE_ARG(aURI);
     605             : 
     606           0 :   nsCOMPtr<mozIStorageStatement> statement;
     607           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     608           0 :   if (NS_FAILED(rv))
     609           0 :     return rv;
     610             : 
     611           0 :   mozStorageStatementScoper scoper(statement);
     612           0 :   ENSURE_ANNO_TYPE(TYPE_STRING, statement);
     613           0 :   rv = statement->GetString(kAnnoIndex_Content, _retval);
     614           0 :   NS_ENSURE_SUCCESS(rv, rv);
     615             : 
     616           0 :   return NS_OK;
     617             : }
     618             : 
     619             : 
     620             : NS_IMETHODIMP
     621           0 : nsAnnotationService::GetItemAnnotationString(int64_t aItemId,
     622             :                                              const nsACString& aName,
     623             :                                              nsAString& _retval)
     624             : {
     625           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     626             : 
     627           0 :   nsCOMPtr<mozIStorageStatement> statement;
     628           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     629           0 :   if (NS_FAILED(rv))
     630           0 :     return rv;
     631             : 
     632           0 :   mozStorageStatementScoper scoper(statement);
     633           0 :   ENSURE_ANNO_TYPE(TYPE_STRING, statement);
     634           0 :   rv = statement->GetString(kAnnoIndex_Content, _retval);
     635           0 :   NS_ENSURE_SUCCESS(rv, rv);
     636             : 
     637           0 :   return NS_OK;
     638             : }
     639             : 
     640             : 
     641             : NS_IMETHODIMP
     642           0 : nsAnnotationService::GetPageAnnotation(nsIURI* aURI,
     643             :                                        const nsACString& aName,
     644             :                                        nsIVariant** _retval)
     645             : {
     646           0 :   NS_ENSURE_ARG(aURI);
     647           0 :   NS_ENSURE_ARG_POINTER(_retval);
     648             : 
     649           0 :   nsCOMPtr<mozIStorageStatement> statement;
     650           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     651           0 :   if (NS_FAILED(rv))
     652           0 :     return rv;
     653             : 
     654           0 :   mozStorageStatementScoper scoper(statement);
     655             : 
     656           0 :   nsCOMPtr<nsIWritableVariant> value = new nsVariant();
     657           0 :   int32_t type = statement->AsInt32(kAnnoIndex_Type);
     658           0 :   switch (type) {
     659             :     case nsIAnnotationService::TYPE_INT32:
     660             :     case nsIAnnotationService::TYPE_INT64:
     661             :     case nsIAnnotationService::TYPE_DOUBLE: {
     662           0 :       rv = value->SetAsDouble(statement->AsDouble(kAnnoIndex_Content));
     663           0 :       break;
     664             :     }
     665             :     case nsIAnnotationService::TYPE_STRING: {
     666           0 :       nsAutoString valueString;
     667           0 :       rv = statement->GetString(kAnnoIndex_Content, valueString);
     668           0 :       if (NS_SUCCEEDED(rv))
     669           0 :         rv = value->SetAsAString(valueString);
     670           0 :       break;
     671             :     }
     672             :     default: {
     673           0 :       rv = NS_ERROR_UNEXPECTED;
     674           0 :       break;
     675             :     }
     676             :   }
     677             : 
     678           0 :   if (NS_SUCCEEDED(rv)) {
     679           0 :     value.forget(_retval);
     680             :   }
     681             : 
     682           0 :   return rv;
     683             : }
     684             : 
     685             : 
     686             : NS_IMETHODIMP
     687           0 : nsAnnotationService::GetItemAnnotation(int64_t aItemId,
     688             :                                        const nsACString& aName,
     689             :                                        nsIVariant** _retval)
     690             : {
     691           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     692           0 :   NS_ENSURE_ARG_POINTER(_retval);
     693             : 
     694           0 :   nsCOMPtr<mozIStorageStatement> statement;
     695           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     696           0 :   if (NS_FAILED(rv))
     697           0 :     return rv;
     698             : 
     699           0 :   mozStorageStatementScoper scoper(statement);
     700             : 
     701           0 :   nsCOMPtr<nsIWritableVariant> value = new nsVariant();
     702           0 :   int32_t type = statement->AsInt32(kAnnoIndex_Type);
     703           0 :   switch (type) {
     704             :     case nsIAnnotationService::TYPE_INT32:
     705             :     case nsIAnnotationService::TYPE_INT64:
     706             :     case nsIAnnotationService::TYPE_DOUBLE: {
     707           0 :       rv = value->SetAsDouble(statement->AsDouble(kAnnoIndex_Content));
     708           0 :       break;
     709             :     }
     710             :     case nsIAnnotationService::TYPE_STRING: {
     711           0 :       nsAutoString valueString;
     712           0 :       rv = statement->GetString(kAnnoIndex_Content, valueString);
     713           0 :       if (NS_SUCCEEDED(rv))
     714           0 :         rv = value->SetAsAString(valueString);
     715           0 :       break;
     716             :     }
     717             :     default: {
     718           0 :       rv = NS_ERROR_UNEXPECTED;
     719           0 :       break;
     720             :     }
     721             :   }
     722             : 
     723           0 :   if (NS_SUCCEEDED(rv)) {
     724           0 :     value.forget(_retval);
     725             :   }
     726             : 
     727           0 :   return rv;
     728             : }
     729             : 
     730             : 
     731             : NS_IMETHODIMP
     732           0 : nsAnnotationService::GetPageAnnotationInt32(nsIURI* aURI,
     733             :                                         const nsACString& aName,
     734             :                                         int32_t* _retval)
     735             : {
     736           0 :   NS_ENSURE_ARG(aURI);
     737           0 :   NS_ENSURE_ARG_POINTER(_retval);
     738             : 
     739           0 :   nsCOMPtr<mozIStorageStatement> statement;
     740           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     741           0 :   if (NS_FAILED(rv))
     742           0 :     return rv;
     743             : 
     744           0 :   mozStorageStatementScoper scoper(statement);
     745           0 :   ENSURE_ANNO_TYPE(TYPE_INT32, statement);
     746           0 :   *_retval = statement->AsInt32(kAnnoIndex_Content);
     747           0 :   NS_ENSURE_SUCCESS(rv, rv);
     748             : 
     749           0 :   return NS_OK;
     750             : }
     751             : 
     752             : 
     753             : NS_IMETHODIMP
     754           0 : nsAnnotationService::GetItemAnnotationInt32(int64_t aItemId,
     755             :                                             const nsACString& aName,
     756             :                                             int32_t* _retval)
     757             : {
     758           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     759           0 :   NS_ENSURE_ARG_POINTER(_retval);
     760             : 
     761           0 :   nsCOMPtr<mozIStorageStatement> statement;
     762           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     763           0 :   if (NS_FAILED(rv))
     764           0 :     return rv;
     765             : 
     766           0 :   mozStorageStatementScoper scoper(statement);
     767           0 :   ENSURE_ANNO_TYPE(TYPE_INT32, statement);
     768           0 :   *_retval = statement->AsInt32(kAnnoIndex_Content);
     769             : 
     770           0 :   return NS_OK;
     771             : }
     772             : 
     773             : 
     774             : NS_IMETHODIMP
     775           0 : nsAnnotationService::GetPageAnnotationInt64(nsIURI* aURI,
     776             :                                             const nsACString& aName,
     777             :                                             int64_t* _retval)
     778             : {
     779           0 :   NS_ENSURE_ARG(aURI);
     780           0 :   NS_ENSURE_ARG_POINTER(_retval);
     781             : 
     782           0 :   nsCOMPtr<mozIStorageStatement> statement;
     783           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     784           0 :   if (NS_FAILED(rv))
     785           0 :     return rv;
     786             : 
     787           0 :   mozStorageStatementScoper scoper(statement);
     788           0 :   ENSURE_ANNO_TYPE(TYPE_INT64, statement);
     789           0 :   *_retval = statement->AsInt64(kAnnoIndex_Content);
     790             : 
     791           0 :   return NS_OK;
     792             : }
     793             : 
     794             : 
     795             : NS_IMETHODIMP
     796           0 : nsAnnotationService::GetItemAnnotationInt64(int64_t aItemId,
     797             :                                             const nsACString& aName,
     798             :                                             int64_t* _retval)
     799             : {
     800           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     801           0 :   NS_ENSURE_ARG_POINTER(_retval);
     802             : 
     803           0 :   nsCOMPtr<mozIStorageStatement> statement;
     804           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     805           0 :   if (NS_FAILED(rv))
     806           0 :     return rv;
     807             : 
     808           0 :   mozStorageStatementScoper scoper(statement);
     809           0 :   ENSURE_ANNO_TYPE(TYPE_INT64, statement);
     810           0 :   *_retval = statement->AsInt64(kAnnoIndex_Content);
     811             : 
     812           0 :   return NS_OK;
     813             : }
     814             : 
     815             : 
     816             : NS_IMETHODIMP
     817           0 : nsAnnotationService::GetPageAnnotationType(nsIURI* aURI,
     818             :                                            const nsACString& aName,
     819             :                                            uint16_t* _retval)
     820             : {
     821           0 :   NS_ENSURE_ARG(aURI);
     822           0 :   NS_ENSURE_ARG_POINTER(_retval);
     823             : 
     824           0 :   nsCOMPtr<mozIStorageStatement> statement;
     825           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     826           0 :   if (NS_FAILED(rv))
     827           0 :     return rv;
     828             : 
     829           0 :   mozStorageStatementScoper scoper(statement);
     830           0 :   *_retval = statement->AsInt32(kAnnoIndex_Type);
     831             : 
     832           0 :   return NS_OK;
     833             : }
     834             : 
     835             : 
     836             : NS_IMETHODIMP
     837           0 : nsAnnotationService::GetItemAnnotationType(int64_t aItemId,
     838             :                                            const nsACString& aName,
     839             :                                            uint16_t* _retval)
     840             : {
     841           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     842           0 :   NS_ENSURE_ARG_POINTER(_retval);
     843             : 
     844           0 :   nsCOMPtr<mozIStorageStatement> statement;
     845           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     846           0 :   if (NS_FAILED(rv))
     847           0 :     return rv;
     848             : 
     849           0 :   mozStorageStatementScoper scoper(statement);
     850           0 :   *_retval = statement->AsInt32(kAnnoIndex_Type);
     851             : 
     852           0 :   return NS_OK;
     853             : }
     854             : 
     855             : 
     856             : NS_IMETHODIMP
     857           0 : nsAnnotationService::GetPageAnnotationDouble(nsIURI* aURI,
     858             :                                              const nsACString& aName,
     859             :                                              double* _retval)
     860             : {
     861           0 :   NS_ENSURE_ARG(aURI);
     862           0 :   NS_ENSURE_ARG_POINTER(_retval);
     863             : 
     864           0 :   nsCOMPtr<mozIStorageStatement> statement;
     865           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     866           0 :   if (NS_FAILED(rv))
     867           0 :     return rv;
     868             : 
     869           0 :   mozStorageStatementScoper scoper(statement);
     870           0 :   ENSURE_ANNO_TYPE(TYPE_DOUBLE, statement);
     871           0 :   *_retval = statement->AsDouble(kAnnoIndex_Content);
     872             : 
     873           0 :   return NS_OK;
     874             : }
     875             : 
     876             : 
     877             : NS_IMETHODIMP
     878           0 : nsAnnotationService::GetItemAnnotationDouble(int64_t aItemId,
     879             :                                              const nsACString& aName,
     880             :                                              double* _retval)
     881             : {
     882           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     883             : 
     884           0 :   nsCOMPtr<mozIStorageStatement> statement;
     885           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     886           0 :   if (NS_FAILED(rv))
     887           0 :     return rv;
     888             : 
     889           0 :   mozStorageStatementScoper scoper(statement);
     890           0 :   ENSURE_ANNO_TYPE(TYPE_DOUBLE, statement);
     891           0 :   *_retval = statement->AsDouble(kAnnoIndex_Content);
     892             : 
     893           0 :   return NS_OK;
     894             : }
     895             : 
     896             : 
     897             : NS_IMETHODIMP
     898           0 : nsAnnotationService::GetPageAnnotationInfo(nsIURI* aURI,
     899             :                                            const nsACString& aName,
     900             :                                            int32_t* _flags,
     901             :                                            uint16_t* _expiration,
     902             :                                            uint16_t* _storageType)
     903             : {
     904           0 :   NS_ENSURE_ARG(aURI);
     905           0 :   NS_ENSURE_ARG_POINTER(_flags);
     906           0 :   NS_ENSURE_ARG_POINTER(_expiration);
     907           0 :   NS_ENSURE_ARG_POINTER(_storageType);
     908             : 
     909           0 :   nsCOMPtr<mozIStorageStatement> statement;
     910           0 :   nsresult rv = StartGetAnnotation(aURI, 0, aName, statement);
     911           0 :   if (NS_FAILED(rv))
     912           0 :     return rv;
     913             : 
     914           0 :   mozStorageStatementScoper scoper(statement);
     915           0 :   *_flags = statement->AsInt32(kAnnoIndex_Flags);
     916           0 :   *_expiration = (uint16_t)statement->AsInt32(kAnnoIndex_Expiration);
     917           0 :   int32_t type = (uint16_t)statement->AsInt32(kAnnoIndex_Type);
     918           0 :   if (type == 0) {
     919             :     // For annotations created before explicit typing,
     920             :     // we can't determine type, just return as string type.
     921           0 :     *_storageType = nsIAnnotationService::TYPE_STRING;
     922             :   }
     923             :   else
     924           0 :     *_storageType = type;
     925             : 
     926           0 :   return NS_OK;
     927             : }
     928             : 
     929             : 
     930             : NS_IMETHODIMP
     931           0 : nsAnnotationService::GetItemAnnotationInfo(int64_t aItemId,
     932             :                                            const nsACString& aName,
     933             :                                            int32_t* _flags,
     934             :                                            uint16_t* _expiration,
     935             :                                            uint16_t* _storageType)
     936             : {
     937           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
     938           0 :   NS_ENSURE_ARG_POINTER(_flags);
     939           0 :   NS_ENSURE_ARG_POINTER(_expiration);
     940           0 :   NS_ENSURE_ARG_POINTER(_storageType);
     941             : 
     942           0 :   nsCOMPtr<mozIStorageStatement> statement;
     943           0 :   nsresult rv = StartGetAnnotation(nullptr, aItemId, aName, statement);
     944           0 :   if (NS_FAILED(rv))
     945           0 :     return rv;
     946             : 
     947           0 :   mozStorageStatementScoper scoper(statement);
     948           0 :   *_flags = statement->AsInt32(kAnnoIndex_Flags);
     949           0 :   *_expiration = (uint16_t)statement->AsInt32(kAnnoIndex_Expiration);
     950           0 :   int32_t type = (uint16_t)statement->AsInt32(kAnnoIndex_Type);
     951           0 :   if (type == 0) {
     952             :     // For annotations created before explicit typing,
     953             :     // we can't determine type, just return as string type.
     954           0 :     *_storageType = nsIAnnotationService::TYPE_STRING;
     955             :   }
     956             :   else {
     957           0 :     *_storageType = type;
     958             :   }
     959             : 
     960           0 :   return NS_OK;
     961             : }
     962             : 
     963             : 
     964             : NS_IMETHODIMP
     965           0 : nsAnnotationService::GetPagesWithAnnotation(const nsACString& aName,
     966             :                                             uint32_t* _resultCount,
     967             :                                             nsIURI*** _results)
     968             : {
     969           0 :   NS_ENSURE_TRUE(!aName.IsEmpty(), NS_ERROR_INVALID_ARG);
     970           0 :   NS_ENSURE_ARG_POINTER(_resultCount);
     971           0 :   NS_ENSURE_ARG_POINTER(_results);
     972             : 
     973           0 :   *_resultCount = 0;
     974           0 :   *_results = nullptr;
     975           0 :   nsCOMArray<nsIURI> results;
     976             : 
     977           0 :   nsresult rv = GetPagesWithAnnotationCOMArray(aName, &results);
     978           0 :   NS_ENSURE_SUCCESS(rv, rv);
     979             : 
     980             :   // Convert to raw array.
     981           0 :   if (results.Count() == 0)
     982           0 :     return NS_OK;
     983             : 
     984           0 :   *_resultCount = results.Count();
     985           0 :   results.Forget(_results);
     986             : 
     987           0 :   return NS_OK;
     988             : }
     989             : 
     990             : 
     991             : nsresult
     992           0 : nsAnnotationService::GetPagesWithAnnotationCOMArray(const nsACString& aName,
     993             :                                                     nsCOMArray<nsIURI>* _results)
     994             : {
     995           0 :   nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
     996             :     "SELECT h.url "
     997             :     "FROM moz_anno_attributes n "
     998             :     "JOIN moz_annos a ON n.id = a.anno_attribute_id "
     999             :     "JOIN moz_places h ON h.id = a.place_id "
    1000             :     "WHERE n.name = :anno_name"
    1001           0 :   );
    1002           0 :   NS_ENSURE_STATE(stmt);
    1003           0 :   mozStorageStatementScoper scoper(stmt);
    1004             : 
    1005           0 :   nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1006           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1007             : 
    1008           0 :   bool hasMore = false;
    1009           0 :   while (NS_SUCCEEDED(rv = stmt->ExecuteStep(&hasMore)) &&
    1010             :          hasMore) {
    1011           0 :     nsAutoCString uristring;
    1012           0 :     rv = stmt->GetUTF8String(0, uristring);
    1013           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1014             : 
    1015             :     // convert to a URI, in case of some invalid URI, just ignore this row
    1016             :     // so we can mostly continue.
    1017           0 :     nsCOMPtr<nsIURI> uri;
    1018           0 :     rv = NS_NewURI(getter_AddRefs(uri), uristring);
    1019           0 :     if (NS_FAILED(rv))
    1020           0 :       continue;
    1021             : 
    1022           0 :     bool added = _results->AppendObject(uri);
    1023           0 :     NS_ENSURE_TRUE(added, NS_ERROR_OUT_OF_MEMORY);
    1024             :   }
    1025             : 
    1026           0 :   return NS_OK;
    1027             : }
    1028             : 
    1029             : 
    1030             : NS_IMETHODIMP
    1031           0 : nsAnnotationService::GetItemsWithAnnotation(const nsACString& aName,
    1032             :                                             uint32_t* _resultCount,
    1033             :                                             int64_t** _results)
    1034             : {
    1035           0 :   NS_ENSURE_TRUE(!aName.IsEmpty(), NS_ERROR_INVALID_ARG);
    1036           0 :   NS_ENSURE_ARG_POINTER(_resultCount);
    1037           0 :   NS_ENSURE_ARG_POINTER(_results);
    1038             : 
    1039           0 :   *_resultCount = 0;
    1040           0 :   *_results = nullptr;
    1041           0 :   nsTArray<int64_t> results;
    1042             : 
    1043           0 :   nsresult rv = GetItemsWithAnnotationTArray(aName, &results);
    1044           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1045             : 
    1046             :   // Convert to raw array.
    1047           0 :   if (results.Length() == 0)
    1048           0 :     return NS_OK;
    1049             : 
    1050           0 :   *_results = static_cast<int64_t*>
    1051           0 :                          (moz_xmalloc(results.Length() * sizeof(int64_t)));
    1052           0 :   NS_ENSURE_TRUE(*_results, NS_ERROR_OUT_OF_MEMORY);
    1053             : 
    1054           0 :   *_resultCount = results.Length();
    1055           0 :   for (uint32_t i = 0; i < *_resultCount; i ++) {
    1056           0 :     (*_results)[i] = results[i];
    1057             :   }
    1058             : 
    1059           0 :   return NS_OK;
    1060             : }
    1061             : 
    1062             : 
    1063             : NS_IMETHODIMP
    1064           0 : nsAnnotationService::GetAnnotationsWithName(const nsACString& aName,
    1065             :                                             uint32_t* _count,
    1066             :                                             mozIAnnotatedResult*** _annotations)
    1067             : {
    1068           0 :   NS_ENSURE_ARG(!aName.IsEmpty());
    1069           0 :   NS_ENSURE_ARG_POINTER(_annotations);
    1070             : 
    1071           0 :   *_count = 0;
    1072           0 :   *_annotations = nullptr;
    1073           0 :   nsCOMArray<mozIAnnotatedResult> annotations;
    1074             : 
    1075           0 :   nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
    1076             :     "SELECT h.guid, h.url, -1, a.type, a.content "
    1077             :     "FROM moz_anno_attributes n "
    1078             :     "JOIN moz_annos a ON n.id = a.anno_attribute_id "
    1079             :     "JOIN moz_places h ON h.id = a.place_id "
    1080             :     "WHERE n.name = :anno_name "
    1081             :     "UNION ALL "
    1082             :     "SELECT b.guid, h.url, b.id, a.type, a.content "
    1083             :     "FROM moz_anno_attributes n "
    1084             :     "JOIN moz_items_annos a ON n.id = a.anno_attribute_id "
    1085             :     "JOIN moz_bookmarks b ON b.id = a.item_id "
    1086             :     "LEFT JOIN moz_places h ON h.id = b.fk "
    1087             :     "WHERE n.name = :anno_name "
    1088           0 :   );
    1089           0 :   NS_ENSURE_STATE(stmt);
    1090           0 :   mozStorageStatementScoper scoper(stmt);
    1091             : 
    1092           0 :   nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
    1093           0 :                                            aName);
    1094           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1095             : 
    1096           0 :   bool hasMore = false;
    1097           0 :   while (NS_SUCCEEDED(rv = stmt->ExecuteStep(&hasMore)) && hasMore) {
    1098           0 :     nsAutoCString guid;
    1099           0 :     rv = stmt->GetUTF8String(0, guid);
    1100           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1101             : 
    1102           0 :     nsCOMPtr<nsIURI> uri;
    1103           0 :     bool uriIsNull = false;
    1104           0 :     rv = stmt->GetIsNull(1, &uriIsNull);
    1105           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1106           0 :     if (!uriIsNull) {
    1107           0 :       nsAutoCString url;
    1108           0 :       rv = stmt->GetUTF8String(1, url);
    1109           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1110           0 :       rv = NS_NewURI(getter_AddRefs(uri), url);
    1111           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1112             :     }
    1113             : 
    1114           0 :     int64_t itemId = stmt->AsInt64(2);
    1115           0 :     int32_t type = stmt->AsInt32(3);
    1116             : 
    1117           0 :     nsCOMPtr<nsIWritableVariant> variant = new nsVariant();
    1118           0 :     switch (type) {
    1119             :       case nsIAnnotationService::TYPE_INT32: {
    1120           0 :         rv = variant->SetAsInt32(stmt->AsInt32(4));
    1121           0 :         break;
    1122             :       }
    1123             :       case nsIAnnotationService::TYPE_INT64: {
    1124           0 :         rv = variant->SetAsInt64(stmt->AsInt64(4));
    1125           0 :         break;
    1126             :       }
    1127             :       case nsIAnnotationService::TYPE_DOUBLE: {
    1128           0 :         rv = variant->SetAsDouble(stmt->AsDouble(4));
    1129           0 :         break;
    1130             :       }
    1131             :       case nsIAnnotationService::TYPE_STRING: {
    1132           0 :         nsAutoString valueString;
    1133           0 :         rv = stmt->GetString(4, valueString);
    1134           0 :         NS_ENSURE_SUCCESS(rv, rv);
    1135             : 
    1136           0 :         rv = variant->SetAsAString(valueString);
    1137           0 :         break;
    1138             :       }
    1139             :       default:
    1140           0 :         MOZ_ASSERT(false, "Unsupported annotation type");
    1141             :         // Move to the next result.
    1142             :         continue;
    1143             :     }
    1144           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1145             : 
    1146             :     nsCOMPtr<mozIAnnotatedResult> anno = new AnnotatedResult(guid, uri, itemId,
    1147           0 :                                                              aName, variant);
    1148           0 :     NS_ENSURE_TRUE(annotations.AppendObject(anno), NS_ERROR_OUT_OF_MEMORY);
    1149             :   }
    1150             : 
    1151             :   // Convert to raw array.
    1152           0 :   if (annotations.Count() == 0)
    1153           0 :     return NS_OK;
    1154             : 
    1155           0 :   *_count = annotations.Count();
    1156           0 :   annotations.Forget(_annotations);
    1157             : 
    1158           0 :   return NS_OK;
    1159             : }
    1160             : 
    1161             : 
    1162             : nsresult
    1163           0 : nsAnnotationService::GetItemsWithAnnotationTArray(const nsACString& aName,
    1164             :                                                   nsTArray<int64_t>* _results)
    1165             : {
    1166           0 :   nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
    1167             :     "SELECT a.item_id "
    1168             :     "FROM moz_anno_attributes n "
    1169             :     "JOIN moz_items_annos a ON n.id = a.anno_attribute_id "
    1170             :     "WHERE n.name = :anno_name"
    1171           0 :   );
    1172           0 :   NS_ENSURE_STATE(stmt);
    1173           0 :   mozStorageStatementScoper scoper(stmt);
    1174             : 
    1175           0 :   nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1176           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1177             : 
    1178           0 :   bool hasMore = false;
    1179           0 :   while (NS_SUCCEEDED(stmt->ExecuteStep(&hasMore)) &&
    1180             :          hasMore) {
    1181           0 :     if (!_results->AppendElement(stmt->AsInt64(0)))
    1182           0 :       return NS_ERROR_OUT_OF_MEMORY;
    1183             :   }
    1184             : 
    1185           0 :   return NS_OK;
    1186             : }
    1187             : 
    1188             : 
    1189             : NS_IMETHODIMP
    1190           0 : nsAnnotationService::GetPageAnnotationNames(nsIURI* aURI,
    1191             :                                             uint32_t* _count,
    1192             :                                             nsIVariant*** _result)
    1193             : {
    1194           0 :   NS_ENSURE_ARG(aURI);
    1195           0 :   NS_ENSURE_ARG_POINTER(_count);
    1196           0 :   NS_ENSURE_ARG_POINTER(_result);
    1197             : 
    1198           0 :   *_count = 0;
    1199           0 :   *_result = nullptr;
    1200             : 
    1201           0 :   nsTArray<nsCString> names;
    1202           0 :   nsresult rv = GetAnnotationNamesTArray(aURI, 0, &names);
    1203           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1204             : 
    1205           0 :   if (names.Length() == 0)
    1206           0 :     return NS_OK;
    1207             : 
    1208           0 :   *_result = static_cast<nsIVariant**>
    1209           0 :                         (moz_xmalloc(sizeof(nsIVariant*) * names.Length()));
    1210           0 :   NS_ENSURE_TRUE(*_result, NS_ERROR_OUT_OF_MEMORY);
    1211             : 
    1212           0 :   for (uint32_t i = 0; i < names.Length(); i ++) {
    1213           0 :     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
    1214           0 :     if (!var) {
    1215             :       // need to release all the variants we've already created
    1216           0 :       for (uint32_t j = 0; j < i; j ++)
    1217           0 :         NS_RELEASE((*_result)[j]);
    1218           0 :       free(*_result);
    1219           0 :       *_result = nullptr;
    1220           0 :       return NS_ERROR_OUT_OF_MEMORY;
    1221             :     }
    1222           0 :     var->SetAsAUTF8String(names[i]);
    1223           0 :     NS_ADDREF((*_result)[i] = var);
    1224             :   }
    1225           0 :   *_count = names.Length();
    1226             : 
    1227           0 :   return NS_OK;
    1228             : }
    1229             : 
    1230             : 
    1231             : nsresult
    1232           0 : nsAnnotationService::GetAnnotationNamesTArray(nsIURI* aURI,
    1233             :                                               int64_t aItemId,
    1234             :                                               nsTArray<nsCString>* _result)
    1235             : {
    1236           0 :   _result->Clear();
    1237             : 
    1238           0 :   bool isItemAnnotation = (aItemId > 0);
    1239           0 :   nsCOMPtr<mozIStorageStatement> statement;
    1240           0 :   if (isItemAnnotation) {
    1241           0 :     statement = mDB->GetStatement(
    1242             :       "SELECT n.name "
    1243             :       "FROM moz_anno_attributes n "
    1244             :       "JOIN moz_items_annos a ON a.anno_attribute_id = n.id "
    1245             :       "WHERE a.item_id = :item_id"
    1246           0 :     );
    1247             :   }
    1248             :   else {
    1249           0 :     statement = mDB->GetStatement(
    1250             :       "SELECT n.name "
    1251             :       "FROM moz_anno_attributes n "
    1252             :       "JOIN moz_annos a ON a.anno_attribute_id = n.id "
    1253             :       "JOIN moz_places h ON h.id = a.place_id "
    1254             :       "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url"
    1255           0 :     );
    1256             :   }
    1257           0 :   NS_ENSURE_STATE(statement);
    1258           0 :   mozStorageStatementScoper scoper(statement);
    1259             : 
    1260             :   nsresult rv;
    1261           0 :   if (isItemAnnotation)
    1262           0 :     rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1263             :   else
    1264           0 :     rv = URIBinder::Bind(statement, NS_LITERAL_CSTRING("page_url"), aURI);
    1265           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1266             : 
    1267           0 :   bool hasResult = false;
    1268           0 :   while (NS_SUCCEEDED(statement->ExecuteStep(&hasResult)) &&
    1269             :          hasResult) {
    1270           0 :     nsAutoCString name;
    1271           0 :     rv = statement->GetUTF8String(0, name);
    1272           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1273           0 :     if (!_result->AppendElement(name))
    1274           0 :       return NS_ERROR_OUT_OF_MEMORY;
    1275             :   }
    1276             : 
    1277           0 :   return NS_OK;
    1278             : }
    1279             : 
    1280             : 
    1281             : NS_IMETHODIMP
    1282           0 : nsAnnotationService::GetItemAnnotationNames(int64_t aItemId,
    1283             :                                             uint32_t* _count,
    1284             :                                             nsIVariant*** _result)
    1285             : {
    1286           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
    1287           0 :   NS_ENSURE_ARG_POINTER(_count);
    1288           0 :   NS_ENSURE_ARG_POINTER(_result);
    1289             : 
    1290           0 :   *_count = 0;
    1291           0 :   *_result = nullptr;
    1292             : 
    1293           0 :   nsTArray<nsCString> names;
    1294           0 :   nsresult rv = GetAnnotationNamesTArray(nullptr, aItemId, &names);
    1295           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1296             : 
    1297           0 :   if (names.Length() == 0)
    1298           0 :     return NS_OK;
    1299             : 
    1300           0 :   *_result = static_cast<nsIVariant**>
    1301           0 :                         (moz_xmalloc(sizeof(nsIVariant*) * names.Length()));
    1302           0 :   NS_ENSURE_TRUE(*_result, NS_ERROR_OUT_OF_MEMORY);
    1303             : 
    1304           0 :   for (uint32_t i = 0; i < names.Length(); i ++) {
    1305           0 :     nsCOMPtr<nsIWritableVariant> var = new nsVariant();
    1306           0 :     if (!var) {
    1307             :       // need to release all the variants we've already created
    1308           0 :       for (uint32_t j = 0; j < i; j ++)
    1309           0 :         NS_RELEASE((*_result)[j]);
    1310           0 :       free(*_result);
    1311           0 :       *_result = nullptr;
    1312           0 :       return NS_ERROR_OUT_OF_MEMORY;
    1313             :     }
    1314           0 :     var->SetAsAUTF8String(names[i]);
    1315           0 :     NS_ADDREF((*_result)[i] = var);
    1316             :   }
    1317           0 :   *_count = names.Length();
    1318             : 
    1319           0 :   return NS_OK;
    1320             : }
    1321             : 
    1322             : 
    1323             : NS_IMETHODIMP
    1324           0 : nsAnnotationService::PageHasAnnotation(nsIURI* aURI,
    1325             :                                        const nsACString& aName,
    1326             :                                        bool* _retval)
    1327             : {
    1328           0 :   NS_ENSURE_ARG(aURI);
    1329           0 :   NS_ENSURE_ARG_POINTER(_retval);
    1330             : 
    1331           0 :   nsresult rv = HasAnnotationInternal(aURI, 0, aName, _retval);
    1332           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1333             : 
    1334           0 :   return NS_OK;
    1335             : }
    1336             : 
    1337             : 
    1338             : NS_IMETHODIMP
    1339           0 : nsAnnotationService::ItemHasAnnotation(int64_t aItemId,
    1340             :                                        const nsACString& aName,
    1341             :                                        bool* _retval)
    1342             : {
    1343           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
    1344           0 :   NS_ENSURE_ARG_POINTER(_retval);
    1345             : 
    1346           0 :   nsresult rv = HasAnnotationInternal(nullptr, aItemId, aName, _retval);
    1347           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1348             : 
    1349           0 :   return NS_OK;
    1350             : }
    1351             : 
    1352             : 
    1353             : /**
    1354             :  * @note We don't remove anything from the moz_anno_attributes table. If we
    1355             :  *       delete the last item of a given name, that item really should go away.
    1356             :  *       It will be cleaned up by expiration.
    1357             :  */
    1358             : nsresult
    1359           0 : nsAnnotationService::RemoveAnnotationInternal(nsIURI* aURI,
    1360             :                                               int64_t aItemId,
    1361             :                                               const nsACString& aName)
    1362             : {
    1363           0 :   bool isItemAnnotation = (aItemId > 0);
    1364           0 :   nsCOMPtr<mozIStorageStatement> statement;
    1365           0 :   if (isItemAnnotation) {
    1366           0 :     statement = mDB->GetStatement(
    1367             :       "DELETE FROM moz_items_annos "
    1368             :       "WHERE item_id = :item_id "
    1369             :         "AND anno_attribute_id = "
    1370             :           "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"
    1371           0 :     );
    1372             :   }
    1373             :   else {
    1374           0 :     statement = mDB->GetStatement(
    1375             :       "DELETE FROM moz_annos "
    1376             :       "WHERE place_id = "
    1377             :           "(SELECT id FROM moz_places WHERE url_hash = hash(:page_url) AND url = :page_url) "
    1378             :         "AND anno_attribute_id = "
    1379             :           "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name)"
    1380           0 :     );
    1381             :   }
    1382           0 :   NS_ENSURE_STATE(statement);
    1383           0 :   mozStorageStatementScoper scoper(statement);
    1384             : 
    1385             :   nsresult rv;
    1386           0 :   if (isItemAnnotation)
    1387           0 :     rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1388             :   else
    1389           0 :     rv = URIBinder::Bind(statement, NS_LITERAL_CSTRING("page_url"), aURI);
    1390           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1391             : 
    1392           0 :   rv = statement->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1393           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1394             : 
    1395           0 :   rv = statement->Execute();
    1396           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1397             : 
    1398           0 :   return NS_OK;
    1399             : }
    1400             : 
    1401             : 
    1402             : NS_IMETHODIMP
    1403           0 : nsAnnotationService::RemovePageAnnotation(nsIURI* aURI,
    1404             :                                           const nsACString& aName)
    1405             : {
    1406           0 :   NS_ENSURE_ARG(aURI);
    1407             : 
    1408           0 :   nsresult rv = RemoveAnnotationInternal(aURI, 0, aName);
    1409           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1410             : 
    1411           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationRemoved(aURI, aName));
    1412             : 
    1413           0 :   return NS_OK;
    1414             : }
    1415             : 
    1416             : 
    1417             : NS_IMETHODIMP
    1418           0 : nsAnnotationService::RemoveItemAnnotation(int64_t aItemId,
    1419             :                                           const nsACString& aName,
    1420             :                                           uint16_t aSource)
    1421             : {
    1422           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
    1423             : 
    1424           0 :   nsresult rv = RemoveAnnotationInternal(nullptr, aItemId, aName);
    1425           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1426             : 
    1427           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationRemoved(aItemId, aName, aSource));
    1428             : 
    1429           0 :   return NS_OK;
    1430             : }
    1431             : 
    1432             : 
    1433             : NS_IMETHODIMP
    1434           0 : nsAnnotationService::RemovePageAnnotations(nsIURI* aURI)
    1435             : {
    1436           0 :   NS_ENSURE_ARG(aURI);
    1437             : 
    1438             :   // Should this be precompiled or a getter?
    1439           0 :   nsCOMPtr<mozIStorageStatement> statement = mDB->GetStatement(
    1440             :     "DELETE FROM moz_annos WHERE place_id = "
    1441             :       "(SELECT id FROM moz_places WHERE url_hash = hash(:page_url) AND url = :page_url)"
    1442           0 :   );
    1443           0 :   NS_ENSURE_STATE(statement);
    1444           0 :   mozStorageStatementScoper scoper(statement);
    1445             : 
    1446           0 :   nsresult rv = URIBinder::Bind(statement, NS_LITERAL_CSTRING("page_url"), aURI);
    1447           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1448             : 
    1449           0 :   rv = statement->Execute();
    1450           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1451             : 
    1452             :   // Update observers
    1453           0 :   NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationRemoved(aURI, EmptyCString()));
    1454             : 
    1455           0 :   return NS_OK;
    1456             : }
    1457             : 
    1458             : 
    1459             : NS_IMETHODIMP
    1460           0 : nsAnnotationService::RemoveItemAnnotations(int64_t aItemId,
    1461             :                                            uint16_t aSource)
    1462             : {
    1463           0 :   NS_ENSURE_ARG_MIN(aItemId, 1);
    1464             : 
    1465             :   // Should this be precompiled or a getter?
    1466           0 :   nsCOMPtr<mozIStorageStatement> statement = mDB->GetStatement(
    1467             :     "DELETE FROM moz_items_annos WHERE item_id = :item_id"
    1468           0 :   );
    1469           0 :   NS_ENSURE_STATE(statement);
    1470           0 :   mozStorageStatementScoper scoper(statement);
    1471             : 
    1472           0 :   nsresult rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1473           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1474             : 
    1475           0 :   rv = statement->Execute();
    1476           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1477             : 
    1478           0 :   NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationRemoved(aItemId, EmptyCString(),
    1479             :                                                  aSource));
    1480             : 
    1481           0 :   return NS_OK;
    1482             : }
    1483             : 
    1484             : 
    1485             : /**
    1486             :  * @note If we use annotations for some standard items like GeckoFlags, it
    1487             :  *       might be a good idea to blacklist these standard annotations from this
    1488             :  *       copy function.
    1489             :  */
    1490             : NS_IMETHODIMP
    1491           0 : nsAnnotationService::CopyPageAnnotations(nsIURI* aSourceURI,
    1492             :                                          nsIURI* aDestURI,
    1493             :                                          bool aOverwriteDest)
    1494             : {
    1495           0 :   NS_ENSURE_ARG(aSourceURI);
    1496           0 :   NS_ENSURE_ARG(aDestURI);
    1497             : 
    1498           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
    1499             : 
    1500           0 :   nsCOMPtr<mozIStorageStatement> sourceStmt = mDB->GetStatement(
    1501             :     "SELECT h.id, n.id, n.name, a2.id "
    1502             :     "FROM moz_places h "
    1503             :     "JOIN moz_annos a ON a.place_id = h.id "
    1504             :     "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id "
    1505             :     "LEFT JOIN moz_annos a2 ON a2.place_id = "
    1506             :       "(SELECT id FROM moz_places WHERE url_hash = hash(:dest_url) AND url = :dest_url) "
    1507             :                           "AND a2.anno_attribute_id = n.id "
    1508             :     "WHERE url = :source_url"
    1509           0 :   );
    1510           0 :   NS_ENSURE_STATE(sourceStmt);
    1511           0 :   mozStorageStatementScoper sourceScoper(sourceStmt);
    1512             : 
    1513           0 :   nsresult rv = URIBinder::Bind(sourceStmt, NS_LITERAL_CSTRING("source_url"), aSourceURI);
    1514           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1515           0 :   rv = URIBinder::Bind(sourceStmt, NS_LITERAL_CSTRING("dest_url"), aDestURI);
    1516           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1517             : 
    1518           0 :   nsCOMPtr<mozIStorageStatement> copyStmt = mDB->GetStatement(
    1519             :     "INSERT INTO moz_annos "
    1520             :     "(place_id, anno_attribute_id, content, flags, expiration, "
    1521             :      "type, dateAdded, lastModified) "
    1522             :     "SELECT (SELECT id FROM moz_places WHERE url_hash = hash(:page_url) AND url = :page_url), "
    1523             :            "anno_attribute_id, content, flags, expiration, type, "
    1524             :            ":date, :date "
    1525             :     "FROM moz_annos "
    1526             :     "WHERE place_id = :page_id "
    1527             :     "AND anno_attribute_id = :name_id"
    1528           0 :   );
    1529           0 :   NS_ENSURE_STATE(copyStmt);
    1530           0 :   mozStorageStatementScoper copyScoper(copyStmt);
    1531             : 
    1532             :   bool hasResult;
    1533           0 :   while (NS_SUCCEEDED(sourceStmt->ExecuteStep(&hasResult)) && hasResult) {
    1534           0 :     int64_t sourcePlaceId = sourceStmt->AsInt64(0);
    1535           0 :     int64_t annoNameID = sourceStmt->AsInt64(1);
    1536           0 :     nsAutoCString annoName;
    1537           0 :     rv = sourceStmt->GetUTF8String(2, annoName);
    1538           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1539           0 :     int64_t annoExistsOnDest = sourceStmt->AsInt64(3);
    1540             : 
    1541           0 :     if (annoExistsOnDest) {
    1542           0 :       if (!aOverwriteDest)
    1543           0 :         continue;
    1544           0 :       rv = RemovePageAnnotation(aDestURI, annoName);
    1545           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1546             :     }
    1547             : 
    1548             :     // Copy the annotation.
    1549           0 :     mozStorageStatementScoper scoper(copyStmt);
    1550           0 :     rv = URIBinder::Bind(copyStmt, NS_LITERAL_CSTRING("page_url"), aDestURI);
    1551           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1552           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), sourcePlaceId);
    1553           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1554           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("name_id"), annoNameID);
    1555           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1556           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("date"), PR_Now());
    1557           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1558             : 
    1559           0 :     rv = copyStmt->Execute();
    1560           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1561             : 
    1562           0 :     NOTIFY_ANNOS_OBSERVERS(OnPageAnnotationSet(aDestURI, annoName));
    1563             :   }
    1564             : 
    1565           0 :   rv = transaction.Commit();
    1566           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1567             : 
    1568           0 :   return NS_OK;
    1569             : }
    1570             : 
    1571             : 
    1572             : NS_IMETHODIMP
    1573           0 : nsAnnotationService::CopyItemAnnotations(int64_t aSourceItemId,
    1574             :                                          int64_t aDestItemId,
    1575             :                                          bool aOverwriteDest,
    1576             :                                          uint16_t aSource)
    1577             : {
    1578           0 :   NS_ENSURE_ARG_MIN(aSourceItemId, 1);
    1579           0 :   NS_ENSURE_ARG_MIN(aDestItemId, 1);
    1580             : 
    1581           0 :   mozStorageTransaction transaction(mDB->MainConn(), false);
    1582             : 
    1583           0 :   nsCOMPtr<mozIStorageStatement> sourceStmt = mDB->GetStatement(
    1584             :     "SELECT n.id, n.name, a2.id "
    1585             :     "FROM moz_bookmarks b "
    1586             :     "JOIN moz_items_annos a ON a.item_id = b.id "
    1587             :     "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id "
    1588             :     "LEFT JOIN moz_items_annos a2 ON a2.item_id = :dest_item_id "
    1589             :                                 "AND a2.anno_attribute_id = n.id "
    1590             :     "WHERE b.id = :source_item_id"
    1591           0 :   );
    1592           0 :   NS_ENSURE_STATE(sourceStmt);
    1593           0 :   mozStorageStatementScoper sourceScoper(sourceStmt);
    1594             : 
    1595           0 :   nsresult rv = sourceStmt->BindInt64ByName(NS_LITERAL_CSTRING("source_item_id"), aSourceItemId);
    1596           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1597           0 :   rv = sourceStmt->BindInt64ByName(NS_LITERAL_CSTRING("dest_item_id"), aDestItemId);
    1598           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1599             : 
    1600           0 :   nsCOMPtr<mozIStorageStatement> copyStmt = mDB->GetStatement(
    1601             :       "INSERT OR REPLACE INTO moz_items_annos "
    1602             :       "(item_id, anno_attribute_id, content, flags, expiration, "
    1603             :        "type, dateAdded, lastModified) "
    1604             :       "SELECT :dest_item_id, anno_attribute_id, content, flags, expiration, "
    1605             :              "type, :date, :date "
    1606             :       "FROM moz_items_annos "
    1607             :       "WHERE item_id = :source_item_id "
    1608             :       "AND anno_attribute_id = :name_id"
    1609           0 :   );
    1610           0 :   NS_ENSURE_STATE(copyStmt);
    1611           0 :   mozStorageStatementScoper copyScoper(copyStmt);
    1612             : 
    1613             :   bool hasResult;
    1614           0 :   while (NS_SUCCEEDED(sourceStmt->ExecuteStep(&hasResult)) && hasResult) {
    1615           0 :     int64_t annoNameID = sourceStmt->AsInt64(0);
    1616           0 :     nsAutoCString annoName;
    1617           0 :     rv = sourceStmt->GetUTF8String(1, annoName);
    1618           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1619           0 :     int64_t annoExistsOnDest = sourceStmt->AsInt64(2);
    1620             : 
    1621           0 :     if (annoExistsOnDest) {
    1622           0 :       if (!aOverwriteDest)
    1623           0 :         continue;
    1624           0 :       rv = RemoveItemAnnotation(aDestItemId, annoName, aSource);
    1625           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1626             :     }
    1627             : 
    1628             :     // Copy the annotation.
    1629           0 :     mozStorageStatementScoper scoper(copyStmt);
    1630           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("dest_item_id"), aDestItemId);
    1631           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1632           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("source_item_id"), aSourceItemId);
    1633           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1634           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("name_id"), annoNameID);
    1635           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1636           0 :     rv = copyStmt->BindInt64ByName(NS_LITERAL_CSTRING("date"), PR_Now());
    1637           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1638             : 
    1639           0 :     rv = copyStmt->Execute();
    1640           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1641             : 
    1642           0 :     NOTIFY_ANNOS_OBSERVERS(OnItemAnnotationSet(aDestItemId, annoName, aSource));
    1643             :   }
    1644             : 
    1645           0 :   rv = transaction.Commit();
    1646           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1647             : 
    1648           0 :   return NS_OK;
    1649             : }
    1650             : 
    1651             : 
    1652             : NS_IMETHODIMP
    1653           1 : nsAnnotationService::AddObserver(nsIAnnotationObserver* aObserver)
    1654             : {
    1655           1 :   NS_ENSURE_ARG(aObserver);
    1656             : 
    1657           1 :   if (mObservers.IndexOfObject(aObserver) >= 0)
    1658           0 :     return NS_ERROR_INVALID_ARG; // Already registered.
    1659           1 :   if (!mObservers.AppendObject(aObserver))
    1660           0 :     return NS_ERROR_OUT_OF_MEMORY;
    1661           1 :   return NS_OK;
    1662             : }
    1663             : 
    1664             : 
    1665             : NS_IMETHODIMP
    1666           0 : nsAnnotationService::RemoveObserver(nsIAnnotationObserver* aObserver)
    1667             : {
    1668           0 :   NS_ENSURE_ARG(aObserver);
    1669             : 
    1670           0 :   if (!mObservers.RemoveObject(aObserver))
    1671           0 :     return NS_ERROR_INVALID_ARG;
    1672           0 :   return NS_OK;
    1673             : }
    1674             : 
    1675             : NS_IMETHODIMP
    1676           0 : nsAnnotationService::GetObservers(uint32_t* _count,
    1677             :                                   nsIAnnotationObserver*** _observers)
    1678             : {
    1679           0 :   NS_ENSURE_ARG_POINTER(_count);
    1680           0 :   NS_ENSURE_ARG_POINTER(_observers);
    1681             : 
    1682           0 :   *_count = 0;
    1683           0 :   *_observers = nullptr;
    1684             : 
    1685           0 :   nsCOMArray<nsIAnnotationObserver> observers(mObservers);
    1686             : 
    1687           0 :   if (observers.Count() == 0)
    1688           0 :     return NS_OK;
    1689             : 
    1690           0 :   *_count = observers.Count();
    1691           0 :   observers.Forget(_observers);
    1692             : 
    1693           0 :   return NS_OK;
    1694             : }
    1695             : 
    1696             : nsresult
    1697           0 : nsAnnotationService::HasAnnotationInternal(nsIURI* aURI,
    1698             :                                            int64_t aItemId,
    1699             :                                            const nsACString& aName,
    1700             :                                            bool* _hasAnno)
    1701             : {
    1702           0 :   bool isItemAnnotation = (aItemId > 0);
    1703           0 :   nsCOMPtr<mozIStorageStatement> stmt;
    1704           0 :   if (isItemAnnotation) {
    1705           0 :     stmt = mDB->GetStatement(
    1706             :       "SELECT b.id, "
    1707             :              "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, "
    1708             :              "a.id, a.dateAdded "
    1709             :       "FROM moz_bookmarks b "
    1710             :       "LEFT JOIN moz_items_annos a ON a.item_id = b.id "
    1711             :                                  "AND a.anno_attribute_id = nameid "
    1712             :       "WHERE b.id = :item_id"
    1713           0 :     );
    1714             :   }
    1715             :   else {
    1716           0 :     stmt = mDB->GetStatement(
    1717             :       "SELECT h.id, "
    1718             :              "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, "
    1719             :              "a.id, a.dateAdded "
    1720             :       "FROM moz_places h "
    1721             :       "LEFT JOIN moz_annos a ON a.place_id = h.id "
    1722             :                            "AND a.anno_attribute_id = nameid "
    1723             :       "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url"
    1724           0 :     );
    1725             :   }
    1726           0 :   NS_ENSURE_STATE(stmt);
    1727           0 :   mozStorageStatementScoper checkAnnoScoper(stmt);
    1728             : 
    1729           0 :   nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1730           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1731           0 :   if (isItemAnnotation)
    1732           0 :     rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1733             :   else
    1734           0 :     rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
    1735           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1736             : 
    1737             :   bool hasResult;
    1738           0 :   rv = stmt->ExecuteStep(&hasResult);
    1739           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1740           0 :   if (!hasResult) {
    1741             :     // We are trying to get an annotation on an invalid bookmarks or
    1742             :     // history entry.
    1743             :     // Here we preserve the old behavior, returning that we don't have the
    1744             :     // annotation, ignoring the fact itemId is invalid.
    1745             :     // Otherwise we should return NS_ERROR_INVALID_ARG, but this will somehow
    1746             :     // break the API.  In future we could want to be pickier.
    1747           0 :     *_hasAnno = false;
    1748             :   }
    1749             :   else {
    1750           0 :     int64_t annotationId = stmt->AsInt64(2);
    1751           0 :     *_hasAnno = (annotationId > 0);
    1752             :   }
    1753             : 
    1754           0 :   return NS_OK;
    1755             : }
    1756             : 
    1757             : 
    1758             : /**
    1759             :  * This loads the statement and steps it once so you can get data out of it.
    1760             :  *
    1761             :  * @note You have to reset the statement when you're done if this succeeds.
    1762             :  * @throws NS_ERROR_NOT_AVAILABLE if the annotation is not found.
    1763             :  */
    1764             : 
    1765             : nsresult
    1766           0 : nsAnnotationService::StartGetAnnotation(nsIURI* aURI,
    1767             :                                         int64_t aItemId,
    1768             :                                         const nsACString& aName,
    1769             :                                         nsCOMPtr<mozIStorageStatement>& aStatement)
    1770             : {
    1771           0 :   bool isItemAnnotation = (aItemId > 0);
    1772             : 
    1773           0 :   if (isItemAnnotation) {
    1774           0 :     aStatement = mDB->GetStatement(
    1775             :       "SELECT a.id, a.item_id, :anno_name, a.content, a.flags, "
    1776             :              "a.expiration, a.type "
    1777             :       "FROM moz_anno_attributes n "
    1778             :       "JOIN moz_items_annos a ON a.anno_attribute_id = n.id "
    1779             :       "WHERE a.item_id = :item_id "
    1780             :       "AND n.name = :anno_name"
    1781           0 :     );
    1782             :   }
    1783             :   else {
    1784           0 :     aStatement = mDB->GetStatement(
    1785             :       "SELECT a.id, a.place_id, :anno_name, a.content, a.flags, "
    1786             :              "a.expiration, a.type "
    1787             :       "FROM moz_anno_attributes n "
    1788             :       "JOIN moz_annos a ON n.id = a.anno_attribute_id "
    1789             :       "JOIN moz_places h ON h.id = a.place_id "
    1790             :       "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url "
    1791             :         "AND n.name = :anno_name"
    1792           0 :     );
    1793             :   }
    1794           0 :   NS_ENSURE_STATE(aStatement);
    1795           0 :   mozStorageStatementScoper getAnnoScoper(aStatement);
    1796             : 
    1797             :   nsresult rv;
    1798           0 :   if (isItemAnnotation)
    1799           0 :     rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1800             :   else
    1801           0 :     rv = URIBinder::Bind(aStatement, NS_LITERAL_CSTRING("page_url"), aURI);
    1802           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1803             : 
    1804           0 :   rv = aStatement->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1805           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1806             : 
    1807           0 :   bool hasResult = false;
    1808           0 :   rv = aStatement->ExecuteStep(&hasResult);
    1809           0 :   if (NS_FAILED(rv) || !hasResult)
    1810           0 :     return NS_ERROR_NOT_AVAILABLE;
    1811             : 
    1812             :   // on success, DON'T reset the statement, the caller needs to read from it,
    1813             :   // and it is the caller's job to reset it.
    1814           0 :   getAnnoScoper.Abandon();
    1815             : 
    1816           0 :   return NS_OK;
    1817             : }
    1818             : 
    1819             : 
    1820             : /**
    1821             :  * This does most of the setup work needed to set an annotation, except for
    1822             :  * binding the the actual value and executing the statement.
    1823             :  * It will either update an existing annotation or insert a new one.
    1824             :  *
    1825             :  * @note The aStatement RESULT IS NOT ADDREFED.  This is just one of the class
    1826             :  *       vars, which control its scope.  DO NOT RELEASE.
    1827             :  *       The caller must take care of resetting the statement if this succeeds.
    1828             :  */
    1829             : nsresult
    1830           0 : nsAnnotationService::StartSetAnnotation(nsIURI* aURI,
    1831             :                                         int64_t aItemId,
    1832             :                                         const nsACString& aName,
    1833             :                                         int32_t aFlags,
    1834             :                                         uint16_t aExpiration,
    1835             :                                         uint16_t aType,
    1836             :                                         nsCOMPtr<mozIStorageStatement>& aStatement)
    1837             : {
    1838           0 :   bool isItemAnnotation = (aItemId > 0);
    1839             : 
    1840           0 :   if (aExpiration == EXPIRE_SESSION) {
    1841           0 :     mHasSessionAnnotations = true;
    1842             :   }
    1843             : 
    1844             :   // Ensure the annotation name exists.
    1845           0 :   nsCOMPtr<mozIStorageStatement> addNameStmt = mDB->GetStatement(
    1846             :     "INSERT OR IGNORE INTO moz_anno_attributes (name) VALUES (:anno_name)"
    1847           0 :   );
    1848           0 :   NS_ENSURE_STATE(addNameStmt);
    1849           0 :   mozStorageStatementScoper scoper(addNameStmt);
    1850             : 
    1851           0 :   nsresult rv = addNameStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1852           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1853           0 :   rv = addNameStmt->Execute();
    1854           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1855             : 
    1856             :   // We have to check 2 things:
    1857             :   // - if the annotation already exists we should update it.
    1858             :   // - we should not allow setting annotations on invalid URIs or itemIds.
    1859             :   // This query will tell us:
    1860             :   // - whether the item or page exists.
    1861             :   // - whether the annotation already exists.
    1862             :   // - the nameID associated with the annotation name.
    1863             :   // - the id and dateAdded of the old annotation, if it exists.
    1864           0 :   nsCOMPtr<mozIStorageStatement> stmt;
    1865           0 :   if (isItemAnnotation) {
    1866           0 :     stmt = mDB->GetStatement(
    1867             :       "SELECT b.id, "
    1868             :              "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, "
    1869             :              "a.id, a.dateAdded "
    1870             :       "FROM moz_bookmarks b "
    1871             :       "LEFT JOIN moz_items_annos a ON a.item_id = b.id "
    1872             :                                  "AND a.anno_attribute_id = nameid "
    1873             :       "WHERE b.id = :item_id"
    1874           0 :     );
    1875             :   }
    1876             :   else {
    1877           0 :     stmt = mDB->GetStatement(
    1878             :       "SELECT h.id, "
    1879             :              "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS nameid, "
    1880             :              "a.id, a.dateAdded "
    1881             :       "FROM moz_places h "
    1882             :       "LEFT JOIN moz_annos a ON a.place_id = h.id "
    1883             :                            "AND a.anno_attribute_id = nameid "
    1884             :       "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url"
    1885           0 :     );
    1886             :   }
    1887           0 :   NS_ENSURE_STATE(stmt);
    1888           0 :   mozStorageStatementScoper checkAnnoScoper(stmt);
    1889             : 
    1890           0 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"), aName);
    1891           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1892           0 :   if (isItemAnnotation)
    1893           0 :     rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
    1894             :   else
    1895           0 :     rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("page_url"), aURI);
    1896           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1897             : 
    1898             :   bool hasResult;
    1899           0 :   rv = stmt->ExecuteStep(&hasResult);
    1900           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1901           0 :   if (!hasResult) {
    1902             :     // We are trying to create an annotation on an invalid bookmark
    1903             :     // or history entry.
    1904           0 :     return NS_ERROR_INVALID_ARG;
    1905             :   }
    1906             : 
    1907           0 :   int64_t fkId = stmt->AsInt64(0);
    1908           0 :   int64_t nameID = stmt->AsInt64(1);
    1909           0 :   int64_t oldAnnoId = stmt->AsInt64(2);
    1910           0 :   int64_t oldAnnoDate = stmt->AsInt64(3);
    1911             : 
    1912           0 :   if (isItemAnnotation) {
    1913           0 :     aStatement = mDB->GetStatement(
    1914             :       "INSERT OR REPLACE INTO moz_items_annos "
    1915             :         "(id, item_id, anno_attribute_id, content, flags, "
    1916             :          "expiration, type, dateAdded, lastModified) "
    1917             :       "VALUES (:id, :fk, :name_id, :content, :flags, "
    1918             :       ":expiration, :type, :date_added, :last_modified)"
    1919           0 :     );
    1920             :   }
    1921             :   else {
    1922           0 :     aStatement = mDB->GetStatement(
    1923             :       "INSERT OR REPLACE INTO moz_annos "
    1924             :         "(id, place_id, anno_attribute_id, content, flags, "
    1925             :          "expiration, type, dateAdded, lastModified) "
    1926             :       "VALUES (:id, :fk, :name_id, :content, :flags, "
    1927             :       ":expiration, :type, :date_added, :last_modified)"
    1928           0 :     );
    1929             :   }
    1930           0 :   NS_ENSURE_STATE(aStatement);
    1931           0 :   mozStorageStatementScoper setAnnoScoper(aStatement);
    1932             : 
    1933             :   // Don't replace existing annotations.
    1934           0 :   if (oldAnnoId > 0) {
    1935           0 :     rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("id"), oldAnnoId);
    1936           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1937           0 :     rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("date_added"), oldAnnoDate);
    1938           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1939             :   }
    1940             :   else {
    1941           0 :     rv = aStatement->BindNullByName(NS_LITERAL_CSTRING("id"));
    1942           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1943           0 :     rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("date_added"), RoundedPRNow());
    1944           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1945             :   }
    1946             : 
    1947           0 :   rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("fk"), fkId);
    1948           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1949           0 :   rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("name_id"), nameID);
    1950           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1951             : 
    1952           0 :   rv = aStatement->BindInt32ByName(NS_LITERAL_CSTRING("flags"), aFlags);
    1953           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1954           0 :   rv = aStatement->BindInt32ByName(NS_LITERAL_CSTRING("expiration"), aExpiration);
    1955           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1956           0 :   rv = aStatement->BindInt32ByName(NS_LITERAL_CSTRING("type"), aType);
    1957           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1958           0 :   rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("last_modified"), RoundedPRNow());
    1959           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1960             : 
    1961             :   // On success, leave the statement open, the caller will set the value
    1962             :   // and execute the statement.
    1963           0 :   setAnnoScoper.Abandon();
    1964             : 
    1965           0 :   return NS_OK;
    1966             : }
    1967             : 
    1968             : ////////////////////////////////////////////////////////////////////////////////
    1969             : //// nsIObserver
    1970             : 
    1971             : NS_IMETHODIMP
    1972           0 : nsAnnotationService::Observe(nsISupports *aSubject,
    1973             :                              const char *aTopic,
    1974             :                              const char16_t *aData)
    1975             : {
    1976           0 :   NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
    1977             : 
    1978           0 :   if (strcmp(aTopic, TOPIC_PLACES_SHUTDOWN) == 0) {
    1979             :     // Remove all session annotations, if any.
    1980           0 :     if (mHasSessionAnnotations) {
    1981           0 :       nsCOMPtr<mozIStorageAsyncStatement> pageAnnoStmt = mDB->GetAsyncStatement(
    1982             :         "DELETE FROM moz_annos WHERE expiration = :expire_session"
    1983           0 :       );
    1984           0 :       NS_ENSURE_STATE(pageAnnoStmt);
    1985           0 :       nsresult rv = pageAnnoStmt->BindInt32ByName(NS_LITERAL_CSTRING("expire_session"),
    1986           0 :                                                   EXPIRE_SESSION);
    1987           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1988             : 
    1989           0 :       nsCOMPtr<mozIStorageAsyncStatement> itemAnnoStmt = mDB->GetAsyncStatement(
    1990             :         "DELETE FROM moz_items_annos WHERE expiration = :expire_session"
    1991           0 :       );
    1992           0 :       NS_ENSURE_STATE(itemAnnoStmt);
    1993           0 :       rv = itemAnnoStmt->BindInt32ByName(NS_LITERAL_CSTRING("expire_session"),
    1994           0 :                                          EXPIRE_SESSION);
    1995           0 :       NS_ENSURE_SUCCESS(rv, rv);
    1996             : 
    1997             :       mozIStorageBaseStatement *stmts[] = {
    1998           0 :         pageAnnoStmt.get()
    1999           0 :       , itemAnnoStmt.get()
    2000           0 :       };
    2001             : 
    2002           0 :       nsCOMPtr<mozIStorageConnection> conn = mDB->MainConn();
    2003           0 :       if (!conn) {
    2004           0 :         return NS_ERROR_UNEXPECTED;
    2005             :       }
    2006           0 :       nsCOMPtr<mozIStoragePendingStatement> ps;
    2007           0 :       rv = conn->ExecuteAsync(stmts, ArrayLength(stmts), nullptr,
    2008           0 :                                          getter_AddRefs(ps));
    2009           0 :       NS_ENSURE_SUCCESS(rv, rv);
    2010             :     }
    2011             :   }
    2012             : 
    2013           0 :   return NS_OK;
    2014             : }

Generated by: LCOV version 1.13