Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit d3a6cfa

Browse files
authored
Merge pull request #40 from safareli/import
Make sure we only `import` directory
2 parents dfd765d + b7aae7e commit d3a6cfa

File tree

5 files changed

+108
-42
lines changed

5 files changed

+108
-42
lines changed

src/SqlSquared/Parser.purs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Data.Maybe (Maybe(..), fromMaybe, isJust)
2424
import Data.NonEmpty ((:|))
2525
import Data.Json.Extended as EJ
2626
import Data.Tuple (Tuple(..), uncurry)
27-
import Data.Path.Pathy as Pt
27+
import SqlSquared.Path as Pt
2828
import Data.String as S
2929

3030
import SqlSquared.Constructors as C
@@ -412,7 +412,8 @@ import_
412412
import_ = asErrorMessage "import declaration" do
413413
_ ← keyword "import"
414414
s ← ident
415-
pure $ Sig.Import s
415+
path ← Pt.parseAnyDirPath P.fail s
416+
pure $ Sig.Import path
416417

417418
variable m t. SqlParser' m t
418419
variable = C.vari <$> variableString
@@ -571,13 +572,7 @@ parenRelation = do
571572
tableRelation m t. SqlParser m t (Sig.Relation t)
572573
tableRelation = do
573574
i ← ident
574-
path ←
575-
Pt.parsePath
576-
(const $ P.fail "incorrect path")
577-
(const $ P.fail "incorrect path")
578-
(pure ∘ E.Right)
579-
(pure ∘ E.Left)
580-
i
575+
path ← Pt.parseAnyFilePath P.fail i
581576
a ← PC.optionMaybe do
582577
_ ← keyword "as"
583578
ident

src/SqlSquared/Path.purs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module SqlSquared.Path
2+
( AnyFilePath
3+
, AnyDirPath
4+
, parseAnyFilePath
5+
, printAnyFilePath
6+
, parseAnyDirPath
7+
, printAnyDirPath
8+
, genAnyFilePath
9+
, genAnyDirPath
10+
) where
11+
12+
import Prelude
13+
import Data.Either as E
14+
import Data.NonEmpty ((:|))
15+
import Data.Path.Pathy as Pt
16+
import Data.Path.Pathy.Gen as PtGen
17+
import Control.Monad.Gen as Gen
18+
import Control.Monad.Rec.Class (class MonadRec)
19+
import SqlSquared.Utils ((∘))
20+
21+
type AnyDirPath = E.Either (Pt.AbsDir Pt.Unsandboxed) (Pt.RelDir Pt.Unsandboxed)
22+
type AnyFilePath = E.Either (Pt.AbsFile Pt.Unsandboxed) (Pt.RelFile Pt.Unsandboxed)
23+
24+
printAnyDirPath :: AnyDirPath -> String
25+
printAnyDirPath = E.either Pt.unsafePrintPath Pt.unsafePrintPath
26+
27+
parseAnyDirPath :: forall m. Applicative m => (forall a. String -> m a) -> String -> m AnyDirPath
28+
parseAnyDirPath fail = Pt.parsePath
29+
(pure ∘ E.Right)
30+
(pure ∘ E.Left)
31+
(const $ fail "Expected a directory path")
32+
(const $ fail "Expected a directory path")
33+
34+
printAnyFilePath :: AnyFilePath -> String
35+
printAnyFilePath = E.either Pt.unsafePrintPath Pt.unsafePrintPath
36+
37+
parseAnyFilePath :: forall m. Applicative m => (forall a. String -> m a) -> String -> m AnyFilePath
38+
parseAnyFilePath fail = Pt.parsePath
39+
(const $ fail "Expected a file path")
40+
(const $ fail "Expected a file path")
41+
(pure ∘ E.Right)
42+
(pure ∘ E.Left)
43+
44+
genAnyFilePath :: forall m. Gen.MonadGen m => MonadRec m => m AnyFilePath
45+
genAnyFilePath = Gen.oneOf
46+
$ (E.LeftPt.unsandbox <$> PtGen.genAbsFilePath)
47+
:| [E.RightPt.unsandbox <$> PtGen.genRelFilePath]
48+
49+
genAnyDirPath :: forall m. Gen.MonadGen m => MonadRec m => m AnyDirPath
50+
genAnyDirPath = Gen.oneOf
51+
$ (E.LeftPt.unsandbox <$> PtGen.genAbsDirPath)
52+
:| [E.RightPt.unsandbox <$> PtGen.genRelDirPath]

src/SqlSquared/Signature.purs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import Data.String as S
6363
import Data.String.Gen as GenS
6464
import Data.Traversable as T
6565
import Matryoshka (Algebra, CoalgebraM, class Corecursive, embed)
66+
import SqlSquared.Path as Pt
6667
import SqlSquared.Signature.BinaryOperator as BO
6768
import SqlSquared.Signature.Case as CS
6869
import SqlSquared.Signature.GroupBy as GB
@@ -139,7 +140,7 @@ data SqlF literal a
139140
| Parens a
140141

