aboutsummaryrefslogtreecommitdiffstats
path: root/src/Store/Query
diff options
context:
space:
mode:
Diffstat (limited to 'src/Store/Query')
-rw-r--r--src/Store/Query/Parser.hs55
-rw-r--r--src/Store/Query/Printer.hs14
-rw-r--r--src/Store/Query/Type.hs15
3 files changed, 76 insertions, 8 deletions
diff --git a/src/Store/Query/Parser.hs b/src/Store/Query/Parser.hs
index 99ddc79..ce2a4dd 100644
--- a/src/Store/Query/Parser.hs
+++ b/src/Store/Query/Parser.hs
@@ -15,9 +15,11 @@ import Data.Vector qualified as V
import Data.Void (Void)
import Store.Exception (ParseError (ParseError))
import Store.Query.Type
+import System.IO.Unsafe (unsafePerformIO)
import Text.Megaparsec qualified as P
import Text.Megaparsec.Char qualified as P
import Text.Megaparsec.Char.Lexer qualified as P
+import Text.Regex.PCRE.String
instance IsString Query where
fromString =
@@ -51,7 +53,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
@@ -78,11 +84,14 @@ instance IsString Query where
comma = void $ lexeme (P.string ",")
embed = void $ lexeme (P.string "EMBED")
eq = void $ lexeme (P.string "==")
+ match = void $ lexeme (P.string "=~")
from = void $ lexeme (P.string "FROM")
on = void $ lexeme (P.string "ON")
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)
@@ -113,11 +122,30 @@ instance IsString Query where
Where <$> comparison
]
- comparison = do
- a <- P.choice [Left <$> value, Right <$> field]
- eq
- b <- P.choice [Left <$> value, Right <$> field]
- pure $ Eq a b
+ comparison =
+ P.choice
+ ( map
+ P.try
+ [ do
+ a <- P.choice [Left <$> value, Right <$> field]
+ eq
+ b <- P.choice [Left <$> value, Right <$> field]
+ pure $ Eq a b,
+ do
+ a <- P.choice [Left <$> value, Right <$> field]
+ match
+ b <- regex
+ pure $ Regex a b
+ ]
+ )
+
+ offsetClause = do
+ offset_
+ Offset <$> lexeme P.decimal
+
+ limitClause = do
+ limit_
+ Limit <$> lexeme P.decimal
fieldSelector =
lexeme $
@@ -230,6 +258,21 @@ instance IsString Query where
fieldPart :: P.Parsec Void String String
fieldPart = P.takeWhile1P Nothing (\c -> not (isSpace c) && c /= ',' && c /= '.')
+ regex = lexeme do
+ ( unsafePerformIO . compile compBlank execBlank
+ <$> between (Just (P.string "\\")) (P.string "/") (P.string "/")
+ )
+ >>= either (\e -> error ("regex failed to compile: " <> show e)) pure
+
+ between (Just e) start end = start >> go
+ where
+ go =
+ P.choice
+ [ e >> (:) <$> P.anySingle <*> go,
+ P.try ((const "") <$> end),
+ (:) <$> P.anySingle <*> go
+ ]
+
joinType :: P.Parsec Void String JoinType
joinType =
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..b431f6c 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
@@ -18,6 +20,7 @@ import Data.Aeson qualified as J
import Data.Map qualified as M
import Store.Query.Field
import Store.Query.Record
+import Text.Regex.PCRE
data Query
= Delete Collection (Maybe WhereClause)
@@ -28,6 +31,8 @@ data Query
(JoinClauses FilePath)
(EmbedClauses FilePath)
(Maybe WhereClause)
+ (Maybe LimitClause)
+ (Maybe OffsetClause)
| Update Collection J.Value (Maybe WhereClause)
data FieldSelector
@@ -63,4 +68,14 @@ data WhereClause
data Comparison
= Eq (Either J.Value Field) (Either J.Value Field)
+ | Regex (Either J.Value Field) Regex
+ deriving (Show)
+
+instance Show Regex where
+ show _ = "<REGEX>"
+
+data LimitClause = Limit Int
+ deriving (Show)
+
+data OffsetClause = Offset Int
deriving (Show)