aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-12-18 19:11:57 +0100
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-12-18 19:12:01 +0100
commit593a53511ec170c67fd3453c88dcda960eac44fe (patch)
treeba9ce2d062649809959a4e21708db6e86fae6b97 /src
parent58e1cf274e80d8dbd4889bb2c99d3a009b590282 (diff)
add `LIMIT`, `ORDER BY` clausesmain
Diffstat (limited to 'src')
-rw-r--r--src/Store/Query.hs42
-rw-r--r--src/Store/Query/Parser.hs16
-rw-r--r--src/Store/Query/Printer.hs14
-rw-r--r--src/Store/Query/Type.hs10
4 files changed, 73 insertions, 9 deletions
diff --git a/src/Store/Query.hs b/src/Store/Query.hs
index 091aae7..4c0f829 100644
--- a/src/Store/Query.hs
+++ b/src/Store/Query.hs
@@ -16,6 +16,7 @@ import Data.Map qualified as M
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import Data.Vector qualified as V
+import GHC.Generics (Generic)
import Store.Exception (DecodeException (DecodeException), MissingFileName (MissingFileName))
import Store.Query.Parser ()
import Store.Query.Printer ()
@@ -24,7 +25,17 @@ import Store.Query.Type
import Store.Store qualified as S
import System.FilePath ((</>))
-query :: Query -> S.StoreM [J.Value]
+data Paginated = Paginated
+ { count :: Int,
+ data_ :: [J.Value]
+ }
+ deriving (Show, Generic)
+
+instance J.ToJSON Paginated
+
+instance J.FromJSON Paginated
+
+query :: Query -> S.StoreM J.Value
query (Delete c w) = do
c' <-
mapM (\fn -> fmap ((fn,) . fromValue c) . decodeFile c $ fn)
@@ -33,7 +44,7 @@ query (Delete c w) = do
lift $ print fps
mapM_ S.deleteFile (map (c </>) fps)
S.commit
- pure []
+ pure (J.toJSON ([] @()))
query (Insert vs c) = do
let vs' = map (\v -> ((c, fileName v), v)) vs
@@ -43,8 +54,8 @@ query (Insert vs c) = do
_ -> throw (MissingFileName v)
mapM_ (\((c, fn), v) -> encodeFile c fn v) vs'
S.commit
- pure []
-query (Select fs c js es w) = do
+ pure (J.toJSON ([] @()))
+query (Select fs c js es w l o) = do
c' <-
mapM (\fn -> fromValue c <$> decodeFile c fn)
=<< S.listFiles c
@@ -64,7 +75,18 @@ query (Select fs c js es w) = do
=<< S.listFiles c
)
es
- pure $ map (Store.Query.select fs) $ where_ w $ embeds es' $ joins js' c'
+ let rs =
+ map (Store.Query.select fs)
+ . where_ w
+ . embeds es'
+ . joins js'
+ $ c'
+ rs' =
+ case l >> o >> pure () of
+ (Just _) ->
+ J.toJSON (Paginated (length rs) . applyLimit l . applyOffset o $ rs)
+ _ -> J.toJSON rs
+ pure rs'
query (Update c v w) = do
c' <-
mapM (\fn -> fmap (((c, fn),) . fromValue c) . decodeFile c $ fn)
@@ -76,7 +98,15 @@ query (Update c v w) = do
)
c''
S.commit
- pure []
+ pure (J.toJSON ([] @()))
+
+applyLimit :: Maybe LimitClause -> [a] -> [a]
+applyLimit Nothing = id
+applyLimit (Just (Limit n)) = take n
+
+applyOffset :: Maybe OffsetClause -> [a] -> [a]
+applyOffset Nothing = id
+applyOffset (Just (Offset n)) = drop n
embeds ::
EmbedClauses (Record [J.Value]) ->
diff --git a/src/Store/Query/Parser.hs b/src/Store/Query/Parser.hs
index 99ddc79..5b7bc1b 100644
--- a/src/Store/Query/Parser.hs
+++ b/src/Store/Query/Parser.hs
@@ -51,7 +51,11 @@ instance IsString Query where
w <- P.optional do
where_
whereClause
- pure $ Select fs c js es w,
+ l <- P.optional do
+ limitClause
+ o <- P.optional do
+ offsetClause
+ pure $ Select fs c js es w l o,
do
update
c <- collection
@@ -83,6 +87,8 @@ instance IsString Query where
or = void $ lexeme (P.string "OR")
select = void $ lexeme (P.string "SELECT")
where_ = void $ lexeme (P.string "WHERE")
+ offset_ = void $ lexeme (P.string "OFFSET")
+ limit_ = void $ lexeme (P.string "LIMIT")
collection = lexeme $ P.takeWhile1P (Just "collection") (not . isSpace)
@@ -119,6 +125,14 @@ instance IsString Query where
b <- P.choice [Left <$> value, Right <$> field]
pure $ Eq a b
+ offsetClause = do
+ offset_
+ Offset <$> lexeme P.decimal
+
+ limitClause = do
+ limit_
+ Limit <$> lexeme P.decimal
+
fieldSelector =
lexeme $
P.choice
diff --git a/src/Store/Query/Printer.hs b/src/Store/Query/Printer.hs
index cff543f..ecde378 100644
--- a/src/Store/Query/Printer.hs
+++ b/src/Store/Query/Printer.hs
@@ -26,7 +26,7 @@ instance Show Query where
Just "INTO",
Just (showCollection c)
]
- show (Select fs c js es w) =
+ show (Select fs c js es w l o) =
intercalate " " . catMaybes $
[ Just "SELECT",
Just (showFieldSelector fs),
@@ -34,7 +34,9 @@ instance Show Query where
Just (showCollection c),
showJoinClauses js,
showEmbedClauses es,
- showWhereClause w
+ showWhereClause w,
+ showLimitClause l,
+ showOffsetClause o
]
show (Update c v w) =
intercalate " " . catMaybes $
@@ -106,6 +108,14 @@ showComparison (Eq a b) = intercalate " " [showArg a, "==", showArg b]
where
showArg = either showValue showField
+showOffsetClause :: Maybe OffsetClause -> Maybe String
+showOffsetClause (Just (Offset n)) = Just (" OFFSET %d" <> show n)
+showOffsetClause Nothing = Nothing
+
+showLimitClause :: Maybe LimitClause -> Maybe String
+showLimitClause (Just (Limit n)) = Just (" LIMIT %d" <> show n)
+showLimitClause Nothing = Nothing
+
showValues :: [J.Value] -> Maybe String
showValues [] = Nothing
showValues vs = Just (intercalate ", " (map showValue vs))
diff --git a/src/Store/Query/Type.hs b/src/Store/Query/Type.hs
index 912d020..2f1f5ec 100644
--- a/src/Store/Query/Type.hs
+++ b/src/Store/Query/Type.hs
@@ -11,6 +11,8 @@ module Store.Query.Type
JoinType (..),
Query (..),
WhereClause (..),
+ LimitClause (..),
+ OffsetClause (..),
)
where
@@ -28,6 +30,8 @@ data Query
(JoinClauses FilePath)
(EmbedClauses FilePath)
(Maybe WhereClause)
+ (Maybe LimitClause)
+ (Maybe OffsetClause)
| Update Collection J.Value (Maybe WhereClause)
data FieldSelector
@@ -64,3 +68,9 @@ data WhereClause
data Comparison
= Eq (Either J.Value Field) (Either J.Value Field)
deriving (Show)
+
+data LimitClause = Limit Int
+ deriving (Show)
+
+data OffsetClause = Offset Int
+ deriving (Show)