aboutsummaryrefslogtreecommitdiffstats
path: root/src/Store/Query.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Store/Query.hs')
-rw-r--r--src/Store/Query.hs73
1 files changed, 57 insertions, 16 deletions
diff --git a/src/Store/Query.hs b/src/Store/Query.hs
index f8575af..ccca93f 100644
--- a/src/Store/Query.hs
+++ b/src/Store/Query.hs
@@ -4,15 +4,18 @@ module Store.Query
)
where
+import Control.Arrow (second)
import Control.Exception (throw)
+import Control.Monad.Trans (lift)
import Data.Aeson qualified as J
import Data.Aeson.Key qualified as JK
import Data.Aeson.KeyMap qualified as JM
-import Data.List (foldl', isSuffixOf)
+import Data.List (foldl', foldl1')
import Data.Map qualified as M
import Data.Maybe (fromMaybe)
+import Data.Text qualified as T
import Data.Vector qualified as V
-import Store.Exception (DecodeException (DecodeException))
+import Store.Exception (DecodeException (DecodeException), MissingFileName (MissingFileName))
import Store.Query.Parser ()
import Store.Query.Printer ()
import Store.Query.Record
@@ -20,30 +23,61 @@ import Store.Query.Type
import Store.Store qualified as S
import System.FilePath ((</>))
-query :: Query -> IO [J.Value]
+query :: Query -> S.StoreM [J.Value]
+query (Delete c w) = do
+ c' <-
+ mapM (\fn -> fmap ((fn,) . fromValue c) . decodeFile $ fn)
+ . map (c </>)
+ =<< S.listFiles c
+ let fps = map fst $ whereBy snd w (map (second (: [])) c')
+ lift $ print fps
+ mapM_ S.deleteFile fps
+ S.commit
+ pure []
+query (Insert vs c) = do
+ let vs' = map (\v -> (fileName v, v)) vs
+
+ fileName v@(J.Object kvs) =
+ case JM.lookup "$fileName" kvs of
+ Just (J.String fileName) -> c </> T.unpack fileName
+ _ -> throw (MissingFileName v)
+ mapM_ (\(fp, v) -> encodeFile fp v) vs'
+ S.commit
+ pure []
query (Select fs c js es w) = do
c' <-
- mapM (fmap (fromValue c) . decodeFile . (c </>)) =<< ls c
+ mapM (fmap (fromValue c) . decodeFile . (c </>))
+ =<< S.listFiles c
js' <-
mapM
( \(JoinClause t c w) ->
- fmap (\j' -> JoinClause t (map (fromValue c) j') w) . mapM (decodeFile . (c </>))
- =<< ls c
+ fmap (\j' -> JoinClause t (map (fromValue c) j') w)
+ . mapM (decodeFile . (c </>))
+ =<< S.listFiles c
)
js
es' <-
mapM
( \(EmbedClause c w) ->
- fmap (\e' -> EmbedClause (fromValue c e') w) . mapM (decodeFile . (c </>))
- =<< ls c
+ fmap (\e' -> EmbedClause (fromValue c e') w)
+ . mapM (decodeFile . (c </>))
+ =<< S.listFiles c
)
es
pure $ map (Store.Query.select fs) $ where_ w $ embeds es' $ joins js' c'
- where
- ls c =
- filter (not . (isSuffixOf "/"))
- <$> S.withStore "." "HEAD" do
- S.listDirectory c
+query (Update c v w) = do
+ c' <-
+ mapM (\fn -> fmap ((fn,) . fromValue c) . decodeFile $ fn)
+ . map (c </>)
+ =<< S.listFiles c
+ let c'' = whereBy snd w (map (second (: [])) c')
+ mapM_
+ ( \(fp, v') ->
+ encodeFile fp (foldl1' union (map toValue v') `union` v)
+ )
+ c''
+ S.commit
+ pure []
embeds ::
EmbedClauses (Record [J.Value]) ->
@@ -121,7 +155,10 @@ select (SelectObject kvs) vs =
select (SelectField f) vs = fromMaybe J.Null (lookups f vs)
where_ :: Maybe WhereClause -> [Records J.Value] -> [Records J.Value]
-where_ w = filter (satisfies w)
+where_ = whereBy id
+
+whereBy :: (a -> [Record J.Value]) -> Maybe WhereClause -> [a] -> [a]
+whereBy f w = filter (satisfies w . f)
satisfies :: Maybe WhereClause -> Records J.Value -> Bool
satisfies Nothing _ = True
@@ -129,6 +166,10 @@ satisfies (Just (And ws)) vs = all (\w -> satisfies (Just w) vs) ws
satisfies (Just (Or ws)) vs = any (\w -> satisfies (Just w) vs) ws
satisfies (Just (Where (Eq f g))) vs = lookups f vs == lookups g vs
-decodeFile :: J.FromJSON a => Collection -> IO a
-decodeFile fp = S.withStore "." "HEAD" do
+decodeFile :: J.FromJSON a => Collection -> S.StoreM a
+decodeFile fp =
fromMaybe (throw DecodeException) . J.decode <$> S.readFile fp
+
+encodeFile :: Collection -> J.Value -> S.StoreM ()
+encodeFile fp v =
+ S.writeFile fp (J.encode v)