{- This file is part of Vervis.
 -
 - Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
 -
 - ♡ Copying is an act of love. Please copy, reuse and share.
 -
 - The author(s) have dedicated all copyright and related and neighboring
 - rights to this software to the public domain worldwide. This software is
 - distributed without any warranty.
 -
 - You should have received a copy of the CC0 Public Domain Dedication along
 - with this software. If not, see
 - <http://creativecommons.org/publicdomain/zero/1.0/>.
 -}

module Database.Persist.Schema
    ( FieldName (..)
    , EntityName (..)
    , UniqueName (..)
    , FieldType (..)
    , MaybeNull (..)
    , Field (..)
    , Entity (..)
    , Unique (..)
    , PersistSchema (..)
    )
where

import Prelude

import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Reader (ReaderT)
import Data.Text (Text)
import Database.Persist.Types (SqlType)

newtype FieldName = FieldName { unFieldName :: Text }

newtype EntityName = EntityName { unEntityName :: Text }

newtype UniqueName = UniqueName { unUniqueName :: Text }

data FieldType = FTPrim SqlType | FTRef

data MaybeNull = MaybeNull | NotNull

data Field = Field
    { fieldName :: FieldName
    , fieldType :: FieldType
    , fieldNull :: MaybeNull
    }

data Entity = Entity
    { entityName    :: EntityName
    , entityFields  :: [Field]
    , entityUniques :: [Unique]
    }

data Unique = Unique
    { uniqueEntity :: EntityName
    , uniqueName   :: UniqueName
    , uniqueFields :: [FieldName]
    }

class PersistSchema backend where
    addEntity
        :: MonadIO m => Entity -> ReaderT backend m ()
    removeEntity
        :: MonadIO m => EntityName -> ReaderT backend m ()
    addField
        :: MonadIO m => Field -> ReaderT backend m ()
    renameField
        :: MonadIO m
        => EntityName -> FieldName -> FieldName -> ReaderT backend m ()
    removeField
        :: MonadIO m => EntityName -> FieldName -> ReaderT backend m ()
    addUnique
        :: MonadIO m => Unique -> ReaderT backend m ()
    renameUnique
        :: MonadIO m
        => EntityName -> UniqueName -> UniqueName -> ReaderT backend m ()
    removeUnique
        :: MonadIO m => EntityName -> UniqueName -> ReaderT backend m ()