packages feed

rfc-redis (empty) → 0.0.0.1

raw patch · 6 files changed

+272/−0 lines, 6 filesdep +basedep +hedisdep +rfc-env

Dependencies added: base, hedis, rfc-env, rfc-prelude, time

Files

+ LICENSE view
@@ -0,0 +1,7 @@+Copyright Robert Fischer (c) 2018++Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,7 @@+RFC Redis+=============++These are the Robert Fischer Commons extensions to the [hedis](https://hackage.haskell.org/package/hedis)+library for [Redis](https://redis.io).  The major difference is making the Redis monad a lot more friendly+for monad transformer stacks, some naming aliases to bring the names in line with `rfc-psql`, and throwing+exceptions when they occur instead of returning them.
+ package.common.yaml view
@@ -0,0 +1,103 @@+- &defaults+  author: Robert Fischer+  maintainer: smokejumperit+rfc@gmail.com+  license: MIT+  license-file: LICENSE++  flags:+    production:+      description: If true, disables failing on warnings and enables aggressive optimizations.+      manual: true+      default: false++  library:+    source-dirs:+      - './src'++  extra-source-files:+    - LICENSE+    - README.md+    - package.yaml+    - package.common.yaml++  default-extensions:+    - ApplicativeDo+    - BangPatterns+    - ConstraintKinds+    - DataKinds+    - DefaultSignatures+    - DeriveFoldable+    - DeriveFunctor+    - DeriveGeneric+    - DeriveLift+    - DeriveTraversable+    - ExistentialQuantification+    - FlexibleContexts+    - FlexibleInstances+    - FunctionalDependencies+    - GADTs+    - GeneralizedNewtypeDeriving+    - InstanceSigs+    - KindSignatures+    - LambdaCase+    - MultiParamTypeClasses+    - MultiWayIf+    - NamedFieldPuns+    - PatternSynonyms+    - RankNTypes+    - ScopedTypeVariables+    - StandaloneDeriving+    - TupleSections+    - TypeApplications+    - TypeFamilies+    - TypeFamilyDependencies+    - TypeOperators  +    - RebindableSyntax+    - MonadFailDesugaring+    - DisambiguateRecordFields++  ghc-options: +    - -Wall+    - -Wcompat +    - -Wincomplete-record-updates +    - -Wincomplete-uni-patterns +    - -Wredundant-constraints +    - -fno-max-relevant-binds +    - -fprint-potential-instances +    - -fprint-explicit-foralls+    - -Wno-missing-monadfail-instances+    - -fno-warn-name-shadowing +    - -fno-warn-tabs +    - -fno-warn-orphans+    - -Wnoncanonical-monad-instances +    - -Wall-missed-specialisations+    - -Wnoncanonical-monadfail-instances +    - -Wimplicit-prelude +    - -Wmissing-exported-signatures +    - -Widentities+    - -j++  when:+  - condition: flag(production)+    then:+      ghc-options:+        - -feager-blackholing +        - -funbox-strict-fields +        - -fstatic-argument-transformation+        - -flate-dmd-anal +        - -fexpose-all-unfoldings +        - -fspecialise-aggressively +        - -fexcess-precision +        - -fmax-simplifier-iterations=15+        - -fsimplifier-phases=4+        - -fstrictness-before=3+        - -funfolding-keeness-factor=1.5+        - -funfolding-use-threshold=150+    else:+      cpp-options:+        - -DDEVELOPMENT+      ghc-options:+        - -freverse-errors+        - -Werror +        - -dcore-lint +        - -dcmm-lint
+ package.yaml view
@@ -0,0 +1,21 @@+name: rfc-redis+version: 0.0.0.1+synopsis: The Redis extensions from the Robert Fischer Commons.+description: >+  Various capabilities supporting @Redis@/@Hedis@ development, including some simplification+  of the interface.+category: redis+github: RobertFischer/rfc/rfc-redis+author: Robert Fischer+license: MIT++_common: !include package.common.yaml++<<: *defaults++dependencies:+  - rfc-prelude +  - rfc-env+  - base >= 4.10 && < 5+  - hedis >= 0.10+  - time >= 1.8
+ rfc-redis.cabal view
@@ -0,0 +1,56 @@+-- This file has been generated from package.yaml by hpack version 0.28.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: 3dad687364e92d4674ca73e95662f4805fa86acadb200d63a957f4ef0ebf02a0++name:           rfc-redis+version:        0.0.0.1+synopsis:       The Redis extensions from the Robert Fischer Commons.+description:    Various capabilities supporting @Redis@/@Hedis@ development, including some simplification of the interface.+category:       redis+homepage:       https://github.com/RobertFischer/rfc#readme+bug-reports:    https://github.com/RobertFischer/rfc/issues+author:         Robert Fischer+maintainer:     smokejumperit+rfc@gmail.com+license:        MIT+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10+extra-source-files:+    LICENSE+    package.common.yaml+    package.yaml+    README.md++source-repository head+  type: git+  location: https://github.com/RobertFischer/rfc+  subdir: rfc-redis++flag production+  description: If true, disables failing on warnings and enables aggressive optimizations.+  manual: True+  default: False++library+  exposed-modules:+      RFC.Redis+  other-modules:+      Paths_rfc_redis+  hs-source-dirs:+      ./src+  default-extensions: ApplicativeDo BangPatterns ConstraintKinds DataKinds DefaultSignatures DeriveFoldable DeriveFunctor DeriveGeneric DeriveLift DeriveTraversable ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns PatternSynonyms RankNTypes ScopedTypeVariables StandaloneDeriving TupleSections TypeApplications TypeFamilies TypeFamilyDependencies TypeOperators RebindableSyntax MonadFailDesugaring DisambiguateRecordFields+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fno-max-relevant-binds -fprint-potential-instances -fprint-explicit-foralls -Wno-missing-monadfail-instances -fno-warn-name-shadowing -fno-warn-tabs -fno-warn-orphans -Wnoncanonical-monad-instances -Wall-missed-specialisations -Wnoncanonical-monadfail-instances -Wimplicit-prelude -Wmissing-exported-signatures -Widentities -j+  build-depends:+      base >=4.10 && <5+    , hedis >=0.10+    , rfc-env+    , rfc-prelude+    , time >=1.8+  if flag(production)+    ghc-options: -feager-blackholing -funbox-strict-fields -fstatic-argument-transformation -flate-dmd-anal -fexpose-all-unfoldings -fspecialise-aggressively -fexcess-precision -fmax-simplifier-iterations=15 -fsimplifier-phases=4 -fstrictness-before=3 -funfolding-keeness-factor=1.5 -funfolding-use-threshold=150+  else+    ghc-options: -freverse-errors -Werror -dcore-lint -dcmm-lint+    cpp-options: -DDEVELOPMENT+  default-language: Haskell2010
+ src/RFC/Redis.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE NoImplicitPrelude #-}+++module RFC.Redis+  ( createConnectionPool+  , ConnectionPool+  , HasRedis(..)+  , RedisException(..)+  , get+  , setex+  ) where++import           Data.Time.Clock ( nominalDay )+import qualified Database.Redis  as R+import           RFC.Env         as Env+import           RFC.Prelude++type ConnectionPool = R.Connection++newtype RedisException = RedisException R.Reply deriving (Typeable, Show)+instance Exception RedisException++class (MonadIO m) => HasRedis m where+  getRedisPool :: m ConnectionPool++  runRedis :: R.Redis a -> m a+  runRedis r = do+    conn <- getRedisPool+    liftIO $ R.runRedis conn r+  {-# INLINEABLE runRedis #-}++instance DefConfig R.ConnectInfo where+  defConfig = R.defaultConnectInfo+  {-# INLINE defConfig #-}++instance FromEnv R.ConnectInfo where+  fromEnv = R.ConnInfo+    <$> envWithDevDefault "REDIS_HOST" (R.connectHost defConfig)+    <*> envWithDefault "REDIS_PORT" (R.connectPort defConfig)+    <*> envWithDefault "REDIS_AUTH" (R.connectAuth defConfig)+    <*> envWithDefault "REDIS_DB" (R.connectDatabase defConfig)+    <*> envWithDefault "REDIS_MAX_CONNS" (R.connectMaxConnections defConfig)+    <*> envWithDefault "REDIS_IDLE_TIMEOUT" (R.connectMaxIdleTime defConfig)+    <*> envWithDefault "REDIS_CONN_TIMEOUT" (Just (nominalDay/24)) -- No timeout by default!+    <*> return Nothing+  {-# INLINEABLE fromEnv #-}++createConnectionPool :: (MonadUnliftIO m, MonadFail m) => m ConnectionPool+createConnectionPool = do+  connInfoResult <- liftIO decodeEnv+  case connInfoResult of+    Left err       -> fail $ "Could not configure Redis connection: " <> err+    Right connInfo -> liftIO $ R.connect connInfo+{-# INLINEABLE createConnectionPool #-}++unpack :: (MonadUnliftIO m) => Either R.Reply a -> m a+unpack (Left reply) = throwIO $ RedisException reply+unpack (Right it)   = return it+{-# INLINE unpack #-}++get :: (HasRedis m, ToText tIn, FromText tOut) => tIn -> m (Maybe tOut)+get key = do+  result <- runRedis . R.get $ toUTF8 key+  maybeResult <- liftIO $ unpack result+  return $ do+    bsResult <- maybeResult+    fromUTF8 bsResult+{-# INLINEABLE get #-}++setex :: (HasRedis m, ToText key, ToText value, TimeUnit expiry) => key -> value -> expiry -> m ()+setex key value expiry = do+    result <- runRedis $ R.setex (toUTF8 key) milliseconds (toUTF8 value)+    _ <- liftIO $ unpack result+    return ()+  where+    milliseconds = fromIntegral ( (convertUnit expiry)::Millisecond )+{-# INLINEABLE setex #-}