packages feed

persistent-audit-0.1.0.0: src/Main.hs

{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import           Data.Text (Text)
import qualified Data.Text as T
import           Data.Text.IO

import           Database.Persist.Audit.Generator
import           Database.Persist.Audit.Parser

import           WithCli

{-
principles
  no foreign keys between audit table and original table, they store the same data but no dependency
  database independence, original models and audit models can be stored in separate dbs

  makes a best attempt, no guarantees

  assumptions made: 
    types ending in Id are foreign pointers
-}

-- data CrossDB = SQLtoMongoDB | MongoDBtoSQL deriving (Eq,Generic,Read,Show, HasArguments)

data CmdOptions = CmdOptions {
  model         :: FilePath -- | Input: Model file to parse
, audit         :: FilePath -- | Ouput: Audit Model file
, auditInstance :: Maybe FilePath -- | Optional Output: ToAudit Instances for models in model file to models in Audit Model File
, crossDB       :: Maybe String -- | Nothing if original models and audit models are in the same database type
                              --   'sqlToMongoDB'
                              --   'mongoDbToSql'
} deriving (Generic, Show, Eq, Read)

instance HasArguments CmdOptions

main :: IO ()
main = withCliModified mods $ \ (ops :: CmdOptions) -> do
  m <- Data.Text.IO.readFile $ model ops
  settings <- case crossDB ops of
      Nothing -> return defaultSettings
      Just c  -> case c of
        "mongoDbToSql" -> return $ defaultSettings {foreignKeyType = MongoKeyInSQL}
        "sqlToMongoDB" -> return $ defaultSettings {foreignKeyType = SQLKeyInMongo}
        _              -> return defaultSettings

  case parseModelsFile m of 
    Left _ -> print $ "Failed to parse the models file with parseEntities function."
    Right models -> do
      Data.Text.IO.writeFile (audit ops) (generateAuditModels settings models)
      case auditInstance ops of
        Nothing -> return ()
        Just auditInstanceFile -> do
          Data.Text.IO.writeFile auditInstanceFile (generateToAuditInstances settings models)
          return ()

  where
    mods =
      AddShortOption "model" 'm' :
      AddShortOption "audit" 'a' :
      AddShortOption "auditInstance" 'i' :
      AddShortOption "crossDB" 'c' :
      []