module Wire.PropertyStore.Cassandra where

import Cassandra
import Data.Id
import Imports
import Polysemy
import Polysemy.Embed
import Wire.API.Properties
import Wire.PropertyStore

interpretPropertyStoreCassandra :: (Member (Embed IO) r) => ClientState -> InterpreterFor PropertyStore r
interpretPropertyStoreCassandra :: forall (r :: EffectRow).
Member (Embed IO) r =>
ClientState -> InterpreterFor PropertyStore r
interpretPropertyStoreCassandra ClientState
casClient =
  (forall (rInitial :: EffectRow) x.
 PropertyStore (Sem rInitial) x -> Sem r x)
-> Sem (PropertyStore : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall (rInitial :: EffectRow) x.
  PropertyStore (Sem rInitial) x -> Sem r x)
 -> Sem (PropertyStore : r) a -> Sem r a)
-> (forall (rInitial :: EffectRow) x.
    PropertyStore (Sem rInitial) x -> Sem r x)
-> Sem (PropertyStore : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$
    (forall x. Client x -> IO x) -> Sem (Embed Client : r) x -> Sem r x
forall (m1 :: * -> *) (m2 :: * -> *) (r :: EffectRow) a.
Member (Embed m2) r =>
(forall x. m1 x -> m2 x) -> Sem (Embed m1 : r) a -> Sem r a
runEmbedded (forall (m :: * -> *) a. MonadIO m => ClientState -> Client a -> m a
runClient @IO ClientState
casClient) (Sem (Embed Client : r) x -> Sem r x)
-> (PropertyStore (Sem rInitial) x -> Sem (Embed Client : r) x)
-> PropertyStore (Sem rInitial) x
-> Sem r x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client x -> Sem (Embed Client : r) x
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (Client x -> Sem (Embed Client : r) x)
-> (PropertyStore (Sem rInitial) x -> Client x)
-> PropertyStore (Sem rInitial) x
-> Sem (Embed Client : r) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
      InsertProperty UserId
u PropertyKey
k RawPropertyValue
v -> UserId -> PropertyKey -> RawPropertyValue -> Client ()
forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> RawPropertyValue -> m ()
insertPropertyImpl UserId
u PropertyKey
k RawPropertyValue
v
      LookupProperty UserId
u PropertyKey
k -> UserId -> PropertyKey -> Client (Maybe RawPropertyValue)
forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> m (Maybe RawPropertyValue)
lookupPropertyImpl UserId
u PropertyKey
k
      CountProperties UserId
u -> UserId -> Client Int
forall (m :: * -> *). MonadClient m => UserId -> m Int
countPropertiesImpl UserId
u
      DeleteProperty UserId
u PropertyKey
k -> UserId -> PropertyKey -> Client ()
forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> m ()
deletePropertyImpl UserId
u PropertyKey
k
      ClearProperties UserId
u -> UserId -> Client ()
forall (m :: * -> *). MonadClient m => UserId -> m ()
clearPropertieImpl UserId
u
      GetPropertyKeys UserId
u -> UserId -> Client [PropertyKey]
forall (m :: * -> *). MonadClient m => UserId -> m [PropertyKey]
lookupPropertyKeyImpl UserId
u
      GetAllProperties UserId
u -> UserId -> Client [(PropertyKey, RawPropertyValue)]
forall (m :: * -> *).
MonadClient m =>
UserId -> m [(PropertyKey, RawPropertyValue)]
getAllPropertiesImpl UserId
u

insertPropertyImpl ::
  (MonadClient m) =>
  UserId ->
  PropertyKey ->
  RawPropertyValue ->
  m ()
insertPropertyImpl :: forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> RawPropertyValue -> m ()
insertPropertyImpl UserId
u PropertyKey
k RawPropertyValue
v =
  RetrySettings -> m () -> m ()
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x5 (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ PrepQuery W (UserId, PropertyKey, RawPropertyValue) ()
-> QueryParams (UserId, PropertyKey, RawPropertyValue) -> m ()
forall (m :: * -> *) a (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, RunQ q) =>
q W a () -> QueryParams a -> m ()
write PrepQuery W (UserId, PropertyKey, RawPropertyValue) ()
propertyInsert (Consistency
-> (UserId, PropertyKey, RawPropertyValue)
-> QueryParams (UserId, PropertyKey, RawPropertyValue)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId
u, PropertyKey
k, RawPropertyValue
v))

deletePropertyImpl :: (MonadClient m) => UserId -> PropertyKey -> m ()
deletePropertyImpl :: forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> m ()
deletePropertyImpl UserId
u PropertyKey
k = RetrySettings -> m () -> m ()
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x5 (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ PrepQuery W (UserId, PropertyKey) ()
-> QueryParams (UserId, PropertyKey) -> m ()
forall (m :: * -> *) a (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, RunQ q) =>
q W a () -> QueryParams a -> m ()
write PrepQuery W (UserId, PropertyKey) ()
propertyDelete (Consistency
-> (UserId, PropertyKey) -> QueryParams (UserId, PropertyKey)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId
u, PropertyKey
k))

clearPropertieImpl :: (MonadClient m) => UserId -> m ()
clearPropertieImpl :: forall (m :: * -> *). MonadClient m => UserId -> m ()
clearPropertieImpl UserId
u = RetrySettings -> m () -> m ()
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x5 (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ PrepQuery W (Identity UserId) ()
-> QueryParams (Identity UserId) -> m ()
forall (m :: * -> *) a (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, RunQ q) =>
q W a () -> QueryParams a -> m ()
write PrepQuery W (Identity UserId) ()
propertyReset (Consistency -> Identity UserId -> QueryParams (Identity UserId)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId -> Identity UserId
forall a. a -> Identity a
Identity UserId
u))

lookupPropertyImpl :: (MonadClient m) => UserId -> PropertyKey -> m (Maybe RawPropertyValue)
lookupPropertyImpl :: forall (m :: * -> *).
MonadClient m =>
UserId -> PropertyKey -> m (Maybe RawPropertyValue)
lookupPropertyImpl UserId
u PropertyKey
k =
  (Identity RawPropertyValue -> RawPropertyValue)
-> Maybe (Identity RawPropertyValue) -> Maybe RawPropertyValue
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Identity RawPropertyValue -> RawPropertyValue
forall a. Identity a -> a
runIdentity
    (Maybe (Identity RawPropertyValue) -> Maybe RawPropertyValue)
-> m (Maybe (Identity RawPropertyValue))
-> m (Maybe RawPropertyValue)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RetrySettings
-> m (Maybe (Identity RawPropertyValue))
-> m (Maybe (Identity RawPropertyValue))
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x1 (PrepQuery R (UserId, PropertyKey) (Identity RawPropertyValue)
-> QueryParams (UserId, PropertyKey)
-> m (Maybe (Identity RawPropertyValue))
forall (m :: * -> *) a b (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, Tuple b, RunQ q) =>
q R a b -> QueryParams a -> m (Maybe b)
query1 PrepQuery R (UserId, PropertyKey) (Identity RawPropertyValue)
propertySelect (Consistency
-> (UserId, PropertyKey) -> QueryParams (UserId, PropertyKey)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId
u, PropertyKey
k)))

