{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

module IntelliMonad.Persist where

import Control.Monad.IO.Class
import Data.List (maximumBy)
import qualified Data.Set as S
import Data.Text (Text)
import Database.Persist hiding (get)
import Database.Persist.Sqlite hiding (get)
import IntelliMonad.Types
import Control.Monad.Trans.State (get)

data StatelessConf = StatelessConf

instance PersistentBackend SqliteConf where
  type Conn SqliteConf = ConnectionPool
  config :: SqliteConf
config =
    SqliteConf
      { sqlDatabase :: SessionName
sqlDatabase = SessionName
"intelli-monad.sqlite3",
        sqlPoolSize :: Int
sqlPoolSize = Int
5
      }
  setup :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
SqliteConf -> m (Maybe (Conn SqliteConf))
setup SqliteConf
p = do
    ConnectionPool
conn <- IO ConnectionPool -> m ConnectionPool
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ConnectionPool -> m ConnectionPool)
-> IO ConnectionPool -> m ConnectionPool
forall a b. (a -> b) -> a -> b
$ SqliteConf -> IO (PersistConfigPool SqliteConf)
forall c. PersistConfig c => c -> IO (PersistConfigPool c)
createPoolConfig SqliteConf
p
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO ()
-> PersistConfigPool SqliteConf
-> IO ()
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool SqliteConf
p (Migration -> ReaderT SqlBackend IO ()
forall (m :: * -> *).
MonadIO m =>
Migration -> ReaderT SqlBackend m ()
runMigration Migration
migrateAll) PersistConfigPool SqliteConf
ConnectionPool
conn
    Maybe ConnectionPool -> m (Maybe ConnectionPool)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ConnectionPool -> m (Maybe ConnectionPool))
-> Maybe ConnectionPool -> m (Maybe ConnectionPool)
forall a b. (a -> b) -> a -> b
$ ConnectionPool -> Maybe ConnectionPool
forall a. a -> Maybe a
Just ConnectionPool
conn
  initialize :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Context -> m ()
initialize Conn SqliteConf
conn Context
context = do
    Key Context
_ <- IO (Key Context) -> m (Key Context)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Key Context) -> m (Key Context))
-> IO (Key Context) -> m (Key Context)
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO (Key Context)
-> PersistConfigPool SqliteConf
-> IO (Key Context)
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) (Context -> ReaderT SqlBackend IO (Key Context)
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Key record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
record -> ReaderT SqlBackend m (Key record)
insert Context
context) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  load :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> SessionName -> m (Maybe Context)
load Conn SqliteConf
conn SessionName
sessionName = do
    ([Entity Context]
a :: [Entity Context]) <- IO [Entity Context] -> m [Entity Context]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Entity Context] -> m [Entity Context])
-> IO [Entity Context] -> m [Entity Context]
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO [Entity Context]
-> PersistConfigPool SqliteConf
-> IO [Entity Context]
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Filter Context]
-> [SelectOpt Context] -> ReaderT SqlBackend IO [Entity Context]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
selectList [EntityField Context SessionName
forall typ. (typ ~ SessionName) => EntityField Context typ
ContextSessionName EntityField Context SessionName -> SessionName -> Filter Context
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Filter v
==. SessionName
sessionName] []) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    if [Entity Context] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Entity Context]
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
      then Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Context
forall a. Maybe a
Nothing
      else Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Context -> m (Maybe Context))
-> Maybe Context -> m (Maybe Context)
forall a b. (a -> b) -> a -> b
$ Context -> Maybe Context
forall a. a -> Maybe a
Just (Context -> Maybe Context) -> Context -> Maybe Context
forall a b. (a -> b) -> a -> b
$ (Context -> Context -> Ordering) -> [Context] -> Context
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (\Context
a0 Context
a1 -> UTCTime -> UTCTime -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Context -> UTCTime
contextCreated Context
a1) (Context -> UTCTime
contextCreated Context
a0)) ([Context] -> Context) -> [Context] -> Context
forall a b. (a -> b) -> a -> b
$ (Entity Context -> Context) -> [Entity Context] -> [Context]
forall a b. (a -> b) -> [a] -> [b]
map (\(Entity Key Context
_ Context
v) -> Context
v) [Entity Context]
a

  loadByKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Key Context -> m (Maybe Context)
