Skip to content

Commit

Permalink
Adds support for view and type blocks
Browse files Browse the repository at this point in the history
Signed-off-by: Mihovil Ilakovac <[email protected]>
  • Loading branch information
infomiho committed Jul 12, 2024
1 parent 24920c0 commit b8196c7
Show file tree
Hide file tree
Showing 30 changed files with 795 additions and 372 deletions.
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 =}
24 changes: 12 additions & 12 deletions waspc/src/Wasp/AppSpec/Entity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,35 @@ import Wasp.AppSpec.Core.Decl (IsDecl)
import Wasp.AppSpec.Entity.Field (Field)
import qualified Wasp.AppSpec.Entity.Field as Field
import qualified Wasp.Psl.Ast.Attribute as Psl.Attribute
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Model.Common as Psl.Model.Common
import Wasp.Psl.Util (doesPslFieldHaveAttribute, findIdBlockAttribute, findIdField)

data Entity = Entity
{ fields :: ![Field],
pslModelBody :: !Psl.Model.Body
pslModelBody :: !Psl.Model.Common.Body
}
deriving (Show, Eq, Data)

instance IsDecl Entity

makeEntity :: Psl.Model.Body -> Entity
makeEntity :: Psl.Model.Common.Body -> Entity
makeEntity body =
Entity
{ fields = makeEntityFieldsFromPslBody body,
pslModelBody = body
}
where
makeEntityFieldsFromPslBody :: Psl.Model.Body -> [Field]
makeEntityFieldsFromPslBody (Psl.Model.Body pslElements) =
Field.pslFieldToEntityField <$> [field | (Psl.Model.ElementField field) <- pslElements]
makeEntityFieldsFromPslBody :: Psl.Model.Common.Body -> [Field]
makeEntityFieldsFromPslBody (Psl.Model.Common.Body pslElements) =
Field.pslFieldToEntityField <$> [field | (Psl.Model.Common.ElementField field) <- pslElements]

getFields :: Entity -> [Field]
getFields = fields

getPslModelBody :: Entity -> Psl.Model.Body
getPslModelBody :: Entity -> Psl.Model.Common.Body
getPslModelBody = pslModelBody

getIdField :: Entity -> Maybe Psl.Model.Field
getIdField :: Entity -> Maybe Psl.Model.Common.Field
getIdField = findIdField . getPslModelBody

isFieldUnique :: String -> Entity -> Maybe Bool
Expand All @@ -57,11 +57,11 @@ doesFieldHaveAttribute :: String -> String -> Entity -> Maybe Bool
doesFieldHaveAttribute fieldName attrName entity =
doesPslFieldHaveAttribute attrName <$> findPslFieldByName fieldName entity

findPslFieldByName :: String -> Entity -> Maybe Psl.Model.Field
findPslFieldByName fieldName Entity {pslModelBody = Psl.Model.Body elements} =
find isField [field | (Psl.Model.ElementField field) <- elements]
findPslFieldByName :: String -> Entity -> Maybe Psl.Model.Common.Field
findPslFieldByName fieldName Entity {pslModelBody = Psl.Model.Common.Body elements} =
find isField [field | (Psl.Model.Common.ElementField field) <- elements]
where
isField Psl.Model.Field {_name = name} = name == fieldName
isField Psl.Model.Common.Field {_name = name} = name == fieldName

getIdBlockAttribute :: Entity -> Maybe Psl.Attribute.Attribute
getIdBlockAttribute = findIdBlockAttribute . getPslModelBody
40 changes: 20 additions & 20 deletions waspc/src/Wasp/AppSpec/Entity/Field.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Wasp.AppSpec.Entity.Field
where

import Data.Data (Data)
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Model.Common as Psl.Model.Common

