mirror of
https://github.com/ilyakooo0/purescript-indexedDB.git
synced 2024-09-11 06:55:48 +03:00
migrate IDBCursor interface to Class & move type definition to own module
This commit is contained in:
parent
54bcd27d7b
commit
23cf9e6410
13
src/Database/IndexedDB/Class.purs
Normal file
13
src/Database/IndexedDB/Class.purs
Normal file
@ -0,0 +1,13 @@
|
||||
-- | Opaque typeclass definitions for easy reuse of functions over
|
||||
-- | imported foreign types.
|
||||
module Database.IndexedDB.Class where
|
||||
|
||||
|
||||
-- | Cursor objects implement the IDBCursor interface.
|
||||
-- | There is only ever one IDBCursor instance representing a given cursor.
|
||||
-- | There is no limit on how many cursors can be used at the same time.
|
||||
class IDBCursor cursor
|
||||
|
||||
-- | A concrete cursor not only shares IDBCursor properties, but also some
|
||||
-- | specific attributes (see KeyCursor or CursorWithValue).
|
||||
class (IDBCursor cursor) <= IDBConcreteCursor cursor
|
@ -3,14 +3,6 @@ const toArray = function toArray(xs) {
|
||||
};
|
||||
|
||||
|
||||
exports._showCursor = function _showCursor(cursor) {
|
||||
return '(IDBCursor ' +
|
||||
'{ direction: ' + cursor.direction +
|
||||
', key: ' + cursor.key +
|
||||
', primaryKey: ' + cursor.primaryKey +
|
||||
' })';
|
||||
};
|
||||
|
||||
exports._showDatabase = function _showDatabase(db) {
|
||||
return '(IDBDatabase ' +
|
||||
'{ name: ' + db.name +
|
||||
|
@ -9,17 +9,14 @@
|
||||
|
||||
module Database.IndexedDB.Core
|
||||
( IDB
|
||||
, CursorDirection(..)
|
||||
, CursorSource(..)
|
||||
, Database
|
||||
, Index
|
||||
, KeyCursor
|
||||
, KeyRange
|
||||
, KeyPath
|
||||
, ObjectStore
|
||||
, Transaction
|
||||
, TransactionMode(..)
|
||||
, ValueCursor
|
||||
, module Database.IndexedDB.IDBKey
|
||||
) where
|
||||
|
||||
@ -35,18 +32,6 @@ import Database.IndexedDB.IDBKey
|
||||
foreign import data IDB :: Effect
|
||||
|
||||
|
||||
-- | A cursor has a direction that determines whether it moves in monotonically
|
||||
-- | increasing or decreasing order of the record keys when iterated, and if it
|
||||
-- | skips duplicated values when iterating indexes.
|
||||
-- | The direction of a cursor also determines if the cursor initial position is at
|
||||
-- | the start of its source or at its end.
|
||||
data CursorDirection
|
||||
= Next
|
||||
| NextUnique
|
||||
| Prev
|
||||
| PrevUnique
|
||||
|
||||
|
||||
-- | If the source of a cursor is an object store, the effective object store of
|
||||
-- | the cursor is that object store and the effective key of the cursor is the
|
||||
-- | cursor’s position. If the source of a cursor is an index, the effective object
|
||||
@ -86,11 +71,6 @@ foreign import data Database :: Type
|
||||
foreign import data Index :: Type
|
||||
|
||||
|
||||
-- | A cursor is used to iterate over a range of records in an index or an object store
|
||||
-- | in a specific direction. A KeyCursor doesn't hold any value.
|
||||
foreign import data KeyCursor :: Type
|
||||
|
||||
|
||||
-- | A key range is a continuous interval over some data type used for keys.
|
||||
foreign import data KeyRange :: Type
|
||||
|
||||
@ -104,20 +84,6 @@ foreign import data ObjectStore :: Type
|
||||
foreign import data Transaction :: Type
|
||||
|
||||
|
||||
-- | A cursor is used to iterate over a range of records in an index or an object store
|
||||
-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
|
||||
foreign import data ValueCursor :: Type
|
||||
|
||||
|
||||
foreign import _showCursor :: forall cursor. cursor -> String
|
||||
instance showKeyCursor :: Show KeyCursor where
|
||||
show = _showCursor
|
||||
|
||||
|
||||
instance showValueCursor :: Show ValueCursor where
|
||||
show = _showCursor
|
||||
|
||||
|
||||
foreign import _showDatabase
|
||||
:: Database
|
||||
-> String
|
||||
@ -153,15 +119,6 @@ instance showTransaction :: Show Transaction where
|
||||
show = _showTransaction
|
||||
|
||||
|
||||
instance showCursorDirection :: Show CursorDirection where
|
||||
show x =
|
||||
case x of
|
||||
Next -> "next"
|
||||
NextUnique -> "nextunique"
|
||||
Prev -> "prev"
|
||||
PrevUnique -> "prevunique"
|
||||
|
||||
|
||||
instance showTransactionMode :: Show TransactionMode where
|
||||
show x =
|
||||
case x of
|
||||
@ -170,16 +127,6 @@ instance showTransactionMode :: Show TransactionMode where
|
||||
VersionChange -> "versionchange"
|
||||
|
||||
|
||||
instance readCursorDirection :: Read CursorDirection where
|
||||
read s =
|
||||
case s of
|
||||
"next" -> Just Next
|
||||
"nextunique" -> Just NextUnique
|
||||
"prev" -> Just Prev
|
||||
"prevunique" -> Just PrevUnique
|
||||
_ -> Nothing
|
||||
|
||||
|
||||
instance readTransactionMode :: Read TransactionMode where
|
||||
read s =
|
||||
case s of
|
||||
|
@ -11,6 +11,14 @@ const successHandler = function successHandler(cb) {
|
||||
};
|
||||
|
||||
|
||||
exports._showCursor = function _showCursor(cursor) {
|
||||
return '(IDBCursor ' +
|
||||
'{ direction: ' + cursor.direction +
|
||||
', key: ' + cursor.key +
|
||||
', primaryKey: ' + cursor.primaryKey +
|
||||
' })';
|
||||
};
|
||||
|
||||
exports._advance = function _advance(cursor, count) {
|
||||
return function aff(success, error) {
|
||||
try {
|
||||
|
@ -1,126 +1,130 @@
|
||||
-- | A cursor is used to iterate over a range of records in an index or
|
||||
-- | an object store in a specific direction.
|
||||
module Database.IndexedDB.IDBCursor
|
||||
( class IDBCursor, advance, continue, continuePrimaryKey, delete, update
|
||||
-- * Cursor Manipulation
|
||||
( KeyCursor
|
||||
, ValueCursor
|
||||
, CursorDirection(..)
|
||||
, advance
|
||||
, continue
|
||||
, continuePrimaryKey
|
||||
, delete
|
||||
, update
|
||||
|
||||
-- * Concrete Cursor Manipulation
|
||||
, direction
|
||||
, key
|
||||
, primaryKey
|
||||
, source
|
||||
, direction'
|
||||
, key'
|
||||
, primaryKey'
|
||||
, source'
|
||||
, value
|
||||
) where
|
||||
|
||||
import Prelude (Unit, ($), (>>>), map)
|
||||
import Prelude (class Show, Unit, ($), (>>>), map)
|
||||
|
||||
import Control.Monad.Aff (Aff)
|
||||
import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
|
||||
import Data.Function.Uncurried as Fn
|
||||
import Data.Function.Uncurried (Fn2, Fn3)
|
||||
import Data.Maybe (Maybe)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Nullable (Nullable, toNullable)
|
||||
import Data.String.Read (read)
|
||||
import Data.String.Read (class Read, read)
|
||||
|
||||
import Database.IndexedDB.Core
|
||||
import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..), toKey, extractForeign)
|
||||
import Database.IndexedDB.Class (class IDBCursor, class IDBConcreteCursor)
|
||||
|
||||
|
||||
--------------------
|
||||
-- TYPES
|
||||
--
|
||||
|
||||
-- | A cursor is used to iterate over a range of records in an index or an object store
|
||||
-- | in a specific direction. A KeyCursor doesn't hold any value.
|
||||
foreign import data KeyCursor :: Type
|
||||
|
||||
|
||||
-- | A cursor is used to iterate over a range of records in an index or an object store
|
||||
-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
|
||||
foreign import data ValueCursor :: Type
|
||||
|
||||
|
||||
-- | A cursor has a direction that determines whether it moves in monotonically
|
||||
-- | increasing or decreasing order of the record keys when iterated, and if it
|
||||
-- | skips duplicated values when iterating indexes.
|
||||
-- | The direction of a cursor also determines if the cursor initial position is at
|
||||
-- | the start of its source or at its end.
|
||||
data CursorDirection
|
||||
= Next
|
||||
| NextUnique
|
||||
| Prev
|
||||
| PrevUnique
|
||||
|
||||
|
||||
--------------------
|
||||
-- INTERFACES
|
||||
--
|
||||
-- | Cursor objects implement the IDBCursor interface.
|
||||
-- | There is only ever one IDBCursor instance representing a given cursor.
|
||||
-- | There is no limit on how many cursors can be used at the same time.
|
||||
class IDBCursor cursor where
|
||||
-- | Advances the cursor through the next count records in range.
|
||||
advance
|
||||
:: forall e
|
||||
. cursor
|
||||
-> Int
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
|
||||
-- | Advances the cursor to the next record in range matching or after key.
|
||||
continue
|
||||
:: forall e k. (IDBKey k)
|
||||
=> cursor
|
||||
-> Maybe k
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
-- | Advances the cursor through the next count records in range.
|
||||
advance
|
||||
:: forall e cursor. (IDBCursor cursor)
|
||||
=> cursor
|
||||
-> Int
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
advance =
|
||||
Fn.runFn2 _advance
|
||||
|
||||
-- | Advances the cursor to the next record in range matching or after key and primaryKey. Throws an "InvalidAccessError" DOMException if the source is not an index.
|
||||
continuePrimaryKey
|
||||
:: forall e k. (IDBKey k)
|
||||
=> cursor
|
||||
-> k
|
||||
-> k
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
|
||||
-- | Delete the record pointed at by the cursor with a new value.
|
||||
delete
|
||||
:: forall e
|
||||
. cursor
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
-- | Advances the cursor to the next record in range matching or after key.
|
||||
continue
|
||||
:: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
|
||||
=> cursor
|
||||
-> Maybe k
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
continue c mk =
|
||||
Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
|
||||
|
||||
-- | Update the record pointed at by the cursor with a new value.
|
||||
-- |
|
||||
-- | Throws a "DataError" DOMException if the effective object store uses
|
||||
-- | in-line keys and the key would have changed.
|
||||
update
|
||||
:: forall val e
|
||||
. cursor
|
||||
-> val
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
|
||||
-- | Advances the cursor to the next record in range matching or after key and primaryKey. Throws an "InvalidAccessError" DOMException if the source is not an index.
|
||||
continuePrimaryKey
|
||||
:: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
|
||||
=> cursor
|
||||
-> k
|
||||
-> k
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
continuePrimaryKey c k1 k2 =
|
||||
Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
|
||||
|
||||
|
||||
-- | Delete the record pointed at by the cursor with a new value.
|
||||
delete
|
||||
:: forall e cursor. (IDBCursor cursor)
|
||||
=> cursor
|
||||
-> Aff (idb :: IDB | e) Unit
|
||||
delete =
|
||||
_delete
|
||||
|
||||
|
||||
-- | Update the record pointed at by the cursor with a new value.
|
||||
-- |
|
||||
-- | Throws a "DataError" DOMException if the effective object store uses
|
||||
-- | in-line keys and the key would have changed.
|
||||
update
|
||||
:: forall val e cursor. (IDBCursor cursor)
|
||||
=> cursor
|
||||
-> val
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
update c =
|
||||
toForeign >>> Fn.runFn2 _update c >>> map Key
|
||||
|
||||
|
||||
--------------------
|
||||
-- ATTRIBUTES
|
||||
--
|
||||
-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
|
||||
direction'
|
||||
:: KeyCursor
|
||||
-> CursorDirection
|
||||
direction' =
|
||||
Fn.runFn2 _direction (read >>> toNullable)
|
||||
|
||||
|
||||
-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
|
||||
-- | if the cursor is advancing or is finished.
|
||||
key'
|
||||
:: forall e
|
||||
. KeyCursor
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
key' =
|
||||
_key >>> map Key
|
||||
|
||||
|
||||
-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
|
||||
-- | if the cursor is advancing or is finished.
|
||||
primaryKey'
|
||||
:: forall e
|
||||
. KeyCursor
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
primaryKey' =
|
||||
_primaryKey >>> map Key
|
||||
|
||||
|
||||
-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
|
||||
source'
|
||||
:: KeyCursor
|
||||
-> CursorSource
|
||||
source' =
|
||||
Fn.runFn3 _source ObjectStore Index
|
||||
|
||||
|
||||
-- NOTE: Polymorphism not used here cause *we want* those methods to be distincs for
|
||||
-- the concrete types mostly for consistency with the Database.IndexedDB.IDBIndex module
|
||||
-- where the IDBIndex interfaces is shared by Index and ObjectStore, but attributes of
|
||||
-- respective concrete types aren't shared.
|
||||
|
||||
|
||||
-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
|
||||
direction
|
||||
:: ValueCursor
|
||||
:: forall cursor. (IDBConcreteCursor cursor)
|
||||
=> cursor
|
||||
-> CursorDirection
|
||||
direction =
|
||||
Fn.runFn2 _direction (read >>> toNullable)
|
||||
@ -129,8 +133,8 @@ direction =
|
||||
-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
|
||||
-- | if the cursor is advancing or is finished.
|
||||
key
|
||||
:: forall e
|
||||
. ValueCursor
|
||||
:: forall e cursor. (IDBConcreteCursor cursor)
|
||||
=> cursor
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
key =
|
||||
_key >>> map Key
|
||||
@ -139,8 +143,8 @@ key =
|
||||
-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
|
||||
-- | if the cursor is advancing or is finished.
|
||||
primaryKey
|
||||
:: forall e
|
||||
. ValueCursor
|
||||
:: forall e cursor. (IDBConcreteCursor cursor)
|
||||
=> cursor
|
||||
-> Aff (idb :: IDB | e) Key
|
||||
primaryKey =
|
||||
_primaryKey >>> map Key
|
||||
@ -148,7 +152,8 @@ primaryKey =
|
||||
|
||||
-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
|
||||
source
|
||||
:: ValueCursor
|
||||
:: forall cursor. (IDBConcreteCursor cursor)
|
||||
=> cursor
|
||||
-> CursorSource
|
||||
source =
|
||||
Fn.runFn3 _source ObjectStore Index
|
||||
@ -165,25 +170,57 @@ value =
|
||||
--------------------
|
||||
-- INSTANCES
|
||||
--
|
||||
instance keyCursorKeyCursor :: IDBCursor KeyCursor where
|
||||
advance = Fn.runFn2 _advance
|
||||
continue c mk = Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
|
||||
continuePrimaryKey c k1 k2 = Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
|
||||
delete = _delete
|
||||
update c = toForeign >>> Fn.runFn2 _update c >>> map Key
|
||||
|
||||
instance idbCursorKeyCursor :: IDBCursor KeyCursor
|
||||
|
||||
|
||||
instance valueCursorKeyCursor :: IDBCursor ValueCursor where
|
||||
advance = Fn.runFn2 _advance
|
||||
continue c mk = Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
|
||||
continuePrimaryKey c k1 k2 = Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
|
||||
delete = _delete
|
||||
update c = toForeign >>> Fn.runFn2 _update c >>> map Key
|
||||
instance idbCursorValueCursor :: IDBCursor ValueCursor
|
||||
|
||||
|
||||
instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
|
||||
|
||||
|
||||
instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
|
||||
|
||||
|
||||
instance showKeyCursor :: Show KeyCursor where
|
||||
show = _showCursor
|
||||
|
||||
|
||||
instance showValueCursor :: Show ValueCursor where
|
||||
show = _showCursor
|
||||
|
||||
|
||||
instance showCursorDirection :: Show CursorDirection where
|
||||
show x =
|
||||
case x of
|
||||
Next -> "next"
|
||||
NextUnique -> "nextunique"
|
||||
Prev -> "prev"
|
||||
PrevUnique -> "prevunique"
|
||||
|
||||
|
||||
|
||||
instance readCursorDirection :: Read CursorDirection where
|
||||
read s =
|
||||
case s of
|
||||
"next" -> Just Next
|
||||
"nextunique" -> Just NextUnique
|
||||
"prev" -> Just Prev
|
||||
"prevunique" -> Just PrevUnique
|
||||
_ -> Nothing
|
||||
|
||||
|
||||
--------------------
|
||||
-- FFI
|
||||
--
|
||||
|
||||
foreign import _showCursor
|
||||
:: forall cursor
|
||||
. cursor
|
||||
-> String
|
||||
|
||||
|
||||
foreign import _advance
|
||||
:: forall cursor e
|
||||
. Fn2 cursor Int (Aff (idb :: IDB | e) Unit)
|
||||
|
@ -13,7 +13,8 @@ import Data.Function.Uncurried (Fn2, Fn3, Fn4)
|
||||
import Data.Maybe (Maybe)
|
||||
import Data.Nullable (Nullable, toMaybe, toNullable)
|
||||
|
||||
import Database.IndexedDB.Core (IDB, CursorDirection, Index, Key, KeyCursor, KeyRange, KeyPath, ObjectStore, ValueCursor)
|
||||
import Database.IndexedDB.Core (IDB, Index, Key, KeyRange, KeyPath, ObjectStore)
|
||||
import Database.IndexedDB.IDBCursor (CursorDirection, KeyCursor, ValueCursor)
|
||||
import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user