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
144
Issues
144
List
Board
Labels
Milestones
Merge Requests
9
Merge Requests
9
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
1c34d7d6
Commit
1c34d7d6
authored
Dec 02, 2024
by
Grégoire Locqueville
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleaned up the database prelude
parent
00f48464
Pipeline
#7069
failed with stages
in 66 minutes and 33 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 @
1c34d7d6
...
@@ -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