mergeful-persistent-0.0.0.0: Support for using mergeful from persistent-based databases

Safe HaskellNone
LanguageHaskell2010

Data.Mergeful.Persistent

Contents

Synopsis

Client side

clientMakeSyncRequestQuery Source #

Arguments

:: (Ord sid, PersistEntity record, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record (Maybe sid)

The server id field

-> EntityField record (Maybe ServerTime)

The server time field

-> EntityField record Bool

The changed flag

-> EntityField record Bool

The deleted flag

-> (record -> a)

How to read an unsynced client item

-> (record -> (sid, Timed a))

How to read a synced client item that's been changed

-> (record -> (sid, ServerTime))

How to read a synced or deleted client item

-> SqlPersistT m (SyncRequest (Key record) sid a) 

Make a sync request

clientMergeSyncResponseQuery Source #

Arguments

:: (Ord sid, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record (Maybe sid)

The server id field

-> EntityField record (Maybe ServerTime)

The server time field

-> EntityField record Bool

The changed flag

-> EntityField record Bool

The deleted flag

-> (sid -> Timed a -> record)

How to build a synced record from a server id and a timed item

-> (record -> (sid, Timed a))

How to read a synced record back into a server id and a timed item

-> (a -> [Update record])

How to update a row with new data

You only need to perform the updates that have anything to do with the data to sync. The housekeeping updates are already taken care of.

-> ItemMergeStrategy a

The merge strategy.

-> SyncResponse (Key record) sid a

The sync response to merge

-> SqlPersistT m () 

Raw processors

clientSyncProcessor Source #

Arguments

:: (Ord sid, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record (Maybe sid)

The server id field

-> EntityField record (Maybe ServerTime)

The server time field

-> EntityField record Bool

The changed flag

-> EntityField record Bool

The deleted flag

-> (sid -> Timed a -> record)

How to build a synced record from a server id and a timed item

-> (record -> (sid, Timed a))

How to read a synced record back into a server id and a timed item

-> (a -> [Update record])

How to update a row with new data

You only need to perform the updates that have anything to do with the data to sync. The housekeeping updates are already taken care of.

-> ClientSyncProcessor (Key record) sid a (SqlPersistT m) 

Merging

data ItemMergeStrategy a #

A strategy to merge conflicts for item synchronisation

Constructors

ItemMergeStrategy 

Fields

Instances
Generic (ItemMergeStrategy a) 
Instance details

Defined in Data.Mergeful.Item

Associated Types

type Rep (ItemMergeStrategy a) :: Type -> Type #

type Rep (ItemMergeStrategy a) 
Instance details

Defined in Data.Mergeful.Item

type Rep (ItemMergeStrategy a) = D1 (MetaData "ItemMergeStrategy" "Data.Mergeful.Item" "mergeful-0.2.0.0-Czn7HU9ZrLaB0R8xfAleR6" False) (C1 (MetaCons "ItemMergeStrategy" PrefixI True) (S1 (MetaSel (Just "itemMergeStrategyMergeChangeConflict") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (a -> a -> ChangeConflictResolution a)) :*: (S1 (MetaSel (Just "itemMergeStrategyMergeClientDeletedConflict") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (a -> ClientDeletedConflictResolution)) :*: S1 (MetaSel (Just "itemMergeStrategyMergeServerDeletedConflict") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (a -> ServerDeletedConflictResolution)))))

mergeFromServerStrategy :: ItemMergeStrategy a #

A merge strategy that takes whatever the server gave the client.

Pro: Clients will converge on the same value.

Con: Conflicting updates will be lost.

mergeFromClientStrategy :: ItemMergeStrategy a #

A merge strategy that keeps whatever the client had.

Pro: does not lose data

Con: Clients will diverge when a conflict occurs

mergeUsingCRDTStrategy :: (a -> a -> a) -> ItemMergeStrategy a #

A merge strategy that uses a CRDT merging function to merge items.

In case of other-than-change conflicts, this will be the same as the mergeFromServerStrategy strategy. If this is not what you want, create your own ItemMergeStrategy manually.

Server side

serverProcessSyncQuery Source #

Arguments

:: (PersistEntity record, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record ServerTime

The server time field

-> [Filter record]

The filters to select the relevant records

Use this if you want per-user syncing

-> (record -> Timed a)

How to load an item from the database

-> (a -> record)

How to add an item in the database with initial server time

-> (a -> [Update record])

How to update a record given new data

-> SyncRequest cid (Key record) a

A sync request

-> SqlPersistT m (SyncResponse cid (Key record) a) 

Process a sync request on the server side

serverProcessSyncWithCustomIdQuery Source #

Arguments

:: (Ord sid, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record sid

The custom id field

-> SqlPersistT m sid

The generator to generate the custom id field

-> EntityField record ServerTime

The server time field

-> [Filter record]

The filters to select the relevant records

Use this if you want per-user syncing

-> (record -> (sid, Timed a))

How to load an item from the database

-> (sid -> a -> record)

How to add an item in the database with initial server time

-> (a -> [Update record])

How to update a record given new data

-> SyncRequest cid sid a

A sync request

-> SqlPersistT m (SyncResponse cid sid a) 

Process a sync request on the server side with a custom id field

You can use this function if you want to use a UUID as your id instead of the sqlkey of the item.

Raw processors

serverSyncProcessor Source #

Arguments

:: (PersistEntity record, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record ServerTime

The server time field

-> [Filter record]

The filters to select the relevant records

Use this if you want per-user syncing

-> (record -> Timed a)

How to load an item from the database

-> (a -> record)

How to add an item in the database with initial server time

-> (a -> [Update record])

How to update a record given new data

-> ServerSyncProcessor cid (Key record) a (SqlPersistT m) 

serverSyncWithCustomIdProcessor Source #

Arguments

:: (Ord sid, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) 
=> EntityField record sid

The custom id field

-> SqlPersistT m sid

The generator to generate the custom id field

-> EntityField record ServerTime

The server time field

-> [Filter record]

The filters to select the relevant records

Use this if you want per-user syncing

-> (record -> (sid, Timed a))

How to load an item from the database

-> (sid -> a -> record)

How to add an item in the database with initialServerTime

-> (a -> [Update record])

How to update a record given new data

-> ServerSyncProcessor cid sid a (SqlPersistT m) 

Utils

Client side

setupClientQuery :: forall record sid a m. (PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) => (a -> record) -> (sid -> Timed a -> record) -> (sid -> Timed a -> record) -> (sid -> ServerTime -> record) -> ClientStore (Key record) sid a -> SqlPersistT m () Source #

Set up a client store.

You shouldn't need this.

clientGetStoreQuery :: forall record sid a m. (Ord sid, PersistEntity record, PersistField sid, PersistEntityBackend record ~ SqlBackend, ToBackendKey SqlBackend record, MonadIO m) => EntityField record (Maybe sid) -> EntityField record (Maybe ServerTime) -> EntityField record Bool -> EntityField record Bool -> (record -> a) -> (record -> (sid, Timed a)) -> (record -> (sid, ServerTime)) -> SqlPersistT m (ClientStore (Key record) sid a) Source #

Get the client store.

You shouldn't need this.

Server side

setupServerQuery :: forall sid record a. (PersistEntity record, PersistEntityBackend record ~ SqlBackend) => (sid -> Timed a -> Entity record) -> ServerStore sid a -> SqlPersistT IO () Source #

Set up the server store

You shouldn't need this.

serverGetStoreQuery :: (Ord sid, PersistEntity record, PersistEntityBackend record ~ SqlBackend) => (Entity record -> (sid, Timed a)) -> SqlPersistT IO (ServerStore sid a) Source #

Get the server store

You shouldn't need this.

Orphan instances