]> Git — Sourcephile - gargantext.git/blob - src/Gargantext/Database/Bashql.hs
[NGRAMS] Table queries ready (qualitative tests, needs more tests)
[gargantext.git] / src / Gargantext / Database / Bashql.hs
1 {-|
2 Module : Gargantext.Database.Bashql
3 Description : BASHQL to deal with Gargantext Database.
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
8 Portability : POSIX
9
10 * BASHQL is a Domain Specific Language to deal with the Database
11
12 * BASHQL = functional (Bash * SQL)
13
14 * Which language to chose when working with a database ? To make it
15 simple, instead of all common Object Relational Mapping (ORM) [1]
16 strategy used nowadays inspired more by object logic than functional
17 logic, the semantics of BASHQL with focus on the function first.
18
19 * BASHQL focus on the function, i.e. use bash language function name,
20 and make it with SQL behind the scene. Then BASHQL is inspired more
21 by Bash language [2] than SQL and then follows its main commands as
22 specification and documentation.
23
24 * Main arguments:
25 1. Theoritical: database and FileSystems are each thought as a single
26 category, assumption based on theoretical work on databases by David Spivak [0].
27 2. Practical argument: basic bash commands are a daily practice among
28 developper community.
29
30 * How to help ?
31 1. Choose a command you like in Bash
32 2. Implement it in Haskell-SQL according to Gargantext Shema (Tree like
33 filesystem)
34 3. Translate it in BASHQL (follow previous implementations)
35 4. Make a pull request (enjoy the community)
36
37 * Implementation strategy: Functional adapations are made to the
38 gargantext languages options and SQL optimization are done continuously
39 during the project. For the Haskellish part, you may be inspired by
40 Turtle implementation written by Gabriel Gonzales [3] which shows how to
41 write Haskell bash translations.
42
43 * Semantics
44 - FileSystem is now a NodeSystem where each File is a Node in a Directed Graph (DG).
45
46 * References
47
48 [0] MIT Press has published "Category theory for the sciences". The book
49 can also be purchased on Amazon. Here are reviews by the MAA, by the
50 AMS, and by SIAM.
51
52 [1] https://en.wikipedia.org/wiki/Object-relational_mapping
53
54 [2] https://en.wikipedia.org/wiki/Bash_(Unix_shell)
55
56 [3] https://github.com/Gabriel439/Haskell-Turtle-Library
57
58 -}
59
60 {-# LANGUAGE NoImplicitPrelude #-}
61 {-# LANGUAGE FlexibleContexts #-}
62
63 module Gargantext.Database.Bashql ( get
64 , ls
65 , home
66 , post
67 , del
68 , mv
69 , put
70 , rename
71 , tree
72 -- , mkCorpus, mkAnnuaire
73 , runCmd'
74 )
75 where
76
77 import Control.Monad.Reader -- (Reader, ask)
78
79 import Data.Text (Text)
80 import Data.List (concat, last)
81
82 import Gargantext.Core.Types
83 import Gargantext.Database.Utils (connectGargandb)
84 import Gargantext.Database.Node
85 import qualified Gargantext.Database.Node.Update as U (Update(..), update)
86 import Gargantext.Prelude
87
88 import Opaleye hiding (FromField)
89
90
91 -- List of NodeId
92 -- type PWD a = PWD UserId [a]
93 type PWD = [NodeId]
94 --data PWD' a = a | PWD' [a]
95
96 rename :: NodeId -> Text -> Cmd [Int]
97 rename n t = mkCmd $ \conn -> U.update (U.Rename n t) conn
98
99 mv :: NodeId -> ParentId -> Cmd [Int]
100 mv n p = mkCmd $ \conn -> U.update (U.Move n p) conn
101
102 -- | TODO get Children or Node
103 get :: PWD -> Cmd [NodeAny]
104 get [] = pure []
105 get pwd = Cmd . ReaderT $ \conn -> runQuery conn $ selectNodesWithParentID (last pwd)
106
107 -- | Home, need to filter with UserId
108 home :: Cmd PWD
109 home = map _node_id <$> Cmd (ReaderT (getNodesWithParentId 0 Nothing))
110
111 -- | ls == get Children
112 ls :: PWD -> Cmd [NodeAny]
113 ls = get
114
115 tree :: PWD -> Cmd [NodeAny]
116 tree p = do
117 ns <- get p
118 children <- mapM (\n -> get [_node_id n]) ns
119 pure $ ns <> concat children
120
121 -- | TODO
122 post :: PWD -> [NodeWrite'] -> Cmd Int64
123 post [] _ = pure 0
124 post _ [] = pure 0
125 post pth ns = Cmd . ReaderT $ insertNodesWithParent (Just $ last pth) ns
126
127 --postR :: PWD -> [NodeWrite'] -> Cmd [Int]
128 --postR [] _ _ = pure [0]
129 --postR _ [] _ = pure [0]
130 --postR pth ns c = mkNodeR (last pth) ns c
131
132 -- | WIP
133 -- rm : mv to trash
134 -- del : empty trash
135 --rm :: Connection -> PWD -> [NodeId] -> IO Int
136 --rm = del
137 del :: [NodeId] -> Cmd Int
138 del [] = pure 0
139 del ns = deleteNodes ns
140
141 -- | TODO
142 put :: U.Update -> Cmd [Int]
143 put u = mkCmd $ U.update u
144
145 -- | TODO
146 -- cd (Home UserId) | (Node NodeId)
147 -- cd Path
148 -- jump NodeId
149 -- touch Dir
150
151 -- type Name = Text
152
153
154 --mkCorpus :: ToJSON a => Name -> (a -> Text) -> [a] -> Cmd NewNode
155 --mkCorpus name title ns = do
156 -- pid <- home
157 --
158 -- let pid' = case lastMay pid of
159 -- Nothing -> printDebug "No home for" name
160 -- Just p -> p
161 --
162 -- let uid = 1
163 -- postNode uid (Just pid') ( Node' NodeCorpus name emptyObject
164 -- (map (\n -> Node' Document (title n) (toJSON n) []) ns)
165 -- )
166 --
167 ---- |
168 ---- import IMTClient as C
169 ---- postAnnuaire "Annuaire IMT" (\n -> (maybe "" identity (C.prenom n)) <> " " <> (maybe "" identity (C.nom n))) (take 30 annuaire)
170 --mkAnnuaire :: ToJSON a => Name -> (a -> Text) -> [a] -> Cmd NewNode
171 --mkAnnuaire name title ns = do
172 -- pid <- lastMay <$> home
173 -- let pid' = case lastMay pid of
174 -- Nothing -> printDebug "No home for" name
175 -- Just p -> p
176 -- let uid = 1
177 -- postNode uid (Just pid') ( Node' Annuaire name emptyObject
178 -- (map (\n -> Node' UserPage (title n) (toJSON n) []) ns)
179 -- )
180
181 --------------------------------------------------------------
182 -- |
183 -- myCorpus <- Prelude.map doc2hyperdataDocument <$> toDocs <$> snd <$> readCsv "doc/corpus_imt/Gargantext_Corpus_small.csv"
184 -- There is an error in the CSV parsing...
185 -- let myCorpus' = Prelude.filter (\n -> T.length (maybe "" identity (hyperdataDocument_title n)) > 30) myCorpus
186
187 -- corporaOf :: Username -> IO [Corpus]
188
189 runCmd' :: Cmd a -> IO a
190 runCmd' f = connectGargandb "gargantext.ini" >>= \c -> runCmd c f