141142
data SqlDeclF a
142-
= Import String
143+
= Import Pt.AnyDirPath
143144
| FunctionDecl (FunctionDeclR a)
144145

145146
newtype SqlModuleF a =
@@ -502,8 +503,8 @@ printSqlDeclF = case _ of
502503
<> "(" <> F.intercalate ", " (append ":"ID.printIdent <$> args) <> ") BEGIN "
503504
<> body
504505
<> " END"
505-
Import s
506-
"IMPORT " <> ID.printIdent s
506+
Import path
507+
"IMPORT " <> ID.printIdent (Pt.printAnyDirPath path)
507508

508509
printSqlQueryF Algebra SqlQueryF String
509510
printSqlQueryF (Query decls expr) = F.intercalate "; " $ L.snoc (printSqlDeclF <$> decls) expr
@@ -588,9 +589,9 @@ encodeJsonSqlDeclF = case _ of
588589
J.~> "args" J.:= args
589590
J.~> "body" J.:= body
590591
J.~> J.jsonEmptyObject
591-
Import s
592+
Import path
592593
"tag" J.:= "import"
593-
J.~> "value" J.:= s
594+
J.~> "value" J.:= Pt.printAnyDirPath path
594595
J.~> J.jsonEmptyObject
595596

596597
encodeJsonSqlQueryF Algebra SqlQueryF J.Json
@@ -712,7 +713,8 @@ decodeJsonSqlDeclF = J.decodeJson >=> \obj → do
712713

713714
decodeImport obj = do
714715
v ← obj J..? "value"
715-
pure $ Import v
716+
path ← Pt.parseAnyDirPath E.Left v
717+
pure $ Import path
716718

717719
decodeJsonSqlQueryF CoalgebraM (E.Either String) SqlQueryF J.Json
718720
decodeJsonSqlQueryF = J.decodeJson >=> \obj → do
@@ -761,16 +763,16 @@ genSqlF genLiteral n
761763
, genSelect n
762764
]
763765

764-
genSqlDeclF m. Gen.MonadGen m CoalgebraM m SqlDeclF Int
766+
genSqlDeclF m. Gen.MonadGen m MonadRec m CoalgebraM m SqlDeclF Int
765767
genSqlDeclF n =
766768
Gen.oneOf $ genImport :|
767769
[ genFunctionDecl n
768770
]
769771

770-
genSqlQueryF m. Gen.MonadGen m CoalgebraM m SqlQueryF Int
772+
genSqlQueryF m. Gen.MonadGen m MonadRec m CoalgebraM m SqlQueryF Int
771773
genSqlQueryF n = Query <$> genDecls n <*> pure n
772774

773-
genSqlModuleF m. Gen.MonadGen m CoalgebraM m SqlModuleF Int
775+
genSqlModuleF m. Gen.MonadGen m MonadRec m CoalgebraM m SqlModuleF Int
774776
genSqlModuleF n = Module <$> genDecls n
775777

776778
genSetLiteral m l. Gen.MonadGen m CoalgebraM m (SqlF l) Int
@@ -878,16 +880,16 @@ genFunctionDecl n = do
878880
args ← L.foldM foldFn L.Nil $ L.range 0 len
879881
pure $ FunctionDecl { ident, args, body: n - 1 }
880882

881-
genImport m a. Gen.MonadGen m m (SqlDeclF a)
882-
genImport = Import <$> genIdent
883+
genImport m a. Gen.MonadGen m MonadRec m m (SqlDeclF a)
884+
genImport = map Import Pt.genAnyDirPath
883885

884886
genIdent m. Gen.MonadGen m m String
885887
genIdent = do
886888
start ← Gen.elements $ "a" :| S.split (S.Pattern "") "bcdefghijklmnopqrstuvwxyz"
887889
body ← map (Int.toStringAs Int.hexadecimal) (Gen.chooseInt 0 100000)
888890
pure $ start <> body
889891

890-
genDecls m. Gen.MonadGen m Int m (L.List (SqlDeclF Int))
892+
genDecls m. Gen.MonadGen m MonadRec m Int m (L.List (SqlDeclF Int))
891893
genDecls n = do
892894
let
893895
foldFn acc _ = do

src/SqlSquared/Signature/Relation.purs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,18 @@ import Control.Monad.Gen as Gen
66
import Control.Monad.Gen.Common as GenC
77
import Control.Monad.Rec.Class (class MonadRec)
88
import Data.Argonaut as J
9-
import Data.Either (Either(..), either)
9+
import Data.Either (Either(..))
1010
import Data.Foldable as F
11-
import Data.Int as Int
1211
import Data.Maybe (Maybe)
1312
import Data.Monoid (mempty)
1413
import Data.NonEmpty ((:|))
15-
import Data.Path.Pathy as Pt
1614
import Data.String.Gen as GenS
1715
import Data.Traversable as T
1816
import Matryoshka (Algebra, CoalgebraM)
17+
import SqlSquared.Path as Pt
1918
import SqlSquared.Signature.Ident as ID
2019
import SqlSquared.Signature.JoinType as JT
2120
import SqlSquared.Utils ((∘))
22-
2321
type JoinRelR a =
2422
{ left Relation a
2523
, right Relation a
@@ -38,7 +36,7 @@ type VariRelR =
3836
}
3937