loadByKey Conn SqliteConf
conn Key Context
key = do
    ([Entity Context]
a :: [Entity Context]) <- IO [Entity Context] -> m [Entity Context]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Entity Context] -> m [Entity Context])
-> IO [Entity Context] -> m [Entity Context]
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO [Entity Context]
-> PersistConfigPool SqliteConf
-> IO [Entity Context]
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Filter Context]
-> [SelectOpt Context] -> ReaderT SqlBackend IO [Entity Context]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
selectList [EntityField Context (Key Context)
forall typ. (typ ~ Key Context) => EntityField Context typ
ContextId EntityField Context (Key Context) -> Key Context -> Filter Context
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Filter v
==. Key Context
key] []) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    if [Entity Context] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Entity Context]
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
      then Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Context
forall a. Maybe a
Nothing
      else Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Context -> m (Maybe Context))
-> Maybe Context -> m (Maybe Context)
forall a b. (a -> b) -> a -> b
$ Context -> Maybe Context
forall a. a -> Maybe a
Just (Context -> Maybe Context) -> Context -> Maybe Context
forall a b. (a -> b) -> a -> b
$ (Context -> Context -> Ordering) -> [Context] -> Context
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (\Context
a0 Context
a1 -> UTCTime -> UTCTime -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Context -> UTCTime
contextCreated Context
a1) (Context -> UTCTime
contextCreated Context
a0)) ([Context] -> Context) -> [Context] -> Context
forall a b. (a -> b) -> a -> b
$ (Entity Context -> Context) -> [Entity Context] -> [Context]
forall a b. (a -> b) -> [a] -> [b]
map (\(Entity Key Context
_ Context
v) -> Context
v) [Entity Context]
a

  save :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Context -> m (Maybe (Key Context))
save Conn SqliteConf
conn Context
context = do
    IO (Maybe (Key Context)) -> m (Maybe (Key Context))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Key Context)) -> m (Maybe (Key Context)))
-> IO (Maybe (Key Context)) -> m (Maybe (Key Context))
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO (Maybe (Key Context))
-> PersistConfigPool SqliteConf
-> IO (Maybe (Key Context))
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) (Key Context -> Maybe (Key Context)
forall a. a -> Maybe a
Just (Key Context -> Maybe (Key Context))
-> ReaderT SqlBackend IO (Key Context)
-> ReaderT SqlBackend IO (Maybe (Key Context))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Context -> ReaderT SqlBackend IO (Key Context)
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Key record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
record -> ReaderT SqlBackend m (Key record)
insert Context
context) PersistConfigPool SqliteConf
Conn SqliteConf
conn

  saveContents :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> [Content] -> m ()
saveContents Conn SqliteConf
conn [Content]
contents = do
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO ()
-> PersistConfigPool SqliteConf
-> IO ()
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Content] -> ReaderT SqlBackend IO ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
[record] -> ReaderT SqlBackend m ()
putMany [Content]
contents) PersistConfigPool SqliteConf
Conn SqliteConf
conn

  listSessions :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> m [SessionName]
listSessions Conn SqliteConf
conn = do
    ([Entity Context]
a :: [Entity Context]) <- IO [Entity Context] -> m [Entity Context]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Entity Context] -> m [Entity Context])
-> IO [Entity Context] -> m [Entity Context]
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO [Entity Context]
-> PersistConfigPool SqliteConf
-> IO [Entity Context]
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Filter Context]
-> [SelectOpt Context] -> ReaderT SqlBackend IO [Entity Context]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
selectList [] []) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    [SessionName] -> m [SessionName]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([SessionName] -> m [SessionName])
-> [SessionName] -> m [SessionName]
forall a b. (a -> b) -> a -> b
$ Set SessionName -> [SessionName]
forall a. Set a -> [a]
S.toList (Set SessionName -> [SessionName])
-> Set SessionName -> [SessionName]
forall a b. (a -> b) -> a -> b
$ [SessionName] -> Set SessionName
forall a. Ord a => [a] -> Set a
S.fromList ([SessionName] -> Set SessionName)
-> [SessionName] -> Set SessionName
forall a b. (a -> b) -> a -> b
$ (Entity Context -> SessionName)
-> [Entity Context] -> [SessionName]
forall a b. (a -> b) -> [a] -> [b]
map (\(Entity Key Context
_ Context
v) -> Context -> SessionName
contextSessionName Context
v) [Entity Context]
a

  deleteSession :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> SessionName -> m ()