lookupPropertyKeyImpl :: (MonadClient m) => UserId -> m [PropertyKey]
lookupPropertyKeyImpl :: forall (m :: * -> *). MonadClient m => UserId -> m [PropertyKey]
lookupPropertyKeyImpl UserId
u =
  (Identity PropertyKey -> PropertyKey)
-> [Identity PropertyKey] -> [PropertyKey]
forall a b. (a -> b) -> [a] -> [b]
map Identity PropertyKey -> PropertyKey
forall a. Identity a -> a
runIdentity
    ([Identity PropertyKey] -> [PropertyKey])
-> m [Identity PropertyKey] -> m [PropertyKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RetrySettings
-> m [Identity PropertyKey] -> m [Identity PropertyKey]
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x1 (PrepQuery R (Identity UserId) (Identity PropertyKey)
-> QueryParams (Identity UserId) -> m [Identity PropertyKey]
forall (m :: * -> *) a b (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, Tuple b, RunQ q) =>
q R a b -> QueryParams a -> m [b]
query PrepQuery R (Identity UserId) (Identity PropertyKey)
propertyKeysSelect (Consistency -> Identity UserId -> QueryParams (Identity UserId)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId -> Identity UserId
forall a. a -> Identity a
Identity UserId
u)))

countPropertiesImpl :: (MonadClient m) => UserId -> m Int
countPropertiesImpl :: forall (m :: * -> *). MonadClient m => UserId -> m Int
countPropertiesImpl UserId
u = do
  Int -> (Identity Int64 -> Int) -> Maybe (Identity Int64) -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 Identity Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Maybe (Identity Int64) -> Int)
