LCOV - code coverage report
Current view: top level - dom/cache - DBAction.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 112 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/cache/DBAction.h"
       8             : 
       9             : #include "mozilla/dom/cache/Connection.h"
      10             : #include "mozilla/dom/cache/DBSchema.h"
      11             : #include "mozilla/dom/cache/FileUtils.h"
      12             : #include "mozilla/dom/quota/PersistenceType.h"
      13             : #include "mozilla/net/nsFileProtocolHandler.h"
      14             : #include "mozIStorageConnection.h"
      15             : #include "mozIStorageService.h"
      16             : #include "mozStorageCID.h"
      17             : #include "nsIFile.h"
      18             : #include "nsIURI.h"
      19             : #include "nsIFileURL.h"
      20             : #include "nsThreadUtils.h"
      21             : 
      22             : namespace mozilla {
      23             : namespace dom {
      24             : namespace cache {
      25             : 
      26             : using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
      27             : using mozilla::dom::quota::PersistenceType;
      28             : 
      29           0 : DBAction::DBAction(Mode aMode)
      30           0 :   : mMode(aMode)
      31             : {
      32           0 : }
      33             : 
      34           0 : DBAction::~DBAction()
      35             : {
      36           0 : }
      37             : 
      38             : void
      39           0 : DBAction::RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo,
      40             :                       Data* aOptionalData)
      41             : {
      42           0 :   MOZ_ASSERT(!NS_IsMainThread());
      43           0 :   MOZ_DIAGNOSTIC_ASSERT(aResolver);
      44           0 :   MOZ_DIAGNOSTIC_ASSERT(aQuotaInfo.mDir);
      45             : 
      46           0 :   if (IsCanceled()) {
      47           0 :     aResolver->Resolve(NS_ERROR_ABORT);
      48           0 :     return;
      49             :   }
      50             : 
      51           0 :   nsCOMPtr<nsIFile> dbDir;
      52           0 :   nsresult rv = aQuotaInfo.mDir->Clone(getter_AddRefs(dbDir));
      53           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
      54           0 :     aResolver->Resolve(rv);
      55           0 :     return;
      56             :   }
      57             : 
      58           0 :   rv = dbDir->Append(NS_LITERAL_STRING("cache"));
      59           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
      60           0 :     aResolver->Resolve(rv);
      61           0 :     return;
      62             :   }
      63             : 
      64           0 :   nsCOMPtr<mozIStorageConnection> conn;
      65             : 
      66             :   // Attempt to reuse the connection opened by a previous Action.
      67           0 :   if (aOptionalData) {
      68           0 :     conn = aOptionalData->GetConnection();
      69             :   }
      70             : 
      71             :   // If there is no previous Action, then we must open one.
      72           0 :   if (!conn) {
      73           0 :     rv = OpenConnection(aQuotaInfo, dbDir, getter_AddRefs(conn));
      74           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
      75           0 :       aResolver->Resolve(rv);
      76           0 :       return;
      77             :     }
      78           0 :     MOZ_DIAGNOSTIC_ASSERT(conn);
      79             : 
      80             :     // Save this connection in the shared Data object so later Actions can
      81             :     // use it.  This avoids opening a new connection for every Action.
      82           0 :     if (aOptionalData) {
      83             :       // Since we know this connection will be around for as long as the
      84             :       // Cache is open, use our special wrapped connection class.  This
      85             :       // will let us perform certain operations once the Cache origin
      86             :       // is closed.
      87           0 :       nsCOMPtr<mozIStorageConnection> wrapped = new Connection(conn);
      88           0 :       aOptionalData->SetConnection(wrapped);
      89             :     }
      90             :   }
      91             : 
      92           0 :   RunWithDBOnTarget(aResolver, aQuotaInfo, dbDir, conn);
      93             : }
      94             : 
      95             : nsresult
      96           0 : DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
      97             :                          mozIStorageConnection** aConnOut)
      98             : {
      99           0 :   MOZ_ASSERT(!NS_IsMainThread());
     100           0 :   MOZ_DIAGNOSTIC_ASSERT(aDBDir);
     101           0 :   MOZ_DIAGNOSTIC_ASSERT(aConnOut);
     102             : 
     103           0 :   nsCOMPtr<mozIStorageConnection> conn;
     104             : 
     105             :   bool exists;
     106           0 :   nsresult rv = aDBDir->Exists(&exists);
     107           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     108             : 
     109           0 :   if (!exists) {
     110           0 :     if (NS_WARN_IF(mMode != Create)) {  return NS_ERROR_FILE_NOT_FOUND; }
     111           0 :     rv = aDBDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
     112           0 :     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     113             :   }
     114             : 
     115           0 :   nsCOMPtr<nsIFile> dbFile;
     116           0 :   rv = aDBDir->Clone(getter_AddRefs(dbFile));
     117           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     118             : 
     119           0 :   rv = dbFile->Append(NS_LITERAL_STRING("caches.sqlite"));
     120           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     121             : 
     122           0 :   rv = dbFile->Exists(&exists);
     123           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     124             : 
     125             :   // Use our default file:// protocol handler directly to construct the database
     126             :   // URL.  This avoids any problems if a plugin registers a custom file://
     127             :   // handler.  If such a custom handler used javascript, then we would have a
     128             :   // bad time running off the main thread here.
     129           0 :   RefPtr<nsFileProtocolHandler> handler = new nsFileProtocolHandler();
     130           0 :   rv = handler->Init();
     131           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     132             : 
     133           0 :   nsCOMPtr<nsIURI> uri;
     134           0 :   rv = handler->NewFileURI(dbFile, getter_AddRefs(uri));
     135           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     136             : 
     137           0 :   nsCOMPtr<nsIFileURL> dbFileUrl = do_QueryInterface(uri);
     138           0 :   if (NS_WARN_IF(!dbFileUrl)) { return NS_ERROR_UNEXPECTED; }
     139             : 
     140           0 :   nsAutoCString type;
     141           0 :   PersistenceTypeToText(PERSISTENCE_TYPE_DEFAULT, type);
     142             : 
     143           0 :   rv = dbFileUrl->SetQuery(
     144           0 :     NS_LITERAL_CSTRING("persistenceType=") + type +
     145           0 :     NS_LITERAL_CSTRING("&group=") + aQuotaInfo.mGroup +
     146           0 :     NS_LITERAL_CSTRING("&origin=") + aQuotaInfo.mOrigin +
     147           0 :     NS_LITERAL_CSTRING("&cache=private"));
     148           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     149             : 
     150             :   nsCOMPtr<mozIStorageService> ss =
     151           0 :     do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
     152           0 :   if (NS_WARN_IF(!ss)) { return NS_ERROR_UNEXPECTED; }
     153             : 
     154           0 :   rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
     155           0 :   if (rv == NS_ERROR_FILE_CORRUPTED) {
     156           0 :     NS_WARNING("Cache database corrupted. Recreating empty database.");
     157             : 
     158           0 :     conn = nullptr;
     159             : 
     160             :     // There is nothing else we can do to recover.  Also, this data can
     161             :     // be deleted by QuotaManager at any time anyways.
     162           0 :     rv = WipeDatabase(aQuotaInfo, dbFile, aDBDir);
     163           0 :     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     164             : 
     165           0 :     rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
     166             :   }
     167           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     168             : 
     169             :   // Check the schema to make sure it is not too old.
     170           0 :   int32_t schemaVersion = 0;
     171           0 :   rv = conn->GetSchemaVersion(&schemaVersion);
     172           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     173           0 :   if (schemaVersion > 0 && schemaVersion < db::kFirstShippedSchemaVersion) {
     174           0 :     conn = nullptr;
     175           0 :     rv = WipeDatabase(aQuotaInfo, dbFile, aDBDir);
     176           0 :     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     177             : 
     178           0 :     rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
     179           0 :     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     180             :   }
     181             : 
     182           0 :   rv = db::InitializeConnection(conn);
     183           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     184             : 
     185           0 :   conn.forget(aConnOut);
     186             : 
     187           0 :   return rv;
     188             : }
     189             : 
     190             : nsresult
     191           0 : DBAction::WipeDatabase(const QuotaInfo& aQuotaInfo, nsIFile* aDBFile,
     192             :                        nsIFile* aDBDir)
     193             : {
     194           0 :   MOZ_DIAGNOSTIC_ASSERT(aDBFile);
     195           0 :   MOZ_DIAGNOSTIC_ASSERT(aDBDir);
     196             : 
     197           0 :   nsresult rv = RemoveNsIFile(aQuotaInfo, aDBFile);
     198           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     199             : 
     200             :   // Note, the -wal journal file will be automatically deleted by sqlite when
     201             :   // the new database is created.  No need to explicitly delete it here.
     202             : 
     203             :   // Delete the morgue as well.
     204           0 :   rv = BodyDeleteDir(aQuotaInfo, aDBDir);
     205           0 :   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
     206             : 
     207           0 :   return rv;
     208             : }
     209             : 
     210           0 : SyncDBAction::SyncDBAction(Mode aMode)
     211           0 :   : DBAction(aMode)
     212             : {
     213           0 : }
     214             : 
     215           0 : SyncDBAction::~SyncDBAction()
     216             : {
     217           0 : }
     218             : 
     219             : void
     220           0 : SyncDBAction::RunWithDBOnTarget(Resolver* aResolver,
     221             :                                 const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
     222             :                                 mozIStorageConnection* aConn)
     223             : {
     224           0 :   MOZ_ASSERT(!NS_IsMainThread());
     225           0 :   MOZ_DIAGNOSTIC_ASSERT(aResolver);
     226           0 :   MOZ_DIAGNOSTIC_ASSERT(aDBDir);
     227           0 :   MOZ_DIAGNOSTIC_ASSERT(aConn);
     228             : 
     229           0 :   nsresult rv = RunSyncWithDBOnTarget(aQuotaInfo, aDBDir, aConn);
     230           0 :   aResolver->Resolve(rv);
     231           0 : }
     232             : 
     233             : } // namespace cache
     234             : } // namespace dom
     235             : } // namespace mozilla

Generated by: LCOV version 1.13