data Field = Field
{ fieldName :: !String,
Expand Down Expand Up @@ -41,35 +41,35 @@ data Scalar
| Unsupported String
deriving (Show, Eq, Data)

pslFieldToEntityField :: Psl.Model.Field -> Field
pslFieldToEntityField :: Psl.Model.Common.Field -> Field
pslFieldToEntityField pslField =
Field
{ fieldName = Psl.Model._name pslField,
{ fieldName = Psl.Model.Common._name pslField,
fieldType =
pslFieldTypeToEntityFieldType
(Psl.Model._type pslField)
(Psl.Model._typeModifiers pslField)
(Psl.Model.Common._type pslField)
(Psl.Model.Common._typeModifiers pslField)
}
where
pslFieldTypeToEntityFieldType :: Psl.Model.FieldType -> [Psl.Model.FieldTypeModifier] -> FieldType
pslFieldTypeToEntityFieldType :: Psl.Model.Common.FieldType -> [Psl.Model.Common.FieldTypeModifier] -> FieldType
pslFieldTypeToEntityFieldType fType fTypeModifiers =
let scalar = pslFieldTypeToScalar fType
in case fTypeModifiers of
[] -> FieldTypeScalar scalar
[Psl.Model.List] -> FieldTypeComposite $ List scalar
[Psl.Model.Optional] -> FieldTypeComposite $ Optional scalar
[Psl.Model.Common.List] -> FieldTypeComposite $ List scalar
[Psl.Model.Common.Optional] -> FieldTypeComposite $ Optional scalar
_ -> error "Not a valid list of modifiers."

pslFieldTypeToScalar :: Psl.Model.FieldType -> Scalar
pslFieldTypeToScalar :: Psl.Model.Common.FieldType -> Scalar
pslFieldTypeToScalar fType = case fType of
Psl.Model.String -> String
Psl.Model.Boolean -> Boolean
Psl.Model.Int -> Int
Psl.Model.BigInt -> BigInt
Psl.Model.Float -> Float
Psl.Model.Decimal -> Decimal
Psl.Model.DateTime -> DateTime
Psl.Model.Json -> Json
Psl.Model.Bytes -> Bytes
Psl.Model.UserType typeName -> UserType typeName
Psl.Model.Unsupported typeName -> Unsupported typeName
Psl.Model.Common.String -> String
Psl.Model.Common.Boolean -> Boolean
Psl.Model.Common.Int -> Int
Psl.Model.Common.BigInt -> BigInt
Psl.Model.Common.Float -> Float
Psl.Model.Common.Decimal -> Decimal
Psl.Model.Common.DateTime -> DateTime
Psl.Model.Common.Json -> Json
Psl.Model.Common.Bytes -> Bytes
Psl.Model.Common.UserType typeName -> UserType typeName
Psl.Model.Common.Unsupported typeName -> Unsupported typeName
4 changes: 2 additions & 2 deletions waspc/src/Wasp/AppSpec/Valid.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import Wasp.AppSpec.Util (isPgBossJobExecutorUsed)
import Wasp.Generator.Crud (crudDeclarationToOperationsList)
import Wasp.Node.Version (oldestWaspSupportedNodeVersion)
import qualified Wasp.Node.Version as V
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Model.Common as Psl.Model.Common
import Wasp.Psl.Valid (getValidDbSystemFromPrismaSchema)
import qualified Wasp.SemanticVersion as SV
import qualified Wasp.SemanticVersion.VersionBound as SVB
Expand Down Expand Up @@ -413,7 +413,7 @@ findFieldByName name = find ((== name) . Entity.Field.fieldName)

-- | This function assumes that @AppSpec@ it operates on was validated beforehand (with @validateAppSpec@ function).
-- We validated that entity field exists, so we can safely use fromJust here.
getIdFieldFromCrudEntity :: AppSpec -> AS.Crud.Crud -> Psl.Model.Field
getIdFieldFromCrudEntity :: AppSpec -> AS.Crud.Crud -> Psl.Model.Common.Field
getIdFieldFromCrudEntity spec crud = fromJust $ Entity.getIdField crudEntity
where
crudEntity = snd $ AS.resolveRef spec (AS.Crud.entity crud)
Expand Down
6 changes: 3 additions & 3 deletions waspc/src/Wasp/Generator/Crud.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ import qualified Wasp.AppSpec as AS
import qualified Wasp.AppSpec.Crud as AS.Crud
import Wasp.Generator.Common (makeJsArrayFromHaskellList)
import qualified Wasp.Generator.Crud.Routes as Routes
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Model.Common as Psl.Model.Common
import qualified Wasp.Util as Util

getCrudOperationJson :: String -> AS.Crud.Crud -> Psl.Model.Field -> Aeson.Value
getCrudOperationJson :: String -> AS.Crud.Crud -> Psl.Model.Common.Field -> Aeson.Value
getCrudOperationJson crudOperationName crud idField =
object
[ "name" .= crudOperationName,
"operations" .= object (map getDataForOperation crudOperations),
"entityUpper" .= crudEntityName,
"entityLower" .= Util.toLowerFirst crudEntityName,
"entitiesArray" .= makeJsArrayFromHaskellList [crudEntityName],
"idFieldName" .= Psl.Model._name idField
"idFieldName" .= Psl.Model.Common._name idField
]
where
crudEntityName = AS.refName $ AS.Crud.entity crud
Expand Down
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
20 changes: 10 additions & 10 deletions waspc/src/Wasp/Generator/DbGenerator/Auth.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Wasp.Generator.Monad
GeneratorError (GenericGeneratorError),
logAndThrowGeneratorError,
)
import qualified Wasp.Psl.Ast.Model as Psl.Model
import qualified Wasp.Psl.Ast.Model.Common as Psl.Model.Common
import qualified Wasp.Psl.Parser.Model as Psl.Parser.Model
import qualified Wasp.Util as Util

Expand Down Expand Up @@ -102,7 +102,7 @@ makeAuthIdentityEntity = case Psl.Parser.Model.parseBody authIdentityPslBody of
authEntityNameText = T.pack authEntityName
authFieldOnAuthIdentityEntityNameText = T.pack authFieldOnAuthIdentityEntityName

makeAuthEntity :: Psl.Model.Field -> (String, AS.Entity.Entity) -> Generator (String, AS.Entity.Entity)
makeAuthEntity :: Psl.Model.Common.Field -> (String, AS.Entity.Entity) -> Generator (String, AS.Entity.Entity)
makeAuthEntity userEntityIdField (userEntityName, _) = case Psl.Parser.Model.parseBody authEntityPslBody of
Left err -> logAndThrowGeneratorError $ GenericGeneratorError $ "Error while generating " ++ authEntityName ++ " entity: " ++ show err
Right pslBody -> return (authEntityName, AS.Entity.makeEntity pslBody)
Expand All @@ -125,8 +125,8 @@ makeAuthEntity userEntityIdField (userEntityName, _) = case Psl.Parser.Model.par
sessionsFieldOnAuthEntityNameText = T.pack sessionsFieldOnAuthEntityName
sessionEntityNameText = T.pack sessionEntityName

userEntityIdTypeText = T.pack $ show . Psl.Model._type $ userEntityIdField
userEntityIdFieldName = T.pack $ Psl.Model._name userEntityIdField
userEntityIdTypeText = T.pack $ show . Psl.Model.Common._type $ userEntityIdField
userEntityIdFieldName = T.pack $ Psl.Model.Common._name userEntityIdField

makeSessionEntity :: Generator (String, AS.Entity.Entity)
makeSessionEntity = case Psl.Parser.Model.parseBody sessionEntityPslBody of
Expand Down Expand Up @@ -160,13 +160,13 @@ injectAuthIntoUserEntity userEntityName entities =
injectRelationToAuth :: AS.Entity.Entity -> AS.Entity.Entity
injectRelationToAuth entity = AS.Entity.makeEntity newPslBody
where
(Psl.Model.Body existingPsl) = AS.Entity.getPslModelBody entity
(Psl.Model.Common.Body existingPsl) = AS.Entity.getPslModelBody entity
relationToAuthEntity =
[ Psl.Model.ElementField $
Psl.Model.Field
[ Psl.Model.Common.ElementField $
Psl.Model.Common.Field
authFieldOnUserEntityName
(Psl.Model.UserType authEntityName)
[Psl.Model.Optional]
(Psl.Model.Common.UserType authEntityName)
[Psl.Model.Common.Optional]
[]
]
newPslBody = Psl.Model.Body $ existingPsl ++ relationToAuthEntity
newPslBody = Psl.Model.Common.Body $ existingPsl ++ relationToAuthEntity
53 changes: 5 additions & 48 deletions waspc/src/Wasp/Psl/Ast/Model.hs
Original file line number Diff line number Diff line change
@@ -1,64 +1,21 @@
{-# LANGUAGE DeriveDataTypeable #-}

module Wasp.Psl.Ast.Model
( Model (..),
Body (..),
Element (..),
Field (..),
FieldType (..),
FieldTypeModifier (..),
getFields,
)
where

import Data.Data (Data)
import Wasp.Psl.Ast.Attribute (Attribute)
import Wasp.Psl.Ast.Common (Name)
import Prelude hiding (Enum)
import Wasp.Psl.Ast.Model.Common
( Body (..),
Element (..),
Field,
)

data Model
= Model
Name
Body
deriving (Show, Eq)

newtype Body = Body [Element]
deriving (Show, Eq, Data)

data Element
= ElementField Field
| ElementBlockAttribute Attribute
deriving (Show, Eq, Data)

-- TODO: To support attributes before the field,
-- we could just have `attrsBefore :: [[Attr]]`,
-- which represents lines, each one with list of attributes.
data Field = Field
{ _name :: String,
_type :: FieldType,
_typeModifiers :: [FieldTypeModifier],
_attrs :: [Attribute]
}
deriving (Show, Eq, Data)

data FieldType
= String
| Boolean
| Int
| BigInt
| Float
| Decimal
| DateTime
| Json
| Bytes
| Unsupported String
| UserType String
deriving (Show, Eq, Data)

data FieldTypeModifier
= List
| Optional
deriving (Show, Eq, Data)

getFields :: Model -> [Field]
getFields (Model _ (Body elements)) = [field | ElementField field <- elements]
52 changes: 52 additions & 0 deletions waspc/src/Wasp/Psl/Ast/Model/Common.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{-# LANGUAGE DeriveDataTypeable #-}

module Wasp.Psl.Ast.Model.Common
( Body (..),
Element (..),
Field (..),
FieldType (..),
FieldTypeModifier (..),
)
where

import Data.Data (Data)
import Wasp.Psl.Ast.Attribute (Attribute)
import Prelude hiding (Enum)

newtype Body = Body [Element]
deriving (Show, Eq, Data)

data Element
= ElementField Field
| ElementBlockAttribute Attribute
deriving (Show, Eq, Data)

-- TODO: To support attributes before the field,
-- we could just have `attrsBefore :: [[Attr]]`,
-- which represents lines, each one with list of attributes.
data Field = Field
{ _name :: String,
_type :: FieldType,
_typeModifiers :: [FieldTypeModifier],
_attrs :: [Attribute]
}
deriving (Show, Eq, Data)

data FieldType
= String
| Boolean
| Int
| BigInt
| Float
| Decimal
| DateTime
| Json
| Bytes
| Unsupported String
| UserType String
deriving (Show, Eq, Data)

data FieldTypeModifier
= List
| Optional
deriving (Show, Eq, Data)
Loading

0 comments on commit b8196c7

Please sign in to comment.