module IHP.IDE.SchemaDesigner.Controller.Helper where

import IHP.ControllerPrelude
import IHP.IDE.SchemaDesigner.Types
import qualified IHP.IDE.SchemaDesigner.Parser as Parser
import qualified Text.Megaparsec as Megaparsec
import qualified IHP.IDE.SchemaDesigner.Compiler as SchemaCompiler
import IHP.IDE.SchemaDesigner.View.Schema.Error

instance ParamReader PostgresType where
    readParameter :: ByteString -> Either ByteString PostgresType
readParameter ByteString
byteString = case Parsec Void Text PostgresType
-> String
-> Text
-> Either (ParseErrorBundle Text Void) PostgresType
forall e s a.
Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
Megaparsec.runParser Parsec Void Text PostgresType
Parser.sqlType String
"" (ByteString -> Text
forall a b. ConvertibleStrings a b => a -> b
cs ByteString
byteString) of
        Left ParseErrorBundle Text Void
error -> ByteString -> Either ByteString PostgresType
forall a b. a -> Either a b
Left (Text -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ ParseErrorBundle Text Void -> Text
forall a. Show a => a -> Text
tshow ParseErrorBundle Text Void
error)
        Right PostgresType
result -> PostgresType -> Either ByteString PostgresType
forall a b. b -> Either a b
Right PostgresType
result



readSchema ::
    ( ?context::ControllerContext
    , ?modelContext::ModelContext
    , ?theAction::controller
    ) => IO [Statement]
readSchema :: IO [Statement]
readSchema = IO (Either ByteString [Statement])
Parser.parseSchemaSql IO (Either ByteString [Statement])
-> (Either ByteString [Statement] -> IO [Statement])
-> IO [Statement]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left ByteString
error -> do ErrorView -> IO ()
forall view controller.
(View view, ?theAction::controller, ?context::ControllerContext,
 ?modelContext::ModelContext) =>
view -> IO ()
render ErrorView :: ByteString -> ErrorView
ErrorView { ByteString
$sel:error:ErrorView :: ByteString
error :: ByteString
error }; [Statement] -> IO [Statement]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
        Right [Statement]
statements -> [Statement] -> IO [Statement]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Statement]
statements

getSqlError :: IO (Maybe ByteString)
getSqlError :: IO (Maybe ByteString)
getSqlError = IO (Either ByteString [Statement])
Parser.parseSchemaSql IO (Either ByteString [Statement])
-> (Either ByteString [Statement] -> IO (Maybe ByteString))
-> IO (Maybe ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left ByteString
error -> do Maybe ByteString -> IO (Maybe ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
error)
        Right [Statement]
statements -> do Maybe ByteString -> IO (Maybe ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ByteString
forall a. Maybe a
Nothing

updateSchema ::
    ( ?context :: ControllerContext
    , ?modelContext::ModelContext
    , ?theAction::controller
    ) => ([Statement] -> [Statement]) -> IO ()
updateSchema :: ([Statement] -> [Statement]) -> IO ()
updateSchema [Statement] -> [Statement]
updateFn = do
    [Statement]
statements <- IO [Statement]
forall controller.
(?context::ControllerContext, ?modelContext::ModelContext,
 ?theAction::controller) =>
IO [Statement]
readSchema
    let statements' :: [Statement]
statements' = [Statement] -> [Statement]
updateFn [Statement]
statements
    [Statement] -> IO ()
SchemaCompiler.writeSchema [Statement]
statements'

getAllObjectNames :: [Statement] -> [Text]
getAllObjectNames :: [Statement] -> [Text]
getAllObjectNames = (Statement -> Maybe Text) -> [Statement] -> [Text]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Statement -> Maybe Text
extractObjectName
    where
        extractObjectName :: Statement -> Maybe Text
extractObjectName (StatementCreateTable CreateTable { Text
$sel:name:CreateTable :: CreateTable -> Text
name :: Text
name }) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
name
        extractObjectName CreateEnumType { Text
$sel:name:StatementCreateTable :: Statement -> Text
name :: Text
name } = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
name
        extractObjectName Statement
_                       = Maybe Text
forall a. Maybe a
Nothing