Refactors extractor to simplify the code.

master
Abhinav Sarkar 2016-07-11 23:36:12 +05:30
parent 3fd28c7bff
commit 4a874d8f46
No known key found for this signature in database
GPG Key ID: 7C9166A6F5465AD5
1 changed files with 71 additions and 51 deletions

View File

@ -1,6 +1,8 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE GADTs #-} {-# LANGUAGE GADTs #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Ringo.Extractor module Ringo.Extractor
( extractDimensionTables ( extractDimensionTables
, extractAllDimensionTables , extractAllDimensionTables
@ -11,6 +13,7 @@ module Ringo.Extractor
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Tree as Tree import qualified Data.Tree as Tree
import Prelude.Compat
import Control.Monad.Reader (Reader, asks) import Control.Monad.Reader (Reader, asks)
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import Data.Monoid ((<>)) import Data.Monoid ((<>))
@ -21,63 +24,81 @@ import Ringo.Types.Internal
import Ringo.Utils import Ringo.Utils
extractFactTable :: Fact -> Reader Env Table extractFactTable :: Fact -> Reader Env Table
extractFactTable fact = do extractFactTable fact = mkTable <$> asks envSettings
allDims <- extractAllDimensionTables fact <*> extractColumns fact
<*> extractFKColumns fact
<*> extractUKColumnNames fact
where
mkTable Settings {..} columns fkColumns ukColNames =
Table { tableName =
extractedFactTableName settingFactPrefix settingFactInfix (factName fact) settingTimeUnit
, tableColumns = columns ++ fkColumns
, tableConstraints = [ UniqueKey $ ukColNames ++ map columnName fkColumns ]
}
extractColumns :: Fact -> Reader Env [Column]
extractColumns fact = do
Settings {..} <- asks envSettings Settings {..} <- asks envSettings
tables <- asks envTables tables <- asks envTables
let table = fromJust . findTable (factTableName fact) $ tables let table = fromJust . findTable (factTableName fact) $ tables
let countColType = settingFactCountColumnType let sourceColumn cName = fromJust . findColumn cName . tableColumns $ table
dimIdColName = settingDimTableIdColumnName
sourceColumn cName = fromJust . findColumn cName . tableColumns $ table
notNullSourceColumnCopy cName = (sourceColumn cName) { columnNullable = NotNull } notNullSourceColumnCopy cName = (sourceColumn cName) { columnNullable = NotNull }
notNullSourceColumnRename scName cName = (notNullSourceColumnCopy scName) { columnName = cName } notNullSourceColumnRename scName cName = (notNullSourceColumnCopy scName) { columnName = cName }
columns = concatFor (factColumns fact) $ \FactColumn {factColTargetColumn = cName, ..} -> return $ concatFor (factColumns fact) $ \FactColumn {factColTargetColumn = cName, ..} ->
case factColType of case factColType of
DimTime -> DimTime ->
[ Column (timeUnitColumnName dimIdColName cName settingTimeUnit) "bigint" NotNull ] [ Column (timeUnitColumnName settingDimTableIdColumnName cName settingTimeUnit) "bigint" NotNull ]
NoDimId -> [ notNullSourceColumnCopy cName ] NoDimId -> [ notNullSourceColumnCopy cName ]
TenantId -> [ notNullSourceColumnCopy cName ] TenantId -> [ notNullSourceColumnCopy cName ]
FactCount {..} -> [ Column cName countColType NotNull ] FactCount {..} -> [ Column cName settingFactCountColumnType NotNull ]
FactCountDistinct {..} -> [ Column cName "json" NotNull ] FactCountDistinct {..} -> [ Column cName "json" NotNull ]
FactSum {..} -> [ notNullSourceColumnRename factColSourceColumn cName ] FactSum {..} -> [ notNullSourceColumnRename factColSourceColumn cName ]
FactMax {..} -> [ notNullSourceColumnRename factColSourceColumn cName ] FactMax {..} -> [ notNullSourceColumnRename factColSourceColumn cName ]
FactMin {..} -> [ notNullSourceColumnRename factColSourceColumn cName ] FactMin {..} -> [ notNullSourceColumnRename factColSourceColumn cName ]
FactAverage {..} -> FactAverage {..} ->
[ Column (cName <> settingAvgCountColumnSuffix) countColType NotNull [ Column (cName <> settingAvgCountColumnSuffix) settingFactCountColumnType NotNull
, notNullSourceColumnRename factColSourceColumn (cName <> settingAvgSumColumnSuffix) , notNullSourceColumnRename factColSourceColumn (cName <> settingAvgSumColumnSuffix)
] ]
_ -> [] _ -> []
fkColumns = for allDims $ \(dimFact, dimTable) -> extractFKColumns :: Fact -> Reader Env [Column]
let colName = factDimFKIdColumnName settingDimPrefix dimIdColName dimFact dimTable tables extractFKColumns fact = do
allDims <- extractAllDimensionTables fact
Settings {..} <- asks envSettings
tables <- asks envTables
return $ for allDims $ \(dimFact, dimTable) ->
let colName = factDimFKIdColumnName settingDimPrefix settingDimTableIdColumnName dimFact dimTable tables
colType = idColTypeToFKIdColType settingDimTableIdColumnType colType = idColTypeToFKIdColType settingDimTableIdColumnType
in Column colName colType NotNull in Column colName colType NotNull
ukColNames = extractUKColumnNames :: Fact -> Reader Env [ColumnName]
(++ map columnName fkColumns) extractUKColumnNames fact = do
. forMaybe (factColumns fact) $ \FactColumn {factColTargetColumn = cName, ..} -> Settings {..} <- asks envSettings
return $ forMaybe (factColumns fact) $ \FactColumn {factColTargetColumn = cName, ..} ->
case factColType of case factColType of
DimTime -> Just $ timeUnitColumnName dimIdColName cName settingTimeUnit DimTime -> Just $ timeUnitColumnName settingDimTableIdColumnName cName settingTimeUnit
NoDimId -> Just cName NoDimId -> Just cName
TenantId -> Just cName TenantId -> Just cName
_ -> Nothing _ -> Nothing
return Table
{ tableName =
extractedFactTableName settingFactPrefix settingFactInfix (factName fact) settingTimeUnit
, tableColumns = columns ++ fkColumns
, tableConstraints = [ UniqueKey ukColNames ]
}
extractDependencies :: Fact -> Reader Env Dependencies extractDependencies :: Fact -> Reader Env Dependencies
extractDependencies fact = do extractDependencies fact = Map.union <$> extractFactDeps fact <*> extractDimensionDeps fact
settings@Settings{..} <- asks envSettings
extractFactDeps :: Fact -> Reader Env Dependencies
extractFactDeps fact = do
Settings{..} <- asks envSettings
facts <- asks envFacts facts <- asks envFacts
let factSourceDeps =
let extractedTable =
extractedFactTableName settingFactPrefix settingFactInfix (factName fact) settingTimeUnit
factSourceDeps =
nub . Tree.flatten . flip Tree.unfoldTree fact $ \fct -> nub . Tree.flatten . flip Tree.unfoldTree fact $ \fct ->
(factTableName fct, parentFacts fct facts) (factTableName fct, parentFacts fct facts)
factDimDeps = factDimDeps =
nub . concat . Tree.flatten . flip Tree.unfoldTree fact $ \fct -> nub . concat . Tree.flatten . flip Tree.unfoldTree fact $ \fct ->
( forMaybe (factColumns fct) $ \FactColumn {..} -> case factColType of ( forMaybe (factColumns fct) $ \FactColumn {..} -> case factColType of
@ -87,13 +108,12 @@ extractDependencies fact = do
, parentFacts fct facts , parentFacts fct facts
) )
dimDeps = Map.fromList [ (settingDimPrefix <> table, [factTableName fact]) return $ Map.singleton extractedTable (factSourceDeps ++ factDimDeps)
| FactColumn {factColType = DimVal table} <- factColumns fact ]
factDeps = Map.singleton (extractedTable settings) (factSourceDeps ++ factDimDeps)
return $ Map.union dimDeps factDeps
where where
extractedTable Settings {..} =
extractedFactTableName settingFactPrefix settingFactInfix (factName fact) settingTimeUnit
parentFacts fct facts = [ fromJust $ findFact pf facts | pf <- factParentNames fct ] parentFacts fct facts = [ fromJust $ findFact pf facts | pf <- factParentNames fct ]
extractDimensionDeps :: Fact -> Reader Env Dependencies
extractDimensionDeps fact = do
Settings{..} <- asks envSettings
return $ Map.fromList [ (settingDimPrefix <> table, [factTableName fact])
| FactColumn {factColType = DimVal table} <- factColumns fact ]