git.iko.soy/purescript-indexed-DB
on master help sign in
migrate IDBCursor interface to Class & move type definition to own module
commit23cf9e6410b880245ded59dec66526091349fcc9 authorKtorZ <matthias.benkort@gmail.com> dateFri 28 Jul 2017, 00:12 (9 years ago) parent54bcd27
6 files changed+164−166
src/Database/IndexedDB/Class.purs+13 src/Database/IndexedDB/Core.js−8 src/Database/IndexedDB/Core.purs−53 src/Database/IndexedDB/IDBCursor.js+8 src/Database/IndexedDB/IDBCursor.purs+141−104 src/Database/IndexedDB/IDBIndex/Internal.purs+2−1
src/Database/IndexedDB/Class.pursnew file+13
@@ -0,0 +1,13 @@
1+-- | Opaque typeclass definitions for easy reuse of functions over
2+-- | imported foreign types.
3+module Database.IndexedDB.Class where
4+
5+
6+-- | Cursor objects implement the IDBCursor interface.
7+-- | There is only ever one IDBCursor instance representing a given cursor.
8+-- | There is no limit on how many cursors can be used at the same time.
9+class IDBCursor cursor
10+
11+-- | A concrete cursor not only shares IDBCursor properties, but also some
12+-- | specific attributes (see KeyCursor or CursorWithValue).
13+class (IDBCursor cursor) <= IDBConcreteCursor cursor
src/Database/IndexedDB/Core.js−8
@@ -3,14 +3,6 @@ const toArray = function toArray(xs) {
33};
44
55
6−exports._showCursor = function _showCursor(cursor) {
7− return '(IDBCursor ' +
8− '{ direction: ' + cursor.direction +
9− ', key: ' + cursor.key +
10− ', primaryKey: ' + cursor.primaryKey +
11− ' })';
12−};
13−
146exports._showDatabase = function _showDatabase(db) {
157 return '(IDBDatabase ' +
168 '{ name: ' + db.name +
src/Database/IndexedDB/Core.purs−53
@@ -9,17 +9,14 @@
99
1010module Database.IndexedDB.Core
1111 ( IDB
12− , CursorDirection(..)
1312 , CursorSource(..)
1413 , Database
1514 , Index
16− , KeyCursor
1715 , KeyRange
1816 , KeyPath
1917 , ObjectStore
2018 , Transaction
2119 , TransactionMode(..)
22− , ValueCursor
2320 , module Database.IndexedDB.IDBKey
2421 ) where
2522
@@ -35,18 +32,6 @@ import Database.IndexedDB.IDBKey
3532foreign import data IDB :: Effect
3633
3734
38−-- | A cursor has a direction that determines whether it moves in monotonically
39−-- | increasing or decreasing order of the record keys when iterated, and if it
40−-- | skips duplicated values when iterating indexes.
41−-- | The direction of a cursor also determines if the cursor initial position is at
42−-- | the start of its source or at its end.
43−data CursorDirection
44− = Next
45− | NextUnique
46− | Prev
47− | PrevUnique
48−
49−
5035-- | If the source of a cursor is an object store, the effective object store of
5136-- | the cursor is that object store and the effective key of the cursor is the
5237-- | cursor’s position. If the source of a cursor is an index, the effective object
@@ -86,11 +71,6 @@ foreign import data Database :: Type
8671foreign import data Index :: Type
8772
8873
89−-- | A cursor is used to iterate over a range of records in an index or an object store
90−-- | in a specific direction. A KeyCursor doesn't hold any value.
91−foreign import data KeyCursor :: Type
92−
93−
9474-- | A key range is a continuous interval over some data type used for keys.
9575foreign import data KeyRange :: Type
9676
@@ -104,20 +84,6 @@ foreign import data ObjectStore :: Type
10484foreign import data Transaction :: Type
10585
10686
107−-- | A cursor is used to iterate over a range of records in an index or an object store
108−-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
109−foreign import data ValueCursor :: Type
110−
111−
112−foreign import _showCursor :: forall cursor. cursor -> String
113−instance showKeyCursor :: Show KeyCursor where
114− show = _showCursor
115−
116−
117−instance showValueCursor :: Show ValueCursor where
118− show = _showCursor
119−
120−
12187foreign import _showDatabase
12288 :: Database
12389 -> String
@@ -153,15 +119,6 @@ instance showTransaction :: Show Transaction where
153119 show = _showTransaction
154120
155121
156−instance showCursorDirection :: Show CursorDirection where
157− show x =
158− case x of
159− Next -> "next"
160− NextUnique -> "nextunique"
161− Prev -> "prev"
162− PrevUnique -> "prevunique"
163−
164−
165122instance showTransactionMode :: Show TransactionMode where
166123 show x =
167124 case x of
@@ -170,16 +127,6 @@ instance showTransactionMode :: Show TransactionMode where
170127 VersionChange -> "versionchange"
171128
172129
173−instance readCursorDirection :: Read CursorDirection where
174− read s =
175− case s of
176− "next" -> Just Next
177− "nextunique" -> Just NextUnique
178− "prev" -> Just Prev
179− "prevunique" -> Just PrevUnique
180− _ -> Nothing
181−
182−
183130instance readTransactionMode :: Read TransactionMode where
184131 read s =
185132 case s of
src/Database/IndexedDB/IDBCursor.js+8
@@ -11,6 +11,14 @@ const successHandler = function successHandler(cb) {
1111};
1212
1313
14+exports._showCursor = function _showCursor(cursor) {
15+ return '(IDBCursor ' +
16+ '{ direction: ' + cursor.direction +
17+ ', key: ' + cursor.key +
18+ ', primaryKey: ' + cursor.primaryKey +
19+ ' })';
20+};
21+
1422exports._advance = function _advance(cursor, count) {
1523 return function aff(success, error) {
1624 try {
src/Database/IndexedDB/IDBCursor.purs+141−104
@@ -1,126 +1,130 @@
11-- | A cursor is used to iterate over a range of records in an index or
22-- | an object store in a specific direction.
33module Database.IndexedDB.IDBCursor
4− ( class IDBCursor, advance, continue, continuePrimaryKey, delete, update
4+ -- * Cursor Manipulation
5+ ( KeyCursor
6+ , ValueCursor
7+ , CursorDirection(..)
8+ , advance
9+ , continue
10+ , continuePrimaryKey
11+ , delete
12+ , update
13+
14+ -- * Concrete Cursor Manipulation
515 , direction
616 , key
717 , primaryKey
818 , source
9− , direction'
10− , key'
11− , primaryKey'
12− , source'
1319 , value
1420 ) where
1521
16−import Prelude (Unit, ($), (>>>), map)
22+import Prelude (class Show, Unit, ($), (>>>), map)
1723
1824import Control.Monad.Aff (Aff)
1925import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
2026import Data.Function.Uncurried as Fn
2127import Data.Function.Uncurried (Fn2, Fn3)
22−import Data.Maybe (Maybe)
28+import Data.Maybe (Maybe(..))
2329import Data.Nullable (Nullable, toNullable)
24−import Data.String.Read (read)
30+import Data.String.Read (class Read, read)
2531
2632import Database.IndexedDB.Core
2733import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..), toKey, extractForeign)
34+import Database.IndexedDB.Class (class IDBCursor, class IDBConcreteCursor)
2835
2936
3037--------------------
31−-- INTERFACES
38+-- TYPES
3239--
33−-- | Cursor objects implement the IDBCursor interface.
34−-- | There is only ever one IDBCursor instance representing a given cursor.
35−-- | There is no limit on how many cursors can be used at the same time.
36−class IDBCursor cursor where
37− -- | Advances the cursor through the next count records in range.
38− advance
39− :: forall e
40− . cursor
41− -> Int
42− -> Aff (idb :: IDB | e) Unit
43−
44− -- | Advances the cursor to the next record in range matching or after key.
45− continue
46− :: forall e k. (IDBKey k)
47− => cursor
48− -> Maybe k
49− -> Aff (idb :: IDB | e) Unit
50−
51− -- | 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.
52− continuePrimaryKey
53− :: forall e k. (IDBKey k)
54− => cursor
55− -> k
56− -> k
57− -> Aff (idb :: IDB | e) Unit
58−
59− -- | Delete the record pointed at by the cursor with a new value.
60− delete
61− :: forall e
62− . cursor
63− -> Aff (idb :: IDB | e) Unit
64−
65− -- | Update the record pointed at by the cursor with a new value.
66− -- |
67− -- | Throws a "DataError" DOMException if the effective object store uses
68− -- | in-line keys and the key would have changed.
69− update
70− :: forall val e
71− . cursor
72− -> val
73− -> Aff (idb :: IDB | e) Key
7440
41+-- | A cursor is used to iterate over a range of records in an index or an object store
42+-- | in a specific direction. A KeyCursor doesn't hold any value.
43+foreign import data KeyCursor :: Type
7544
76−--------------------
77−-- ATTRIBUTES
78−--
79−-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
80−direction'
81− :: KeyCursor
82− -> CursorDirection
83−direction' =
84− Fn.runFn2 _direction (read >>> toNullable)
8545
46+-- | A cursor is used to iterate over a range of records in an index or an object store
47+-- | in a specific direction. A ValueCursor also holds the value corresponding to matching key.
48+foreign import data ValueCursor :: Type
8649
87−-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
88−-- | if the cursor is advancing or is finished.
89−key'
90− :: forall e
91− . KeyCursor
92− -> Aff (idb :: IDB | e) Key
93−key' =
94− _key >>> map Key
9550
51+-- | A cursor has a direction that determines whether it moves in monotonically
52+-- | increasing or decreasing order of the record keys when iterated, and if it
53+-- | skips duplicated values when iterating indexes.
54+-- | The direction of a cursor also determines if the cursor initial position is at
55+-- | the start of its source or at its end.
56+data CursorDirection
57+ = Next
58+ | NextUnique
59+ | Prev
60+ | PrevUnique
9661
97−-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
98−-- | if the cursor is advancing or is finished.
99−primaryKey'
100− :: forall e
101− . KeyCursor
102− -> Aff (idb :: IDB | e) Key
103−primaryKey' =
104− _primaryKey >>> map Key
10562
63+--------------------
64+-- INTERFACES
65+--
10666
107−-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
108−source'
109− :: KeyCursor
110− -> CursorSource
111−source' =
112− Fn.runFn3 _source ObjectStore Index
113−
67+-- | Advances the cursor through the next count records in range.
68+advance
69+ :: forall e cursor. (IDBCursor cursor)
70+ => cursor
71+ -> Int
72+ -> Aff (idb :: IDB | e) Unit
73+advance =
74+ Fn.runFn2 _advance
75+
76+
77+-- | Advances the cursor to the next record in range matching or after key.
78+continue
79+ :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
80+ => cursor
81+ -> Maybe k
82+ -> Aff (idb :: IDB | e) Unit
83+continue c mk =
84+ Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
85+
86+
87+-- | 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.
88+continuePrimaryKey
89+ :: forall e k cursor. (IDBKey k) => (IDBCursor cursor)
90+ => cursor
91+ -> k
92+ -> k
93+ -> Aff (idb :: IDB | e) Unit
94+continuePrimaryKey c k1 k2 =
95+ Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
96+
97+
98+-- | Delete the record pointed at by the cursor with a new value.
99+delete
100+ :: forall e cursor. (IDBCursor cursor)
101+ => cursor
102+ -> Aff (idb :: IDB | e) Unit
103+delete =
104+ _delete
105+
106+
107+-- | Update the record pointed at by the cursor with a new value.
108+-- |
109+-- | Throws a "DataError" DOMException if the effective object store uses
110+-- | in-line keys and the key would have changed.
111+update
112+ :: forall val e cursor. (IDBCursor cursor)
113+ => cursor
114+ -> val
115+ -> Aff (idb :: IDB | e) Key
116+update c =
117+ toForeign >>> Fn.runFn2 _update c >>> map Key
114118
115−-- NOTE: Polymorphism not used here cause *we want* those methods to be distincs for
116−-- the concrete types mostly for consistency with the Database.IndexedDB.IDBIndex module
117−-- where the IDBIndex interfaces is shared by Index and ObjectStore, but attributes of
118−-- respective concrete types aren't shared.
119119
120+--------------------
121+-- ATTRIBUTES
122+--
120123
121124-- | Returns the direction (Next|NextUnique|Prev|PrevUnique) of the cursor.
122125direction
123− :: ValueCursor
126+ :: forall cursor. (IDBConcreteCursor cursor)
127+ => cursor
124128 -> CursorDirection
125129direction =
126130 Fn.runFn2 _direction (read >>> toNullable)
@@ -129,8 +133,8 @@ direction =
129133-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
130134-- | if the cursor is advancing or is finished.
131135key
132− :: forall e
133− . ValueCursor
136+ :: forall e cursor. (IDBConcreteCursor cursor)
137+ => cursor
134138 -> Aff (idb :: IDB | e) Key
135139key =
136140 _key >>> map Key
@@ -139,8 +143,8 @@ key =
139143-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
140144-- | if the cursor is advancing or is finished.
141145primaryKey
142− :: forall e
143− . ValueCursor
146+ :: forall e cursor. (IDBConcreteCursor cursor)
147+ => cursor
144148 -> Aff (idb :: IDB | e) Key
145149primaryKey =
146150 _primaryKey >>> map Key
@@ -148,7 +152,8 @@ primaryKey =
148152
149153-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
150154source
151− :: ValueCursor
155+ :: forall cursor. (IDBConcreteCursor cursor)
156+ => cursor
152157 -> CursorSource
153158source =
154159 Fn.runFn3 _source ObjectStore Index
@@ -165,25 +170,57 @@ value =
165170--------------------
166171-- INSTANCES
167172--
168−instance keyCursorKeyCursor :: IDBCursor KeyCursor where
169− advance = Fn.runFn2 _advance
170− continue c mk = Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
171− continuePrimaryKey c k1 k2 = Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
172− delete = _delete
173− update c = toForeign >>> Fn.runFn2 _update c >>> map Key
174173
174+instance idbCursorKeyCursor :: IDBCursor KeyCursor
175+
176+
177+instance idbCursorValueCursor :: IDBCursor ValueCursor
178+
179+
180+instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
181+
182+
183+instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
184+
185+
186+instance showKeyCursor :: Show KeyCursor where
187+ show = _showCursor
175188
176−instance valueCursorKeyCursor :: IDBCursor ValueCursor where
177− advance = Fn.runFn2 _advance
178− continue c mk = Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
179− continuePrimaryKey c k1 k2 = Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
180− delete = _delete
181− update c = toForeign >>> Fn.runFn2 _update c >>> map Key
189+
190+instance showValueCursor :: Show ValueCursor where
191+ show = _showCursor
192+
193+
194+instance showCursorDirection :: Show CursorDirection where
195+ show x =
196+ case x of
197+ Next -> "next"
198+ NextUnique -> "nextunique"
199+ Prev -> "prev"
200+ PrevUnique -> "prevunique"
201+
202+
203+
204+instance readCursorDirection :: Read CursorDirection where
205+ read s =
206+ case s of
207+ "next" -> Just Next
208+ "nextunique" -> Just NextUnique
209+ "prev" -> Just Prev
210+ "prevunique" -> Just PrevUnique
211+ _ -> Nothing
182212
183213
184214--------------------
185215-- FFI
186216--
217+
218+foreign import _showCursor
219+ :: forall cursor
220+ . cursor
221+ -> String
222+
223+
187224foreign import _advance
188225 :: forall cursor e
189226 . Fn2 cursor Int (Aff (idb :: IDB | e) Unit)
src/Database/IndexedDB/IDBIndex/Internal.purs+2−1
@@ -13,7 +13,8 @@ import Data.Function.Uncurried (Fn2, Fn3, Fn4)
1313import Data.Maybe (Maybe)
1414import Data.Nullable (Nullable, toMaybe, toNullable)
1515
16−import Database.IndexedDB.Core (IDB, CursorDirection, Index, Key, KeyCursor, KeyRange, KeyPath, ObjectStore, ValueCursor)
16+import Database.IndexedDB.Core (IDB, Index, Key, KeyRange, KeyPath, ObjectStore)
17+import Database.IndexedDB.IDBCursor (CursorDirection, KeyCursor, ValueCursor)
1718import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..))
1819
1920