diff options
Diffstat (limited to 'src/Store/Query.hs')
-rw-r--r-- | src/Store/Query.hs | 73 |
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) |