diff --git a/.eslintrc b/.eslintrc index 2208c78..b79b0b6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,6 +8,7 @@ }, "globals": { "indexedDB": true, + "IDBKeyRange": true, "PS": true }, "rules": { diff --git a/src/Database/IndexedDB/IDBKeyRange.js b/src/Database/IndexedDB/IDBKeyRange.js new file mode 100644 index 0000000..6afd85a --- /dev/null +++ b/src/Database/IndexedDB/IDBKeyRange.js @@ -0,0 +1,42 @@ +exports._bound = function _bound(lower, upper, lowerOpen, upperOpen) { + try { + return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen); + } catch (e) { + // NOTE + // An exception can only be thrown if lower >= upper. In such case, + // We fallback to the lower bound only. + return exports._only(lower); + } +}; + +exports._includes = function _includes(range, key) { + return range.includes(key); +}; + +exports._lower = function _lower(range) { + return range.lower; +}; + +exports._lowerBound = function _lowerBound(lower, open) { + return IDBKeyRange.lowerBound(lower, open); +}; + +exports._lowerOpen = function _lowerOpen(range) { + return range.lowerOpen; +}; + +exports._only = function _only(key) { + return IDBKeyRange.only(key); +}; + +exports._upper = function _upper(range) { + return range.upper; +}; + +exports._upperBound = function _upperBound(upper, open) { + return IDBKeyRange.upperBound(upper, open); +}; + +exports._upperOpen = function _upperOpen(range) { + return range.upperOpen; +}; diff --git a/src/Database/IndexedDB/IDBKeyRange.purs b/src/Database/IndexedDB/IDBKeyRange.purs new file mode 100644 index 0000000..f677bb5 --- /dev/null +++ b/src/Database/IndexedDB/IDBKeyRange.purs @@ -0,0 +1,109 @@ +module Database.IndexedDB.IDBKeyRange + ( class IDBKeyRange, includes + , Range(..) + , new + , lower + , upper + , lowerOpen + , upperOpen + ) where + +import Prelude + +import Data.Function.Uncurried as Fn +import Data.Function.Uncurried (Fn2, Fn4) +import Data.Foreign (Foreign) + +import Database.IndexedDB.Core (KeyRange) +import Database.IndexedDB.IDBKey.Internal (Key(..), extractForeign) + + +-------------------- +-- INTERFACES +-- +class IDBKeyRange range where + includes :: range -> Key -> Boolean + + +data Range key + = Only key + | LowerBound { lower :: key, lowerOpen :: Boolean } + | UpperBound { upper :: key, upperOpen :: Boolean } + | Bound { lower :: key, upper :: key, lowerOpen :: Boolean, upperOpen :: Boolean } + + +new :: Range Key -> KeyRange +new range = + case range of + Only key -> + _only (extractForeign key) + + LowerBound { lower: key, lowerOpen: open } -> + Fn.runFn2 _lowerBound (extractForeign key) open + + UpperBound { upper: key, upperOpen: open } -> + Fn.runFn2 _upperBound (extractForeign key) open + + Bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } -> + Fn.runFn4 _bound (extractForeign key1) (extractForeign key2) open1 open2 + + +-------------------- +-- ATTRIBUTES +-- +lower :: KeyRange -> Key +lower = + _lower >>> Key + + +upper :: KeyRange -> Key +upper = + _upper >>> Key + + +lowerOpen :: KeyRange -> Boolean +lowerOpen = + _lowerOpen + + +upperOpen :: KeyRange -> Boolean +upperOpen = + _upperOpen + + +-------------------- +-- INSTANCES +-- +instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange where + includes range = + extractForeign >>> Fn.runFn2 _includes range + + +-------------------- +-- FFI +-- +foreign import _bound :: Fn4 Foreign Foreign Boolean Boolean KeyRange + + +foreign import _includes :: forall range. Fn2 range Foreign Boolean + + +foreign import _lower :: KeyRange -> Foreign + + +foreign import _lowerBound :: Fn2 Foreign Boolean KeyRange + + +foreign import _lowerOpen :: KeyRange -> Boolean + + +foreign import _only :: Foreign -> KeyRange + + +foreign import _upper :: KeyRange -> Foreign + + +foreign import _upperBound :: Fn2 Foreign Boolean KeyRange + + +foreign import _upperOpen :: KeyRange -> Boolean