4038
type TableRelR =
41-
{ path Either (Pt.AbsFile Pt.Unsandboxed) (Pt.RelFile Pt.Unsandboxed)
39+
{ path Pt.AnyFilePath
4240
, alias Maybe String
4341
}
4442

@@ -91,7 +89,7 @@ printRelation = case _ of
9189
":" <> ID.printIdent vari <> F.foldMap (\a → " AS " <> ID.printIdent a) alias
9290
TableRelation { path, alias } →
9391
"`"
94-
<> either Pt.unsafePrintPath Pt.unsafePrintPath path
92+
<> Pt.printAnyFilePath path
9593
<> "`"
9694
<> F.foldMap (\x → " AS " <> ID.printIdent x) alias
9795
JoinRelation { left, right, joinType, clause } →
@@ -117,7 +115,7 @@ encodeJsonRelation = case _ of
117115
J.~> J.jsonEmptyObject
118116
TableRelation { path, alias } →
119117
"tag" J.:= "table relation"
120-
J.~> "path" J.:= either Pt.unsafePrintPath Pt.unsafePrintPath path
118+
J.~> "path" J.:= Pt.printAnyFilePath path
121119
J.~> "alias" J.:= alias
122120
J.~> J.jsonEmptyObject
123121
JoinRelation { left, right, joinType, clause } →
@@ -150,13 +148,7 @@ decodeJsonRelation = J.decodeJson >=> \obj → do
150148

151149
decodeTableRelation obj = do
152150
pathStr ← obj J..? "path"
153-
path ←
154-
Pt.parsePath
155-
(const $ Left "incorrect path")
156-
(const $ Left "incorrect path")
157-
(RightRight)
158-
(RightLeft)
159-
pathStr
151+
path ← Pt.parseAnyFilePath Left pathStr
160152
alias ← obj J..? "alias"
161153
pure $ TableRelation { path, alias }
162154

@@ -186,13 +178,7 @@ genRelation n =
186178
alias ← GenC.genMaybe GenS.genUnicodeString
187179
pure $ VariRelation { vari, alias }
188180
genTable = do
189-
let
190-
pathPart =
191-
map (Int.toStringAs Int.hexadecimal) (Gen.chooseInt 0 100000)
192-
dirs ← map Pt.dir <$> Gen.resize (const n) (Gen.unfoldable pathPart m (Array String))
193-
fileName ← map Pt.file pathPart
194-
let
195-
path = Left $ Pt.rootDir Pt.</> F.foldl (\a b → b Pt.</> a) fileName dirs
181+
path ← Pt.genAnyFilePath
196182
alias ← GenC.genMaybe GenS.genUnicodeString
197183
pure $ TableRelation { path, alias }
198184
genExpr = do

test/src/Parse.purs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ parseFail s =
4040
E.Left err → pure unit
4141
E.Right (sql SqlQuery) → Assert.assert s false
4242

43+
parseFailWith e. String String TestSuite (testOutput Console.TESTOUTPUT | e)
44+
parseFailWith s err =
45+
test "parse/failWith"
46+
case parseQuery s of
47+
E.Left err' →
48+
if show err' == err
49+
then pure unit
50+
else Assert.assert
51+
("expected query:" <> s <>
52+
"\n\n to fail input error: " <> err <>
53+
"\n\n but instead fot error: " <> show err')
54+
false
55+
E.Right (sql SqlQuery) →
56+
Assert.assert
57+
("expected to fail with:" <> err <>
58+
"\n\tbut input query:" <> s <>
59+
"\n\twas parsed as:" <> printQuery sql)
60+
false
61+
4362
testSuite e. TestSuite (testOutput Console.TESTOUTPUT | e)
4463
testSuite = suite "parsers" do
4564
testSuite1
@@ -51,6 +70,14 @@ testSuite = suite "parsers" do
5170

5271
testSuite1 e. TestSuite (testOutput Console.TESTOUTPUT | e)
5372
testSuite1 = do
73+
parseFailWith """
74+
import `/path/To/Your/File/myModule`; SELECT id("HELLO")
75+
""" "(ParseError \"Expected a directory path\" (Position { line: 2, column: 12 }))"
76+
77+
parseSucc """
78+
import `/path/To/Your/File/myModule/`; SELECT id("HELLO")
79+
"""
80+
5481
parseSucc """
5582
a := 1; SELECT * FROM `/test`
5683
"""
@@ -157,6 +184,10 @@ testSuite1 = do
157184
"""
158185

159186
parseSucc """
187+
import `foo/`; select * from `/test`
188+
"""
189+
190+
parseFail """
160191
import foo; select * from `/test`
161192
"""
162193

0 commit comments

Comments
 (0)