diff options
Diffstat (limited to 'src/Store/Query')
-rw-r--r-- | src/Store/Query/Parser.hs | 55 | ||||
-rw-r--r-- | src/Store/Query/Printer.hs | 14 | ||||
-rw-r--r-- | src/Store/Query/Type.hs | 15 |
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) |