Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for view and type blocks #2179

Merged
merged 3 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions waspc/data/Generator/templates/db/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@
{=& . =}

{=/ enumSchemas =}
{=# viewSchemas =}
{=& . =}

{=/ viewSchemas =}
{=# typeSchemas =}
{=& . =}

{=/ typeSchemas =}
6 changes: 6 additions & 0 deletions waspc/src/Wasp/Generator/DbGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ genPrismaSchema spec = do
object
[ "modelSchemas" .= (entityToPslModelSchema <$> entities),
"enumSchemas" .= enumSchemas,
"viewSchemas" .= viewSchemas,
"typeSchemas" .= typeSchemas,
"datasourceSchema" .= generateConfigBlockSchema (getDatasource datasourceProvider),
"generatorSchemas" .= (generateConfigBlockSchema <$> generators)
]
Expand All @@ -85,6 +87,10 @@ genPrismaSchema spec = do

enumSchemas = Psl.Generator.Schema.generateSchemaBlock . Psl.Schema.EnumBlock <$> Psl.Schema.getEnums prismaSchemaAst

viewSchemas = Psl.Generator.Schema.generateSchemaBlock . Psl.Schema.ViewBlock <$> Psl.Schema.getViews prismaSchemaAst

typeSchemas = Psl.Generator.Schema.generateSchemaBlock . Psl.Schema.TypeBlock <$> Psl.Schema.getTypes prismaSchemaAst

generateConfigBlockSchema = Psl.Generator.Schema.generateSchemaBlock . Psl.Schema.ConfigBlock

getDatasource datasourceProvider =
Expand Down
12 changes: 12 additions & 0 deletions waspc/src/Wasp/Psl/Ast/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module Wasp.Psl.Ast.Schema
( Schema (..),
Block (..),
getModels,
getViews,
getTypes,
getEnums,
getDatasources,
getGenerators,
Expand All @@ -12,20 +14,30 @@ import Wasp.Psl.Ast.ConfigBlock (ConfigBlock)
import qualified Wasp.Psl.Ast.ConfigBlock as Psl.ConfigBlock
import Wasp.Psl.Ast.Enum (Enum)
import Wasp.Psl.Ast.Model (Model)
import Wasp.Psl.Ast.Type (Type)
import Wasp.Psl.Ast.View (View)
import Prelude hiding (Enum)

data Schema = Schema [Block]
deriving (Show, Eq)

data Block
= ModelBlock Model
| ViewBlock View
| TypeBlock Type
| EnumBlock Enum
| ConfigBlock ConfigBlock
deriving (Show, Eq)

getModels :: Schema -> [Model]
getModels (Schema blocks) = [model | ModelBlock model <- blocks]

getViews :: Schema -> [View]
getViews (Schema blocks) = [view | ViewBlock view <- blocks]

getTypes :: Schema -> [Type]
getTypes (Schema blocks) = [typeBlock | TypeBlock typeBlock <- blocks]

getEnums :: Schema -> [Enum]
getEnums (Schema blocks) = [enum | EnumBlock enum <- blocks]

Expand Down
13 changes: 13 additions & 0 deletions waspc/src/Wasp/Psl/Ast/Type.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Wasp.Psl.Ast.Type
( Type (..),
)
where

import Wasp.Psl.Ast.Common (Name)
import Wasp.Psl.Ast.Model (Body)

data Type
= Type
Name
Body
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So does type actually support anything that can go into Model body, or is it a subset? That is relevant both here for AST and also for parser. If it is indeed anything that goes into model, then great. If not (and I would guess so, at least for view), then I would consider putting a comment here explaining that a bit.
Same goes for view.

Copy link
Contributor Author

@infomiho infomiho Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So does type actually support anything that can go into Model body, or is it a subset?

I'm only looking at this from the point of view of Prisma grammar and type and view are separate blocks. They are not subsets of model in any way.

You can however, use composite types (type block) in models by using them as field types e.g.:

model MyModel {
  id String @id
  someType SomeType
}

type SomeType {
  name String
  age Int
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments to both view and type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i meant in the sense that their ast/parser is subset of model's

deriving (Show, Eq)
13 changes: 13 additions & 0 deletions waspc/src/Wasp/Psl/Ast/View.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Wasp.Psl.Ast.View
( View (..),
)
where

import Wasp.Psl.Ast.Common (Name)
import Wasp.Psl.Ast.Model (Body)

data View
= View
Name
Body
deriving (Show, Eq)
4 changes: 4 additions & 0 deletions waspc/src/Wasp/Psl/Generator/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import qualified Wasp.Psl.Ast.ConfigBlock as Psl.ConfigBlock
import qualified Wasp.Psl.Ast.Enum as Psl.Enum
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Schema as Psl.Schema
import qualified Wasp.Psl.Ast.Type as Psl.Type
import qualified Wasp.Psl.Ast.View as Psl.View
import Wasp.Psl.Generator.Common (PslSource)
import Wasp.Psl.Generator.ConfigBlock (generateConfigBlockKeyValuePairs)
import Wasp.Psl.Generator.Enum (generateEnumBody)
Expand All @@ -15,6 +17,8 @@ import Wasp.Psl.Generator.Model (generateModelBody)
generateSchemaBlock :: Psl.Schema.Block -> PslSource
generateSchemaBlock = \case
Psl.Schema.ModelBlock (Psl.Model.Model name body) -> "model " ++ name ++ " {\n" ++ generateModelBody body ++ "}"
Psl.Schema.ViewBlock (Psl.View.View name body) -> "view " ++ name ++ " {\n" ++ generateModelBody body ++ "}"
Psl.Schema.TypeBlock (Psl.Type.Type name body) -> "type " ++ name ++ " {\n" ++ generateModelBody body ++ "}"
Psl.Schema.EnumBlock (Psl.Enum.Enum name values) -> "enum " ++ name ++ " {\n" ++ generateEnumBody values ++ "}"
Psl.Schema.ConfigBlock (Psl.ConfigBlock.ConfigBlock Psl.ConfigBlock.Datasource name content) -> "datasource " ++ name ++ " {\n" ++ generateConfigBlockKeyValuePairs content ++ "}"
Psl.Schema.ConfigBlock (Psl.ConfigBlock.ConfigBlock Psl.ConfigBlock.Generator name content) -> "generator " ++ name ++ " {\n" ++ generateConfigBlockKeyValuePairs content ++ "}"
1 change: 1 addition & 0 deletions waspc/src/Wasp/Psl/Parser/Model.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Wasp.Psl.Parser.Model
( parseBody,
model,
body,
)
where

Expand Down
4 changes: 4 additions & 0 deletions waspc/src/Wasp/Psl/Parser/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import Wasp.Psl.Parser.Common (SourceCode, whiteSpace)
import Wasp.Psl.Parser.ConfigBlock (configBlock)
import Wasp.Psl.Parser.Enum (enum)
import Wasp.Psl.Parser.Model (model)
import Wasp.Psl.Parser.Type (typeBlock)
import Wasp.Psl.Parser.View (view)

parsePrismaSchema :: SourceCode -> Either Parsec.ParseError Psl.Schema.Schema
parsePrismaSchema = Parsec.parse schema ""
Expand All @@ -32,6 +34,8 @@ schema = do
many $
choice
[ Psl.Schema.ModelBlock <$> model,
Psl.Schema.ViewBlock <$> view,
Psl.Schema.TypeBlock <$> typeBlock,
Martinsos marked this conversation as resolved.
Show resolved Hide resolved
Psl.Schema.EnumBlock <$> enum,
Psl.Schema.ConfigBlock <$> configBlock
]
Expand Down
32 changes: 32 additions & 0 deletions waspc/src/Wasp/Psl/Parser/Type.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Wasp.Psl.Parser.Type
( typeBlock,
)
where

import Text.Parsec.String (Parser)
import qualified Wasp.Psl.Ast.Type as Psl.Type
import Wasp.Psl.Parser.Common
( braces,
identifier,
reserved,
)
import Wasp.Psl.Parser.Model (body)

-- | Parses PSL (Prisma Schema Language) type.
-- Example of PSL type:
-- type Photo {
-- height Int @default(200)
-- width Int @default(100)
-- url String
-- }
--
-- PSL type blocks have the same syntax as
-- Prisma model blocks, but they are prefixed with
-- `type` keyword. That's why we are reusing the
-- `body` parser from `Model` to parse the body
-- of the type block.
typeBlock :: Parser Psl.Type.Type
typeBlock = do
reserved "type"
typeName <- identifier
Psl.Type.Type typeName <$> braces body
31 changes: 31 additions & 0 deletions waspc/src/Wasp/Psl/Parser/View.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Wasp.Psl.Parser.View
( view,
)
where

import Text.Parsec.String (Parser)
import qualified Wasp.Psl.Ast.View as Psl.View
import Wasp.Psl.Parser.Common
( braces,
identifier,
reserved,
)
import Wasp.Psl.Parser.Model (body)

-- | Parses PSL (Prisma Schema Language) view.
-- Example of PSL view:
-- view User {
-- id Int @id
-- name String
-- }
--
-- PSL view blocks have the same syntax as
-- Prisma model blocks, but they are prefixed with
-- `view` keyword. That's why we are reusing the
-- `body` parser from `Model` to parse the body
-- of the type block.
view :: Parser Psl.View.View
view = do
reserved "view"
viewName <- identifier
Psl.View.View viewName <$> braces body
10 changes: 10 additions & 0 deletions waspc/test/Psl/Generator/SchemaTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import qualified Wasp.Psl.Ast.ConfigBlock as Psl.ConfigBlock
import qualified Wasp.Psl.Ast.Enum as Psl.Enum
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Schema as Psl.Schema
import qualified Wasp.Psl.Ast.Type as Psl.Type
import qualified Wasp.Psl.Ast.View as Psl.View
import Wasp.Psl.Generator.Schema (generateSchemaBlock)
import qualified Wasp.Psl.Parser.Schema as Psl.Parser.Schema

Expand All @@ -24,6 +26,8 @@ instance Arbitrary Psl.Schema.Block where
arbitrary =
oneof
[ Psl.Schema.ModelBlock <$> arbitrary,
Psl.Schema.ViewBlock <$> arbitrary,
Psl.Schema.TypeBlock <$> arbitrary,
Psl.Schema.EnumBlock <$> arbitrary,
Psl.Schema.ConfigBlock <$> arbitrary
]
Expand All @@ -34,6 +38,12 @@ instance Arbitrary Psl.Schema.Schema where
instance Arbitrary Psl.Model.Model where
arbitrary = Psl.Model.Model <$> arbitraryIdentifier <*> arbitrary

instance Arbitrary Psl.View.View where
arbitrary = Psl.View.View <$> arbitraryIdentifier <*> arbitrary

instance Arbitrary Psl.Type.Type where
arbitrary = Psl.Type.Type <$> arbitraryIdentifier <*> arbitrary

instance Arbitrary Psl.Model.Body where
arbitrary = do
fieldElement <- Psl.Model.ElementField <$> arbitrary
Expand Down
82 changes: 81 additions & 1 deletion waspc/test/Psl/Parser/SchemaTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import qualified Wasp.Psl.Ast.ConfigBlock as Psl.ConfigBlock
import qualified Wasp.Psl.Ast.Enum as Psl.Enum
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Schema as Psl.Schema
import qualified Wasp.Psl.Ast.Type as Psl.Type
import qualified Wasp.Psl.Ast.View as Psl.View
import qualified Wasp.Psl.Parser.Schema as Psl.Parser

spec_parsePslSchema :: Spec
Expand Down Expand Up @@ -84,6 +86,21 @@ spec_parsePslSchema = do

}

view UserInfo {
id Int?
email String?
name String?
bio String?

@@ignore
}

type Photo {
height Int @default(200)
width Int @default(100)
url String
}

// Some comments at the end
|]
expectedAst =
Expand Down Expand Up @@ -291,7 +308,70 @@ spec_parsePslSchema = do
"Role"
[ Psl.Enum.ElementValue "USER" [],
Psl.Enum.ElementValue "ADMIN" []
]
],
Psl.Schema.ViewBlock $
Psl.View.View
"UserInfo"
( Psl.Model.Body
[ Psl.Model.ElementField $
Psl.Model.Field
"id"
Psl.Model.Int
[Psl.Model.Optional]
[],
Psl.Model.ElementField $
Psl.Model.Field
"email"
Psl.Model.String
[Psl.Model.Optional]
[],
Psl.Model.ElementField $
Psl.Model.Field
"name"
Psl.Model.String
[Psl.Model.Optional]
[],
Psl.Model.ElementField $
Psl.Model.Field
"bio"
Psl.Model.String
[Psl.Model.Optional]
[],
Psl.Model.ElementBlockAttribute $
Psl.Attribute.Attribute "ignore" []
]
),
Psl.Schema.TypeBlock $
Psl.Type.Type
"Photo"
( Psl.Model.Body
[ Psl.Model.ElementField $
Psl.Model.Field
"height"
Psl.Model.Int
[]
[ Psl.Attribute.Attribute
"default"
[ Psl.Argument.ArgUnnamed $ Psl.Argument.NumberExpr "200"
]
],
Psl.Model.ElementField $
Psl.Model.Field
"width"
Psl.Model.Int
[]
[ Psl.Attribute.Attribute
"default"
[Psl.Argument.ArgUnnamed $ Psl.Argument.NumberExpr "100"]
],
Psl.Model.ElementField $
Psl.Model.Field
"url"
Psl.Model.String
[]
[]
]
)
]

it "Prisma file is correctly parsed" $ do
Expand Down
Loading
Loading