LCOV - code coverage report
Current view: directory - toolkit/components/places - nsAnnotationService.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 892 742 83.2 %
Date: 2012-06-02 Functions: 64 57 89.1 %

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

Generated by: LCOV version 1.7