Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
195
Issues
195
List
Board
Labels
Milestones
Merge Requests
12
Merge Requests
12
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
ac72d900
Commit
ac72d900
authored
Dec 02, 2024
by
Grégoire Locqueville
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleaned up the database prelude
parent
8001ba68
Pipeline
#7092
passed with stages
in 58 minutes and 32 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
93 additions
and
48 deletions
+93
-48
Prelude.hs
src/Gargantext/Database/Prelude.hs
+93
-48
No files found.
src/Gargantext/Database/Prelude.hs
View file @
ac72d900
...
@@ -9,12 +9,50 @@ Portability : POSIX
...
@@ -9,12 +9,50 @@ Portability : POSIX
-}
-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ConstraintKinds
#-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE LambdaCase
#-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TupleSections #-}
module
Gargantext.Database.Prelude
where
module
Gargantext.Database.Prelude
(
-- * Types and Constraints
-- $typesAndConstraints
--
-- ** Environment Constraints
HasConnectionPool
(
..
)
,
IsDBEnv
,
IsDBEnvExtra
-- ** Command Monad Constraints
,
IsCmd
,
IsDBCmd
,
IsDBCmdExtra
-- ** Existential Versions of the Above Constraints, for Convenience
,
Cmd
,
CmdRandom
,
DBCmd
,
DBCmdWithEnv
,
DBCmdExtra
-- ** Miscellaneous Type(s)
,
JSONB
-- * Functions
-- ** Executing DB Queries
-- *** PostgreSQL.Simple
,
execPGSQuery
,
runPGSQuery
,
runPGSQuery_
-- *** Opaleye
,
runOpaQuery
,
runCountOpaQuery
-- ** Other Functions
,
runCmd
,
createDBIfNotExists
,
dbCheck
,
formatPGSQuery
,
fromField'
,
mkCmd
,
restrictMaybe
)
where
import
Control.Exception.Safe
(
throw
)
import
Control.Exception.Safe
(
throw
)
import
Control.Lens
(
Getter
,
view
)
import
Control.Lens
(
Getter
,
view
)
...
@@ -35,24 +73,37 @@ import Gargantext.Core.Config (HasConfig(..))
...
@@ -35,24 +73,37 @@ import Gargantext.Core.Config (HasConfig(..))
import
Gargantext.Core.Mail.Types
(
HasMail
)
import
Gargantext.Core.Mail.Types
(
HasMail
)
import
Gargantext.Core.NLP
(
HasNLPServer
)
import
Gargantext.Core.NLP
(
HasNLPServer
)
import
Gargantext.Prelude
import
Gargantext.Prelude
import
Opaleye
(
Unpackspec
,
showSql
,
FromFields
,
Select
,
runSelect
,
SqlJsonb
,
DefaultFromField
,
toFields
,
matchMaybe
,
MaybeFields
)
import
Opaleye
(
FromFields
,
Select
,
runSelect
,
SqlJsonb
,
DefaultFromField
,
toFields
,
matchMaybe
,
MaybeFields
)
import
Opaleye.Aggregate
(
countRows
)
import
Opaleye.Aggregate
(
countRows
)
import
Opaleye.Internal.Constant
qualified
import
Opaleye.Internal.Constant
qualified
import
Opaleye.Internal.Operators
qualified
import
Opaleye.Internal.Operators
qualified
import
Shelly
qualified
as
SH
import
Shelly
qualified
as
SH
-------------------------------------------------------
-- $typesAndConstraints
--
-- The names of the constraints and types in this module are chosen based on
-- the following guidelines:
-- * By default, constraints are relatively lenient. Stricter constraints are
-- obtained by appending the `Extra` suffix to the minimal constraint name.
-- * `IsDBEnv(Extra)` applies to the environment; the basic constraint allows
-- access to the database, and the `Extra` variant offers some more
-- capabilities such as access to mail.
-- * `IsCmd` is the basic constraint for command monads. Append `DB` to it to get
-- a monad of commands that can talk to the database. Append `Extra` to get
-- the ability to send mail, make use of the NLP server and deal with central
-- exchange notifications. Append `Random` to get access to randomness.
-- * Existential versions of the constraints bear the same name as the constraint
-- they are based on, but without the `Is` prefix.
class
HasConnectionPool
env
where
class
HasConnectionPool
env
where
connPool
::
Getter
env
(
Pool
Connection
)
connPool
::
Getter
env
(
Pool
Connection
)
instance
HasConnectionPool
(
Pool
Connection
)
where
instance
HasConnectionPool
(
Pool
Connection
)
where
connPool
=
identity
connPool
=
identity
-------------------------------------------------------
-- | The most basic constraints for an environment with a database.
type
JSONB
=
DefaultFromField
SqlJsonb
-- If possible, try to not add more constraints here. When performing
-------------------------------------------------------
-- | If possible, try to not add more constraints here. When performing
-- a query/update on the DB, one shouldn't need more than being able to
-- a query/update on the DB, one shouldn't need more than being able to
-- fetch from the underlying 'env' the connection pool and access the
-- fetch from the underlying 'env' the connection pool and access the
-- 'GargConfig' for some sensible defaults to store into the DB.
-- 'GargConfig' for some sensible defaults to store into the DB.
...
@@ -61,6 +112,8 @@ type IsDBEnv env =
...
@@ -61,6 +112,8 @@ type IsDBEnv env =
,
HasConfig
env
,
HasConfig
env
)
)
-- | Constraints for a full-fledged environment, with a database, mail exchange,
-- NLP processing, notifications.
type
IsDBEnvExtra
env
=
type
IsDBEnvExtra
env
=
(
IsDBEnv
env
(
IsDBEnv
env
,
HasMail
env
,
HasMail
env
...
@@ -68,6 +121,9 @@ type IsDBEnvExtra env =
...
@@ -68,6 +121,9 @@ type IsDBEnvExtra env =
,
CET
.
HasCentralExchangeNotification
env
,
CET
.
HasCentralExchangeNotification
env
)
)
-- | The most general constraints for commands. To interact with the database,
-- or access extra features (such as sending mail), you'll need to add some more
-- constraints (see the rest of this module)
type
IsCmd
env
err
m
=
type
IsCmd
env
err
m
=
(
MonadReader
env
m
(
MonadReader
env
m
,
MonadError
err
m
,
MonadError
err
m
...
@@ -82,25 +138,41 @@ type IsDBCmd env err m =
...
@@ -82,25 +138,41 @@ type IsDBCmd env err m =
,
IsDBEnv
env
,
IsDBEnv
env
)
)
-- | Full-fledged command class. Types in this class provide commands that can
-- interact with the database, perform NLP processing, etc.
type
IsDBCmdExtra
env
err
m
=
type
IsDBCmdExtra
env
err
m
=
(
IsCmd
env
err
m
(
IsCmd
env
err
m
,
IsDBEnvExtra
env
,
IsDBEnvExtra
env
)
)
-- | Basic command with access to randomness. It feels a little ad hoc to have
-- such a constraint instead of substituting it (and its counterpart existential
-- type `CmdRandom`) with its definition every time it appears in the codebase,
-- but I tried to doing that substitution and it wasn't so easy.
type
IsCmdRandom
env
err
m
=
type
IsCmdRandom
env
err
m
=
(
MonadReader
env
m
(
IsCmd
env
err
m
,
MonadError
err
m
,
MonadRandom
m
,
MonadBaseControl
IO
m
,
MonadRandom
m
)
)
-- | Barebones command type, without any built-in ability to interact with the
-- database or do stuff like email exchanges.
type
Cmd
env
err
a
=
forall
m
.
IsCmd
env
err
m
=>
m
a
type
CmdRandom
env
err
a
=
forall
m
.
IsCmdRandom
env
err
m
=>
m
a
-- | Basic command type with access to randomness
type
Cmd
env
err
a
=
forall
m
.
IsCmd
env
err
m
=>
m
a
type
CmdRandom
env
err
a
=
forall
m
.
IsCmdRandom
env
err
m
=>
m
a
type
DBCmdExtra
err
a
=
forall
m
env
.
IsDBCmdExtra
env
err
m
=>
m
a
type
DBCmdWithEnv
env
err
a
=
forall
m
.
IsDBCmd
env
err
m
=>
m
a
type
DBCmd
err
a
=
forall
m
env
.
IsDBCmd
env
err
m
=>
m
a
-- | Command type that allows for interaction with the database.
type
DBCmd
err
a
=
forall
m
env
.
IsDBCmd
env
err
m
=>
m
a
-- | Command type that allows for interaction with the database. Similar to
-- `DBCmd`, except you can constraint the environment type some more.
type
DBCmdWithEnv
env
err
a
=
forall
m
.
IsDBCmd
env
err
m
=>
m
a
-- | Full-fledged command types, with access to the database, mail, NLP
-- processing and central exchange notifications.
type
DBCmdExtra
err
a
=
forall
m
env
.
IsDBCmdExtra
env
err
m
=>
m
a
type
JSONB
=
DefaultFromField
SqlJsonb
fromInt64ToInt
::
Int64
->
Int
fromInt64ToInt
::
Int64
->
Int
fromInt64ToInt
=
fromIntegral
fromInt64ToInt
=
fromIntegral
...
@@ -130,10 +202,6 @@ runCountOpaQuery q = do
...
@@ -130,10 +202,6 @@ runCountOpaQuery q = do
formatPGSQuery
::
PGS
.
ToRow
a
=>
PGS
.
Query
->
a
->
DBCmd
err
DB
.
ByteString
formatPGSQuery
::
PGS
.
ToRow
a
=>
PGS
.
Query
->
a
->
DBCmd
err
DB
.
ByteString
formatPGSQuery
q
a
=
mkCmd
$
\
conn
->
PGS
.
formatQuery
conn
q
a
formatPGSQuery
q
a
=
mkCmd
$
\
conn
->
PGS
.
formatQuery
conn
q
a
-- TODO use runPGSQueryDebug everywhere
runPGSQuery'
::
(
PGS
.
ToRow
a
,
PGS
.
FromRow
b
)
=>
PGS
.
Query
->
a
->
DBCmd
err
[
b
]
runPGSQuery'
q
a
=
mkCmd
$
\
conn
->
PGS
.
query
conn
q
a
runPGSQuery
::
(
PGS
.
FromRow
r
,
PGS
.
ToRow
q
)
runPGSQuery
::
(
PGS
.
FromRow
r
,
PGS
.
ToRow
q
)
=>
PGS
.
Query
->
q
->
DBCmd
err
[
r
]
=>
PGS
.
Query
->
q
->
DBCmd
err
[
r
]
runPGSQuery
q
a
=
mkCmd
$
\
conn
->
catch
(
PGS
.
query
conn
q
a
)
(
printError
conn
)
runPGSQuery
q
a
=
mkCmd
$
\
conn
->
catch
(
PGS
.
query
conn
q
a
)
(
printError
conn
)
...
@@ -143,22 +211,6 @@ runPGSQuery q a = mkCmd $ \conn -> catch (PGS.query conn q a) (printError conn)
...
@@ -143,22 +211,6 @@ runPGSQuery q a = mkCmd $ \conn -> catch (PGS.query conn q a) (printError conn)
hPutStrLn
stderr
q'
hPutStrLn
stderr
q'
throw
(
SomeException
e
)
throw
(
SomeException
e
)
{-
-- TODO
runPGSQueryFold :: ( CmdM env err m
, PGS.FromRow r
)
=> PGS.Query -> a -> (a -> r -> IO a) -> m a
runPGSQueryFold q initialState consume = mkCmd $ \conn -> catch (PGS.fold_ conn initialState consume) (printError conn)
where
printError c (SomeException e) = do
q' <- PGS.formatQuery c q
hPutStrLn stderr q'
throw (SomeException e)
-}
-- | TODO catch error
-- | TODO catch error
runPGSQuery_
::
(
PGS
.
FromRow
r
)
runPGSQuery_
::
(
PGS
.
FromRow
r
)
=>
PGS
.
Query
->
DBCmd
err
[
r
]
=>
PGS
.
Query
->
DBCmd
err
[
r
]
...
@@ -171,10 +223,6 @@ runPGSQuery_ q = mkCmd $ \conn -> catch (PGS.query_ conn q) printError
...
@@ -171,10 +223,6 @@ runPGSQuery_ q = mkCmd $ \conn -> catch (PGS.query_ conn q) printError
execPGSQuery
::
PGS
.
ToRow
a
=>
PGS
.
Query
->
a
->
DBCmd
err
Int64
execPGSQuery
::
PGS
.
ToRow
a
=>
PGS
.
Query
->
a
->
DBCmd
err
Int64
execPGSQuery
q
a
=
mkCmd
$
\
conn
->
PGS
.
execute
conn
q
a
execPGSQuery
q
a
=
mkCmd
$
\
conn
->
PGS
.
execute
conn
q
a
------------------------------------------------------------------------
-- connectGargandb :: SettingsFile -> IO Connection
-- connectGargandb sf = readConfig sf >>= \params -> connect (DBConfig.unTOMLConnectInfo params)
fromField'
::
(
Typeable
b
,
FromJSON
b
)
=>
Field
->
Maybe
DB
.
ByteString
->
Conversion
b
fromField'
::
(
Typeable
b
,
FromJSON
b
)
=>
Field
->
Maybe
DB
.
ByteString
->
Conversion
b
fromField'
field
mb
=
do
fromField'
field
mb
=
do
...
@@ -188,9 +236,6 @@ fromField' field mb = do
...
@@ -188,9 +236,6 @@ fromField' field mb = do
,
show
v
,
show
v
]
]
printSqlOpa
::
Default
Unpackspec
a
a
=>
Select
a
->
IO
()
printSqlOpa
=
putStrLn
.
maybe
"Empty query"
identity
.
showSql
dbCheck
::
DBCmd
err
Bool
dbCheck
::
DBCmd
err
Bool
dbCheck
=
do
dbCheck
=
do
r
::
[
PGS
.
Only
Text
]
<-
runPGSQuery_
"select username from public.auth_user"
r
::
[
PGS
.
Only
Text
]
<-
runPGSQuery_
"select username from public.auth_user"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment