LCOV - code coverage report
Current view: top level - dom/indexedDB - IDBKeyRange.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 215 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 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 "IDBKeyRange.h"
       8             : 
       9             : #include "Key.h"
      10             : #include "mozilla/ErrorResult.h"
      11             : #include "mozilla/dom/BindingUtils.h"
      12             : #include "mozilla/dom/IDBKeyRangeBinding.h"
      13             : #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
      14             : 
      15             : namespace mozilla {
      16             : namespace dom {
      17             : 
      18             : using namespace mozilla::dom::indexedDB;
      19             : 
      20             : namespace {
      21             : 
      22             : nsresult
      23           0 : GetKeyFromJSVal(JSContext* aCx,
      24             :                 JS::Handle<JS::Value> aVal,
      25             :                 Key& aKey)
      26             : {
      27           0 :   nsresult rv = aKey.SetFromJSVal(aCx, aVal);
      28           0 :   if (NS_FAILED(rv)) {
      29           0 :     MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
      30           0 :     return rv;
      31             :   }
      32             : 
      33           0 :   if (aKey.IsUnset()) {
      34           0 :     return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
      35             :   }
      36             : 
      37           0 :   return NS_OK;
      38             : }
      39             : 
      40             : } // namespace
      41             : 
      42           0 : IDBKeyRange::IDBKeyRange(nsISupports* aGlobal,
      43             :                          bool aLowerOpen,
      44             :                          bool aUpperOpen,
      45           0 :                          bool aIsOnly)
      46             :   : mGlobal(aGlobal)
      47           0 :   , mCachedLowerVal(JS::UndefinedValue())
      48           0 :   , mCachedUpperVal(JS::UndefinedValue())
      49             :   , mLowerOpen(aLowerOpen)
      50             :   , mUpperOpen(aUpperOpen)
      51             :   , mIsOnly(aIsOnly)
      52             :   , mHaveCachedLowerVal(false)
      53             :   , mHaveCachedUpperVal(false)
      54           0 :   , mRooted(false)
      55             : {
      56           0 :   AssertIsOnOwningThread();
      57           0 : }
      58             : 
      59           0 : IDBKeyRange::~IDBKeyRange()
      60             : {
      61           0 :   DropJSObjects();
      62           0 : }
      63             : 
      64           0 : IDBLocaleAwareKeyRange::IDBLocaleAwareKeyRange(nsISupports* aGlobal,
      65             :                                                bool aLowerOpen,
      66             :                                                bool aUpperOpen,
      67           0 :                                                bool aIsOnly)
      68           0 :   : IDBKeyRange(aGlobal, aLowerOpen, aUpperOpen, aIsOnly)
      69             : {
      70           0 :   AssertIsOnOwningThread();
      71           0 : }
      72             : 
      73           0 : IDBLocaleAwareKeyRange::~IDBLocaleAwareKeyRange()
      74             : {
      75           0 :   DropJSObjects();
      76           0 : }
      77             : 
      78             : // static
      79             : nsresult
      80           0 : IDBKeyRange::FromJSVal(JSContext* aCx,
      81             :                        JS::Handle<JS::Value> aVal,
      82             :                        IDBKeyRange** aKeyRange)
      83             : {
      84           0 :   MOZ_ASSERT_IF(!aCx, aVal.isUndefined());
      85             : 
      86           0 :   RefPtr<IDBKeyRange> keyRange;
      87             : 
      88           0 :   if (aVal.isNullOrUndefined()) {
      89             :     // undefined and null returns no IDBKeyRange.
      90           0 :     keyRange.forget(aKeyRange);
      91           0 :     return NS_OK;
      92             :   }
      93             : 
      94           0 :   JS::Rooted<JSObject*> obj(aCx, aVal.isObject() ? &aVal.toObject() : nullptr);
      95           0 :   bool isValidKey = aVal.isPrimitive();
      96           0 :   if (!isValidKey) {
      97             :     js::ESClass cls;
      98           0 :     if (!js::GetBuiltinClass(aCx, obj, &cls)) {
      99           0 :       return NS_ERROR_UNEXPECTED;
     100             :     }
     101           0 :     isValidKey = cls == js::ESClass::Array || cls == js::ESClass::Date;
     102             :   }
     103           0 :   if (isValidKey) {
     104             :     // A valid key returns an 'only' IDBKeyRange.
     105           0 :     keyRange = new IDBKeyRange(nullptr, false, false, true);
     106             : 
     107           0 :     nsresult rv = GetKeyFromJSVal(aCx, aVal, keyRange->Lower());
     108           0 :     if (NS_FAILED(rv)) {
     109           0 :       return rv;
     110             :     }
     111             :   }
     112             :   else {
     113           0 :     MOZ_ASSERT(aVal.isObject());
     114             :     // An object is not permitted unless it's another IDBKeyRange.
     115           0 :     if (NS_FAILED(UNWRAP_OBJECT(IDBKeyRange, obj, keyRange))) {
     116           0 :       return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
     117             :     }
     118             :   }
     119             : 
     120           0 :   keyRange.forget(aKeyRange);
     121           0 :   return NS_OK;
     122             : }
     123             : 
     124             : // static
     125             : already_AddRefed<IDBKeyRange>
     126           0 : IDBKeyRange::FromSerialized(const SerializedKeyRange& aKeyRange)
     127             : {
     128             :   RefPtr<IDBKeyRange> keyRange =
     129           0 :     new IDBKeyRange(nullptr, aKeyRange.lowerOpen(), aKeyRange.upperOpen(),
     130           0 :                     aKeyRange.isOnly());
     131           0 :   keyRange->Lower() = aKeyRange.lower();
     132           0 :   if (!keyRange->IsOnly()) {
     133           0 :     keyRange->Upper() = aKeyRange.upper();
     134             :   }
     135           0 :   return keyRange.forget();
     136             : }
     137             : 
     138             : void
     139           0 : IDBKeyRange::ToSerialized(SerializedKeyRange& aKeyRange) const
     140             : {
     141           0 :   aKeyRange.lowerOpen() = LowerOpen();
     142           0 :   aKeyRange.upperOpen() = UpperOpen();
     143           0 :   aKeyRange.isOnly() = IsOnly();
     144             : 
     145           0 :   aKeyRange.lower() = Lower();
     146           0 :   if (!IsOnly()) {
     147           0 :     aKeyRange.upper() = Upper();
     148             :   }
     149           0 : }
     150             : 
     151             : void
     152           0 : IDBKeyRange::GetBindingClause(const nsACString& aKeyColumnName,
     153             :                               nsACString& _retval) const
     154             : {
     155           0 :   NS_NAMED_LITERAL_CSTRING(andStr, " AND ");
     156           0 :   NS_NAMED_LITERAL_CSTRING(spacecolon, " :");
     157           0 :   NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
     158             : 
     159           0 :   if (IsOnly()) {
     160             :     // Both keys are set and they're equal.
     161           0 :     _retval = andStr + aKeyColumnName + NS_LITERAL_CSTRING(" =") +
     162           0 :               spacecolon + lowerKey;
     163           0 :     return;
     164             :   }
     165             : 
     166           0 :   nsAutoCString clause;
     167             : 
     168           0 :   if (!Lower().IsUnset()) {
     169             :     // Lower key is set.
     170           0 :     clause.Append(andStr + aKeyColumnName);
     171           0 :     clause.AppendLiteral(" >");
     172           0 :     if (!LowerOpen()) {
     173           0 :       clause.Append('=');
     174             :     }
     175           0 :     clause.Append(spacecolon + lowerKey);
     176             :   }
     177             : 
     178           0 :   if (!Upper().IsUnset()) {
     179             :     // Upper key is set.
     180           0 :     clause.Append(andStr + aKeyColumnName);
     181           0 :     clause.AppendLiteral(" <");
     182           0 :     if (!UpperOpen()) {
     183           0 :       clause.Append('=');
     184             :     }
     185           0 :     clause.Append(spacecolon + NS_LITERAL_CSTRING("upper_key"));
     186             :   }
     187             : 
     188           0 :   _retval = clause;
     189             : }
     190             : 
     191             : nsresult
     192           0 : IDBKeyRange::BindToStatement(mozIStorageStatement* aStatement) const
     193             : {
     194           0 :   MOZ_ASSERT(aStatement);
     195             : 
     196           0 :   NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
     197             : 
     198           0 :   if (IsOnly()) {
     199           0 :     return Lower().BindToStatement(aStatement, lowerKey);
     200             :   }
     201             : 
     202             :   nsresult rv;
     203             : 
     204           0 :   if (!Lower().IsUnset()) {
     205           0 :     rv = Lower().BindToStatement(aStatement, lowerKey);
     206           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     207           0 :       return rv;
     208             :     }
     209             :   }
     210             : 
     211           0 :   if (!Upper().IsUnset()) {
     212           0 :     rv = Upper().BindToStatement(aStatement, NS_LITERAL_CSTRING("upper_key"));
     213           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     214           0 :       return rv;
     215             :     }
     216             :   }
     217             : 
     218           0 :   return NS_OK;
     219             : }
     220             : 
     221             : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
     222             : 
     223           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBKeyRange)
     224           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
     225           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     226             : 
     227           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBKeyRange)
     228           0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedLowerVal)
     229           0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedUpperVal)
     230           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     231             : 
     232           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBKeyRange)
     233           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
     234           0 :   tmp->DropJSObjects();
     235           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     236             : 
     237           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBKeyRange)
     238           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     239           0 : NS_INTERFACE_MAP_END
     240             : 
     241           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBKeyRange)
     242           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBKeyRange)
     243             : 
     244           0 : NS_IMPL_ISUPPORTS_INHERITED0(IDBLocaleAwareKeyRange, IDBKeyRange)
     245             : 
     246             : void
     247           0 : IDBKeyRange::DropJSObjects()
     248             : {
     249           0 :   if (!mRooted) {
     250           0 :     return;
     251             :   }
     252           0 :   mCachedLowerVal.setUndefined();
     253           0 :   mCachedUpperVal.setUndefined();
     254           0 :   mHaveCachedLowerVal = false;
     255           0 :   mHaveCachedUpperVal = false;
     256           0 :   mRooted = false;
     257           0 :   mozilla::DropJSObjects(this);
     258             : }
     259             : 
     260             : bool
     261           0 : IDBKeyRange::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
     262             : {
     263           0 :   return IDBKeyRangeBinding::Wrap(aCx, this, aGivenProto, aReflector);
     264             : }
     265             : 
     266             : bool
     267           0 : IDBLocaleAwareKeyRange::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
     268             : {
     269           0 :   return IDBLocaleAwareKeyRangeBinding::Wrap(aCx, this, aGivenProto, aReflector);
     270             : }
     271             : 
     272             : void
     273           0 : IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
     274             :                       ErrorResult& aRv)
     275             : {
     276           0 :   AssertIsOnOwningThread();
     277             : 
     278           0 :   if (!mHaveCachedLowerVal) {
     279           0 :     if (!mRooted) {
     280           0 :       mozilla::HoldJSObjects(this);
     281           0 :       mRooted = true;
     282             :     }
     283             : 
     284           0 :     aRv = Lower().ToJSVal(aCx, mCachedLowerVal);
     285           0 :     if (aRv.Failed()) {
     286           0 :       return;
     287             :     }
     288             : 
     289           0 :     mHaveCachedLowerVal = true;
     290             :   }
     291             : 
     292           0 :   aResult.set(mCachedLowerVal);
     293             : }
     294             : 
     295             : void
     296           0 : IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
     297             :                       ErrorResult& aRv)
     298             : {
     299           0 :   AssertIsOnOwningThread();
     300             : 
     301           0 :   if (!mHaveCachedUpperVal) {
     302           0 :     if (!mRooted) {
     303           0 :       mozilla::HoldJSObjects(this);
     304           0 :       mRooted = true;
     305             :     }
     306             : 
     307           0 :     aRv = Upper().ToJSVal(aCx, mCachedUpperVal);
     308           0 :     if (aRv.Failed()) {
     309           0 :       return;
     310             :     }
     311             : 
     312           0 :     mHaveCachedUpperVal = true;
     313             :   }
     314             : 
     315           0 :   aResult.set(mCachedUpperVal);
     316             : }
     317             : 
     318             : bool
     319           0 : IDBKeyRange::Includes(JSContext* aCx,
     320             :                       JS::Handle<JS::Value> aValue,
     321             :                       ErrorResult& aRv) const
     322             : {
     323           0 :   Key key;
     324           0 :   aRv = GetKeyFromJSVal(aCx, aValue, key);
     325           0 :   if (aRv.Failed()) {
     326           0 :     return false;
     327             :   }
     328             : 
     329           0 :   MOZ_ASSERT(!(Lower().IsUnset() && Upper().IsUnset()));
     330           0 :   MOZ_ASSERT_IF(IsOnly(),
     331             :     !Lower().IsUnset() && !LowerOpen() &&
     332             :     Lower() == Upper() && LowerOpen() == UpperOpen());
     333             : 
     334           0 :   if (!Lower().IsUnset()) {
     335           0 :     switch (Key::CompareKeys(Lower(), key)) {
     336             :     case 1:
     337           0 :       return false;
     338             :     case 0:
     339             :       // Identical keys.
     340           0 :       return !LowerOpen();
     341             :     case -1:
     342           0 :       if (IsOnly()) {
     343           0 :         return false;
     344             :       }
     345           0 :       break;
     346             :     default:
     347           0 :       MOZ_CRASH();
     348             :     }
     349             :   }
     350             : 
     351           0 :   if (!Upper().IsUnset()) {
     352           0 :     switch (Key::CompareKeys(key, Upper())) {
     353             :     case 1:
     354           0 :       return false;
     355             :     case 0:
     356             :       // Identical keys.
     357           0 :       return !UpperOpen();
     358             :     case -1:
     359           0 :       break;
     360             :     }
     361             :   }
     362             : 
     363           0 :   return true;
     364             : }
     365             : 
     366             : // static
     367             : already_AddRefed<IDBKeyRange>
     368           0 : IDBKeyRange::Only(const GlobalObject& aGlobal,
     369             :                   JS::Handle<JS::Value> aValue,
     370             :                   ErrorResult& aRv)
     371             : {
     372             :   RefPtr<IDBKeyRange> keyRange =
     373           0 :     new IDBKeyRange(aGlobal.GetAsSupports(), false, false, true);
     374             : 
     375           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower());
     376           0 :   if (aRv.Failed()) {
     377           0 :     return nullptr;
     378             :   }
     379             : 
     380           0 :   return keyRange.forget();
     381             : }
     382             : 
     383             : // static
     384             : already_AddRefed<IDBKeyRange>
     385           0 : IDBKeyRange::LowerBound(const GlobalObject& aGlobal,
     386             :                         JS::Handle<JS::Value> aValue,
     387             :                         bool aOpen,
     388             :                         ErrorResult& aRv)
     389             : {
     390             :   RefPtr<IDBKeyRange> keyRange =
     391           0 :     new IDBKeyRange(aGlobal.GetAsSupports(), aOpen, true, false);
     392             : 
     393           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Lower());
     394           0 :   if (aRv.Failed()) {
     395           0 :     return nullptr;
     396             :   }
     397             : 
     398           0 :   return keyRange.forget();
     399             : }
     400             : 
     401             : // static
     402             : already_AddRefed<IDBKeyRange>
     403           0 : IDBKeyRange::UpperBound(const GlobalObject& aGlobal,
     404             :                         JS::Handle<JS::Value> aValue,
     405             :                         bool aOpen,
     406             :                         ErrorResult& aRv)
     407             : {
     408             :   RefPtr<IDBKeyRange> keyRange =
     409           0 :     new IDBKeyRange(aGlobal.GetAsSupports(), true, aOpen, false);
     410             : 
     411           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aValue, keyRange->Upper());
     412           0 :   if (aRv.Failed()) {
     413           0 :     return nullptr;
     414             :   }
     415             : 
     416           0 :   return keyRange.forget();
     417             : }
     418             : 
     419             : // static
     420             : already_AddRefed<IDBKeyRange>
     421           0 : IDBKeyRange::Bound(const GlobalObject& aGlobal,
     422             :                    JS::Handle<JS::Value> aLower,
     423             :                    JS::Handle<JS::Value> aUpper,
     424             :                    bool aLowerOpen,
     425             :                    bool aUpperOpen,
     426             :                    ErrorResult& aRv)
     427             : {
     428             :   RefPtr<IDBKeyRange> keyRange =
     429           0 :     new IDBKeyRange(aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
     430             : 
     431           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower());
     432           0 :   if (aRv.Failed()) {
     433           0 :     return nullptr;
     434             :   }
     435             : 
     436           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper());
     437           0 :   if (aRv.Failed()) {
     438           0 :     return nullptr;
     439             :   }
     440             : 
     441           0 :   if (keyRange->Lower() > keyRange->Upper() ||
     442           0 :       (keyRange->Lower() == keyRange->Upper() && (aLowerOpen || aUpperOpen))) {
     443           0 :     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     444           0 :     return nullptr;
     445             :   }
     446             : 
     447           0 :   return keyRange.forget();
     448             : }
     449             : 
     450             : // static
     451             : already_AddRefed<IDBLocaleAwareKeyRange>
     452           0 : IDBLocaleAwareKeyRange::Bound(const GlobalObject& aGlobal,
     453             :                               JS::Handle<JS::Value> aLower,
     454             :                               JS::Handle<JS::Value> aUpper,
     455             :                               bool aLowerOpen,
     456             :                               bool aUpperOpen,
     457             :                               ErrorResult& aRv)
     458             : {
     459             :   RefPtr<IDBLocaleAwareKeyRange> keyRange =
     460           0 :     new IDBLocaleAwareKeyRange(aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
     461             : 
     462           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aLower, keyRange->Lower());
     463           0 :   if (aRv.Failed()) {
     464           0 :     return nullptr;
     465             :   }
     466             : 
     467           0 :   aRv = GetKeyFromJSVal(aGlobal.Context(), aUpper, keyRange->Upper());
     468           0 :   if (aRv.Failed()) {
     469           0 :     return nullptr;
     470             :   }
     471             : 
     472           0 :   if (keyRange->Lower() == keyRange->Upper() && (aLowerOpen || aUpperOpen)) {
     473           0 :     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
     474           0 :     return nullptr;
     475             :   }
     476             : 
     477           0 :   return keyRange.forget();
     478             : }
     479             : 
     480             : } // namespace dom
     481             : } // namespace mozilla

Generated by: LCOV version 1.13