review implementation structure completely. See details

- Introduce type-class for almost all IDB* interfaces

- Expose only methods in type classes and use plain function for attributes getter (methods are
  shared between some entities but not attributes)

- Normalize naming for foreign functions (always start with a _)

- Remove any external imports in native modules (duplicate helper functions in necessary modules
  and inject constructors and helpers from PureScript when necessary)

- Finalize implementation of IDBIndex interface

- Use an Database.IndexedDB.IDBKey.Internal module to hide implementation details about key

- Remove all warnings
This commit is contained in:
KtorZ 2017-06-29 14:34:33 +02:00
parent 607929ce98
commit 464d609156
No known key found for this signature in database
GPG Key ID: 3F72E8BC2894C015
18 changed files with 800 additions and 460 deletions

View File

@ -1,30 +1,4 @@
exports.toArray = function toArray(xs) {
return Array.prototype.slice.apply(xs);
};
exports.noOp = function noOp() {
return function eff() {
// Nothing
};
};
exports.noOp2 = function noOp2() {
return exports.noOp;
};
exports.errorHandler = function errorHandler(cb) {
return function _handler(e) {
cb(new Error(e.target.error.name));
};
};
exports.successHandler = function successHandler(cb) {
return function _handler(e) {
cb(e.target.result);
};
};
exports._showIDBDatabase = function _showIDBDatabase(db) {
exports._showDatabase = function _showDatabase(db) {
return '(IDBDatabase ' +
'{ name: ' + db.name +
', objectStoreNames: [' + exports.toArray(db.objectStoreNames).join(', ') + ']' +
@ -32,7 +6,7 @@ exports._showIDBDatabase = function _showIDBDatabase(db) {
' })';
};
exports._showIDBObjectStore = function _showIDBObjectStore(store) {
exports._showObjectStore = function _showObjectStore(store) {
return '(IDBObjectStore ' +
'{ autoIncrement: ' + store.autoIncrement +
', indexNames: [' + exports.toArray(store.indexNames).join(', ') + ']' +
@ -41,7 +15,7 @@ exports._showIDBObjectStore = function _showIDBObjectStore(store) {
' })';
};
exports._showIDBTransaction = function _showIDBTransaction(tx) {
exports._showTransaction = function _showTransaction(tx) {
return '(IDBTransaction ' +
'{ error: ' + tx.error +
', mode: ' + tx.mode +

View File

@ -1,72 +1,110 @@
module Database.IndexedDB.Core
( INDEXED_DB
, IDBCursorSource(..)
, IDBDatabase
, IDBIndex
, IDBKeyCursor
, IDBKeyRange
, IDBObjectStore
, IDBTransaction
, IDBTransactionMode(..)
, IDBValueCursor
, module Database.IndexedDB.IDBCursorDirection
( class FromString, parse
, INDEXED_DB
, CursorDirection(..)
, CursorSource(..)
, Database
, Index
, KeyCursor
, KeyRange
, ObjectStore
, Transaction
, TransactionMode(..)
, ValueCursor
, module Database.IndexedDB.IDBKey
) where
import Prelude
import Prelude (class Show)
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (kind Effect, Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn4, Fn7)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toNullable)
import Control.Monad.Eff (kind Effect)
import Data.Maybe (Maybe(..))
import Database.IndexedDB.IDBCursorDirection
import Database.IndexedDB.IDBKey
data IDBTransactionMode = ReadOnly | ReadWrite | VersionChange
class FromString a where
parse :: String -> Maybe a
data IDBCursorSource = IDBObjectStore IDBObjectStore | IDBIndex IDBIndex
data CursorDirection = Next | NextUnique | Prev | PrevUnique
data CursorSource = ObjectStore ObjectStore | Index Index
data TransactionMode = ReadOnly | ReadWrite | VersionChange
foreign import data INDEXED_DB :: Effect
foreign import data IDBDatabase :: Type
foreign import data Database :: Type
foreign import data IDBIndex :: Type
foreign import data Index :: Type
foreign import data IDBKeyCursor :: Type
foreign import data KeyCursor :: Type
foreign import data IDBKeyRange :: Type
foreign import data KeyRange :: Type
foreign import data IDBObjectStore :: Type
foreign import data ObjectStore :: Type
foreign import data IDBTransaction :: Type
foreign import data Transaction :: Type
foreign import data IDBValueCursor :: Type
foreign import data ValueCursor :: Type
foreign import _showIDBDatabase :: IDBDatabase -> String
instance showIDBDatabase :: Show IDBDatabase where
show = _showIDBDatabase
foreign import _showDatabase :: Database -> String
instance showDatabase :: Show Database where
show = _showDatabase
foreign import _showIDBObjectStore :: IDBObjectStore -> String
instance showIDBObjectStore :: Show IDBObjectStore where
show = _showIDBObjectStore
foreign import _showObjectStore :: ObjectStore -> String
instance showObjectStore :: Show ObjectStore where
show = _showObjectStore
foreign import _showIDBTransaction :: IDBTransaction -> String
instance showIDBTransaction :: Show IDBTransaction where
show = _showIDBTransaction
foreign import _showTransaction :: Transaction -> String
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
ReadOnly -> "readonly"
ReadWrite -> "readwrite"
VersionChange -> "versionchange"
instance fromStringCursorDirection :: FromString CursorDirection where
parse s =
case s of
"next" -> Just Next
"nextunique" -> Just NextUnique
"prev" -> Just Prev
"prevunique" -> Just PrevUnique
_ -> Nothing
instance fromStringTransactionMode :: FromString TransactionMode where
parse s =
case s of
"readonly" -> Just ReadOnly
"readwrite" -> Just ReadWrite
"versionchange" -> Just VersionChange
_ -> Nothing

View File

@ -1,7 +1,14 @@
const $Core = require('Database.IndexedDB.Core/foreign');
const errorHandler = function errorHandler(cb) {
return function _handler(e) {
cb(new Error(e.target.error.name));
};
};
const errorHandler = $Core.errorHandler;
const successHandler = $Core.successHandler;
const successHandler = function successHandler(cb) {
return function _handler(e) {
cb(e.target.result);
};
};
exports._advance = function _advance(cursor, count) {

View File

@ -1,92 +1,140 @@
module Database.IndexedDB.IDBCursor
( class IDBCursor, advance, continue, continuePrimaryKey, delete, direction, key, primaryKey, source, update
, class IDBCursorWithValue, value
( class IDBCursor, advance, continue, continuePrimaryKey, delete, update
, direction
, key
, primaryKey
, source
, direction'
, key'
, primaryKey'
, source'
, value
) where
import Prelude (Unit, (>>>))
import Prelude (Unit, (>>>))
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toNullable)
import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toNullable)
import Data.Foreign (Foreign, toForeign, unsafeFromForeign)
import Database.IndexedDB.Core
import Database.IndexedDB.IDBCursorDirection as IDBCursorDirection
--------------------
-- INTERFACES
--
class IDBCursor cursor where
advance :: forall eff. cursor -> Int -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
continue :: forall eff. cursor -> Maybe IDBKey -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
continuePrimaryKey :: forall eff. cursor -> IDBKey -> IDBKey -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
continue :: forall eff. cursor -> Maybe Key -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
continuePrimaryKey :: forall eff. cursor -> Key -> Key -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
delete :: forall eff. cursor -> Aff (idb ::INDEXED_DB, exception :: EXCEPTION | eff) Unit
direction :: cursor -> IDBCursorDirection
key :: cursor -> IDBKey
primaryKey :: cursor -> IDBKey
source :: cursor -> IDBCursorSource
update :: forall val eff. cursor -> val -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey
update :: forall val eff. cursor -> val -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Key
class IDBCursor cursor <= IDBCursorWithValue cursor where
value :: forall val. cursor -> val
--------------------
-- ATTRIBUTES
--
direction :: KeyCursor -> CursorDirection
direction =
Fn.runFn2 _direction (parse >>> toNullable)
instance keyCursorKeyCursor :: IDBCursor IDBKeyCursor where
key :: KeyCursor -> Key
key =
_key
primaryKey :: KeyCursor -> Key
primaryKey =
_primaryKey
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.
direction' :: ValueCursor -> CursorDirection
direction' =
Fn.runFn2 _direction (parse >>> toNullable)
key' :: ValueCursor -> Key
key' =
_key
primaryKey' :: ValueCursor -> Key
primaryKey' =
_primaryKey
source' :: ValueCursor -> CursorSource
source' =
Fn.runFn3 _source ObjectStore Index
value :: forall val. ValueCursor -> val
value =
_value >>> unsafeFromForeign
--------------------
-- INSTANCES
--
instance keyCursorKeyCursor :: IDBCursor KeyCursor where
advance = Fn.runFn2 _advance
continue c mk = Fn.runFn2 _continue c (toNullable mk)
continuePrimaryKey = Fn.runFn3 _continuePrimaryKey
delete = _delete
direction = Fn.runFn2 _direction (IDBCursorDirection.fromString >>> toNullable)
key = _key
primaryKey = _primaryKey
source = Fn.runFn3 _source IDBObjectStore IDBIndex
update c = toForeign >>> Fn.runFn2 _update c
instance valueCursorKeyCursor :: IDBCursor IDBValueCursor where
instance valueCursorKeyCursor :: IDBCursor ValueCursor where
advance = Fn.runFn2 _advance
continue c mk = Fn.runFn2 _continue c (toNullable mk)
continuePrimaryKey = Fn.runFn3 _continuePrimaryKey
delete = _delete
direction = Fn.runFn2 _direction (IDBCursorDirection.fromString >>> toNullable)
key = _key
primaryKey = _primaryKey
source = Fn.runFn3 _source IDBObjectStore IDBIndex
update c = toForeign >>> Fn.runFn2 _update c
instance valueCursorWithValueCursor :: IDBCursorWithValue IDBValueCursor where
value = _value >>> unsafeFromForeign
--------------------
-- FFI
--
foreign import _advance :: forall cursor eff. Fn2 cursor Int (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _continue :: forall cursor eff. Fn2 cursor (Nullable IDBKey) (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _continue :: forall cursor eff. Fn2 cursor (Nullable Key) (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _continuePrimaryKey :: forall cursor eff. Fn3 cursor IDBKey IDBKey (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _continuePrimaryKey :: forall cursor eff. Fn3 cursor Key Key (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _delete :: forall cursor eff. cursor -> (Aff (idb ::INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _direction :: forall cursor. Fn2 (String -> Nullable IDBCursorDirection) cursor IDBCursorDirection
foreign import _direction :: forall cursor. Fn2 (String -> Nullable CursorDirection) cursor CursorDirection
foreign import _key :: forall cursor. cursor -> IDBKey
foreign import _key :: forall cursor. cursor -> Key
foreign import _primaryKey :: forall cursor. cursor -> IDBKey
foreign import _primaryKey :: forall cursor. cursor -> Key
foreign import _source :: forall cursor. Fn3 (IDBObjectStore -> IDBCursorSource) (IDBIndex -> IDBCursorSource) cursor IDBCursorSource
foreign import _source :: forall cursor. Fn3 (ObjectStore -> CursorSource) (Index -> CursorSource) cursor CursorSource
foreign import _update :: forall cursor eff. Fn2 cursor Foreign (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey)
foreign import _update :: forall cursor eff. Fn2 cursor Foreign (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Key)
foreign import _value :: forall cursor val. cursor -> val

View File

@ -1,27 +0,0 @@
module Database.IndexedDB.IDBCursorDirection where
import Prelude (class Show)
import Data.Maybe (Maybe(..))
data IDBCursorDirection = Next | NextUnique | Prev | PrevUnique
instance showIDBCursorDirection :: Show IDBCursorDirection where
show x =
case x of
Next -> "next"
NextUnique -> "nextunique"
Prev -> "prev"
PrevUnique -> "prevunique"
fromString :: String -> Maybe IDBCursorDirection
fromString s =
case s of
"next" -> Just Next
"nextunique" -> Just NextUnique
"prev" -> Just Prev
"prevunique" -> Just PrevUnique
_ -> Nothing

View File

@ -1,10 +1,9 @@
const Core = require('Database.IndexedDB.Core');
const $Core = require('Database.IndexedDB.Core/foreign');
const toArray = $Core.toArray;
exports.close = function close(db) {
exports._close = function _close(db) {
return function eff() {
try {
db.close();
@ -52,33 +51,24 @@ exports._deleteObjectStore = function _deleteObjectStore(db, name) {
};
};
exports.name = function name(db) {
exports._name = function _name(db) {
return db.name;
};
exports.objectStoreNames = function objectStoreNames(db) {
exports._objectStoreNames = function _objectStoreNames(db) {
return toArray(db.objectStoreNames);
};
exports._transaction = function _transaction(db, stores, mode) {
exports._transaction = function _transaction(show, db, stores, mode) {
return function eff() {
var mode_;
try {
if (mode instanceof Core.ReadOnly) {
mode_ = 'readonly';
} else if (mode instanceof Core.ReadWrite) {
mode_ = 'readwrite';
} else {
mode_ = 'versionchange';
}
return db.transaction(stores, mode_);
return db.transaction(stores, show(mode));
} catch (e) {
throw new Error(e.name);
}
};
};
exports.version = function version(db) {
exports._version = function _version(db) {
return db.version;
};

View File

@ -1,42 +1,84 @@
module Database.IndexedDB.IDBDatabase where
module Database.IndexedDB.IDBDatabase
( class IDBDatabase, close, createObjectStore, deleteObjectStore, transaction
, name
, objectStoreNames
, version
) where
import Prelude
import Prelude (Unit, show)
import Control.Monad.Aff(Aff)
import Control.Monad.Eff(Eff)
import Control.Monad.Eff.Exception(EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried(Fn2, Fn3)
import Data.Maybe(Maybe)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3, Fn4)
import Database.IndexedDB.Core
foreign import close :: forall eff. IDBDatabase -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
--------------------
-- INTERFACE
--
class IDBDatabase db where
close :: forall eff. db -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
createObjectStore :: forall eff. db -> String -> { keyPath :: Array String, autoIncrement :: Boolean } -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore
deleteObjectStore :: forall eff . db -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore
transaction :: forall eff. db -> Array String -> TransactionMode -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Transaction
foreign import _createObjectStore :: forall a eff. Fn3 IDBDatabase String { keyPath :: Array String, autoIncrement :: Boolean } (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore)
createObjectStore :: forall eff. IDBDatabase -> String -> { keyPath :: Array String, autoIncrement :: Boolean } -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore
createObjectStore db name opts =
Fn.runFn3 _createObjectStore db name opts
--------------------
-- ATTRIBUTES
--
name :: Database -> String
name =
_name
foreign import _deleteObjectStore :: forall eff. Fn2 IDBDatabase String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore)
deleteObjectStore :: forall eff . IDBDatabase -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore
deleteObjectStore db name =
Fn.runFn2 _deleteObjectStore db name
objectStoreNames :: Database -> Array String
objectStoreNames =
_objectStoreNames
foreign import name :: IDBDatabase -> String
version :: Database -> Int
version =
_version
foreign import objectStoreNames :: IDBDatabase -> Array String
--------------------
-- INSTANCES
--
instance idbDatabaseDatabase :: IDBDatabase Database where
close =
_close
createObjectStore db name' opts =
Fn.runFn3 _createObjectStore db name' opts
deleteObjectStore db name' =
Fn.runFn2 _deleteObjectStore db name'
transaction db stores mode' =
Fn.runFn4 _transaction show db stores mode'
foreign import _transaction :: forall eff. Fn3 IDBDatabase (Array String) IDBTransactionMode (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBTransaction)
transaction :: forall eff. IDBDatabase -> Array String -> IDBTransactionMode -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBTransaction
transaction db stores mode =
Fn.runFn3 _transaction db stores mode
--------------------
-- FFI
--
foreign import _close :: forall db eff. db -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
foreign import version :: IDBDatabase -> Int
foreign import _createObjectStore :: forall db eff. Fn3 db String { keyPath :: Array String, autoIncrement :: Boolean } (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore)
foreign import _deleteObjectStore :: forall db eff. Fn2 db String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore)
foreign import _name :: Database -> String
foreign import _objectStoreNames :: Database -> Array String
foreign import _transaction :: forall db eff. Fn4 (db -> String) db (Array String) TransactionMode (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Transaction)
foreign import _version :: Database -> Int

View File

@ -1,11 +1,21 @@
const $Core = require('Database.IndexedDB.Core/foreign');
const errorHandler = function errorHandler(cb) {
return function _handler(e) {
cb(new Error(e.target.error.name));
};
};
const noOp = $Core.noOp;
const noOp2 = $Core.noOp2;
const errorHandler = $Core.errorHandler;
const noOp = function noOp() {
return function eff() {
// Nothing
};
};
const noOp2 = function noOp2() {
return exports.noOp;
};
exports.deleteDatabase = function deleteDatabase(name) {
exports._deleteDatabase = function _deleteDatabase(name) {
return function aff(success, error) {
const request = indexedDB.deleteDatabase(name);

View File

@ -1,27 +1,39 @@
module Database.IndexedDB.IDBFactory where
import Prelude
import Prelude (Unit)
import Control.Monad.Aff(Aff)
import Control.Monad.Eff(Eff)
import Control.Monad.Eff.Exception(EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried(Fn4)
import Data.Maybe(Maybe, fromMaybe)
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn4)
import Data.Maybe (Maybe, fromMaybe)
import Database.IndexedDB.Core
type IDBOpenRequest eff =
--------------------
-- INTERFACE
--
type OpenRequest eff =
{ onBlocked :: Maybe (Eff (idb :: INDEXED_DB | eff) Unit)
, onUpgradeNeeded :: Maybe (IDBDatabase -> Eff (idb :: INDEXED_DB | eff) Unit)
, onUpgradeNeeded :: Maybe (Database -> Eff (idb :: INDEXED_DB | eff) Unit)
}
foreign import deleteDatabase :: forall eff. String -> Aff (idb :: INDEXED_DB | eff) Int
deleteDatabase :: forall eff. String -> Aff (idb :: INDEXED_DB | eff) Int
deleteDatabase =
_deleteDatabase
foreign import _open :: forall a eff. Fn4 (a -> Maybe a -> a) String (Maybe Int) (IDBOpenRequest eff) (Aff (idb :: INDEXED_DB | eff) IDBDatabase)
open :: forall eff . String -> Maybe Int -> IDBOpenRequest eff -> Aff (idb :: INDEXED_DB | eff) IDBDatabase
open :: forall eff . String -> Maybe Int -> OpenRequest eff -> Aff (idb :: INDEXED_DB | eff) Database
open name mver req =
Fn.runFn4 _open fromMaybe name mver req
--------------------
-- FFI
--
foreign import _deleteDatabase :: forall eff. String -> Aff (idb :: INDEXED_DB | eff) Int
foreign import _open :: forall a eff. Fn4 (a -> Maybe a -> a) String (Maybe Int) (OpenRequest eff) (Aff (idb :: INDEXED_DB | eff) Database)

View File

@ -0,0 +1,95 @@
const errorHandler = function errorHandler(cb) {
return function _handler(e) {
cb(new Error(e.target.error.name));
};
};
const successHandler = function successHandler(cb) {
return function _handler(e) {
cb(e.target.result);
};
};
exports._keyPath = function _keyPath(index) {
return index.keyPath;
};
exports._multiEntry = function _multiEntry(index) {
return index.multiEntry;
};
exports._name = function _name(index) {
return index.name;
};
exports._objectStore = function _objectStore(index) {
return index.obectStore;
};
exports._unique = function _unique(index) {
return index.unique;
};
exports._count = function _count(index, query) {
return function aff(success, error) {
const request = index.count(query);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._get = function _get(index, range) {
return function aff(success, error) {
const request = index.get(range);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
/*
* NOTE: Require some additional work. The array (which isn't necessarily a list of
* polymorphic types in js) can't be easily translated to a PureScript array.
*
* However, it may be doable to convert the result to some key / value structure with values of
* different types.
exports._getAll = function _getAll(index, query, count) {
return function aff(success, error) {
const request = index.getAll(query, count);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
*/
exports._getAllKeys = function _getAllKeys(index, range, count) {
return function aff(success, error) {
const request = index.getAllKeys(range, count || undefined);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._getKey = function _getKey(index, range) {
return function aff(success, error) {
const request = index.getKey(range);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._openCursor = function _openCursor(index, query, dir) {
return function aff(success, error) {
const request = index.openCursor(query, dir);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._openKeyCursor = function _openKeyCursor(index, query, dir) {
return function aff(success, error) {
const request = index.openKeyCursor(query, dir);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};

View File

@ -0,0 +1,138 @@
module Database.IndexedDB.IDBIndex
( class IDBIndex, count, get, getAllKeys, getKey, openCursor, openKeyCursor
, keyPath
, multiEntry
, name
, unique
) where
import Prelude
import Control.Monad.Aff (Aff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toMaybe, toNullable)
import Data.Foreign (Foreign, unsafeFromForeign)
import Database.IndexedDB.Core (INDEXED_DB, CursorDirection, Index, Key, KeyCursor, KeyRange, ObjectStore, ValueCursor)
--------------------
-- INTERFACES
--
class IDBIndex index where
count :: forall eff. index -> Maybe KeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Int
get :: forall a eff. index -> KeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Maybe a)
getAllKeys :: forall eff. index -> Maybe KeyRange -> Maybe Int -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Array Key)
getKey :: forall eff. index -> KeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Maybe Key)
openCursor :: forall eff. index -> Maybe KeyRange -> Maybe CursorDirection -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ValueCursor
openKeyCursor :: forall eff. index -> Maybe KeyRange -> Maybe CursorDirection -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) KeyCursor
--------------------
-- ATTRIBUTES
--
keyPath :: Index -> String
keyPath =
_keyPath
multiEntry :: Index -> Boolean
multiEntry =
_multiEntry
name :: Index -> String
name =
_name
objectStore :: Index -> ObjectStore
objectStore =
_objectStore
unique :: Index -> Boolean
unique =
_unique
--------------------
-- INSTANCES
--
instance idbIndexIndex :: IDBIndex Index where
count index range =
Fn.runFn2 _count index (toNullable range)
get index range =
(toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get index range
getAllKeys index range count =
Fn.runFn3 _getAllKeys index (toNullable range) (toNullable count)
getKey index range =
toMaybe <$> Fn.runFn2 _getKey index range
openCursor index range dir =
Fn.runFn3 _openCursor index (toNullable range) (toNullable dir)
openKeyCursor index range dir =
Fn.runFn3 _openKeyCursor index (toNullable range) (toNullable dir)
instance idbIndexObjectStore :: IDBIndex ObjectStore where
count store range =
Fn.runFn2 _count store (toNullable range)
get store range =
(toMaybe >>> map unsafeFromForeign) <$> Fn.runFn2 _get store range
getAllKeys store range count =
Fn.runFn3 _getAllKeys store (toNullable range) (toNullable count)
getKey store range =
toMaybe <$> Fn.runFn2 _getKey store range
openCursor store range dir =
Fn.runFn3 _openCursor store (toNullable range) (toNullable dir)
openKeyCursor store range dir =
Fn.runFn3 _openKeyCursor store (toNullable range) (toNullable dir)
--------------------
-- FFI
--
foreign import _keyPath :: Index -> String
foreign import _multiEntry :: Index -> Boolean
foreign import _name :: Index -> String
foreign import _objectStore :: Index -> ObjectStore
foreign import _unique :: Index -> Boolean
foreign import _count :: forall index eff. Fn2 index (Nullable KeyRange) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Int)
foreign import _get :: forall index eff. Fn2 index KeyRange (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Nullable Foreign))
foreign import _getAllKeys :: forall index eff. Fn3 index (Nullable KeyRange) (Nullable Int) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Array Key))
foreign import _getKey :: forall index eff. Fn2 index KeyRange (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Nullable Key))
foreign import _openCursor :: forall index eff. Fn3 index (Nullable KeyRange) (Nullable CursorDirection) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ValueCursor)
foreign import _openKeyCursor :: forall index eff. Fn3 index (Nullable KeyRange) (Nullable CursorDirection) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) KeyCursor)

View File

@ -1,97 +1,5 @@
module Database.IndexedDB.IDBKey
( IDBKey
, class IsIDBKey, toIDBKey , fromIDBKey , unsafeFromIDBKey
) where
( module Database.IndexedDB.IDBKey.Internal
) where
import Prelude
import Control.Alt ((<|>))
import Control.Monad.Except (ExceptT(..), runExceptT)
import Data.Date as Date
import Data.DateTime (DateTime(..), Time(..))
import Data.Enum (fromEnum, toEnum)
import Data.Foreign as Foreign
import Data.Foreign (Foreign, F)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn4, Fn7)
import Data.List.NonEmpty (NonEmptyList(..))
import Data.List.Types (List(..))
import Data.NonEmpty (NonEmpty(..))
import Data.Either (Either(..), isRight)
import Data.Identity (Identity(..))
import Data.Nullable (Nullable, toNullable)
import Data.Time as Time
import Data.Traversable (traverse)
newtype IDBKey = IDBKey Foreign
class IsIDBKey a where
toIDBKey :: a -> IDBKey
fromIDBKey :: IDBKey -> F a
unsafeFromIDBKey :: IDBKey -> a
instance eqIDBKey :: Eq IDBKey where
eq a b = (runExceptT >>> runIdentity >>> isRight) $
eq <$> ((fromIDBKey a) :: F Int) <*> fromIDBKey b
<|>
eq <$> ((fromIDBKey a) :: F String) <*> fromIDBKey b
<|>
eq <$> ((fromIDBKey a) :: F DateTime) <*> fromIDBKey b
where
runIdentity :: forall a. Identity a -> a
runIdentity (Identity x) = x
instance isIDBKeyInt :: IsIDBKey Int where
toIDBKey = Foreign.toForeign >>> IDBKey
fromIDBKey (IDBKey f) = Foreign.readInt f
unsafeFromIDBKey (IDBKey f) = Foreign.unsafeFromForeign f
instance isIDBKeyString :: IsIDBKey String where
toIDBKey = Foreign.toForeign >>> IDBKey
fromIDBKey (IDBKey f) = Foreign.readString f
unsafeFromIDBKey (IDBKey f) = Foreign.unsafeFromForeign f
instance isIDBKeyDate :: IsIDBKey DateTime where
toIDBKey (DateTime d t) = IDBKey $ Fn.runFn7 _dateTimeToForeign
(fromEnum $ Date.year d)
(fromEnum $ Date.month d)
(fromEnum $ Date.day d)
(fromEnum $ Time.hour t)
(fromEnum $ Time.minute t)
(fromEnum $ Time.second t)
(fromEnum $ Time.millisecond t)
fromIDBKey (IDBKey f) = Fn.runFn4 _readDateTime dateTime dateTimeF dateTimeE f
unsafeFromIDBKey (IDBKey f) = Fn.runFn2 _unsafeReadDateTime dateTime f
instance isIDBKeyArray :: IsIDBKey a => IsIDBKey (Array a) where
toIDBKey = Foreign.toForeign >>> IDBKey
fromIDBKey (IDBKey f) = Foreign.readArray f >>= traverse (IDBKey >>> fromIDBKey)
unsafeFromIDBKey (IDBKey f) = map unsafeFromIDBKey (Foreign.unsafeFromForeign f)
foreign import _dateTimeToForeign :: Fn7 Int Int Int Int Int Int Int Foreign
foreign import _readDateTime :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
foreign import _unsafeReadDateTime :: Fn2 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) Foreign DateTime
dateTime :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime
dateTime y m d h mi s ms =
toNullable $ DateTime
<$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
<*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
dateTimeF :: DateTime -> F DateTime
dateTimeF =
Right >>> Identity >>> ExceptT
dateTimeE :: String -> F DateTime
dateTimeE =
Foreign.TypeMismatch "Date" >>> flip NonEmpty Nil >>> NonEmptyList >>> Left >>> Identity >>> ExceptT
import Database.IndexedDB.IDBKey.Internal(Key, class IDBKey, toKey, fromKey, unsafeFromKey)

View File

@ -0,0 +1,117 @@
module Database.IndexedDB.IDBKey.Internal
( Key(..)
, class IDBKey, toKey , fromKey , unsafeFromKey
, extractForeign
) where
import Prelude
import Control.Alt ((<|>))
import Control.Monad.Except (ExceptT(..), runExceptT)
import Data.Date as Date
import Data.DateTime (DateTime(..), Time(..))
import Data.Enum (fromEnum, toEnum)
import Data.Foreign as Foreign
import Data.Foreign (Foreign, F)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn4, Fn7)
import Data.List.NonEmpty (NonEmptyList(..))
import Data.List.Types (List(..))
import Data.NonEmpty (NonEmpty(..))
import Data.Either (Either(..), isRight)
import Data.Identity (Identity(..))
import Data.Nullable (Nullable, toNullable)
import Data.Time as Time
import Data.Traversable (traverse)
newtype Key = Key Foreign
extractForeign :: Key -> Foreign
extractForeign (Key f) =
f
--------------------
-- INTERFACES
--
class IDBKey a where
toKey :: a -> Key
fromKey :: Key -> F a
unsafeFromKey :: Key -> a
--------------------
-- INSTANCES
--
instance eqKey :: Eq Key where
eq a b = (runExceptT >>> runIdentity >>> isRight) $
eq <$> ((fromKey a) :: F Int) <*> fromKey b
<|>
eq <$> ((fromKey a) :: F String) <*> fromKey b
<|>
eq <$> ((fromKey a) :: F DateTime) <*> fromKey b
where
runIdentity :: forall a. Identity a -> a
runIdentity (Identity x) = x
instance idbKeyInt :: IDBKey Int where
toKey = Foreign.toForeign >>> Key
fromKey (Key f) = Foreign.readInt f
unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
instance idbKeyString :: IDBKey String where
toKey = Foreign.toForeign >>> Key
fromKey (Key f) = Foreign.readString f
unsafeFromKey (Key f) = Foreign.unsafeFromForeign f
instance idbKeyDate :: IDBKey DateTime where
toKey (DateTime d t) = Key $ Fn.runFn7 _dateTimeToForeign
(fromEnum $ Date.year d)
(fromEnum $ Date.month d)
(fromEnum $ Date.day d)
(fromEnum $ Time.hour t)
(fromEnum $ Time.minute t)
(fromEnum $ Time.second t)
(fromEnum $ Time.millisecond t)
fromKey (Key f) = Fn.runFn4 _readDateTime dateTime dateTimeF dateTimeE f
unsafeFromKey (Key f) = Fn.runFn2 _unsafeReadDateTime dateTime f
instance idbKeyArray :: IDBKey a => IDBKey (Array a) where
toKey = Foreign.toForeign >>> Key
fromKey (Key f) = Foreign.readArray f >>= traverse (Key >>> fromKey)
unsafeFromKey (Key f) = map unsafeFromKey (Foreign.unsafeFromForeign f)
dateTime :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime
dateTime y m d h mi s ms =
toNullable $ DateTime
<$> (Date.canonicalDate <$> toEnum y <*> toEnum m <*> toEnum d)
<*> (Time <$> toEnum h <*> toEnum mi <*> toEnum s <*> toEnum ms)
dateTimeF :: DateTime -> F DateTime
dateTimeF =
Right >>> Identity >>> ExceptT
dateTimeE :: String -> F DateTime
dateTimeE =
Foreign.TypeMismatch "Date" >>> flip NonEmpty Nil >>> NonEmptyList >>> Left >>> Identity >>> ExceptT
--------------------
-- FFI
--
foreign import _dateTimeToForeign :: Fn7 Int Int Int Int Int Int Int Foreign
foreign import _readDateTime :: Fn4 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) (DateTime -> F DateTime) (String -> F DateTime) Foreign (F DateTime)
foreign import _unsafeReadDateTime :: Fn2 (Int -> Int -> Int -> Int -> Int -> Int -> Int -> Nullable DateTime) Foreign DateTime

View File

@ -1,8 +1,19 @@
const $Core = require('Database.IndexedDB.Core/foreign');
const errorHandler = function errorHandler(cb) {
return function _handler(e) {
cb(new Error(e.target.error.name));
};
};
const successHandler = function successHandler(cb) {
return function _handler(e) {
cb(e.target.result);
};
};
const toArray = function toArray(xs) {
return Array.prototype.slice.apply(xs);
};
const toArray = $Core.toArray;
const errorHandler = $Core.errorHandler;
const successHandler = $Core.successHandler;
exports._add = function _add(store, value, key) {
return function aff(success, error) {
@ -12,11 +23,11 @@ exports._add = function _add(store, value, key) {
};
};
exports.autoIncrement = function autoIncrement(store) {
exports._autoIncrement = function _autoIncrement(store) {
return store.autoIncrement;
};
exports.clear = function clear(store) {
exports._clear = function _clear(store) {
return function aff(success, error) {
const request = store.clear();
request.onsuccess = successHandler(success);
@ -24,14 +35,6 @@ exports.clear = function clear(store) {
};
};
exports._count = function _count(store, query) {
return function aff(success, error) {
const request = store.count(query);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._createIndex = function _createIndex(store, name, path, params) {
return function eff() {
var keyPath;
@ -69,39 +72,7 @@ exports._deleteIndex = function _deleteIndex(store, name) {
exports._delete = function _delete(store, query) {
return function aff(success, error) {
const request = store.delete(query || undefined);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._get = function _get(store, query) {
return function aff(success, error) {
const request = store.get(query || undefined);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._getKey = function _getKey(store, query) {
return function aff(success, error) {
const request = store.getKey(query || undefined);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._getAll = function _getAll(store, query, count) {
return function aff(success, error) {
const request = store.getAll(query, count);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._getAllKeys = function _getAllKeys(store, query, count) {
return function aff(success, error) {
const request = store.getAllKeys(query, count);
const request = store.delete(query);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
@ -117,11 +88,11 @@ exports._index = function _index(store, name) {
};
};
exports.indexNames = function indexNames(store) {
exports._indexNames = function _indexNames(store) {
return toArray(store.indexNames);
};
exports.keyPath = function keyPath(store) {
exports._keyPath = function _keyPath(store) {
const path = store.keyPath;
if (Array.isArray(path)) {
@ -135,26 +106,10 @@ exports.keyPath = function keyPath(store) {
return [];
};
exports.name = function name(store) {
exports._name = function _name(store) {
return store.name;
};
exports._openCursor = function _openCursor(store, query, dir) {
return function aff(success, error) {
const request = store.openCursor(query, dir);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._openKeyCursor = function _openKeyCursor(store, query, dir) {
return function aff(success, error) {
const request = store.openKeyCursor(query, dir);
request.onsuccess = successHandler(success);
request.onerror = errorHandler(error);
};
};
exports._put = function _put(store, value, key) {
return function aff(success, error) {
const request = store.put(value, key || undefined);

View File

@ -1,118 +1,119 @@
module Database.IndexedDB.IDBObjectStore
( add
( class IDBObjectStore, add, clear, createIndex, delete, deleteIndex, index, put
, autoIncrement
, clear
, count
, createIndex
, delete
, deleteIndex
, get
, getAllKeys
, getKey
, index
, indexNames
, keyPath
, name
, openCursor
, openKeyCursor
, put
) where
import Prelude
import Prelude (Unit, ($), (<$>))
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3, Fn4)
import Data.Maybe (Maybe, fromMaybe)
import Data.Nullable (Nullable, toMaybe, toNullable)
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn3, Fn4)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toNullable)
import Data.Foreign (Foreign)
import Database.IndexedDB.Core
import Database.IndexedDB.Core (INDEXED_DB, Index, KeyRange, ObjectStore)
import Database.IndexedDB.IDBKey.Internal (extractForeign, Key(Key))
foreign import _add :: forall value eff. Fn3 IDBObjectStore value (Nullable IDBKey) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey)
add :: forall value eff. IDBObjectStore -> value -> Maybe IDBKey -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey
add store value mkey =
Fn.runFn3 _add store value (toNullable mkey)
--------------------
-- INTERFACES
--
class IDBObjectStore store where
add :: forall value eff. store -> value -> Maybe Key -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Key
clear :: forall eff. store -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
createIndex :: forall eff. store -> String -> (Array String) -> { unique :: Boolean, multiEntry :: Boolean } -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Index
delete :: forall eff. store -> KeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
deleteIndex :: forall eff. store -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
index :: forall eff. store -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Index
put :: forall value eff. store -> value -> Maybe Key -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Key
foreign import autoIncrement :: IDBObjectStore -> Boolean
--------------------
-- ATTRIBUTES
--
autoIncrement :: ObjectStore -> Boolean
autoIncrement =
_autoIncrement
foreign import clear :: IDBObjectStore -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION) Unit
indexNames :: ObjectStore -> Array String
indexNames =
_indexNames
foreign import _count :: forall eff. Fn2 IDBObjectStore (Nullable IDBKeyRange) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Int)
count :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Int
count store range =
Fn.runFn2 _count store (toNullable range)
keyPath :: ObjectStore -> Array String
keyPath =
_keyPath
foreign import _createIndex :: forall eff. Fn4 IDBObjectStore String (Array String) { unique :: Boolean, multiEntry :: Boolean } (Eff (idb :: INDEXED_DB, exception :: EXCEPTION) IDBIndex)
createIndex :: forall eff. IDBObjectStore -> String -> (Array String) -> { unique :: Boolean, multiEntry :: Boolean } -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION) IDBIndex
createIndex store name path params =
Fn.runFn4 _createIndex store name path params
name :: ObjectStore -> String
name =
_name
foreign import _delete :: forall eff. Fn2 IDBObjectStore (Nullable IDBKeyRange) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
delete :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
delete store range =
Fn.runFn2 _delete store (toNullable range)
--------------------
-- INSTANCES
--
instance idbObjectStoreObjectStore :: IDBObjectStore ObjectStore where
add store value key =
Key <$> Fn.runFn3 _add store value (toNullable $ extractForeign <$> key)
clear =
_clear
createIndex store name' path params =
Fn.runFn4 _createIndex store name' path params
delete store range =
Fn.runFn2 _delete store range
deleteIndex store name' =
Fn.runFn2 _deleteIndex store name'
index store name' =
Fn.runFn2 _index store name'
put store value key =
Key <$> Fn.runFn3 _put store value (toNullable $ extractForeign <$> key)
foreign import _deleteIndex :: forall eff. Fn2 IDBObjectStore String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION) Unit)
deleteIndex :: forall eff. IDBObjectStore -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION) Unit
deleteIndex store name =
Fn.runFn2 _deleteIndex store name
--------------------
-- FFI
--
foreign import _add :: forall value eff. Fn3 ObjectStore value (Nullable Foreign) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Foreign)
foreign import _get :: forall a eff. Fn2 IDBObjectStore (Nullable IDBKeyRange) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Nullable a))
get :: forall a eff. IDBObjectStore -> Maybe IDBKeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Maybe a)
get store range =
toMaybe <$> Fn.runFn2 _get store (toNullable range)
foreign import _autoIncrement :: ObjectStore -> Boolean
foreign import _getKey :: forall eff. Fn2 IDBObjectStore (Nullable IDBKeyRange) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Nullable IDBKey))
getKey :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Maybe IDBKey)
getKey store range =
toMaybe <$> Fn.runFn2 _getKey store (toNullable range)
foreign import _clear :: forall eff. ObjectStore -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
foreign import _getAllKeys :: forall eff. Fn3 IDBObjectStore (Nullable IDBKeyRange) (Nullable Int) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Array IDBKey))
getAllKeys :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Maybe Int -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) (Array IDBKey)
getAllKeys store range count =
Fn.runFn3 _getAllKeys store (toNullable range) (toNullable count)
foreign import _createIndex :: forall eff. Fn4 ObjectStore String (Array String) { unique :: Boolean, multiEntry :: Boolean } (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Index)
foreign import _openCursor :: forall eff. Fn3 IDBObjectStore (Nullable IDBKeyRange) (Nullable IDBCursorDirection) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBValueCursor)
openCursor :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Maybe IDBCursorDirection -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBValueCursor
openCursor store range dir =
Fn.runFn3 _openCursor store (toNullable range) (toNullable dir)
foreign import _delete :: forall eff. Fn2 ObjectStore KeyRange (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _openKeyCursor :: forall eff. Fn3 IDBObjectStore (Nullable IDBKeyRange) (Nullable IDBCursorDirection) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKeyCursor)
openKeyCursor :: forall eff. IDBObjectStore -> Maybe IDBKeyRange -> Maybe IDBCursorDirection -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKeyCursor
openKeyCursor store range dir =
Fn.runFn3 _openKeyCursor store (toNullable range) (toNullable dir)
foreign import _deleteIndex :: forall eff. Fn2 ObjectStore String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit)
foreign import _index :: forall eff. Fn2 IDBObjectStore String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION) IDBIndex)
index :: forall eff. IDBObjectStore -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION) IDBIndex
index store name =
Fn.runFn2 _index store name
foreign import _index :: forall eff. Fn2 ObjectStore String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Index)
foreign import indexNames :: IDBObjectStore -> Array String
foreign import _indexNames :: ObjectStore -> Array String
foreign import keyPath :: IDBObjectStore -> Array String
foreign import _keyPath :: ObjectStore -> Array String
foreign import name :: IDBObjectStore -> String
foreign import _name :: ObjectStore -> String
foreign import _put :: forall value eff. Fn3 IDBObjectStore value (Nullable IDBKey) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey)
put :: forall value eff. IDBObjectStore -> value -> Maybe IDBKey -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBKey
put store value mkey =
Fn.runFn3 _put store value (toNullable mkey)
foreign import _put :: forall value eff. Fn3 ObjectStore value (Nullable Foreign) (Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Foreign)

View File

@ -1,8 +1,4 @@
const Maybe = require('Data.Maybe');
const Core = require('Database.IndexedDB.Core');
exports.abort = function abort(tx) {
exports._abort = function _abort(tx) {
return function eff() {
try {
tx.abort();
@ -12,20 +8,20 @@ exports.abort = function abort(tx) {
};
};
exports.error = function error(tx) {
exports._error = function _error(tx) {
return tx.error == null
? Maybe.Nothing()
: Maybe.Just(new Error(tx.error.name));
? null
: new Error(tx.error.name);
};
exports.mode = function mode(tx) {
exports._mode = function _mode(ReadOnly, ReadWrite, VersionChange, tx) {
if (tx.mode === 'readwrite') {
return Core.ReadWrite();
return ReadWrite;
} else if (tx.mode === 'versionchange') {
return Core.VersionChange();
return VersionChange;
}
return Core.ReadOnly();
return ReadOnly;
};
exports._objectStore = function _objectStore(tx, name) {

View File

@ -1,27 +1,63 @@
module Database.IndexedDB.IDBTransaction where
module Database.IndexedDB.IDBTransaction
(class IDBTransaction, abort, objectStore
, error
, mode
) where
import Prelude
import Prelude (Unit, (>>>))
import Control.Monad.Aff(Aff)
import Control.Monad.Eff(Eff)
import Control.Monad.Eff.Exception(EXCEPTION, Error)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried(Fn2)
import Data.Maybe(Maybe)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Exception (EXCEPTION, Error)
import Data.Function.Uncurried as Fn
import Data.Function.Uncurried (Fn2, Fn4)
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, toMaybe)
import Database.IndexedDB.Core
import Database.IndexedDB.Core (INDEXED_DB, ObjectStore, Transaction, TransactionMode(..))
foreign import abort :: forall eff. IDBTransaction -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
--------------------
-- INTERFACES
--
class IDBTransaction tx where
abort :: forall eff. tx -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
objectStore :: forall eff. tx -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore
foreign import _objectStore :: forall eff. Fn2 IDBTransaction String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore)
objectStore :: forall eff. IDBTransaction -> String -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) IDBObjectStore
objectStore tx name =
Fn.runFn2 _objectStore tx name
--------------------
-- ATTRIBUTES
--
error :: Transaction -> Maybe Error
error =
_error >>> toMaybe
foreign import mode :: IDBTransaction -> IDBTransactionMode
mode :: Transaction -> TransactionMode
mode =
Fn.runFn4 _mode ReadOnly ReadWrite VersionChange
foreign import error :: IDBTransaction -> Maybe Error
--------------------
-- INSTANCES
--
instance idbTransactionTransaction :: IDBTransaction Transaction where
objectStore tx name =
Fn.runFn2 _objectStore tx name
abort =
_abort
--------------------
-- FFI
--
foreign import _abort :: forall tx eff. tx -> Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
foreign import _error :: Transaction -> (Nullable Error)
foreign import _mode :: Fn4 TransactionMode TransactionMode TransactionMode Transaction TransactionMode
foreign import _objectStore :: forall tx eff. Fn2 tx String (Eff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) ObjectStore)