git.iko.soy/purescript-indexed-DB
on master help sign in
review top-level API -> use of opaque classes
commit3b53339870109209e39374af524e8e09b43f9a0b authorKtorZ <matthias.benkort@gmail.com> dateFri 28 Jul 2017, 10:51 (9 years ago) parent23cf9e6
17 files changed+861−745
src/Database/IndexedDB/Class.purs−13 src/Database/IndexedDB/Core.js+8 src/Database/IndexedDB/Core.purs+206−40 src/Database/IndexedDB/IDBCursor.js−9 src/Database/IndexedDB/IDBCursor.purs+27−106 src/Database/IndexedDB/IDBDatabase.js+10−2 src/Database/IndexedDB/IDBDatabase.purs+86−62 src/Database/IndexedDB/IDBFactory.purs+16−2 src/Database/IndexedDB/IDBIndex/Internal.js → src/Database/IndexedDB/IDBIndex.js src/Database/IndexedDB/IDBIndex.purs+214−7 src/Database/IndexedDB/IDBIndex/Internal.purs−257 src/Database/IndexedDB/IDBKey.purs+8−1 src/Database/IndexedDB/IDBKey/Internal.purs+25−25 src/Database/IndexedDB/IDBKeyRange.purs+66−48 src/Database/IndexedDB/IDBObjectStore.js−1 src/Database/IndexedDB/IDBObjectStore.purs+157−136 src/Database/IndexedDB/IDBTransaction.purs+38−36
src/Database/IndexedDB/Class.pursdeleted−13
@@ -1,13 +0,0 @@
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,6 +3,14 @@ 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+
614exports._showDatabase = function _showDatabase(db) {
715 return '(IDBDatabase ' +
816 '{ name: ' + db.name +
src/Database/IndexedDB/Core.purs+206−40
@@ -8,15 +8,32 @@
88-- | by the API.
99
1010module Database.IndexedDB.Core
11+ -- * Effects
1112 ( IDB
12− , CursorSource(..)
13+
14+ -- * Types
1315 , Database
1416 , Index
17+ , KeyCursor
1518 , KeyRange
16− , KeyPath
1719 , ObjectStore
1820 , Transaction
21+ , ValueCursor
22+ , CursorDirection(..)
23+ , CursorSource(..)
24+ , KeyPath
1925 , TransactionMode(..)
26+
27+ -- * Classes
28+ , class IDBConcreteCursor
29+ , class IDBCursor
30+ , class IDBDatabase
31+ , class IDBIndex
32+ , class IDBKeyRange
33+ , class IDBTransaction
34+ , class IDBObjectStore
35+
36+ -- * Re-Exports
2037 , module Database.IndexedDB.IDBKey
2138 ) where
2239
@@ -28,10 +45,64 @@ import Data.String.Read (class Read)
2845
2946import Database.IndexedDB.IDBKey
3047
48+
49+--------------------
50+-- Effects
51+--
52+
3153-- | IDB Effects, manifestation that something happened with the IndexedDB
3254foreign import data IDB :: Effect
3355
3456
57+--------------------
58+-- TYPES
59+--
60+
61+-- | Each origin has an associated set of databases. A database has zero or more object
62+-- | stores which hold the data stored in the database.
63+foreign import data Database :: Type
64+
65+
66+-- | An index allows looking up records in an object store using properties of the values
67+-- | in the object stores records.
68+foreign import data Index :: Type
69+
70+
71+-- | A key range is a continuous interval over some data type used for keys.
72+foreign import data KeyRange :: Type
73+
74+
75+-- | A cursor is used to iterate over a range of records in an index or an object store
76+-- | in a specific direction. A KeyCursor doesn't hold any value.
77+foreign import data KeyCursor :: Type
78+
79+
80+-- | A Transaction is used to interact with the data in a database.
81+-- | Whenever data is read or written to the database it is done by using a transaction.
82+foreign import data Transaction :: Type
83+
84+
85+-- | An object store is the primary storage mechanism for storing data in a database.
86+foreign import data ObjectStore :: Type
87+
88+
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 ValueCursor also holds the value corresponding to matching key.
91+foreign import data ValueCursor :: Type
92+
93+
94+-- | A cursor has a direction that determines whether it moves in monotonically
95+-- | increasing or decreasing order of the record keys when iterated, and if it
96+-- | skips duplicated values when iterating indexes.
97+-- | The direction of a cursor also determines if the cursor initial position is at
98+-- | the start of its source or at its end.
99+data CursorDirection
100+ = Next
101+ | NextUnique
102+ | Prev
103+ | PrevUnique
104+
105+
35106-- | If the source of a cursor is an object store, the effective object store of
36107-- | the cursor is that object store and the effective key of the cursor is the
37108-- | cursor’s position. If the source of a cursor is an index, the effective object
@@ -42,6 +113,16 @@ data CursorSource
42113 | Index Index
43114
44115
116+-- | A key path is a list of strings that defines how to extract a key from a value.
117+-- | A valid key path is one of:
118+-- |
119+-- | - An empty list.
120+-- | - An singleton identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].
121+-- | - A singleton string consisting of two or more identifiers separated by periods (U+002E FULL STOP).
122+-- | - A non-empty list containing only strings conforming to the above requirements.
123+type KeyPath = Array String
124+
125+
45126-- | A transaction has a mode that determines which types of interactions can be performed
46127-- | upon that transaction. The mode is set when the transaction is created and remains
47128-- | fixed for the life of the transaction.
@@ -51,74 +132,114 @@ data TransactionMode
51132 | VersionChange -- ^ The transaction is allowed to read, modify and delete data from existing object stores, and can also create and remove object stores and indexes.
52133
53134
135+--------------------
136+-- Classes
137+--
54138
55−-- | A key path is a list of strings that defines how to extract a key from a value.
56−-- | A valid key path is one of:
57−-- |
58−-- | - An empty list.
59−-- | - An singleton identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].
60−-- | - A singleton string consisting of two or more identifiers separated by periods (U+002E FULL STOP).
61−-- | - A non-empty list containing only strings conforming to the above requirements.
62−type KeyPath = Array String
139+-- | A concrete cursor not only shares IDBCursor properties, but also some
140+-- | specific attributes (see KeyCursor or CursorWithValue).
141+class (IDBCursor cursor) <= IDBConcreteCursor cursor
63142
64143
65−-- | Each origin has an associated set of databases. A database has zero or more object
66−-- | stores which hold the data stored in the database.
67−foreign import data Database :: Type
144+-- | Cursor objects implement the IDBCursor interface.
145+-- | There is only ever one IDBCursor instance representing a given cursor.
146+-- | There is no limit on how many cursors can be used at the same time.
147+class IDBCursor cursor
68148
69−-- | An index allows looking up records in an object store using properties of the values
70−-- | in the object stores records.
71−foreign import data Index :: Type
72149
150+-- | The IDBDatabase interface represents a connection to a database.
151+class IDBDatabase db
73152
74−-- | A key range is a continuous interval over some data type used for keys.
75−foreign import data KeyRange :: Type
76153
154+-- | The IDBIndex interface represents an index handle.
155+-- | Any of these methods throw an "TransactionInactiveError" DOMException
156+-- | if called when the transaction is not active.
157+class IDBIndex index
77158
78−-- | An object store is the primary storage mechanism for storing data in a database.
79−foreign import data ObjectStore :: Type
80159
160+-- | The IDBKeyRange interface represents a key range.
161+class IDBKeyRange range
81162
82−-- | A Transaction is used to interact with the data in a database.
83−-- | Whenever data is read or written to the database it is done by using a transaction.
84−foreign import data Transaction :: Type
85163
164+-- | The IDBtransaction interface.
165+class IDBTransaction tx
86166
87−foreign import _showDatabase
88− :: Database
89− -> String
90−instance showDatabase :: Show Database where
91− show = _showDatabase
167+
168+-- | The IDBObjectStore interface represents an object store handle.
169+class IDBObjectStore store
170+
171+
172+--------------------
173+-- INSTANCES
174+--
175+
176+instance idbCursorKeyCursor :: IDBCursor KeyCursor
177+
178+
179+instance idbCursorValueCursor :: IDBCursor ValueCursor
180+
181+
182+instance idbConcreteCursorKeyCursor :: IDBConcreteCursor KeyCursor
183+
184+
185+instance idbConcreteCursorValueCursor :: IDBConcreteCursor ValueCursor
186+
187+
188+instance idbDatabaseDatabase :: IDBDatabase Database
189+
190+
191+instance idbIndexIndex :: IDBIndex Index
192+
193+
194+instance idbIndexObjectStore :: IDBIndex ObjectStore
195+
196+
197+instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange
198+
199+
200+instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore
201+
202+
203+instance idbTransactionTransaction :: IDBTransaction Transaction
204+
205+
206+instance showKeyCursor :: Show KeyCursor where
207+ show = _showCursor
208+
209+
210+instance showValueCursor :: Show ValueCursor where
211+ show = _showCursor
92212
93213
94−foreign import _showIndex
95− :: Index
96− -> String
97214instance showIndex :: Show Index where
98215 show = _showIndex
99216
100217
101−foreign import _showKeyRange
102− :: KeyRange
103− -> String
104218instance showKeyRange :: Show KeyRange where
105219 show = _showKeyRange
106220
107221
108−foreign import _showObjectStore
109− :: ObjectStore
110− -> String
111222instance showObjectStore :: Show ObjectStore where
112223 show = _showObjectStore
113224
114225
115−foreign import _showTransaction
116− :: Transaction
117− -> String
118226instance showTransaction :: Show Transaction where
119227 show = _showTransaction
120228
121229
230+instance showDatabase :: Show Database where
231+ show = _showDatabase
232+
233+
234+instance showCursorDirection :: Show CursorDirection where
235+ show x =
236+ case x of
237+ Next -> "next"
238+ NextUnique -> "nextunique"
239+ Prev -> "prev"
240+ PrevUnique -> "prevunique"
241+
242+
122243instance showTransactionMode :: Show TransactionMode where
123244 show x =
124245 case x of
@@ -127,6 +248,16 @@ instance showTransactionMode :: Show TransactionMode where
127248 VersionChange -> "versionchange"
128249
129250
251+instance readCursorDirection :: Read CursorDirection where
252+ read s =
253+ case s of
254+ "next" -> Just Next
255+ "nextunique" -> Just NextUnique
256+ "prev" -> Just Prev
257+ "prevunique" -> Just PrevUnique
258+ _ -> Nothing
259+
260+
130261instance readTransactionMode :: Read TransactionMode where
131262 read s =
132263 case s of
@@ -134,3 +265,38 @@ instance readTransactionMode :: Read TransactionMode where
134265 "readwrite" -> Just ReadWrite
135266 "versionchange" -> Just VersionChange
136267 _ -> Nothing
268+
269+
270+--------------------
271+-- FFI
272+--
273+
274+foreign import _showCursor
275+ :: forall cursor
276+ . cursor
277+ -> String
278+
279+
280+foreign import _showDatabase
281+ :: Database
282+ -> String
283+
284+
285+foreign import _showIndex
286+ :: Index
287+ -> String
288+
289+
290+foreign import _showKeyRange
291+ :: KeyRange
292+ -> String
293+
294+
295+foreign import _showObjectStore
296+ :: ObjectStore
297+ -> String
298+
299+
300+foreign import _showTransaction
301+ :: Transaction
302+ -> String
src/Database/IndexedDB/IDBCursor.js−9
@@ -10,15 +10,6 @@ const successHandler = function successHandler(cb) {
1010 };
1111};
1212
13−
14−exports._showCursor = function _showCursor(cursor) {
15− return '(IDBCursor ' +
16− '{ direction: ' + cursor.direction +
17− ', key: ' + cursor.key +
18− ', primaryKey: ' + cursor.primaryKey +
19− ' })';
20−};
21−
2213exports._advance = function _advance(cursor, count) {
2314 return function aff(success, error) {
2415 try {
src/Database/IndexedDB/IDBCursor.purs+27−106
@@ -1,17 +1,14 @@
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− -- * Cursor Manipulation
5− ( KeyCursor
6− , ValueCursor
7− , CursorDirection(..)
8− , advance
4+ -- * Interface
5+ ( advance
96 , continue
107 , continuePrimaryKey
118 , delete
129 , update
1310
14− -- * Concrete Cursor Manipulation
11+ -- * Attributes
1512 , direction
1613 , key
1714 , primaryKey
@@ -19,45 +16,19 @@ module Database.IndexedDB.IDBCursor
1916 , value
2017 ) where
2118
22−import Prelude (class Show, Unit, ($), (>>>), map)
19+import Prelude (Unit, ($), (>>>), map)
2320
2421import Control.Monad.Aff (Aff)
2522import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
2623import Data.Function.Uncurried as Fn
2724import Data.Function.Uncurried (Fn2, Fn3)
28−import Data.Maybe (Maybe(..))
25+import Data.Maybe (Maybe)
2926import Data.Nullable (Nullable, toNullable)
30−import Data.String.Read (class Read, read)
27+import Data.String.Read (read)
3128
3229import Database.IndexedDB.Core
33−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..), toKey, extractForeign)
34−import Database.IndexedDB.Class (class IDBCursor, class IDBConcreteCursor)
35−
36−
37−--------------------
38−-- TYPES
39−--
40−
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
44−
45−
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
49−
50−
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
30+import Database.IndexedDB.IDBKey.Internal (class IDBKey, toKey)
31+import Database.IndexedDB.IDBKey.Internal as IDBKey
6132
6233
6334--------------------
@@ -81,7 +52,7 @@ continue
8152 -> Maybe k
8253 -> Aff (idb :: IDB | e) Unit
8354continue c mk =
84− Fn.runFn2 _continue c (toNullable $ map (toKey >>> extractForeign) mk)
55+ Fn.runFn2 _continue c (toNullable $ map (toKey >>> IDBKey.toForeign) mk)
8556
8657
8758-- | 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.
@@ -92,7 +63,7 @@ continuePrimaryKey
9263 -> k
9364 -> Aff (idb :: IDB | e) Unit
9465continuePrimaryKey c k1 k2 =
95− Fn.runFn3 _continuePrimaryKey c (extractForeign $ toKey k1) (extractForeign $ toKey k2)
66+ Fn.runFn3 _continuePrimaryKey c (IDBKey.toForeign $ toKey k1) (IDBKey.toForeign $ toKey k2)
9667
9768
9869-- | Delete the record pointed at by the cursor with a new value.
@@ -109,12 +80,12 @@ delete =
10980-- | Throws a "DataError" DOMException if the effective object store uses
11081-- | in-line keys and the key would have changed.
11182update
112− :: forall val e cursor. (IDBCursor cursor)
83+ :: forall val e cursor key. (IDBCursor cursor) => (IDBKey key)
11384 => cursor
11485 -> val
115− -> Aff (idb :: IDB | e) Key
86+ -> Aff (idb :: IDB | e) key
11687update c =
117− toForeign >>> Fn.runFn2 _update c >>> map Key
88+ toForeign >>> Fn.runFn2 _update c
11889
11990
12091--------------------
@@ -133,21 +104,21 @@ direction =
133104-- | Returns the key of the cursor. Throws a "InvalidStateError" DOMException
134105-- | if the cursor is advancing or is finished.
135106key
136− :: forall e cursor. (IDBConcreteCursor cursor)
107+ :: forall e cursor key. (IDBConcreteCursor cursor) => (IDBKey key)
137108 => cursor
138− -> Aff (idb :: IDB | e) Key
109+ -> Aff (idb :: IDB | e) key
139110key =
140− _key >>> map Key
111+ _key
141112
142113
143114-- | Returns the effective key of the cursor. Throws a "InvalidStateError" DOMException
144115-- | if the cursor is advancing or is finished.
145116primaryKey
146− :: forall e cursor. (IDBConcreteCursor cursor)
117+ :: forall e cursor key. (IDBConcreteCursor cursor) => (IDBKey key)
147118 => cursor
148− -> Aff (idb :: IDB | e) Key
119+ -> Aff (idb :: IDB | e) key
149120primaryKey =
150− _primaryKey >>> map Key
121+ _primaryKey
151122
152123
153124-- | Returns the IDBObjectStore or IDBIndex the cursor was opened from.
@@ -167,60 +138,10 @@ value =
167138 _value >>> unsafeFromForeign
168139
169140
170−--------------------
171−-- INSTANCES
172−--
173−
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
188−
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
212−
213−
214141--------------------
215142-- FFI
216143--
217144
218−foreign import _showCursor
219− :: forall cursor
220− . cursor
221− -> String
222−
223−
224145foreign import _advance
225146 :: forall cursor e
226147 . Fn2 cursor Int (Aff (idb :: IDB | e) Unit)
@@ -248,15 +169,15 @@ foreign import _direction
248169
249170
250171foreign import _key
251− :: forall cursor e
252− . cursor
253− -> Aff (idb :: IDB | e) Foreign
172+ :: forall cursor e key. (IDBKey key)
173+ => cursor
174+ -> Aff (idb :: IDB | e) key
254175
255176
256177foreign import _primaryKey
257− :: forall cursor e
258− . cursor
259− -> Aff (idb :: IDB | e) Foreign
178+ :: forall cursor e key. (IDBKey key)
179+ => cursor
180+ -> Aff (idb :: IDB | e) key
260181
261182
262183foreign import _source
@@ -265,8 +186,8 @@ foreign import _source
265186
266187
267188foreign import _update
268− :: forall cursor e
269− . Fn2 cursor Foreign (Aff (idb :: IDB | e) Foreign)
189+ :: forall cursor e key. (IDBKey key)
190+ => Fn2 cursor Foreign (Aff (idb :: IDB | e) key)
270191
271192
272193foreign import _value
src/Database/IndexedDB/IDBDatabase.js+10−2
@@ -1,7 +1,15 @@
1−const $Core = require('Database.IndexedDB.Core/foreign');
1+const toArray = function toArray(xs) {
2+ return Array.prototype.slice.apply(xs);
3+};
24
3−const toArray = $Core.toArray;
45
6+exports._showDatabase = function _showDatabase(db) {
7+ return '(IDBDatabase ' +
8+ '{ name: ' + db.name +
9+ ', objectStoreNames: [' + toArray(db.objectStoreNames).join(', ') + ']' +
10+ ', version: ' + db.version +
11+ ' })';
12+};
513
614exports._close = function _close(db) {
715 return function aff(success, error) {
src/Database/IndexedDB/IDBDatabase.purs+86−62
@@ -1,76 +1,116 @@
11-- | Each origin has an associated set of databases. A database has zero or more object
22-- | stores which hold the data stored in the database.
33module Database.IndexedDB.IDBDatabase
4− ( class IDBDatabase, close, createObjectStore, deleteObjectStore, transaction
5− , StoreName
4+ -- * Types
5+ ( StoreName
6+ , ObjectStoreParameters
7+ , defaultParameters
8+
9+ -- * Interface
10+ , close
11+ , createObjectStore
12+ , deleteObjectStore
13+ , transaction
14+
15+ -- * Attributes
616 , name
717 , objectStoreNames
818 , version
19+
20+ -- * Event handlers
921 , onAbort
1022 , onClose
1123 , onError
1224 , onVersionChange
1325 ) where
1426
15−import Prelude (Unit, show)
27+import Prelude (Unit, show)
1628
17−import Control.Monad.Aff (Aff)
18−import Control.Monad.Eff (Eff)
19−import Control.Monad.Eff.Exception (Error)
20−import Data.Function.Uncurried as Fn
21−import Data.Function.Uncurried (Fn2, Fn3)
29+import Control.Monad.Aff (Aff)
30+import Control.Monad.Eff (Eff)
31+import Control.Monad.Eff.Exception (Error)
32+import Data.Function.Uncurried as Fn
33+import Data.Function.Uncurried (Fn2, Fn3)
2234
2335import Database.IndexedDB.Core
24−import Database.IndexedDB.IDBObjectStore (IDBObjectStoreParameters)
2536
2637
2738--------------------
28−-- INTERFACE
39+-- TYPES
2940--
30−-- | The IDBDatabase interface represents a connection to a database.
31−class IDBDatabase db where
32− -- | Closes the connection once all running transactions have finished.
33− close
34− :: forall e
35− . db
36− -> Aff (idb :: IDB | e) Unit
3741
38− -- | Creates a new object store with the given name and options and returns a new IDBObjectStore.
39− -- |
40− -- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction
41− createObjectStore
42− :: forall e
43− . db
44− -> StoreName
45− -> IDBObjectStoreParameters
46− -> Aff (idb :: IDB | e) ObjectStore
47−
48− -- | Deletes the object store with the given name.
49− -- |
50− -- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
51− deleteObjectStore
52− :: forall e
53− . db
54− -> StoreName
55− -> Aff (idb :: IDB | e) ObjectStore
42+-- | Type alias for StoreName
43+type StoreName = String
5644
57− -- | Returns a new transaction with the given mode (ReadOnly|ReadWrite)
58− -- | and scope which in the form of an array of object store names.
59− transaction
60− :: forall e
61− . db
62− -> Array StoreName
63− -> TransactionMode
64− -> Aff (idb :: IDB | e) Transaction
6545
46+-- | Options provided when creating an object store.
47+type ObjectStoreParameters =
48+ { keyPath :: KeyPath
49+ , autoIncrement :: Boolean
50+ }
6651
67−-- | Type alias for StoreName
68−type StoreName = String
52+
53+defaultParameters :: ObjectStoreParameters
54+defaultParameters =
55+ { keyPath : []
56+ , autoIncrement : false
57+ }
58+
59+
60+--------------------
61+-- INTERFACE
62+--
63+
64+-- | Closes the connection once all running transactions have finished.
65+close
66+ :: forall e db. (IDBDatabase db)
67+ => db
68+ -> Aff (idb :: IDB | e) Unit
69+close =
70+ _close
71+
72+
73+-- | Creates a new object store with the given name and options and returns a new IDBObjectStore.
74+-- |
75+-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction
76+createObjectStore
77+ :: forall e db. (IDBDatabase db)
78+ => db
79+ -> StoreName
80+ -> ObjectStoreParameters
81+ -> Aff (idb :: IDB | e) ObjectStore
82+createObjectStore db name' opts =
83+ Fn.runFn3 _createObjectStore db name' opts
84+
85+
86+-- | Deletes the object store with the given name.
87+-- |
88+-- | Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
89+deleteObjectStore
90+ :: forall e db. (IDBDatabase db)
91+ => db
92+ -> StoreName
93+ -> Aff (idb :: IDB | e) ObjectStore
94+deleteObjectStore db name' =
95+ Fn.runFn2 _deleteObjectStore db name'
96+
97+
98+-- | Returns a new transaction with the given mode (ReadOnly|ReadWrite)
99+-- | and scope which in the form of an array of object store names.
100+transaction
101+ :: forall e db. (IDBDatabase db)
102+ => db
103+ -> Array StoreName
104+ -> TransactionMode
105+ -> Aff (idb :: IDB | e) Transaction
106+transaction db stores mode' =
107+ Fn.runFn3 _transaction db stores (show mode')
69108
70109
71110--------------------
72111-- ATTRIBUTES
73112--
113+
74114-- | Returns the name of the database.
75115name
76116 :: Database
@@ -139,26 +179,10 @@ onVersionChange db f =
139179 Fn.runFn2 _onVersionChange db f
140180
141181
142−--------------------
143−-- INSTANCES
144−--
145−instance idbDatabaseDatabase :: IDBDatabase Database where
146− close =
147− _close
148−
149− createObjectStore db name' opts =
150− Fn.runFn3 _createObjectStore db name' opts
151−
152− deleteObjectStore db name' =
153− Fn.runFn2 _deleteObjectStore db name'
154−
155− transaction db stores mode' =
156− Fn.runFn3 _transaction db stores (show mode')
157−
158−
159182--------------------
160183-- FFI
161184--
185+
162186foreign import _close
163187 :: forall db e
164188 . db
src/Database/IndexedDB/IDBFactory.purs+16−2
@@ -1,7 +1,16 @@
11-- | Database objects are accessed through methods on the IDBFactory interface.
22-- | A single object implementing this interface is present in the global scope
33-- | of environments that support Indexed DB operations.
4−module Database.IndexedDB.IDBFactory where
4+module Database.IndexedDB.IDBFactory
5+ -- * Types
6+ ( Callbacks
7+ , DatabaseName
8+ , Version
9+
10+ -- * Interface
11+ , deleteDatabase
12+ , open
13+ ) where
514
615import Prelude (Unit)
716
@@ -15,8 +24,9 @@ import Database.IndexedDB.Core
1524
1625
1726--------------------
18−-- INTERFACE
27+-- TYPES
1928--
29+
2030-- Type alias for binding listeners to an initial open action.
2131type Callbacks e =
2232 { onBlocked :: Maybe (Eff (| e) Unit)
@@ -32,6 +42,10 @@ type DatabaseName = String
3242type Version = Int
3343
3444
45+--------------------
46+-- INTERFACE
47+--
48+
3549-- | Attempts to delete the named database. If the database already exists
3650-- | and there are open connections that don’t close in response to a
3751-- | `versionchange` event, the request will be blocked until all they close.
src/Database/IndexedDB/IDBIndex/Internal.js → src/Database/IndexedDB/IDBIndex.jsrenamed

The content is the same.

src/Database/IndexedDB/IDBIndex.purs+214−7
@@ -1,16 +1,223 @@
11-- | An index allows looking up records in an object store using properties of the values
22-- | in the object stores records.
33module Database.IndexedDB.IDBIndex
4− ( module Database.IndexedDB.IDBIndex.Internal
5− ) where
4+ -- * Types
5+ ( Callbacks
6+
7+ -- * Interface
8+ , count
9+ , get
10+ , getAllKeys
11+ , getKey
12+ , openCursor
13+ , openKeyCursor
614
7−import Database.IndexedDB.IDBIndex.Internal
8− ( class IDBIndex, count, get, getAllKeys, getKey, openCursor, openKeyCursor
9− , IDBIndexParameters
15+ -- * Attributes
1016 , keyPath
1117 , multiEntry
1218 , name
1319 , objectStore
1420 , unique
15− , defaultParameters
16− )
21+ ) where
22+
23+import Prelude (Unit, map, show, (<$>), (>>>))
24+
25+import Control.Monad.Aff (Aff)
26+import Control.Monad.Eff (Eff)
27+import Control.Monad.Eff.Exception (Error)
28+import Data.Foreign (Foreign, unsafeFromForeign)
29+import Data.Function.Uncurried as Fn
30+import Data.Function.Uncurried (Fn2, Fn3, Fn4)
31+import Data.Maybe (Maybe)
32+import Data.Nullable (Nullable, toMaybe, toNullable)
33+
34+import Database.IndexedDB.Core
35+import Database.IndexedDB.IDBKey.Internal (class IDBKey, toKey)
36+
37+
38+--------------------
39+-- TYPES
40+--
41+
42+-- | Callbacks to manipulate a cursor from an Open*Cursor call
43+type Callbacks cursor e =
44+ { onSuccess :: cursor -> Eff ( | e) Unit
45+ , onError :: Error -> Eff ( | e) Unit
46+ , onComplete :: Eff ( | e) Unit
47+ }
48+
49+
50+--------------------
51+-- INTERFACES
52+--
53+
54+-- | Retrieves the number of records matching the key range in query.
55+count
56+ :: forall e index. (IDBIndex index)
57+ => index
58+ -> Maybe KeyRange
59+ -> Aff (idb :: IDB | e) Int
60+count index range =
61+ Fn.runFn2 _count index (toNullable range)
62+
63+
64+-- | Retrieves the value of the first record matching the given key range in query.
65+-- |
66+-- | NOTE
67+-- | The coercion from `a` to any type is unsafe and might throw a runtime error if incorrect.
68+get
69+ :: forall a e index. (IDBIndex index)
70+ => index
71+ -> KeyRange
72+ -> Aff (idb :: IDB | e) (Maybe a)
73+get index range =
74+ (toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get index range
75+
76+
77+-- | Retrieves the keys of records matching the given key range in query
78+-- | (up to the number given if given).
79+getAllKeys
80+ :: forall e index key. (IDBIndex index) => (IDBKey key)
81+ => index
82+ -> Maybe KeyRange
83+ -> Maybe Int
84+ -> Aff (idb :: IDB | e) (Array key)
85+getAllKeys index range n =
86+ Fn.runFn3 _getAllKeys index (toNullable range) (toNullable n)
87+
88+
89+-- | Retrieves the key of the first record matching the given key or key range in query.
90+getKey
91+ :: forall e index key. (IDBIndex index) => (IDBKey key)
92+ => index
93+ -> KeyRange
94+ -> Aff (idb :: IDB | e) (Maybe key)
95+getKey index range =
96+ toMaybe <$> Fn.runFn2 _getKey index range
97+
98+
99+-- | Opens a ValueCursor over the records matching query, ordered by direction.
100+-- | If query is `Nothing`, all records in index are matched.
101+openCursor
102+ :: forall e e' index. (IDBIndex index)
103+ => index
104+ -> Maybe KeyRange
105+ -> CursorDirection
106+ -> Callbacks ValueCursor e'
107+ -> Aff (idb :: IDB | e) Unit
108+openCursor index range dir cb =
109+ Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
110+
111+
112+-- | Opens a KeyCursor over the records matching query, ordered by direction.
113+-- | If query is `Nothing`, all records in index are matched.
114+openKeyCursor
115+ :: forall e e' index. (IDBIndex index)
116+ => index
117+ -> Maybe KeyRange
118+ -> CursorDirection
119+ -> Callbacks KeyCursor e'
120+ -> Aff (idb :: IDB | e) Unit
121+openKeyCursor index range dir cb =
122+ Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
123+
124+
125+--------------------
126+-- ATTRIBUTES
127+--
128+-- | Returns the key path of the index.
129+keyPath
130+ :: Index
131+ -> KeyPath
132+keyPath =
133+ _keyPath
134+
135+
136+-- | Returns true if the index's multiEntry flag is set.
137+multiEntry
138+ :: Index
139+ -> Boolean
140+multiEntry =
141+ _multiEntry
142+
143+
144+-- | Returns the name of the index.
145+name
146+ :: Index
147+ -> String
148+name =
149+ _name
150+
151+
152+-- | Returns the IDBObjectStore the index belongs to.
153+objectStore
154+ :: Index
155+ -> ObjectStore
156+objectStore =
157+ _objectStore
158+
159+
160+-- | Returns true if the index's unique flag is set.
161+unique
162+ :: Index
163+ -> Boolean
164+unique =
165+ _unique
166+
167+
168+--------------------
169+-- FFI
170+--
171+foreign import _keyPath
172+ :: Index
173+ -> Array String
174+
175+
176+foreign import _multiEntry
177+ :: Index
178+ -> Boolean
179+
180+
181+foreign import _name
182+ :: Index
183+ -> String
184+
185+
186+foreign import _objectStore
187+ :: Index
188+ -> ObjectStore
189+
190+
191+foreign import _unique
192+ :: Index
193+ -> Boolean
194+
195+
196+foreign import _count
197+ :: forall index e
198+ . Fn2 index (Nullable KeyRange) (Aff (idb :: IDB | e) Int)
199+
200+
201+foreign import _get
202+ :: forall index e
203+ . Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable Foreign))
204+
205+
206+foreign import _getAllKeys
207+ :: forall index e k. (IDBKey k)
208+ => Fn3 index (Nullable KeyRange) (Nullable Int) (Aff (idb :: IDB | e) (Array k))
209+
210+
211+foreign import _getKey
212+ :: forall index e k. (IDBKey k)
213+ => Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable k))
214+
215+
216+foreign import _openCursor
217+ :: forall index e e'
218+ . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor e') (Aff (idb :: IDB | e) Unit)
219+
220+
221+foreign import _openKeyCursor
222+ :: forall index e e'
223+ . Fn4 index (Nullable KeyRange) String (Callbacks KeyCursor e') (Aff (idb :: IDB | e) Unit)
src/Database/IndexedDB/IDBIndex/Internal.pursdeleted−257
@@ -1,257 +0,0 @@
1−-- | An index allows looking up records in an object store using properties of the values
2−-- | in the object stores records.
3−module Database.IndexedDB.IDBIndex.Internal where
4−
5−import Prelude
6−
7−import Control.Monad.Aff (Aff)
8−import Control.Monad.Eff (Eff)
9−import Control.Monad.Eff.Exception (Error)
10−import Data.Foreign (Foreign, unsafeFromForeign)
11−import Data.Function.Uncurried as Fn
12−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
13−import Data.Maybe (Maybe)
14−import Data.Nullable (Nullable, toMaybe, toNullable)
15−
16−import Database.IndexedDB.Core (IDB, Index, Key, KeyRange, KeyPath, ObjectStore)
17−import Database.IndexedDB.IDBCursor (CursorDirection, KeyCursor, ValueCursor)
18−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..))
19−
20−
21−--------------------
22−-- INTERFACES
23−--
24−-- | The IDBIndex interface represents an index handle.
25−-- | Any of these methods throw an "TransactionInactiveError" DOMException
26−-- | if called when the transaction is not active.
27−class IDBIndex index where
28− -- | Retrieves the number of records matching the key range in query.
29− count
30− :: forall e
31− . index
32− -> Maybe KeyRange
33− -> Aff (idb :: IDB | e) Int
34−
35− -- | Retrieves the value of the first record matching the given key range in query.
36− -- |
37− -- | NOTE
38− -- | The coercion from `a` to any type is unsafe and might throw a runtime error if incorrect.
39− get
40− :: forall a e
41− . index
42− -> KeyRange
43− -> Aff (idb :: IDB | e) (Maybe a)
44−
45− -- | Retrieves the keys of records matching the given key range in query
46− -- | (up to the number given if given).
47− getAllKeys
48− :: forall e
49− . index
50− -> Maybe KeyRange
51− -> Maybe Int
52− -> Aff (idb :: IDB | e) (Array Key)
53−
54− -- | Retrieves the key of the first record matching the given key or key range in query.
55− getKey
56− :: forall e
57− . index
58− -> KeyRange
59− -> Aff (idb :: IDB | e) (Maybe Key)
60−
61− -- | Opens a ValueCursor over the records matching query, ordered by direction.
62− -- | If query is `Nothing`, all records in index are matched.
63− openCursor
64− :: forall e e'
65− . index
66− -> Maybe KeyRange
67− -> CursorDirection
68− -> Callbacks ValueCursor e'
69− -> Aff (idb :: IDB | e) Unit
70−
71− -- | Opens a KeyCursor over the records matching query, ordered by direction.
72− -- | If query is `Nothing`, all records in index are matched.
73− openKeyCursor
74− :: forall e e'
75− . index
76− -> Maybe KeyRange
77− -> CursorDirection
78− -> Callbacks KeyCursor e'
79− -> Aff (idb :: IDB | e) Unit
80−
81−
82−-- | Flags to set on the index.
83−-- |
84−-- | An index has a `unique` flag. When this flag is set, the index enforces that no
85−-- | two records in the index has the same key. If a record in the index’s referenced
86−-- | object store is attempted to be inserted or modified such that evaluating the index’s
87−-- | key path on the records new value yields a result which already exists in the index,
88−-- | then the attempted modification to the object store fails.
89−-- |
90−-- | An index has a `multiEntry` flag. This flag affects how the index behaves when the
91−-- | result of evaluating the index’s key path yields an array key. If the `multiEntry` flag
92−-- | is unset, then a single record whose key is an array key is added to the index.
93−-- | If the `multiEntry` flag is true, then the one record is added to the index for each
94−-- | of the subkeys.
95−type IDBIndexParameters =
96− { unique :: Boolean
97− , multiEntry :: Boolean
98− }
99−
100−
101−-- | Callbacks to manipulate a cursor from an Open*Cursor call
102−type Callbacks cursor e =
103− { onSuccess :: cursor -> Eff ( | e) Unit
104− , onError :: Error -> Eff ( | e) Unit
105− , onComplete :: Eff ( | e) Unit
106− }
107−
108−
109−defaultParameters :: IDBIndexParameters
110−defaultParameters =
111− { unique : false
112− , multiEntry : false
113− }
114−
115−
116−--------------------
117−-- ATTRIBUTES
118−--
119−-- | Returns the key path of the index.
120−keyPath
121− :: Index
122− -> KeyPath
123−keyPath =
124− _keyPath
125−
126−
127−-- | Returns true if the index's multiEntry flag is set.
128−multiEntry
129− :: Index
130− -> Boolean
131−multiEntry =
132− _multiEntry
133−
134−
135−-- | Returns the name of the index.
136−name
137− :: Index
138− -> String
139−name =
140− _name
141−
142−
143−-- | Returns the IDBObjectStore the index belongs to.
144−objectStore
145− :: Index
146− -> ObjectStore
147−objectStore =
148− _objectStore
149−
150−
151−-- | Returns true if the index's unique flag is set.
152−unique
153− :: Index
154− -> Boolean
155−unique =
156− _unique
157−
158−
159−--------------------
160−-- INSTANCES
161−--
162−instance idbIndexIndex :: IDBIndex Index where
163− count index range =
164− Fn.runFn2 _count index (toNullable range)
165−
166− get index range =
167− (toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get index range
168−
169− getAllKeys index range count =
170− map Key <$> Fn.runFn3 _getAllKeys index (toNullable range) (toNullable count)
171−
172− getKey index range =
173− (toMaybe >>> map Key) <$> Fn.runFn2 _getKey index range
174−
175− openCursor index range dir cb =
176− Fn.runFn4 _openCursor index (toNullable range) (show dir) cb
177−
178− openKeyCursor index range dir cb =
179− Fn.runFn4 _openKeyCursor index (toNullable range) (show dir) cb
180−
181−
182−instance idbIndexObjectStore :: IDBIndex ObjectStore where
183− count store range =
184− Fn.runFn2 _count store (toNullable range)
185−
186− get store range =
187− (toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get store range
188−
189− getAllKeys store range count =
190− map Key <$> Fn.runFn3 _getAllKeys store (toNullable range) (toNullable count)
191−
192− getKey store range =
193− (toMaybe >>> map Key) <$> Fn.runFn2 _getKey store range
194−
195− openCursor store range dir cb =
196− Fn.runFn4 _openCursor store (toNullable range) (show dir) cb
197−
198− openKeyCursor store range dir cb =
199− Fn.runFn4 _openKeyCursor store (toNullable range) (show dir) cb
200−
201−
202−--------------------
203−-- FFI
204−--
205−foreign import _keyPath
206− :: Index
207− -> Array String
208−
209−
210−foreign import _multiEntry
211− :: Index
212− -> Boolean
213−
214−
215−foreign import _name
216− :: Index
217− -> String
218−
219−
220−foreign import _objectStore
221− :: Index
222− -> ObjectStore
223−
224−
225−foreign import _unique
226− :: Index
227− -> Boolean
228−
229−
230−foreign import _count
231− :: forall index e
232− . Fn2 index (Nullable KeyRange) (Aff (idb :: IDB | e) Int)
233−
234−
235−foreign import _get
236− :: forall index e
237− . Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable Foreign))
238−
239−
240−foreign import _getAllKeys
241− :: forall index e
242− . Fn3 index (Nullable KeyRange) (Nullable Int) (Aff (idb :: IDB | e) (Array Foreign))
243−
244−
245−foreign import _getKey
246− :: forall index e
247− . Fn2 index KeyRange (Aff (idb :: IDB | e) (Nullable Foreign))
248−
249−
250−foreign import _openCursor
251− :: forall index e e'
252− . Fn4 index (Nullable KeyRange) String (Callbacks ValueCursor e') (Aff (idb :: IDB | e) Unit)
253−
254−
255−foreign import _openKeyCursor
256− :: forall index e e'
257− . Fn4 index (Nullable KeyRange) String (Callbacks KeyCursor e') (Aff (idb :: IDB | e) Unit)
src/Database/IndexedDB/IDBKey.purs+8−1
@@ -5,4 +5,11 @@ module Database.IndexedDB.IDBKey
55 ( module Database.IndexedDB.IDBKey.Internal
66 ) where
77
8−import Database.IndexedDB.IDBKey.Internal(class IDBKey, Key, none, toKey, fromKey, unsafeFromKey)
8+import Database.IndexedDB.IDBKey.Internal
9+ ( class IDBKey
10+ , Key
11+ , none
12+ , toKey
13+ , fromKey
14+ , unsafeFromKey
15+ )
src/Database/IndexedDB/IDBKey/Internal.purs+25−25
@@ -2,41 +2,41 @@
22-- |
33-- | NOTE: Binary keys aren't supported yet.
44module Database.IndexedDB.IDBKey.Internal
5− ( Key(..)
6− , none
7− , class IDBKey, toKey , fromKey , unsafeFromKey
8− , extractForeign
9− ) where
5+ ( Key
6+ , class IDBKey, toKey , fromKey , unsafeFromKey
7+ , none
8+ , toForeign
9+ ) where
1010
1111import Prelude
1212
13−import Control.Alt ((<|>))
14−import Control.Monad.Except (ExceptT(..), runExceptT)
15−import Data.Date as Date
16−import Data.DateTime (DateTime(..), Time(..))
17−import Data.Enum (fromEnum, toEnum)
18−import Data.Foreign as Foreign
19−import Data.Foreign (Foreign, F)
20−import Data.Function.Uncurried as Fn
21−import Data.Function.Uncurried (Fn2, Fn4, Fn7)
22−import Data.List.NonEmpty (NonEmptyList(..))
23−import Data.List.Types (List(..))
24−import Data.NonEmpty (NonEmpty(..))
25−import Data.Either (Either(..), either, isRight)
26−import Data.Maybe (Maybe(..))
27−import Data.Identity (Identity(..))
28−import Data.Nullable (Nullable, toNullable)
29−import Data.Time as Time
30−import Data.Traversable (traverse)
13+import Control.Alt ((<|>))
14+import Control.Monad.Except (ExceptT(..), runExceptT)
15+import Data.Date as Date
16+import Data.DateTime (DateTime(..), Time(..))
17+import Data.Either (Either(..), either, isRight)
18+import Data.Enum (fromEnum, toEnum)
19+import Data.Foreign as Foreign
20+import Data.Foreign (Foreign, F)
21+import Data.Function.Uncurried as Fn
22+import Data.Function.Uncurried (Fn2, Fn4, Fn7)
23+import Data.Identity (Identity(..))
24+import Data.List.NonEmpty (NonEmptyList(..))
25+import Data.List.Types (List(..))
26+import Data.Maybe (Maybe(..))
27+import Data.NonEmpty (NonEmpty(..))
28+import Data.Nullable (Nullable, toNullable)
29+import Data.Time as Time
30+import Data.Traversable (traverse)
3131
3232
3333newtype Key = Key Foreign
3434
3535
36−extractForeign
36+toForeign
3737 :: Key
3838 -> Foreign
39−extractForeign (Key f) =
39+toForeign (Key f) =
4040 f
4141
4242
src/Database/IndexedDB/IDBKeyRange.purs+66−48
@@ -1,17 +1,25 @@
11-- | A key has an associated type which is one of: number, date, string, binary, or array.
22module Database.IndexedDB.IDBKeyRange
3− ( class IDBKeyRange, includes
3+ -- * Types
4+ ( Open
5+
6+ -- * Constructors
47 , only
58 , lowerBound
69 , upperBound
710 , bound
11+
12+ -- * Interface
13+ , includes
14+
15+ -- * Attributes
816 , lower
917 , upper
1018 , lowerOpen
1119 , upperOpen
1220 ) where
1321
14−import Prelude
22+import Prelude (($), (>>>))
1523
1624import Data.Foreign (Foreign)
1725import Data.Function.Uncurried as Fn
@@ -19,29 +27,29 @@ import Data.Function.Uncurried (Fn2, Fn4)
1927import Data.Maybe (Maybe)
2028import Data.Nullable (Nullable, toMaybe)
2129
22−import Database.IndexedDB.Core (KeyRange)
23−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(..), toKey, extractForeign)
30+import Database.IndexedDB.Core (class IDBKeyRange, KeyRange)
31+import Database.IndexedDB.IDBKey.Internal (class IDBKey, toKey, toForeign)
2432
2533
2634--------------------
27−-- INTERFACES
35+-- TYPES
2836--
29−-- | The IDBKeyRange interface represents a key range.
30−class IDBKeyRange range where
31− -- | Returns true if key is included in the range, and false otherwise.
32− includes :: forall k. (IDBKey k) => range -> k -> Boolean
3337
3438-- | Type alias for open
3539type Open = Boolean
3640
3741
42+--------------------
43+-- CONSTRUCTORS
44+--
45+
3846-- | Returns a new IDBKeyRange spanning only key.
3947only
4048 :: forall a. (IDBKey a)
4149 => a
4250 -> KeyRange
4351only key =
44− _only (extractForeign $ toKey key)
52+ _only (toForeign $ toKey key)
4553
4654
4755-- | Returns a new IDBKeyRange starting at key with no upper bound.
@@ -52,7 +60,7 @@ lowerBound
5260 -> Open
5361 -> KeyRange
5462lowerBound key open =
55− Fn.runFn2 _lowerBound (extractForeign $ toKey key) open
63+ Fn.runFn2 _lowerBound (toForeign $ toKey key) open
5664
5765
5866-- | Returns a new IDBKeyRange with no lower bound and ending at key.
@@ -63,7 +71,7 @@ upperBound
6371 -> Open
6472 -> KeyRange
6573upperBound key open =
66− Fn.runFn2 _upperBound (extractForeign $ toKey key) open
74+ Fn.runFn2 _upperBound (toForeign $ toKey key) open
6775
6876
6977-- | Returns a new IDBKeyRange spanning from `lower` to `upper`.
@@ -77,7 +85,21 @@ bound
7785 -> Maybe KeyRange
7886bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
7987 toMaybe
80− $ Fn.runFn4 _bound (extractForeign $ toKey key1) (extractForeign $ toKey key2) open1 open2
88+ $ Fn.runFn4 _bound (toForeign $ toKey key1) (toForeign $ toKey key2) open1 open2
89+
90+
91+--------------------
92+-- INTERFACE
93+--
94+
95+-- | Returns true if key is included in the range, and false otherwise.
96+includes
97+ :: forall k range. (IDBKey k) => (IDBKeyRange range)
98+ => range
99+ -> k
100+ -> Boolean
101+includes range =
102+ toKey >>> toForeign >>> Fn.runFn2 _includes range
81103
82104
83105--------------------
@@ -85,47 +107,54 @@ bound { lower: key1, upper: key2, lowerOpen: open1, upperOpen: open2 } =
85107--
86108-- | Returns lower bound if any.
87109lower
88− :: KeyRange
89− -> Maybe Key
110+ :: forall key. (IDBKey key)
111+ => KeyRange
112+ -> Maybe key
90113lower =
91− _lower >>> toMaybe >>> map Key
114+ _lower >>> toMaybe
92115
93116
94117-- | Returns upper bound if any.
95118upper
96− :: KeyRange
97− -> Maybe Key
119+ :: forall key. (IDBKey key)
120+ => KeyRange
121+ -> Maybe key
98122upper =
99− _upper >>> toMaybe >>> map Key
123+ _upper >>> toMaybe
100124
101125
102126-- | Returns true if the lower open flag is set, false otherwise.
103127lowerOpen
104− :: KeyRange
105− -> Boolean
128+ :: KeyRange
129+ -> Boolean
106130lowerOpen =
107131 _lowerOpen
108132
109133
110134-- | Returns true if the upper open flag is set, false otherwise.
111135upperOpen
112− :: KeyRange
113− -> Boolean
136+ :: KeyRange
137+ -> Boolean
114138upperOpen =
115139 _upperOpen
116140
117141
118142--------------------
119−-- INSTANCES
143+-- FFI
120144--
121−instance idbKeyRangeKeyRange :: IDBKeyRange KeyRange where
122− includes range =
123− toKey >>> extractForeign >>> Fn.runFn2 _includes range
145+
146+foreign import _only
147+ :: Foreign
148+ -> KeyRange
149+
150+foreign import _lowerBound
151+ :: Fn2 Foreign Boolean KeyRange
152+
153+
154+foreign import _upperBound
155+ :: Fn2 Foreign Boolean KeyRange
124156
125157
126−--------------------
127−-- FFI
128−--
129158foreign import _bound
130159 :: Fn4 Foreign Foreign Boolean Boolean (Nullable KeyRange)
131160
@@ -136,12 +165,15 @@ foreign import _includes
136165
137166
138167foreign import _lower
139− :: KeyRange
140− -> Nullable Foreign
168+ :: forall key. (IDBKey key)
169+ => KeyRange
170+ -> Nullable key
141171
142172
143−foreign import _lowerBound
144− :: Fn2 Foreign Boolean KeyRange
173+foreign import _upper
174+ :: forall key. (IDBKey key)
175+ => KeyRange
176+ -> Nullable key
145177
146178
147179foreign import _lowerOpen
@@ -149,20 +181,6 @@ foreign import _lowerOpen
149181 -> Boolean
150182
151183
152−foreign import _only
153− :: Foreign
154− -> KeyRange
155−
156−
157−foreign import _upper
158− :: KeyRange
159− -> Nullable Foreign
160−
161−
162−foreign import _upperBound
163− :: Fn2 Foreign Boolean KeyRange
164−
165−
166184foreign import _upperOpen
167185 :: KeyRange
168186 -> Boolean
src/Database/IndexedDB/IDBObjectStore.js−1
@@ -140,4 +140,3 @@ exports._put = function _put(store, value, key) {
140140exports._transaction = function _transaction(store) {
141141 return store.transaction;
142142};
143−
src/Database/IndexedDB/IDBObjectStore.purs+157−136
@@ -1,125 +1,172 @@
11-- | An object store is the primary storage mechanism for storing data in a database.
22module Database.IndexedDB.IDBObjectStore
3− ( class IDBObjectStore, add, clear, createIndex, delete, deleteIndex, index, put
4− , module Database.IndexedDB.IDBIndex.Internal
5− , IDBObjectStoreParameters
6− , IndexName
3+ -- * Types
4+ ( IndexName
5+ , IndexParameters
6+ , defaultParameters
7+
8+ -- * Interface
9+ , add
10+ , clear
11+ , createIndex
12+ , delete
13+ , deleteIndex
14+ , index
15+ , put
16+
17+ -- * Attributes
718 , autoIncrement
819 , indexNames
920 , keyPath
1021 , name
1122 , transaction
12− , defaultParameters
13− ) where
1423
15−import Prelude (Unit, ($), (<$>), (>>>))
24+ -- * Re-Exports
25+ , module Database.IndexedDB.IDBIndex
26+ ) where
1627
17−import Control.Monad.Aff (Aff)
18−import Data.Foreign (Foreign)
19−import Data.Function.Uncurried as Fn
20−import Data.Function.Uncurried (Fn2, Fn3, Fn4)
21−import Data.Maybe (Maybe)
22−import Data.Nullable (Nullable, toNullable)
28+import Prelude (Unit, ($), (<$>), (>>>))
2329
24−import Database.IndexedDB.Core (IDB, Index, KeyRange, KeyPath, ObjectStore, Transaction)
25−import Database.IndexedDB.IDBIndex.Internal (class IDBIndex, IDBIndexParameters, count, get, getAllKeys, getKey, openCursor, openKeyCursor)
26−import Database.IndexedDB.IDBKey.Internal (class IDBKey, Key(Key), extractForeign, toKey)
30+import Control.Monad.Aff (Aff)
31+import Data.Foreign (Foreign)
32+import Data.Function.Uncurried as Fn
33+import Data.Function.Uncurried (Fn2, Fn3, Fn4)
34+import Data.Maybe (Maybe)
35+import Data.Nullable (Nullable, toNullable)
2736
37+import Database.IndexedDB.Core
38+import Database.IndexedDB.IDBIndex (count, get, getAllKeys, getKey, openCursor, openKeyCursor)
39+import Database.IndexedDB.IDBKey.Internal (class IDBKey, toForeign, toKey)
2840
2941--------------------
30−-- INTERFACES
42+-- TYPES
3143--
32−-- | The IDBObjectStore interface represents an object store handle.
33−class IDBObjectStore store where
34− -- | Adds or updates a record in store with the given value and key.
35− -- |
36− -- | If the store uses in-line keys and key is specified a "DataError" DOMException
37− -- | will be thrown.
38− -- |
39− -- | If add() is used, and if a record with the key already exists the request will fail,
40− -- | with a "ConstraintError" DOMException.
41− add
42− :: forall v k e. (IDBKey k)
43− => store
44− -> v
45− -> Maybe k
46− -> Aff (idb :: IDB | e) Key
47−
48− -- | Deletes all records in store.
49− clear
50− :: forall e
51− . store
52− -> Aff (idb :: IDB | e) Unit
53−
54− -- | Creates a new index in store with the given name, keyPath and options and
55− -- | returns a new IDBIndex. If the keyPath and options define constraints that
56− -- | cannot be satisfied with the data already in store the upgrade transaction
57− -- | will abort with a "ConstraintError" DOMException.
58− -- |
59− -- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
60− createIndex
61− :: forall e
62− . store
63− -> IndexName
64− -> KeyPath
65− -> IDBIndexParameters
66− -> Aff (idb :: IDB | e) Index
67−
68− -- | Deletes records in store with the given key or in the given key range in query.
69− delete
70− :: forall e
71− . store
72− -> KeyRange
73− -> Aff (idb :: IDB | e) Unit
74−
75− -- | Deletes the index in store with the given name.
76− -- |
77− -- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
78− deleteIndex
79− :: forall e
80− . store
81− -> IndexName
82− -> Aff (idb :: IDB | e) Unit
83−
84− -- | Returns an IDBIndex for the index named name in store.
85− index
86− :: forall e
87− . store
88− -> IndexName
89− -> Aff (idb :: IDB | e) Index
90−
91− -- | Adds or updates a record in store with the given value and key.
92− -- |
93− -- | If the store uses in-line keys and key is specified a "DataError" DOMException
94− -- | will be thrown.
95− -- |
96− -- | If put() is used, any existing record with the key will be replaced.
97− put
98− :: forall v k e. (IDBKey k)
99− => store
100− -> v
101− -> Maybe k
102− -> Aff (idb :: IDB | e) Key
103−
10444
10545-- | Type alias for IndexName
10646type IndexName = String
10747
10848
109−-- | Options provided when creating an object store.
110−type IDBObjectStoreParameters =
111− { keyPath :: KeyPath
112− , autoIncrement :: Boolean
49+-- | Flags to set on the index.
50+-- |
51+-- | An index has a `unique` flag. When this flag is set, the index enforces that no
52+-- | two records in the index has the same key. If a record in the index’s referenced
53+-- | object store is attempted to be inserted or modified such that evaluating the index’s
54+-- | key path on the records new value yields a result which already exists in the index,
55+-- | then the attempted modification to the object store fails.
56+-- |
57+-- | An index has a `multiEntry` flag. This flag affects how the index behaves when the
58+-- | result of evaluating the index’s key path yields an array key. If the `multiEntry` flag
59+-- | is unset, then a single record whose key is an array key is added to the index.
60+-- | If the `multiEntry` flag is true, then the one record is added to the index for each
61+-- | of the subkeys.
62+type IndexParameters =
63+ { unique :: Boolean
64+ , multiEntry :: Boolean
11365 }
11466
11567
116−defaultParameters :: IDBObjectStoreParameters
68+defaultParameters :: IndexParameters
11769defaultParameters =
118− { keyPath : []
119− , autoIncrement : false
70+ { unique : false
71+ , multiEntry : false
12072 }
12173
12274
75+--------------------
76+-- INTERFACES
77+--
78+
79+-- | Adds or updates a record in store with the given value and key.
80+-- |
81+-- | If the store uses in-line keys and key is specified a "DataError" DOMException
82+-- | will be thrown.
83+-- |
84+-- | If add() is used, and if a record with the key already exists the request will fail,
85+-- | with a "ConstraintError" DOMException.
86+add
87+ :: forall e key val store. (IDBKey key) => (IDBObjectStore store)
88+ => store
89+ -> val
90+ -> Maybe key
91+ -> Aff (idb :: IDB | e) key
92+add store value key =
93+ Fn.runFn3 _add store value (toNullable $ (toKey >>> toForeign) <$> key)
94+
95+
96+-- | Deletes all records in store.
97+clear
98+ :: forall e store. (IDBObjectStore store)
99+ => store
100+ -> Aff (idb :: IDB | e) Unit
101+clear =
102+ _clear
103+
104+
105+-- | Creates a new index in store with the given name, keyPath and options and
106+-- | returns a new IDBIndex. If the keyPath and options define constraints that
107+-- | cannot be satisfied with the data already in store the upgrade transaction
108+-- | will abort with a "ConstraintError" DOMException.
109+-- |
110+-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
111+createIndex
112+ :: forall e store. (IDBObjectStore store)
113+ => store
114+ -> IndexName
115+ -> KeyPath
116+ -> IndexParameters
117+ -> Aff (idb :: IDB | e) Index
118+createIndex store name' path params =
119+ Fn.runFn4 _createIndex store name' path params
120+
121+
122+-- | Deletes records in store with the given key or in the given key range in query.
123+delete
124+ :: forall e store. (IDBObjectStore store)
125+ => store
126+ -> KeyRange
127+ -> Aff (idb :: IDB | e) Unit
128+delete store range =
129+ Fn.runFn2 _delete store range
130+
131+
132+-- | Deletes the index in store with the given name.
133+-- |
134+-- | Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
135+deleteIndex
136+ :: forall e store. (IDBObjectStore store)
137+ => store
138+ -> IndexName
139+ -> Aff (idb :: IDB | e) Unit
140+deleteIndex store name' =
141+ Fn.runFn2 _deleteIndex store name'
142+
143+
144+-- | Returns an IDBIndex for the index named name in store.
145+index
146+ :: forall e store. (IDBObjectStore store)
147+ => store
148+ -> IndexName
149+ -> Aff (idb :: IDB | e) Index
150+index store name' =
151+ Fn.runFn2 _index store name'
152+
153+
154+-- | Adds or updates a record in store with the given value and key.
155+-- |
156+-- | If the store uses in-line keys and key is specified a "DataError" DOMException
157+-- | will be thrown.
158+-- |
159+-- | If put() is used, any existing record with the key will be replaced.
160+put
161+ :: forall e val key store. (IDBKey key) => (IDBObjectStore store)
162+ => store
163+ -> val
164+ -> Maybe key
165+ -> Aff (idb :: IDB | e) key
166+put store value key =
167+ Fn.runFn3 _put store value (toNullable $ (toKey >>> toForeign) <$> key)
168+
169+
123170--------------------
124171-- ATTRIBUTES
125172--
@@ -163,38 +210,12 @@ transaction =
163210 _transaction
164211
165212
166−--------------------
167−-- INSTANCES
168−--
169−instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore where
170− add store value key =
171− Key <$> Fn.runFn3 _add store value (toNullable $ (toKey >>> extractForeign) <$> key)
172−
173− clear =
174− _clear
175−
176− createIndex store name' path params =
177− Fn.runFn4 _createIndex store name' path params
178−
179− delete store range =
180− Fn.runFn2 _delete store range
181−
182− deleteIndex store name' =
183− Fn.runFn2 _deleteIndex store name'
184−
185− index store name' =
186− Fn.runFn2 _index store name'
187−
188− put store value key =
189− Key <$> Fn.runFn3 _put store value (toNullable $ (toKey >>> extractForeign) <$> key)
190−
191−
192213--------------------
193214-- FFI
194215--
195216foreign import _add
196− :: forall value e
197− . Fn3 ObjectStore value (Nullable Foreign) (Aff (idb :: IDB | e) Foreign)
217+ :: forall e key val store. (IDBKey key)
218+ => Fn3 store val (Nullable Foreign) (Aff (idb :: IDB | e) key)
198219
199220
200221foreign import _autoIncrement
@@ -203,29 +224,29 @@ foreign import _autoIncrement
203224
204225
205226foreign import _clear
206− :: forall e
207− . ObjectStore
227+ :: forall e store
228+ . store
208229 -> Aff (idb :: IDB | e) Unit
209230
210231
211232foreign import _createIndex
212− :: forall e
213− . Fn4 ObjectStore String (Array String) { unique :: Boolean, multiEntry :: Boolean } (Aff (idb :: IDB | e) Index)
233+ :: forall e store
234+ . Fn4 store String (Array String) { unique :: Boolean, multiEntry :: Boolean } (Aff (idb :: IDB | e) Index)
214235
215236
216237foreign import _delete
217− :: forall e
218− . Fn2 ObjectStore KeyRange (Aff (idb :: IDB | e) Unit)
238+ :: forall e store
239+ . Fn2 store KeyRange (Aff (idb :: IDB | e) Unit)
219240
220241
221242foreign import _deleteIndex
222− :: forall e
223− . Fn2 ObjectStore String (Aff (idb :: IDB | e) Unit)
243+ :: forall e store
244+ . Fn2 store String (Aff (idb :: IDB | e) Unit)
224245
225246
226247foreign import _index
227− :: forall e
228− . Fn2 ObjectStore String (Aff (idb :: IDB | e) Index)
248+ :: forall e store
249+ . Fn2 store String (Aff (idb :: IDB | e) Index)
229250
230251
231252foreign import _indexNames
@@ -244,8 +265,8 @@ foreign import _name
244265
245266
246267foreign import _put
247− :: forall value e
248− . Fn3 ObjectStore value (Nullable Foreign) (Aff (idb :: IDB | e) Foreign)
268+ :: forall e key val store. (IDBKey key)
269+ => Fn3 store val (Nullable Foreign) (Aff (idb :: IDB | e) key)
249270
250271
251272foreign import _transaction
src/Database/IndexedDB/IDBTransaction.purs+38−36
@@ -1,9 +1,14 @@
1−-- | A Transaction is used to interact with the data in a database.
2−-- | Whenever data is read or written to the database it is done by using a transaction.
1+-- | An object store is the primary storage mechanism for storing data in a database.
32module Database.IndexedDB.IDBTransaction
4− (class IDBTransaction, abort, objectStore
3+ -- * Interface
4+ ( abort
5+ , objectStore
6+
7+ -- * Attributes
58 , error
69 , mode
10+
11+ -- * Event Handlers
712 , onAbort
813 , onComplete
914 , onError
@@ -19,33 +24,38 @@ import Data.Function.Uncurried (Fn2, Fn4)
1924import Data.Maybe (Maybe)
2025import Data.Nullable (Nullable, toMaybe)
2126
22−import Database.IndexedDB.Core (IDB, Database, ObjectStore, Transaction, TransactionMode(..))
27+import Database.IndexedDB.Core
2328
2429
2530--------------------
2631-- INTERFACES
2732--
28−-- | The IDBtransaction interface.
29−class IDBTransaction tx where
30− -- | Aborts the transaction. All pending requests will fail with a "AbortError"
31− -- | DOMException and all changes made to the database will be reverted.
32− abort
33− :: forall e
34− . tx
35− -> Aff (idb :: IDB | e) Unit
36−
37− -- | Returns an IDBObjectStore in the transaction's scope.
38− objectStore
39− :: forall e
40− . tx
41− -> String
42− -> Aff (idb :: IDB | e) ObjectStore
33+
34+-- | Aborts the transaction. All pending requests will fail with a "AbortError"
35+-- | DOMException and all changes made to the database will be reverted.
36+abort
37+ :: forall e tx. (IDBTransaction tx)
38+ => tx
39+ -> Aff (idb :: IDB | e) Unit
40+abort =
41+ _abort
42+
43+
44+-- | Returns an IDBObjectStore in the transaction's scope.
45+objectStore
46+ :: forall e tx. (IDBTransaction tx)
47+ => tx
48+ -> String
49+ -> Aff (idb :: IDB | e) ObjectStore
50+objectStore tx name =
51+ Fn.runFn2 _objectStore tx name
4352
4453
4554--------------------
4655-- ATTRIBUTES
4756--
48−-- | Returns the transaction’s connection.
57+
58+--- | Returns the transaction’s connection.
4959db
5060 :: Transaction
5161 -> Database
@@ -60,6 +70,7 @@ error
6070error =
6171 _error >>> toMaybe
6272
73+
6374-- | Returns the mode the transaction was created with (`ReadOnly|ReadWrite`)
6475-- | , or `VersionChange` for an upgrade transaction.
6576mode
@@ -77,17 +88,19 @@ objectStoreNames
7788objectStoreNames =
7889 _objectStoreNames
7990
91+
8092--------------------
8193-- EVENT HANDLERS
8294--
95+
8396-- | Event handler for the `abort` event.
8497onAbort
8598 :: forall e e'
8699 . Transaction
87100 -> Eff ( | e') Unit
88101 -> Aff (idb :: IDB | e) Unit
89−onAbort db f =
90− Fn.runFn2 _onAbort db f
102+onAbort db' f =
103+ Fn.runFn2 _onAbort db' f
91104
92105
93106-- | Event handler for the `complete` event.
@@ -96,8 +109,8 @@ onComplete
96109 . Transaction
97110 -> Eff ( | e') Unit
98111 -> Aff (idb :: IDB | e) Unit
99−onComplete db f =
100− Fn.runFn2 _onComplete db f
112+onComplete db' f =
113+ Fn.runFn2 _onComplete db' f
101114
102115
103116-- | Event handler for the `error` event.
@@ -110,20 +123,10 @@ onError db' f =
110123 Fn.runFn2 _onError db' f
111124
112125
113−--------------------
114−-- INSTANCES
115−--
116−instance idbTransactionTransaction :: IDBTransaction Transaction where
117− objectStore tx name =
118− Fn.runFn2 _objectStore tx name
119−
120− abort =
121− _abort
122−
123−
124126--------------------
125127-- FFI
126128--
129+
127130foreign import _abort
128131 :: forall tx e
129132 . tx
@@ -167,4 +170,3 @@ foreign import _onComplete
167170foreign import _onError
168171 :: forall tx e e'
169172 . Fn2 tx (Error -> Eff ( | e') Unit) (Aff (idb :: IDB | e) Unit)
170−