deleteSession Conn SqliteConf
conn SessionName
sessionName = do
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO ()
-> PersistConfigPool SqliteConf
-> IO ()
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Filter Context] -> ReaderT SqlBackend IO ()
forall backend (m :: * -> *) record.
(PersistQueryWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m ()
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record] -> ReaderT SqlBackend m ()
deleteWhere [EntityField Context SessionName
forall typ. (typ ~ SessionName) => EntityField Context typ
ContextSessionName EntityField Context SessionName -> SessionName -> Filter Context
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Filter v
==. SessionName
sessionName]) PersistConfigPool SqliteConf
Conn SqliteConf
conn

  listKeys :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> m [Unique KeyValue]
listKeys Conn SqliteConf
conn = do
    ([Entity KeyValue]
a :: [Entity KeyValue]) <- IO [Entity KeyValue] -> m [Entity KeyValue]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Entity KeyValue] -> m [Entity KeyValue])
-> IO [Entity KeyValue] -> m [Entity KeyValue]
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO [Entity KeyValue]
-> PersistConfigPool SqliteConf
-> IO [Entity KeyValue]
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([Filter KeyValue]
-> [SelectOpt KeyValue] -> ReaderT SqlBackend IO [Entity KeyValue]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
selectList [] []) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    [Unique KeyValue] -> m [Unique KeyValue]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Unique KeyValue] -> m [Unique KeyValue])
-> [Unique KeyValue] -> m [Unique KeyValue]
forall a b. (a -> b) -> a -> b
$ [[Unique KeyValue]] -> [Unique KeyValue]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Unique KeyValue]] -> [Unique KeyValue])
-> [[Unique KeyValue]] -> [Unique KeyValue]
forall a b. (a -> b) -> a -> b
$ (Entity KeyValue -> [Unique KeyValue])
-> [Entity KeyValue] -> [[Unique KeyValue]]
forall a b. (a -> b) -> [a] -> [b]
map (\(Entity Key KeyValue
_ KeyValue
v) -> KeyValue -> [Unique KeyValue]
forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys KeyValue
v) [Entity KeyValue]
a
  getKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Unique KeyValue -> m (Maybe SessionName)
getKey Conn SqliteConf
conn Unique KeyValue
key = do
    (Maybe (Entity KeyValue)
a :: Maybe (Entity KeyValue)) <- IO (Maybe (Entity KeyValue)) -> m (Maybe (Entity KeyValue))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Entity KeyValue)) -> m (Maybe (Entity KeyValue)))
-> IO (Maybe (Entity KeyValue)) -> m (Maybe (Entity KeyValue))
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO (Maybe (Entity KeyValue))
-> PersistConfigPool SqliteConf
-> IO (Maybe (Entity KeyValue))
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) (Unique KeyValue -> ReaderT SqlBackend IO (Maybe (Entity KeyValue))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Unique record -> ReaderT SqlBackend m (Maybe (Entity record))
getBy Unique KeyValue
key) PersistConfigPool SqliteConf
Conn SqliteConf
conn
    case Maybe (Entity KeyValue)
a of
      Maybe (Entity KeyValue)
Nothing -> Maybe SessionName -> m (Maybe SessionName)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SessionName
forall a. Maybe a
Nothing
      Just (Entity Key KeyValue
_ KeyValue
v) -> Maybe SessionName -> m (Maybe SessionName)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe SessionName -> m (Maybe SessionName))
-> Maybe SessionName -> m (Maybe SessionName)
forall a b. (a -> b) -> a -> b
$ SessionName -> Maybe SessionName
forall a. a -> Maybe a
Just (SessionName -> Maybe SessionName)
-> SessionName -> Maybe SessionName
forall a b. (a -> b) -> a -> b
$ KeyValue -> SessionName
keyValueValue KeyValue
v
  setKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Unique KeyValue -> SessionName -> m ()
setKey Conn SqliteConf
conn (KeyName SessionName
n' SessionName
k') SessionName
value = do
    let d :: KeyValue
d = SessionName -> SessionName -> SessionName -> KeyValue
KeyValue SessionName
n' SessionName
k' SessionName
value
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO ()
-> PersistConfigPool SqliteConf
-> IO ()
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) ([KeyValue] -> ReaderT SqlBackend IO ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
[record] -> ReaderT SqlBackend m ()
putMany [Item [KeyValue]
KeyValue
d]) PersistConfigPool SqliteConf
Conn SqliteConf
conn
  deleteKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn SqliteConf -> Unique KeyValue -> m ()
deleteKey Conn SqliteConf
conn Unique KeyValue
key = do
    IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SqliteConf
