LCOV - code coverage report
Current view: directory - dom/src/storage - nsDOMStoragePersistentDB.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 444 314 70.7 %
Date: 2012-06-02 Functions: 31 27 87.1 %

       1                 : /* -*- Mode: C++; tab-width: 2; 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.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Mozilla Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Neil Deakin <enndeakin@sympatico.ca>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsCOMPtr.h"
      40                 : #include "nsDOMError.h"
      41                 : #include "nsDOMStorage.h"
      42                 : #include "nsDOMStorageDBWrapper.h"
      43                 : #include "nsDOMStoragePersistentDB.h"
      44                 : #include "nsIFile.h"
      45                 : #include "nsIVariant.h"
      46                 : #include "nsIEffectiveTLDService.h"
      47                 : #include "nsAppDirectoryServiceDefs.h"
      48                 : #include "mozStorageCID.h"
      49                 : #include "mozStorageHelper.h"
      50                 : #include "mozIStorageService.h"
      51                 : #include "mozIStorageBindingParamsArray.h"
      52                 : #include "mozIStorageBindingParams.h"
      53                 : #include "mozIStorageValueArray.h"
      54                 : #include "mozIStorageFunction.h"
      55                 : #include "nsNetUtil.h"
      56                 : 
      57                 : using namespace mozilla;
      58                 : 
      59                 : // Temporary tables for a storage scope will be flushed if found older
      60                 : // then this time in seconds since the load
      61                 : #define TEMP_TABLE_MAX_AGE (10) // seconds
      62                 : 
      63                 : class nsReverseStringSQLFunction : public mozIStorageFunction
      64              78 : {
      65                 :   NS_DECL_ISUPPORTS
      66                 :   NS_DECL_MOZISTORAGEFUNCTION
      67                 : };
      68                 : 
      69             936 : NS_IMPL_ISUPPORTS1(nsReverseStringSQLFunction, mozIStorageFunction)
      70                 : 
      71                 : NS_IMETHODIMP
      72               0 : nsReverseStringSQLFunction::OnFunctionCall(
      73                 :     mozIStorageValueArray *aFunctionArguments, nsIVariant **aResult)
      74                 : {
      75                 :   nsresult rv;
      76                 : 
      77               0 :   nsCAutoString stringToReverse;
      78               0 :   rv = aFunctionArguments->GetUTF8String(0, stringToReverse);
      79               0 :   NS_ENSURE_SUCCESS(rv, rv);
      80                 : 
      81               0 :   nsCAutoString result;
      82               0 :   ReverseString(stringToReverse, result);
      83                 : 
      84                 :   nsCOMPtr<nsIWritableVariant> outVar(do_CreateInstance(
      85               0 :       NS_VARIANT_CONTRACTID, &rv));
      86               0 :   NS_ENSURE_SUCCESS(rv, rv);
      87                 : 
      88               0 :   rv = outVar->SetAsAUTF8String(result);
      89               0 :   NS_ENSURE_SUCCESS(rv, rv);
      90                 : 
      91               0 :   *aResult = outVar.get();
      92               0 :   outVar.forget();
      93               0 :   return NS_OK;
      94                 : }
      95                 : 
      96                 : class nsIsOfflineSQLFunction : public mozIStorageFunction
      97              78 : {
      98                 :   NS_DECL_ISUPPORTS
      99                 :   NS_DECL_MOZISTORAGEFUNCTION
     100                 : };
     101                 : 
     102             936 : NS_IMPL_ISUPPORTS1(nsIsOfflineSQLFunction, mozIStorageFunction)
     103                 : 
     104             154 : nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
     105             154 : : mStatements(mConnection)
     106                 : {
     107             154 :   mTempTableLoads.Init(16);
     108             154 : }
     109                 : 
     110                 : NS_IMETHODIMP
     111               0 : nsIsOfflineSQLFunction::OnFunctionCall(
     112                 :     mozIStorageValueArray *aFunctionArguments, nsIVariant **aResult)
     113                 : {
     114                 :   nsresult rv;
     115                 : 
     116               0 :   nsCAutoString scope;
     117               0 :   rv = aFunctionArguments->GetUTF8String(0, scope);
     118               0 :   NS_ENSURE_SUCCESS(rv, rv);
     119                 : 
     120               0 :   nsCAutoString domain;
     121               0 :   rv = nsDOMStorageDBWrapper::GetDomainFromScopeKey(scope, domain);
     122               0 :   NS_ENSURE_SUCCESS(rv, rv);
     123                 : 
     124               0 :   bool hasOfflinePermission = IsOfflineAllowed(domain);
     125               0 :   NS_ENSURE_SUCCESS(rv, rv);
     126                 : 
     127                 :   nsCOMPtr<nsIWritableVariant> outVar(do_CreateInstance(
     128               0 :       NS_VARIANT_CONTRACTID, &rv));
     129               0 :   NS_ENSURE_SUCCESS(rv, rv);
     130                 : 
     131               0 :   rv = outVar->SetAsBool(hasOfflinePermission);
     132               0 :   NS_ENSURE_SUCCESS(rv, rv);
     133                 : 
     134               0 :   *aResult = outVar.get();
     135               0 :   outVar.forget();
     136               0 :   return NS_OK;
     137                 : }
     138                 : 
     139                 : nsresult
     140             116 : nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
     141                 : {
     142                 :   nsresult rv;
     143                 : 
     144             232 :   nsCOMPtr<nsIFile> storageFile;
     145                 :   rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
     146             116 :                               getter_AddRefs(storageFile));
     147             116 :   NS_ENSURE_SUCCESS(rv, rv);
     148              78 :   rv = storageFile->Append(aDatabaseName);
     149              78 :   NS_ENSURE_SUCCESS(rv, rv);
     150                 : 
     151             156 :   nsCOMPtr<mozIStorageService> service;
     152                 : 
     153              78 :   service = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
     154              78 :   NS_ENSURE_SUCCESS(rv, rv);
     155              78 :   rv = service->OpenUnsharedDatabase(storageFile, getter_AddRefs(mConnection));
     156              78 :   if (rv == NS_ERROR_FILE_CORRUPTED) {
     157                 :     // delete the db and try opening again
     158               0 :     rv = storageFile->Remove(false);
     159               0 :     NS_ENSURE_SUCCESS(rv, rv);
     160               0 :     rv = service->OpenUnsharedDatabase(storageFile, getter_AddRefs(mConnection));
     161                 :   }
     162              78 :   NS_ENSURE_SUCCESS(rv, rv);
     163                 : 
     164             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     165              78 :         MOZ_STORAGE_UNIQUIFY_QUERY_STR "PRAGMA temp_store = MEMORY"));
     166              78 :   NS_ENSURE_SUCCESS(rv, rv);
     167                 : 
     168             156 :   mozStorageTransaction transaction(mConnection, false);
     169                 : 
     170                 :   // Ensure Gecko 1.9.1 storage table
     171             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     172                 :          "CREATE TABLE IF NOT EXISTS webappsstore2 ("
     173                 :          "scope TEXT, "
     174                 :          "key TEXT, "
     175                 :          "value TEXT, "
     176                 :          "secure INTEGER, "
     177              78 :          "owner TEXT)"));
     178              78 :   NS_ENSURE_SUCCESS(rv, rv);
     179                 : 
     180             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     181                 :         "CREATE UNIQUE INDEX IF NOT EXISTS scope_key_index"
     182              78 :         " ON webappsstore2(scope, key)"));
     183              78 :   NS_ENSURE_SUCCESS(rv, rv);
     184                 : 
     185             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     186                 :          "CREATE TEMPORARY TABLE webappsstore2_temp ("
     187                 :          "scope TEXT, "
     188                 :          "key TEXT, "
     189                 :          "value TEXT, "
     190                 :          "secure INTEGER, "
     191                 :          "owner TEXT, "
     192              78 :          "modified INTEGER DEFAULT 0)"));
     193              78 :   NS_ENSURE_SUCCESS(rv, rv);
     194                 : 
     195             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     196                 :         "CREATE UNIQUE INDEX scope_key_index_temp"
     197              78 :         " ON webappsstore2_temp(scope, key)"));
     198              78 :   NS_ENSURE_SUCCESS(rv, rv);
     199                 : 
     200                 : 
     201             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     202                 :         "CREATE TEMPORARY VIEW webappsstore2_view AS "
     203                 :         "SELECT scope, key, value, secure, owner FROM webappsstore2_temp "
     204                 :         "UNION ALL "
     205                 :         "SELECT scope, key, value, secure, owner FROM webappsstore2 "
     206                 :           "WHERE NOT EXISTS ("
     207                 :             "SELECT scope, key FROM webappsstore2_temp "
     208              78 :             "WHERE scope = webappsstore2.scope AND key = webappsstore2.key)"));
     209              78 :   NS_ENSURE_SUCCESS(rv, rv);
     210                 : 
     211                 :   // carry deletion to both the temporary table and the disk table
     212             156 :   rv = mConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     213                 :         "CREATE TEMPORARY TRIGGER webappsstore2_view_delete_trigger "
     214                 :         "INSTEAD OF DELETE ON webappsstore2_view "
     215                 :         "BEGIN "
     216                 :           "DELETE FROM webappsstore2_temp "
     217                 :           "WHERE scope = OLD.scope AND key = OLD.key; "
     218                 :           "DELETE FROM webappsstore2 "
     219                 :           "WHERE scope = OLD.scope AND key = OLD.key; "
     220              78 :         "END"));
     221              78 :   NS_ENSURE_SUCCESS(rv, rv);
     222                 : 
     223             156 :   nsCOMPtr<mozIStorageFunction> function1(new nsReverseStringSQLFunction());
     224              78 :   NS_ENSURE_TRUE(function1, NS_ERROR_OUT_OF_MEMORY);
     225                 : 
     226              78 :   rv = mConnection->CreateFunction(NS_LITERAL_CSTRING("REVERSESTRING"), 1, function1);
     227              78 :   NS_ENSURE_SUCCESS(rv, rv);
     228                 : 
     229             156 :   nsCOMPtr<mozIStorageFunction> function2(new nsIsOfflineSQLFunction());
     230              78 :   NS_ENSURE_TRUE(function2, NS_ERROR_OUT_OF_MEMORY);
     231                 : 
     232              78 :   rv = mConnection->CreateFunction(NS_LITERAL_CSTRING("ISOFFLINE"), 1, function2);
     233              78 :   NS_ENSURE_SUCCESS(rv, rv);
     234                 : 
     235                 :   bool exists;
     236                 : 
     237                 :   // Check if there is storage of Gecko 1.9.0 and if so, upgrade that storage
     238                 :   // to actual webappsstore2 table and drop the obsolete table. First process
     239                 :   // this newer table upgrade to priority potential duplicates from older
     240                 :   // storage table.
     241             156 :   rv = mConnection->TableExists(NS_LITERAL_CSTRING("webappsstore"),
     242              78 :                                 &exists);
     243              78 :   NS_ENSURE_SUCCESS(rv, rv);
     244                 : 
     245              78 :   if (exists) {
     246               0 :       rv = mConnection->ExecuteSimpleSQL(
     247               0 :              NS_LITERAL_CSTRING("INSERT OR IGNORE INTO "
     248                 :                                 "webappsstore2(scope, key, value, secure, owner) "
     249                 :                                 "SELECT REVERSESTRING(domain) || '.:', key, value, secure, owner "
     250               0 :                                 "FROM webappsstore"));
     251               0 :       NS_ENSURE_SUCCESS(rv, rv);
     252                 : 
     253               0 :       rv = mConnection->ExecuteSimpleSQL(
     254               0 :              NS_LITERAL_CSTRING("DROP TABLE webappsstore"));
     255               0 :       NS_ENSURE_SUCCESS(rv, rv);
     256                 :   }
     257                 : 
     258                 :   // Check if there is storage of Gecko 1.8 and if so, upgrade that storage
     259                 :   // to actual webappsstore2 table and drop the obsolete table. Potential
     260                 :   // duplicates will be ignored.
     261             156 :   rv = mConnection->TableExists(NS_LITERAL_CSTRING("moz_webappsstore"),
     262              78 :                                 &exists);
     263              78 :   NS_ENSURE_SUCCESS(rv, rv);
     264                 : 
     265              78 :   if (exists) {
     266               0 :       rv = mConnection->ExecuteSimpleSQL(
     267               0 :              NS_LITERAL_CSTRING("INSERT OR IGNORE INTO "
     268                 :                                 "webappsstore2(scope, key, value, secure, owner) "
     269                 :                                 "SELECT REVERSESTRING(domain) || '.:', key, value, secure, domain "
     270               0 :                                 "FROM moz_webappsstore"));
     271               0 :       NS_ENSURE_SUCCESS(rv, rv);
     272                 : 
     273               0 :       rv = mConnection->ExecuteSimpleSQL(
     274               0 :              NS_LITERAL_CSTRING("DROP TABLE moz_webappsstore"));
     275               0 :       NS_ENSURE_SUCCESS(rv, rv);
     276                 :   }
     277                 : 
     278              78 :   rv = transaction.Commit();
     279              78 :   NS_ENSURE_SUCCESS(rv, rv);
     280                 : 
     281              78 :   return NS_OK;
     282                 : }
     283                 : 
     284                 : void
     285              74 : nsDOMStoragePersistentDB::Close()
     286                 : {
     287                 :   // Finalize the cached statements.
     288              74 :   mStatements.FinalizeStatements();
     289                 : 
     290             148 :   DebugOnly<nsresult> rv = mConnection->Close();
     291              74 :   MOZ_ASSERT(NS_SUCCEEDED(rv));
     292              74 : }
     293                 : 
     294                 : nsresult
     295             106 : nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
     296                 : {
     297             106 :   TimeStamp timeStamp;
     298                 : 
     299             106 :   if (!mTempTableLoads.Get(aStorage->GetScopeDBKey(), &timeStamp)) {
     300                 :     nsresult rv;
     301                 : 
     302               8 :     rv = MaybeCommitInsertTransaction();
     303               8 :     NS_ENSURE_SUCCESS(rv, rv);
     304                 : 
     305                 :     nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     306                 :       "INSERT INTO webappsstore2_temp (scope, key, value, secure, owner) "
     307                 :         "SELECT scope, key, value, secure, owner FROM webappsstore2 "
     308                 :         "WHERE scope = :scope "
     309                 :           "AND NOT EXISTS ( "
     310                 :             "SELECT scope, key FROM webappsstore2_temp "
     311                 :             "WHERE scope = webappsstore2.scope AND key = webappsstore2.key "
     312                 :           ") "
     313              24 :     );
     314               8 :     NS_ENSURE_STATE(stmt);
     315              16 :     mozStorageStatementScoper scope(stmt);
     316                 : 
     317              16 :     rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), 
     318               8 :                                     aStorage->GetScopeDBKey());
     319               8 :     NS_ENSURE_SUCCESS(rv, rv);
     320                 : 
     321               8 :     rv = stmt->Execute();
     322               8 :     NS_ENSURE_SUCCESS(rv, rv);
     323                 : 
     324               8 :     mTempTableLoads.Put(aStorage->GetScopeDBKey(), TimeStamp::Now());
     325                 : 
     326              16 :     DOMStorageImpl::gStorageDB->EnsureTempTableFlushTimer();
     327                 :   }
     328                 : 
     329             106 :   return NS_OK;
     330                 : }
     331                 : 
     332                 : /* static */
     333                 : PLDHashOperator
     334               8 : nsDOMStoragePersistentDB::FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
     335                 :                                               TimeStamp& aData,
     336                 :                                               void* aUserArg)
     337                 : {
     338               8 :   FlushTemporaryTableData* data = (FlushTemporaryTableData*)aUserArg;
     339                 : 
     340               8 :   if (!data->mForce && 
     341               0 :       ((TimeStamp::Now() - aData).ToSeconds() < TEMP_TABLE_MAX_AGE))
     342               0 :     return PL_DHASH_NEXT;
     343                 : 
     344                 :   {
     345                 :     nsCOMPtr<mozIStorageStatement> stmt =
     346                 :       data->mDB->mStatements.GetCachedStatement(
     347                 :         "INSERT OR REPLACE INTO webappsstore2 "
     348                 :          "SELECT scope, key, value, secure, owner FROM webappsstore2_temp "
     349                 :          "WHERE scope = :scope AND modified = 1"
     350              24 :       );
     351               8 :     NS_ENSURE_TRUE(stmt, PL_DHASH_STOP);
     352              16 :     mozStorageStatementScoper scope(stmt);
     353                 : 
     354               8 :     data->mRV = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
     355               8 :     NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
     356                 : 
     357               8 :     data->mRV = stmt->Execute();
     358               8 :     NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
     359                 :   }
     360                 : 
     361                 :   {
     362                 :     nsCOMPtr<mozIStorageStatement> stmt =
     363                 :       data->mDB->mStatements.GetCachedStatement(
     364                 :         "DELETE FROM webappsstore2_temp "
     365                 :          "WHERE scope = :scope "
     366              24 :       );
     367               8 :     NS_ENSURE_TRUE(stmt, PL_DHASH_STOP);
     368              16 :     mozStorageStatementScoper scope(stmt);
     369                 : 
     370               8 :     data->mRV = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
     371               8 :     NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
     372                 : 
     373               8 :     data->mRV = stmt->Execute();
     374               8 :     NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
     375                 :   }
     376                 : 
     377               8 :   return PL_DHASH_REMOVE;
     378                 : }
     379                 : 
     380                 : nsresult
     381              74 : nsDOMStoragePersistentDB::FlushTemporaryTables(bool force)
     382                 : {
     383             148 :   mozStorageTransaction trans(mConnection, false);
     384                 : 
     385                 :   nsresult rv;
     386                 : 
     387                 :   FlushTemporaryTableData data;
     388              74 :   data.mDB = this;
     389              74 :   data.mForce = force;
     390              74 :   data.mRV = NS_OK;
     391                 : 
     392              74 :   mTempTableLoads.Enumerate(FlushTemporaryTable, &data);
     393              74 :   NS_ENSURE_SUCCESS(data.mRV, data.mRV);
     394                 : 
     395              74 :   rv = trans.Commit();
     396              74 :   NS_ENSURE_SUCCESS(rv, rv);
     397                 : 
     398              74 :   rv = MaybeCommitInsertTransaction();
     399              74 :   NS_ENSURE_SUCCESS(rv, rv);
     400                 : 
     401              74 :   return NS_OK;
     402                 : }
     403                 : 
     404                 : nsresult
     405              38 : nsDOMStoragePersistentDB::GetAllKeys(DOMStorageImpl* aStorage,
     406                 :                                      nsTHashtable<nsSessionStorageEntry>* aKeys)
     407                 : {
     408                 :   nsresult rv;
     409                 : 
     410              38 :   rv = MaybeCommitInsertTransaction();
     411              38 :   NS_ENSURE_SUCCESS(rv, rv);
     412                 : 
     413              38 :   rv = EnsureLoadTemporaryTableForStorage(aStorage);
     414              38 :   NS_ENSURE_SUCCESS(rv, rv);
     415                 : 
     416                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     417                 :     "SELECT key, value, secure FROM webappsstore2_temp "
     418                 :     "WHERE scope = :scope "
     419             114 :   );
     420              38 :   NS_ENSURE_STATE(stmt);
     421              76 :   mozStorageStatementScoper scope(stmt);
     422                 : 
     423              76 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     424              38 :                                   aStorage->GetScopeDBKey());
     425              38 :   NS_ENSURE_SUCCESS(rv, rv);
     426                 : 
     427                 :   bool exists;
     428              92 :   while (NS_SUCCEEDED(rv = stmt->ExecuteStep(&exists)) && exists) {
     429              32 :     nsAutoString key;
     430              16 :     rv = stmt->GetString(0, key);
     431              16 :     NS_ENSURE_SUCCESS(rv, rv);
     432                 : 
     433              32 :     nsAutoString value;
     434              16 :     rv = stmt->GetString(1, value);
     435              16 :     NS_ENSURE_SUCCESS(rv, rv);
     436                 : 
     437              16 :     PRInt32 secureInt = 0;
     438              16 :     rv = stmt->GetInt32(2, &secureInt);
     439              16 :     NS_ENSURE_SUCCESS(rv, rv);
     440                 : 
     441              16 :     nsSessionStorageEntry* entry = aKeys->PutEntry(key);
     442              16 :     NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
     443                 : 
     444              16 :     entry->mItem = new nsDOMStorageItem(aStorage, key, value, secureInt);
     445              16 :     if (!entry->mItem) {
     446               0 :       aKeys->RawRemoveEntry(entry);
     447               0 :       return NS_ERROR_OUT_OF_MEMORY;
     448                 :     }
     449                 :   }
     450                 : 
     451              38 :   return NS_OK;
     452                 : }
     453                 : 
     454                 : nsresult
     455              50 : nsDOMStoragePersistentDB::GetKeyValue(DOMStorageImpl* aStorage,
     456                 :                                       const nsAString& aKey,
     457                 :                                       nsAString& aValue,
     458                 :                                       bool* aSecure)
     459                 : {
     460                 :   nsresult rv;
     461                 : 
     462              50 :   rv = MaybeCommitInsertTransaction();
     463              50 :   NS_ENSURE_SUCCESS(rv, rv);
     464                 : 
     465              50 :   rv = EnsureLoadTemporaryTableForStorage(aStorage);
     466              50 :   NS_ENSURE_SUCCESS(rv, rv);
     467                 : 
     468                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     469                 :     "SELECT value, secure FROM webappsstore2_temp "
     470                 :     "WHERE scope = :scope "
     471                 :       "AND key = :key "
     472             150 :   );
     473              50 :   NS_ENSURE_STATE(stmt);
     474             100 :   mozStorageStatementScoper scope(stmt);
     475                 : 
     476             100 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     477              50 :                                   aStorage->GetScopeDBKey());
     478              50 :   NS_ENSURE_SUCCESS(rv, rv);
     479             100 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key"),
     480              50 :                               aKey);
     481              50 :   NS_ENSURE_SUCCESS(rv, rv);
     482                 : 
     483                 :   bool exists;
     484              50 :   rv = stmt->ExecuteStep(&exists);
     485              50 :   NS_ENSURE_SUCCESS(rv, rv);
     486                 : 
     487              50 :   PRInt32 secureInt = 0;
     488              50 :   if (exists) {
     489              32 :     rv = stmt->GetString(0, aValue);
     490              32 :     NS_ENSURE_SUCCESS(rv, rv);
     491                 : 
     492              32 :     rv = stmt->GetInt32(1, &secureInt);
     493              32 :     NS_ENSURE_SUCCESS(rv, rv);
     494                 :   }
     495                 :   else {
     496              18 :     rv = NS_ERROR_DOM_NOT_FOUND_ERR;
     497                 :   }
     498                 : 
     499              50 :   *aSecure = !!secureInt;
     500                 : 
     501              50 :   return rv;
     502                 : }
     503                 : 
     504                 : nsresult
     505              18 : nsDOMStoragePersistentDB::SetKey(DOMStorageImpl* aStorage,
     506                 :                                  const nsAString& aKey,
     507                 :                                  const nsAString& aValue,
     508                 :                                  bool aSecure,
     509                 :                                  PRInt32 aQuota,
     510                 :                                  bool aExcludeOfflineFromUsage,
     511                 :                                  PRInt32 *aNewUsage)
     512                 : {
     513                 :   nsresult rv;
     514                 : 
     515              18 :   rv = EnsureLoadTemporaryTableForStorage(aStorage);
     516              18 :   NS_ENSURE_SUCCESS(rv, rv);
     517                 : 
     518              18 :   PRInt32 usage = 0;
     519              18 :   if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
     520               6 :     rv = GetUsage(aStorage, aExcludeOfflineFromUsage, &usage);
     521               6 :     NS_ENSURE_SUCCESS(rv, rv);
     522                 :   }
     523                 : 
     524              18 :   usage += aKey.Length() + aValue.Length();
     525                 : 
     526              36 :   nsAutoString previousValue;
     527                 :   bool secure;
     528              18 :   rv = aStorage->GetCachedValue(aKey, previousValue, &secure);
     529              18 :   if (NS_SUCCEEDED(rv)) {
     530               0 :     if (!aSecure && secure)
     531               0 :       return NS_ERROR_DOM_SECURITY_ERR;
     532               0 :     usage -= aKey.Length() + previousValue.Length();
     533                 :   }
     534                 : 
     535              18 :   if (usage > aQuota) {
     536               0 :     return NS_ERROR_DOM_QUOTA_REACHED;
     537                 :   }
     538                 : 
     539              18 :   rv = EnsureInsertTransaction();
     540              18 :   NS_ENSURE_SUCCESS(rv, rv);
     541                 : 
     542                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     543                 :     "INSERT OR REPLACE INTO webappsstore2_temp (scope, key, value, secure, modified) "
     544                 :     "VALUES (:scope, :key, :value, :secure, 1) "
     545              54 :   );
     546              18 :   NS_ENSURE_STATE(stmt);
     547              36 :   mozStorageStatementScoper scopeinsert(stmt);
     548                 : 
     549              36 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     550              18 :                                   aStorage->GetScopeDBKey());
     551              18 :   NS_ENSURE_SUCCESS(rv, rv);
     552              36 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key"),
     553              18 :                               aKey);
     554              18 :   NS_ENSURE_SUCCESS(rv, rv);
     555              36 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("value"),
     556              18 :                               aValue);
     557              18 :   NS_ENSURE_SUCCESS(rv, rv);
     558              36 :   rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("secure"),
     559              18 :                              aSecure ? 1 : 0);
     560              18 :   NS_ENSURE_SUCCESS(rv, rv);
     561                 : 
     562              18 :   rv = stmt->Execute();
     563              18 :   NS_ENSURE_SUCCESS(rv, rv);
     564                 : 
     565              18 :   if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
     566                 :     // No need to set mCachedOwner since it was set by GetUsage()
     567               6 :     mCachedUsage = usage;
     568                 :   }
     569                 : 
     570              18 :   *aNewUsage = usage;
     571                 : 
     572              18 :   MarkScopeDirty(aStorage);
     573                 : 
     574              18 :   return NS_OK;
     575                 : }
     576                 : 
     577                 : nsresult
     578               0 : nsDOMStoragePersistentDB::SetSecure(DOMStorageImpl* aStorage,
     579                 :                                     const nsAString& aKey,
     580                 :                                     const bool aSecure)
     581                 : {
     582                 :   nsresult rv;
     583                 : 
     584               0 :   rv = EnsureLoadTemporaryTableForStorage(aStorage);
     585               0 :   NS_ENSURE_SUCCESS(rv, rv);
     586                 : 
     587               0 :   rv = EnsureInsertTransaction();
     588               0 :   NS_ENSURE_SUCCESS(rv, rv);
     589                 : 
     590                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     591                 :     "UPDATE webappsstore2_temp "
     592                 :     "SET secure = :secure, modified = 1 "
     593                 :     "WHERE scope = :scope "
     594                 :       "AND key = :key "
     595               0 :   );
     596               0 :   NS_ENSURE_STATE(stmt);
     597               0 :   mozStorageStatementScoper scope(stmt);
     598                 : 
     599               0 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     600               0 :                                   aStorage->GetScopeDBKey());
     601               0 :   NS_ENSURE_SUCCESS(rv, rv);
     602               0 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key"),
     603               0 :                               aKey);
     604               0 :   NS_ENSURE_SUCCESS(rv, rv);
     605               0 :   rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("secure"),
     606               0 :                              aSecure ? 1 : 0);
     607               0 :   NS_ENSURE_SUCCESS(rv, rv);
     608                 : 
     609               0 :   rv = stmt->Execute();
     610               0 :   NS_ENSURE_SUCCESS(rv, rv);
     611                 : 
     612               0 :   MarkScopeDirty(aStorage);
     613                 : 
     614               0 :   return NS_OK;
     615                 : }
     616                 : 
     617                 : nsresult
     618               6 : nsDOMStoragePersistentDB::RemoveKey(DOMStorageImpl* aStorage,
     619                 :                                     const nsAString& aKey,
     620                 :                                     bool aExcludeOfflineFromUsage,
     621                 :                                     PRInt32 aKeyUsage)
     622                 : {
     623                 :   nsresult rv;
     624                 : 
     625               6 :   rv = MaybeCommitInsertTransaction();
     626               6 :   NS_ENSURE_SUCCESS(rv, rv);
     627                 : 
     628                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     629                 :     "DELETE FROM webappsstore2_view "
     630                 :     "WHERE scope = :scope "
     631                 :       "AND key = :key "
     632              18 :   );
     633               6 :   NS_ENSURE_STATE(stmt);
     634              12 :   mozStorageStatementScoper scope(stmt);
     635                 : 
     636               6 :   if (DomainMaybeCached(
     637               6 :       aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage))) {
     638               0 :     mCachedUsage = 0;
     639               0 :     mCachedOwner.Truncate();
     640                 :   }
     641                 : 
     642              12 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     643               6 :                                   aStorage->GetScopeDBKey());
     644               6 :   NS_ENSURE_SUCCESS(rv, rv);
     645              12 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("key"),
     646               6 :                               aKey);
     647               6 :   NS_ENSURE_SUCCESS(rv, rv);
     648                 : 
     649               6 :   rv = stmt->Execute();
     650               6 :   NS_ENSURE_SUCCESS(rv, rv);
     651                 : 
     652               6 :   MarkScopeDirty(aStorage);
     653                 : 
     654               6 :   return NS_OK;
     655                 : }
     656                 : 
     657                 : nsresult
     658               6 : nsDOMStoragePersistentDB::ClearStorage(DOMStorageImpl* aStorage)
     659                 : {
     660                 :   nsresult rv;
     661                 : 
     662               6 :   rv = MaybeCommitInsertTransaction();
     663               6 :   NS_ENSURE_SUCCESS(rv, rv);
     664                 : 
     665                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     666                 :     "DELETE FROM webappsstore2_view "
     667                 :     "WHERE scope = :scope "
     668              18 :   );
     669               6 :   NS_ENSURE_STATE(stmt);
     670              12 :   mozStorageStatementScoper scope(stmt);
     671                 : 
     672               6 :   mCachedUsage = 0;
     673               6 :   mCachedOwner.Truncate();
     674                 : 
     675              12 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     676               6 :                                   aStorage->GetScopeDBKey());
     677               6 :   NS_ENSURE_SUCCESS(rv, rv);
     678                 : 
     679               6 :   rv = stmt->Execute();
     680               6 :   NS_ENSURE_SUCCESS(rv, rv);
     681                 : 
     682               6 :   MarkScopeDirty(aStorage);
     683                 : 
     684               6 :   return NS_OK;
     685                 : }
     686                 : 
     687                 : nsresult
     688              48 : nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
     689                 :                                       bool aIncludeSubDomains)
     690                 : {
     691                 :   nsresult rv;
     692                 : 
     693              48 :   rv = MaybeCommitInsertTransaction();
     694              48 :   NS_ENSURE_SUCCESS(rv, rv);
     695                 : 
     696                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     697                 :     "DELETE FROM webappsstore2_view "
     698                 :     "WHERE scope GLOB :scope "
     699             144 :   );
     700              48 :   NS_ENSURE_STATE(stmt);
     701              96 :   mozStorageStatementScoper scope(stmt);
     702                 : 
     703              96 :   nsCAutoString subdomainsDBKey;
     704              48 :   nsDOMStorageDBWrapper::CreateDomainScopeDBKey(aOwner, subdomainsDBKey);
     705                 : 
     706              48 :   if (DomainMaybeCached(subdomainsDBKey)) {
     707               0 :     mCachedUsage = 0;
     708               0 :     mCachedOwner.Truncate();
     709                 :   }
     710                 : 
     711              48 :   if (!aIncludeSubDomains)
     712               0 :     subdomainsDBKey.AppendLiteral(":");
     713              48 :   subdomainsDBKey.AppendLiteral("*");
     714                 : 
     715              96 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
     716              48 :                                   subdomainsDBKey);
     717              48 :   NS_ENSURE_SUCCESS(rv, rv);
     718                 : 
     719              48 :   rv = stmt->Execute();
     720              48 :   NS_ENSURE_SUCCESS(rv, rv);
     721                 : 
     722              48 :   MarkAllScopesDirty();
     723                 : 
     724              48 :   return NS_OK;
     725                 : }
     726                 : 
     727                 : 
     728                 : nsresult
     729              12 : nsDOMStoragePersistentDB::RemoveOwners(const nsTArray<nsString> &aOwners,
     730                 :                                        bool aIncludeSubDomains,
     731                 :                                        bool aMatch)
     732                 : {
     733              12 :   if (aOwners.Length() == 0) {
     734              12 :     if (aMatch) {
     735               1 :       return NS_OK;
     736                 :     }
     737                 : 
     738              11 :     return RemoveAll();
     739                 :   }
     740                 : 
     741                 :   // Using nsString here because it is going to be very long
     742               0 :   nsCString expression;
     743                 : 
     744               0 :   if (aMatch) {
     745               0 :     expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope IN (");
     746                 :   } else {
     747               0 :     expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope NOT IN (");
     748                 :   }
     749                 : 
     750               0 :   for (PRUint32 i = 0; i < aOwners.Length(); i++) {
     751               0 :     if (i)
     752               0 :       expression.AppendLiteral(" UNION ");
     753                 : 
     754                 :     expression.AppendLiteral(
     755               0 :       "SELECT DISTINCT scope FROM webappsstore2_temp WHERE scope GLOB :scope");
     756               0 :     expression.AppendInt(i);
     757               0 :     expression.AppendLiteral(" UNION ");
     758                 :     expression.AppendLiteral(
     759               0 :       "SELECT DISTINCT scope FROM webappsstore2 WHERE scope GLOB :scope");
     760               0 :     expression.AppendInt(i);
     761                 :   }
     762               0 :   expression.AppendLiteral(");");
     763                 : 
     764               0 :   nsCOMPtr<mozIStorageStatement> statement;
     765                 : 
     766                 :   nsresult rv;
     767                 : 
     768               0 :   rv = MaybeCommitInsertTransaction();
     769               0 :   NS_ENSURE_SUCCESS(rv, rv);
     770                 : 
     771               0 :   rv = mConnection->CreateStatement(expression,
     772               0 :                                     getter_AddRefs(statement));
     773               0 :   NS_ENSURE_SUCCESS(rv, rv);
     774                 : 
     775               0 :   for (PRUint32 i = 0; i < aOwners.Length(); i++) {
     776               0 :     nsCAutoString quotaKey;
     777                 :     rv = nsDOMStorageDBWrapper::CreateDomainScopeDBKey(
     778               0 :       NS_ConvertUTF16toUTF8(aOwners[i]), quotaKey);
     779                 : 
     780               0 :     if (DomainMaybeCached(quotaKey)) {
     781               0 :       mCachedUsage = 0;
     782               0 :       mCachedOwner.Truncate();
     783                 :     }
     784                 : 
     785               0 :     if (!aIncludeSubDomains)
     786               0 :       quotaKey.AppendLiteral(":");
     787               0 :     quotaKey.AppendLiteral("*");
     788                 : 
     789               0 :     nsCAutoString paramName;
     790               0 :     paramName.Assign("scope");
     791               0 :     paramName.AppendInt(i);
     792                 : 
     793               0 :     rv = statement->BindUTF8StringByName(paramName, quotaKey);
     794               0 :     NS_ENSURE_SUCCESS(rv, rv);
     795                 :   }
     796                 : 
     797               0 :   rv = statement->Execute();
     798               0 :   NS_ENSURE_SUCCESS(rv, rv);
     799                 : 
     800               0 :   MarkAllScopesDirty();
     801                 : 
     802               0 :   return NS_OK;
     803                 : }
     804                 : 
     805                 : nsresult
     806              11 : nsDOMStoragePersistentDB::RemoveAll()
     807                 : {
     808                 :   nsresult rv;
     809                 : 
     810              11 :   rv = MaybeCommitInsertTransaction();
     811              11 :   NS_ENSURE_SUCCESS(rv, rv);
     812                 : 
     813                 :   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
     814                 :     "DELETE FROM webappsstore2_view "
     815              33 :   );
     816              11 :   NS_ENSURE_STATE(stmt);
     817              22 :   mozStorageStatementScoper scope(stmt);
     818                 : 
     819              11 :   rv = stmt->Execute();
     820              11 :   NS_ENSURE_SUCCESS(rv, rv);
     821                 : 
     822              11 :   MarkAllScopesDirty();
     823                 : 
     824              11 :   return NS_OK;
     825                 : }
     826                 : 
     827                 : nsresult
     828               6 : nsDOMStoragePersistentDB::GetUsage(DOMStorageImpl* aStorage,
     829                 :                                    bool aExcludeOfflineFromUsage,
     830                 :                                    PRInt32 *aUsage)
     831                 : {
     832               6 :   return GetUsageInternal(aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage),
     833                 :                                                         aExcludeOfflineFromUsage,
     834              12 :                                                         aUsage);
     835                 : }
     836                 : 
     837                 : nsresult
     838               0 : nsDOMStoragePersistentDB::GetUsage(const nsACString& aDomain,
     839                 :                                    bool aIncludeSubDomains,
     840                 :                                    PRInt32 *aUsage)
     841                 : {
     842                 :   nsresult rv;
     843                 : 
     844               0 :   nsCAutoString quotadomainDBKey;
     845                 :   rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
     846                 :                                                      aIncludeSubDomains,
     847                 :                                                      false,
     848               0 :                                                      quotadomainDBKey);
     849               0 :   NS_ENSURE_SUCCESS(rv, rv);
     850                 : 
     851               0 :   return GetUsageInternal(quotadomainDBKey, false, aUsage);
     852                 : }
     853                 : 
     854                 : nsresult
     855               6 : nsDOMStoragePersistentDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
     856                 :                                            bool aExcludeOfflineFromUsage,
     857                 :                                            PRInt32 *aUsage)
     858                 : {
     859               6 :   if (aQuotaDomainDBKey == mCachedOwner) {
     860               2 :     *aUsage = mCachedUsage;
     861               2 :     return NS_OK;
     862                 :   }
     863                 : 
     864                 :   nsresult rv;
     865                 : 
     866               4 :   rv = MaybeCommitInsertTransaction();
     867               4 :   NS_ENSURE_SUCCESS(rv, rv);
     868                 : 
     869               8 :   nsCOMPtr<mozIStorageStatement> stmt;
     870               4 :   if (aExcludeOfflineFromUsage) {
     871                 :     stmt = mStatements.GetCachedStatement(
     872                 :       "SELECT SUM(LENGTH(key) + LENGTH(value)) "
     873                 :       "FROM ( "
     874                 :         "SELECT key, value FROM webappsstore2_temp "
     875                 :         "WHERE scope GLOB :scope "
     876                 :           "AND NOT ISOFFLINE(scope) "
     877                 :         "UNION ALL "
     878                 :         "SELECT key, value FROM webappsstore2 "
     879                 :         "WHERE scope GLOB :scope "
     880                 :           "AND NOT ISOFFLINE(scope) "
     881                 :           "AND NOT EXISTS ( "
     882                 :             "SELECT scope, key "
     883                 :             "FROM webappsstore2_temp "
     884                 :             "WHERE scope = webappsstore2.scope "
     885                 :               "AND key = webappsstore2.key "
     886                 :           ") "
     887                 :       ") "
     888               8 :     );
     889                 :   } else {
     890                 :     stmt = mStatements.GetCachedStatement(
     891                 :       "SELECT SUM(LENGTH(key) + LENGTH(value)) "
     892                 :       "FROM ( "
     893                 :         "SELECT key,value FROM webappsstore2_temp "
     894                 :         "WHERE scope GLOB :scope "
     895                 :         "UNION ALL "
     896                 :         "SELECT key,value FROM webappsstore2 "
     897                 :         "WHERE scope GLOB :scope "
     898                 :           "AND NOT EXISTS ( "
     899                 :             "SELECT scope, key "
     900                 :             "FROM webappsstore2_temp "
     901                 :             "WHERE scope = webappsstore2.scope "
     902                 :               "AND key = webappsstore2.key "
     903                 :           ") "
     904                 :       ") "
     905               0 :     );
     906                 :   }
     907               4 :   NS_ENSURE_STATE(stmt);
     908               8 :   mozStorageStatementScoper scope(stmt);
     909                 : 
     910               8 :   nsCAutoString scopeValue(aQuotaDomainDBKey);
     911               4 :   scopeValue += NS_LITERAL_CSTRING("*");
     912                 : 
     913               4 :   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), scopeValue);
     914               4 :   NS_ENSURE_SUCCESS(rv, rv);
     915                 : 
     916                 :   bool exists;
     917               4 :   rv = stmt->ExecuteStep(&exists);
     918               4 :   NS_ENSURE_SUCCESS(rv, rv);
     919                 : 
     920               4 :   if (!exists) {
     921               0 :     *aUsage = 0;
     922               0 :     return NS_OK;
     923                 :   }
     924                 : 
     925               4 :   rv = stmt->GetInt32(0, aUsage);
     926               4 :   NS_ENSURE_SUCCESS(rv, rv);
     927                 : 
     928               4 :   if (!aQuotaDomainDBKey.IsEmpty()) {
     929               4 :     mCachedOwner = aQuotaDomainDBKey;
     930               4 :     mCachedUsage = *aUsage;
     931                 :   }
     932                 : 
     933               4 :   return NS_OK;
     934                 : }
     935                 : 
     936                 : nsresult
     937              18 : nsDOMStoragePersistentDB::EnsureInsertTransaction()
     938                 : {
     939              18 :   if (!mConnection)
     940               0 :     return NS_ERROR_UNEXPECTED;
     941                 : 
     942                 :   bool transactionInProgress;
     943              18 :   nsresult rv = mConnection->GetTransactionInProgress(&transactionInProgress);
     944              18 :   NS_ENSURE_SUCCESS(rv, rv);
     945                 : 
     946              18 :   if (transactionInProgress)
     947               0 :     return NS_OK;
     948                 : 
     949              18 :   rv = mConnection->BeginTransaction();
     950              18 :   NS_ENSURE_SUCCESS(rv, rv);
     951                 : 
     952              18 :   return NS_OK;
     953                 : }
     954                 : 
     955                 : nsresult
     956             245 : nsDOMStoragePersistentDB::MaybeCommitInsertTransaction()
     957                 : {
     958             245 :   if (!mConnection)
     959               0 :     return NS_ERROR_UNEXPECTED;
     960                 : 
     961                 :   bool transactionInProgress;
     962             245 :   nsresult rv = mConnection->GetTransactionInProgress(&transactionInProgress);
     963             245 :   if (NS_FAILED(rv)) {
     964                 :     NS_WARNING("nsDOMStoragePersistentDB::MaybeCommitInsertTransaction: "
     965               0 :                "connection probably already dead");
     966                 :   }
     967                 : 
     968             245 :   if (NS_FAILED(rv) || !transactionInProgress)
     969             227 :     return NS_OK;
     970                 : 
     971              18 :   rv = mConnection->CommitTransaction();
     972              18 :   NS_ENSURE_SUCCESS(rv, rv);
     973                 : 
     974              18 :   return NS_OK;
     975                 : }
     976                 : 
     977                 : bool
     978              54 : nsDOMStoragePersistentDB::DomainMaybeCached(const nsACString& aDomain)
     979                 : {
     980              54 :   if (mCachedOwner.IsEmpty())
     981              50 :     return false;
     982                 : 
     983                 :   // if cached owner contains colon we must ignore it
     984               4 :   if (mCachedOwner[mCachedOwner.Length() - 1] == ':')
     985                 :     return StringBeginsWith(aDomain, Substring(mCachedOwner, 0,
     986               0 :                                                mCachedOwner.Length() - 1));
     987                 :   else
     988               4 :     return StringBeginsWith(aDomain, mCachedOwner);
     989                 : }

Generated by: LCOV version 1.7