-> m (Maybe (Identity Int64)) -> m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RetrySettings
-> m (Maybe (Identity Int64)) -> m (Maybe (Identity Int64))
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x1 (PrepQuery R (Identity UserId) (Identity Int64)
-> QueryParams (Identity UserId) -> m (Maybe (Identity Int64))
forall (m :: * -> *) a b (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, Tuple b, RunQ q) =>
q R a b -> QueryParams a -> m (Maybe b)
query1 PrepQuery R (Identity UserId) (Identity Int64)
propertyCount (Consistency -> Identity UserId -> QueryParams (Identity UserId)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId -> Identity UserId
forall a. a -> Identity a
Identity UserId
u)))

getAllPropertiesImpl :: (MonadClient m) => UserId -> m [(PropertyKey, RawPropertyValue)]
getAllPropertiesImpl :: forall (m :: * -> *).
MonadClient m =>
UserId -> m [(PropertyKey, RawPropertyValue)]
getAllPropertiesImpl UserId
u =
  RetrySettings
-> m [(PropertyKey, RawPropertyValue)]
-> m [(PropertyKey, RawPropertyValue)]
forall (m :: * -> *) a.
MonadClient m =>
RetrySettings -> m a -> m a
retry RetrySettings
x1 (PrepQuery R (Identity UserId) (PropertyKey, RawPropertyValue)
-> QueryParams (Identity UserId)
-> m [(PropertyKey, RawPropertyValue)]
forall (m :: * -> *) a b (q :: * -> * -> * -> *).
(MonadClient m, Tuple a, Tuple b, RunQ q) =>
q R a b -> QueryParams a -> m [b]
query PrepQuery R (Identity UserId) (PropertyKey, RawPropertyValue)
propertyKeysValuesSelect (Consistency -> Identity UserId -> QueryParams (Identity UserId)
forall a. Consistency -> a -> QueryParams a
params Consistency
LocalQuorum (UserId -> Identity UserId
forall a. a -> Identity a
Identity UserId
u)))

-------------------------------------------------------------------------------
-- Queries

propertyInsert :: PrepQuery W (UserId, PropertyKey, RawPropertyValue) ()
propertyInsert :: PrepQuery W (UserId, PropertyKey, RawPropertyValue) ()
propertyInsert = PrepQuery W (UserId, PropertyKey, RawPropertyValue) ()
"INSERT INTO properties (user, key, value) VALUES (?, ?, ?)"

propertyDelete :: PrepQuery W (UserId, PropertyKey) ()
propertyDelete :: PrepQuery W (UserId, PropertyKey) ()
propertyDelete = PrepQuery W (UserId, PropertyKey) ()
"DELETE FROM properties where user = ? and key = ?"

propertyReset :: PrepQuery W (Identity UserId) ()
propertyReset :: PrepQuery W (Identity UserId) ()
propertyReset = PrepQuery W (Identity UserId) ()
"DELETE FROM properties where user = ?"

propertySelect :: PrepQuery R (UserId, PropertyKey) (Identity RawPropertyValue)
propertySelect :: PrepQuery R (UserId, PropertyKey) (Identity RawPropertyValue)
propertySelect = PrepQuery R (UserId, PropertyKey) (Identity RawPropertyValue)
"SELECT value FROM properties where user = ? and key = ?"

propertyKeysSelect :: PrepQuery R (Identity UserId) (Identity PropertyKey)
propertyKeysSelect :: PrepQuery R (Identity UserId) (Identity PropertyKey)
propertyKeysSelect = PrepQuery R (Identity UserId) (Identity PropertyKey)
"SELECT key FROM properties where user = ?"

propertyKeysValuesSelect :: PrepQuery R (Identity UserId) (PropertyKey, RawPropertyValue)
propertyKeysValuesSelect :: PrepQuery R (Identity UserId) (PropertyKey, RawPropertyValue)
propertyKeysValuesSelect = PrepQuery R (Identity UserId) (PropertyKey, RawPropertyValue)
"SELECT key, value FROM properties where user = ?"

propertyCount :: PrepQuery R (Identity UserId) (Identity Int64)
propertyCount :: PrepQuery R (Identity UserId) (Identity Int64)
propertyCount = PrepQuery R (Identity UserId) (Identity Int64)
"SELECT COUNT(*) FROM properties where user = ?"