-> PersistConfigBackend SqliteConf IO ()
-> PersistConfigPool SqliteConf
-> IO ()
forall c (m :: * -> *) a.
(PersistConfig c, MonadUnliftIO m) =>
c -> PersistConfigBackend c m a -> PersistConfigPool c -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
SqliteConf
-> PersistConfigBackend SqliteConf m a
-> PersistConfigPool SqliteConf
-> m a
runPool (forall p. PersistentBackend p => p
config @SqliteConf) (Unique KeyValue -> ReaderT SqlBackend IO ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Unique record -> ReaderT SqlBackend m ()
deleteBy Unique KeyValue
key) PersistConfigPool SqliteConf
Conn SqliteConf
conn

instance PersistentBackend StatelessConf where
  type Conn StatelessConf = ()
  config :: StatelessConf
config = StatelessConf
StatelessConf
  setup :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
StatelessConf -> m (Maybe (Conn StatelessConf))
setup StatelessConf
_ = Maybe (Conn StatelessConf) -> m (Maybe (Conn StatelessConf))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Conn StatelessConf) -> m (Maybe (Conn StatelessConf)))
-> Maybe (Conn StatelessConf) -> m (Maybe (Conn StatelessConf))
forall a b. (a -> b) -> a -> b
$ () -> Maybe ()
forall a. a -> Maybe a
Just ()
  initialize :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Context -> m ()
initialize Conn StatelessConf
_ Context
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  load :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> SessionName -> m (Maybe Context)
load Conn StatelessConf
_ SessionName
_ = Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Context
forall a. Maybe a
Nothing
  loadByKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Key Context -> m (Maybe Context)
loadByKey Conn StatelessConf
_ Key Context
_ = Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Context
forall a. Maybe a
Nothing
  save :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Context -> m (Maybe (Key Context))
save Conn StatelessConf
_ Context
_ = Maybe (Key Context) -> m (Maybe (Key Context))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Key Context)
forall a. Maybe a
Nothing
  saveContents :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> [Content] -> m ()
saveContents Conn StatelessConf
_ [Content]
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  listSessions :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> m [SessionName]
listSessions Conn StatelessConf
_ = [SessionName] -> m [SessionName]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
  deleteSession :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> SessionName -> m ()
deleteSession Conn StatelessConf
_ SessionName
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  listKeys :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> m [Unique KeyValue]
listKeys Conn StatelessConf
_ = [Unique KeyValue] -> m [Unique KeyValue]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
  getKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Unique KeyValue -> m (Maybe SessionName)
getKey Conn StatelessConf
_ Unique KeyValue
_ = Maybe SessionName -> m (Maybe SessionName)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SessionName
forall a. Maybe a
Nothing
  setKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Unique KeyValue -> SessionName -> m ()
setKey Conn StatelessConf
_ Unique KeyValue
_ SessionName
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  deleteKey :: forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
Conn StatelessConf -> Unique KeyValue -> m ()
deleteKey Conn StatelessConf
_ Unique KeyValue
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

withDB :: forall p m a. (MonadIO m, MonadFail m, PersistentBackend p) => (Conn p -> m a) -> m a
withDB :: forall p (m :: * -> *) a.
(MonadIO m, MonadFail m, PersistentBackend p) =>
(Conn p -> m a) -> m a
withDB Conn p -> m a
func =
  p -> m (Maybe (Conn p))
forall p (m :: * -> *).
(PersistentBackend p, MonadIO m, MonadFail m) =>
p -> m (Maybe (Conn p))
forall (m :: * -> *).
(MonadIO m, MonadFail m) =>
p -> m (Maybe (Conn p))
setup (forall p. PersistentBackend p => p
config @p) m (Maybe (Conn p)) -> (Maybe (Conn p) -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Maybe (Conn p)
Nothing -> String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Can not open a database."
    Just (Conn p
conn :: Conn p) -> Conn p -> m a
func Conn p
conn

withBackend :: forall a m. (MonadIO m, MonadFail m) => (forall p. PersistentBackend p => p -> Prompt m a) -> Prompt m a
withBackend :: forall a (m :: * -> *).
(MonadIO m, MonadFail m) =>
(forall p. PersistentBackend p => p -> Prompt m a) -> Prompt m a
withBackend forall p. PersistentBackend p => p -> Prompt m a
func = do
  (PromptEnv
env :: PromptEnv) <- StateT PromptEnv m PromptEnv
forall (m :: * -> *) s. Monad m => StateT s m s
get
  case (PromptEnv
env) of
    (PromptEnv [ToolProxy]
_ [CustomInstructionProxy]
_ Context
_ (PersistProxy t
v) [HookProxy]
_) -> t -> Prompt m a
forall p. PersistentBackend p => p -> Prompt m a
func t
v