Skip to content
Snippets Groups Projects
Commit f0ec4320 authored by Ramakrishnan Muthukrishnan's avatar Ramakrishnan Muthukrishnan
Browse files

refactor code to reduce duplication of the code

Type class instances for `redeemVoucher` function has a lot of
code duplication. This change refactors them to reuse the main
logic of the code and abstract out parts that differ between
instances.
parent 9b048546
No related branches found
No related tags found
1 merge request!26Initial implementation of Persistence using sqlite
...@@ -26,6 +26,9 @@ import qualified Database.SQLite.Simple as Sqlite ...@@ -26,6 +26,9 @@ import qualified Database.SQLite.Simple as Sqlite
import Database.SQLite.Simple.FromRow import Database.SQLite.Simple.FromRow
( FromRow(fromRow) ( FromRow(fromRow)
) )
import Data.Maybe
( listToMaybe
)
-- | A voucher is a unique identifier which can be associated with a payment. -- | A voucher is a unique identifier which can be associated with a payment.
-- A paid voucher can be redeemed for ZKAPs which can themselves be exchanged -- A paid voucher can be redeemed for ZKAPs which can themselves be exchanged
...@@ -95,32 +98,28 @@ instance VoucherDatabase VoucherDatabaseState where ...@@ -95,32 +98,28 @@ instance VoucherDatabase VoucherDatabaseState where
redeemVoucher MemoryDB{ paid = paid, redeemed = redeemed } voucher fingerprint = do redeemVoucher MemoryDB{ paid = paid, redeemed = redeemed } voucher fingerprint = do
unpaid <- Set.notMember voucher <$> readIORef paid unpaid <- Set.notMember voucher <$> readIORef paid
existingFingerprint <- Map.lookup voucher <$> readIORef redeemed existingFingerprint <- Map.lookup voucher <$> readIORef redeemed
case (unpaid, existingFingerprint) of let insertFn voucher fingerprint = modifyIORef redeemed (Map.insert voucher fingerprint)
(True, _) -> redeemVoucherHelper (unpaid, existingFingerprint) voucher fingerprint insertFn
return $ Left NotPaid
(False, Nothing) -> do
modifyIORef redeemed (Map.insert voucher fingerprint)
return $ Right ()
(False, Just fingerprint') ->
if fingerprint == fingerprint' then
return $ Right ()
else
return $ Left AlreadyRedeemed
redeemVoucher SQLiteDB { conn = conn } voucher fingerprint = do redeemVoucher SQLiteDB { conn = conn } voucher fingerprint = do
unpaid <- isVoucherUnpaid conn voucher unpaid <- isVoucherUnpaid conn voucher
existingFingerprint <- getVoucherFingerprint conn voucher existingFingerprint <- listToMaybe <$> getVoucherFingerprint conn voucher
case (unpaid, existingFingerprint) of let insertFn = insertVoucherAndFingerprint conn
(True, _) -> redeemVoucherHelper (unpaid, existingFingerprint) voucher fingerprint insertFn
return $ Left NotPaid
(False, []) -> do redeemVoucherHelper :: (Bool, Maybe Fingerprint) -> Voucher -> Fingerprint -> (Voucher -> Fingerprint -> IO ()) -> IO (Either RedeemError ())
insertVoucherAndFingerprint conn voucher fingerprint redeemVoucherHelper (unpaid, existingFingerprint) voucher fingerprint insertFn = do
case (unpaid, existingFingerprint) of
(True, _) ->
return $ Left NotPaid
(False, Nothing) -> do
insertFn voucher fingerprint
return $ Right ()
(False, Just fingerprint') ->
if fingerprint == fingerprint' then
return $ Right () return $ Right ()
(False, [fingerprint']) -> else
if fingerprint == fingerprint' then return $ Left AlreadyRedeemed
return $ Right ()
else
return $ Left AlreadyRedeemed
-- | Create a new, empty MemoryVoucherDatabase. -- | Create a new, empty MemoryVoucherDatabase.
memory :: IO VoucherDatabaseState memory :: IO VoucherDatabaseState
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment