dom/indexedDB/IDBTransaction.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=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/. */
     7 #ifndef mozilla_dom_indexeddb_idbtransaction_h__
     8 #define mozilla_dom_indexeddb_idbtransaction_h__
    10 #include "mozilla/Attributes.h"
    11 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
    13 #include "mozIStorageConnection.h"
    14 #include "mozIStorageStatement.h"
    15 #include "mozIStorageFunction.h"
    16 #include "mozilla/dom/DOMError.h"
    17 #include "nsIRunnable.h"
    19 #include "nsAutoPtr.h"
    20 #include "nsClassHashtable.h"
    21 #include "nsHashKeys.h"
    22 #include "nsInterfaceHashtable.h"
    23 #include "nsRefPtrHashtable.h"
    25 #include "mozilla/dom/IDBTransactionBinding.h"
    26 #include "mozilla/dom/indexedDB/IDBDatabase.h"
    27 #include "mozilla/dom/indexedDB/IDBWrapperCache.h"
    28 #include "mozilla/dom/indexedDB/FileInfo.h"
    30 class nsIThread;
    31 class nsPIDOMWindow;
    33 namespace mozilla {
    34 class EventChainPreVisitor;
    35 } // namespace mozilla
    37 BEGIN_INDEXEDDB_NAMESPACE
    39 class AsyncConnectionHelper;
    40 class CommitHelper;
    41 class IDBRequest;
    42 class IndexedDBDatabaseChild;
    43 class IndexedDBTransactionChild;
    44 class IndexedDBTransactionParent;
    45 struct ObjectStoreInfo;
    46 class TransactionThreadPool;
    47 class UpdateRefcountFunction;
    49 class IDBTransactionListener
    50 {
    51 public:
    52   NS_IMETHOD_(MozExternalRefCountType) AddRef() = 0;
    53   NS_IMETHOD_(MozExternalRefCountType) Release() = 0;
    55   // Called just before dispatching the final events on the transaction.
    56   virtual nsresult NotifyTransactionPreComplete(IDBTransaction* aTransaction) = 0;
    57   // Called just after dispatching the final events on the transaction.
    58   virtual nsresult NotifyTransactionPostComplete(IDBTransaction* aTransaction) = 0;
    59 };
    61 class IDBTransaction : public IDBWrapperCache,
    62                        public nsIRunnable
    63 {
    64   friend class AsyncConnectionHelper;
    65   friend class CommitHelper;
    66   friend class IndexedDBDatabaseChild;
    67   friend class ThreadObserver;
    68   friend class TransactionThreadPool;
    70 public:
    71   NS_DECL_ISUPPORTS_INHERITED
    72   NS_DECL_NSIRUNNABLE
    74   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
    76   enum Mode
    77   {
    78     READ_ONLY = 0,
    79     READ_WRITE,
    80     VERSION_CHANGE,
    82     // Only needed for IPC serialization helper, should never be used in code.
    83     MODE_INVALID
    84   };
    86   enum ReadyState
    87   {
    88     INITIAL = 0,
    89     LOADING,
    90     COMMITTING,
    91     DONE
    92   };
    94   static already_AddRefed<IDBTransaction>
    95   Create(IDBDatabase* aDatabase,
    96          const Sequence<nsString>& aObjectStoreNames,
    97          Mode aMode,
    98          bool aDispatchDelayed)
    99   {
   100     return CreateInternal(aDatabase, aObjectStoreNames, aMode, aDispatchDelayed,
   101                           false);
   102   }
   104   // nsIDOMEventTarget
   105   virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   107   void OnNewRequest();
   108   void OnRequestFinished();
   109   void OnRequestDisconnected();
   111   void RemoveObjectStore(const nsAString& aName);
   113   void SetTransactionListener(IDBTransactionListener* aListener);
   115   bool StartSavepoint();
   116   nsresult ReleaseSavepoint();
   117   void RollbackSavepoint();
   119   // Only meant to be called on mStorageThread!
   120   nsresult GetOrCreateConnection(mozIStorageConnection** aConnection);
   122   already_AddRefed<mozIStorageStatement>
   123   GetCachedStatement(const nsACString& aQuery);
   125   template<int N>
   126   already_AddRefed<mozIStorageStatement>
   127   GetCachedStatement(const char (&aQuery)[N])
   128   {
   129     return GetCachedStatement(NS_LITERAL_CSTRING(aQuery));
   130   }
   132   bool IsOpen() const;
   134   bool IsFinished() const
   135   {
   136     return mReadyState > LOADING;
   137   }
   139   bool IsWriteAllowed() const
   140   {
   141     return mMode == READ_WRITE || mMode == VERSION_CHANGE;
   142   }
   144   bool IsAborted() const
   145   {
   146     return NS_FAILED(mAbortCode);
   147   }
   149   // 'Get' prefix is to avoid name collisions with the enum
   150   Mode GetMode()
   151   {
   152     return mMode;
   153   }
   155   IDBDatabase* Database()
   156   {
   157     NS_ASSERTION(mDatabase, "This should never be null!");
   158     return mDatabase;
   159   }
   161   DatabaseInfo* DBInfo() const
   162   {
   163     return mDatabaseInfo;
   164   }
   166   already_AddRefed<IDBObjectStore>
   167   GetOrCreateObjectStore(const nsAString& aName,
   168                          ObjectStoreInfo* aObjectStoreInfo,
   169                          bool aCreating);
   171   already_AddRefed<FileInfo> GetFileInfo(nsIDOMBlob* aBlob);
   172   void AddFileInfo(nsIDOMBlob* aBlob, FileInfo* aFileInfo);
   174   void ClearCreatedFileInfos();
   176   void
   177   SetActor(IndexedDBTransactionChild* aActorChild)
   178   {
   179     NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
   180     mActorChild = aActorChild;
   181   }
   183   void
   184   SetActor(IndexedDBTransactionParent* aActorParent)
   185   {
   186     NS_ASSERTION(!aActorParent || !mActorParent,
   187                  "Shouldn't have more than one!");
   188     mActorParent = aActorParent;
   189   }
   191   IndexedDBTransactionChild*
   192   GetActorChild() const
   193   {
   194     return mActorChild;
   195   }
   197   IndexedDBTransactionParent*
   198   GetActorParent() const
   199   {
   200     return mActorParent;
   201   }
   203   nsresult
   204   Abort(IDBRequest* aRequest);
   206   nsresult
   207   Abort(nsresult aAbortCode);
   209   nsresult
   210   GetAbortCode() const
   211   {
   212     return mAbortCode;
   213   }
   215 #ifdef MOZ_ENABLE_PROFILER_SPS
   216   uint64_t
   217   GetSerialNumber() const
   218   {
   219     return mSerialNumber;
   220   }
   221 #endif
   223   // nsWrapperCache
   224   virtual JSObject*
   225   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   227   // WebIDL
   228   nsPIDOMWindow*
   229   GetParentObject() const
   230   {
   231     return GetOwner();
   232   }
   234   IDBTransactionMode
   235   GetMode(ErrorResult& aRv) const;
   237   IDBDatabase*
   238   Db() const
   239   {
   240     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   241     return mDatabase;
   242   }
   244   DOMError*
   245   GetError(ErrorResult& aRv);
   247   already_AddRefed<IDBObjectStore>
   248   ObjectStore(const nsAString& aName, ErrorResult& aRv);
   250   void
   251   Abort(ErrorResult& aRv)
   252   {
   253     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   254     aRv = AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
   255   }
   257   IMPL_EVENT_HANDLER(abort)
   258   IMPL_EVENT_HANDLER(complete)
   259   IMPL_EVENT_HANDLER(error)
   261   already_AddRefed<DOMStringList>
   262   GetObjectStoreNames(ErrorResult& aRv);
   264 private:
   265   nsresult
   266   AbortInternal(nsresult aAbortCode,
   267                 already_AddRefed<mozilla::dom::DOMError> aError);
   269   // Should only be called directly through IndexedDBDatabaseChild.
   270   static already_AddRefed<IDBTransaction>
   271   CreateInternal(IDBDatabase* aDatabase,
   272                  const Sequence<nsString>& aObjectStoreNames,
   273                  Mode aMode,
   274                  bool aDispatchDelayed,
   275                  bool aIsVersionChangeTransactionChild);
   277   IDBTransaction(IDBDatabase* aDatabase);
   278   ~IDBTransaction();
   280   nsresult CommitOrRollback();
   282   nsRefPtr<IDBDatabase> mDatabase;
   283   nsRefPtr<DatabaseInfo> mDatabaseInfo;
   284   nsRefPtr<DOMError> mError;
   285   nsTArray<nsString> mObjectStoreNames;
   286   ReadyState mReadyState;
   287   Mode mMode;
   288   uint32_t mPendingRequests;
   290   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
   291     mCachedStatements;
   293   nsRefPtr<IDBTransactionListener> mListener;
   295   // Only touched on the database thread.
   296   nsCOMPtr<mozIStorageConnection> mConnection;
   298   // Only touched on the database thread.
   299   uint32_t mSavepointCount;
   301   nsTArray<nsRefPtr<IDBObjectStore> > mCreatedObjectStores;
   302   nsTArray<nsRefPtr<IDBObjectStore> > mDeletedObjectStores;
   304   nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
   305   nsRefPtrHashtable<nsISupportsHashKey, FileInfo> mCreatedFileInfos;
   307   IndexedDBTransactionChild* mActorChild;
   308   IndexedDBTransactionParent* mActorParent;
   310   nsresult mAbortCode;
   311 #ifdef MOZ_ENABLE_PROFILER_SPS
   312   uint64_t mSerialNumber;
   313 #endif
   314   bool mCreating;
   316 #ifdef DEBUG
   317   bool mFiredCompleteOrAbort;
   318 #endif
   319 };
   321 class CommitHelper MOZ_FINAL : public nsIRunnable
   322 {
   323 public:
   324   NS_DECL_THREADSAFE_ISUPPORTS
   325   NS_DECL_NSIRUNNABLE
   327   CommitHelper(IDBTransaction* aTransaction,
   328                IDBTransactionListener* aListener,
   329                const nsTArray<nsRefPtr<IDBObjectStore> >& mUpdatedObjectStores);
   330   CommitHelper(IDBTransaction* aTransaction,
   331                nsresult aAbortCode);
   332   ~CommitHelper();
   334   template<class T>
   335   bool AddDoomedObject(nsCOMPtr<T>& aCOMPtr)
   336   {
   337     if (aCOMPtr) {
   338       if (!mDoomedObjects.AppendElement(do_QueryInterface(aCOMPtr))) {
   339         NS_ERROR("Out of memory!");
   340         return false;
   341       }
   342       aCOMPtr = nullptr;
   343     }
   344     return true;
   345   }
   347 private:
   348   // Writes new autoincrement counts to database
   349   nsresult WriteAutoIncrementCounts();
   351   // Updates counts after a successful commit
   352   void CommitAutoIncrementCounts();
   354   // Reverts counts when a transaction is aborted
   355   void RevertAutoIncrementCounts();
   357   nsRefPtr<IDBTransaction> mTransaction;
   358   nsRefPtr<IDBTransactionListener> mListener;
   359   nsCOMPtr<mozIStorageConnection> mConnection;
   360   nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
   361   nsAutoTArray<nsCOMPtr<nsISupports>, 10> mDoomedObjects;
   362   nsAutoTArray<nsRefPtr<IDBObjectStore>, 10> mAutoIncrementObjectStores;
   364   nsresult mAbortCode;
   365 };
   367 class UpdateRefcountFunction MOZ_FINAL : public mozIStorageFunction
   368 {
   369 public:
   370   NS_DECL_THREADSAFE_ISUPPORTS
   371   NS_DECL_MOZISTORAGEFUNCTION
   373   UpdateRefcountFunction(FileManager* aFileManager)
   374   : mFileManager(aFileManager), mInSavepoint(false)
   375   { }
   377   ~UpdateRefcountFunction()
   378   { }
   380   void StartSavepoint()
   381   {
   382     MOZ_ASSERT(!mInSavepoint);
   383     MOZ_ASSERT(!mSavepointEntriesIndex.Count());
   385     mInSavepoint = true;
   386   }
   388   void ReleaseSavepoint()
   389   {
   390     MOZ_ASSERT(mInSavepoint);
   392     mSavepointEntriesIndex.Clear();
   394     mInSavepoint = false;
   395   }
   397   void RollbackSavepoint()
   398   {
   399     MOZ_ASSERT(mInSavepoint);
   401     mInSavepoint = false;
   403     mSavepointEntriesIndex.EnumerateRead(RollbackSavepointCallback, nullptr);
   405     mSavepointEntriesIndex.Clear();
   406   }
   408   void ClearFileInfoEntries()
   409   {
   410     mFileInfoEntries.Clear();
   411   }
   413   nsresult WillCommit(mozIStorageConnection* aConnection);
   414   void DidCommit();
   415   void DidAbort();
   417 private:
   418   class FileInfoEntry
   419   {
   420   public:
   421     FileInfoEntry(FileInfo* aFileInfo)
   422     : mFileInfo(aFileInfo), mDelta(0), mSavepointDelta(0)
   423     { }
   425     ~FileInfoEntry()
   426     { }
   428     nsRefPtr<FileInfo> mFileInfo;
   429     int32_t mDelta;
   430     int32_t mSavepointDelta;
   431   };
   433   enum UpdateType {
   434     eIncrement,
   435     eDecrement
   436   };
   438   class DatabaseUpdateFunction
   439   {
   440   public:
   441     DatabaseUpdateFunction(mozIStorageConnection* aConnection,
   442                            UpdateRefcountFunction* aFunction)
   443     : mConnection(aConnection), mFunction(aFunction), mErrorCode(NS_OK)
   444     { }
   446     bool Update(int64_t aId, int32_t aDelta);
   447     nsresult ErrorCode()
   448     {
   449       return mErrorCode;
   450     }
   452   private:
   453     nsresult UpdateInternal(int64_t aId, int32_t aDelta);
   455     nsCOMPtr<mozIStorageConnection> mConnection;
   456     nsCOMPtr<mozIStorageStatement> mUpdateStatement;
   457     nsCOMPtr<mozIStorageStatement> mSelectStatement;
   458     nsCOMPtr<mozIStorageStatement> mInsertStatement;
   460     UpdateRefcountFunction* mFunction;
   462     nsresult mErrorCode;
   463   };
   465   nsresult ProcessValue(mozIStorageValueArray* aValues,
   466                         int32_t aIndex,
   467                         UpdateType aUpdateType);
   469   nsresult CreateJournals();
   471   nsresult RemoveJournals(const nsTArray<int64_t>& aJournals);
   473   static PLDHashOperator
   474   DatabaseUpdateCallback(const uint64_t& aKey,
   475                          FileInfoEntry* aValue,
   476                          void* aUserArg);
   478   static PLDHashOperator
   479   FileInfoUpdateCallback(const uint64_t& aKey,
   480                          FileInfoEntry* aValue,
   481                          void* aUserArg);
   483   static PLDHashOperator
   484   RollbackSavepointCallback(const uint64_t& aKey,
   485                             FileInfoEntry* aValue,
   486                             void* aUserArg);
   488   FileManager* mFileManager;
   489   nsClassHashtable<nsUint64HashKey, FileInfoEntry> mFileInfoEntries;
   490   nsDataHashtable<nsUint64HashKey, FileInfoEntry*> mSavepointEntriesIndex;
   492   nsTArray<int64_t> mJournalsToCreateBeforeCommit;
   493   nsTArray<int64_t> mJournalsToRemoveAfterCommit;
   494   nsTArray<int64_t> mJournalsToRemoveAfterAbort;
   496   bool mInSavepoint;
   497 };
   499 END_INDEXEDDB_NAMESPACE
   501 #endif // mozilla_dom_indexeddb_idbtransaction_h__

mercurial