ringo/src/Ringo/Extractor/Internal.hs

80 lines
3.1 KiB
Haskell
Raw Normal View History

module Ringo.Extractor.Internal where
import qualified Data.Map as Map
import qualified Data.Text as Text
import Control.Monad.Reader (Reader, asks)
2015-12-16 16:57:10 +05:30
import Data.Function (on)
import Data.Maybe (mapMaybe, fromMaybe, fromJust)
import Data.Monoid ((<>))
2015-12-16 16:57:10 +05:30
import Data.List (nub, nubBy)
import Ringo.Types
import Ringo.Utils
2015-12-16 03:03:47 +05:30
dimColumnName :: Text.Text -> ColumnName -> ColumnName
dimColumnName dimName columnName =
fromMaybe columnName . Text.stripPrefix (dimName <> "_") $ columnName
2015-12-16 16:57:10 +05:30
timeUnitColumnName :: ColumnName -> TimeUnit -> ColumnName
timeUnitColumnName colName timeUnit = colName <> "_" <> timeUnitName timeUnit <> "_id"
averageCountColummName :: ColumnName -> ColumnName
averageCountColummName colName = colName <> "_count"
averageSumColumnName :: ColumnName -> ColumnName
averageSumColumnName colName = colName <> "_sum"
countDistinctColumnName :: ColumnName -> ColumnName
countDistinctColumnName colName = colName <> "_hll"
factDimFKIdColumnName :: Text.Text -> TableName -> ColumnName
factDimFKIdColumnName dimPrefix dimTableName =
fromMaybe dimTableName (Text.stripPrefix dimPrefix dimTableName) <> "_id"
extractedFactTableName :: Text.Text -> TableName -> TimeUnit -> TableName
extractedFactTableName factPrefix factName timeUnit =
factPrefix <> factName <> "_by_" <> timeUnitName timeUnit
2015-12-16 03:03:47 +05:30
extractDimensionTables :: Fact -> Reader Env [Table]
extractDimensionTables fact = do
tables <- asks envTables
prefix <- settingDimPrefix <$> asks envSettings
let table = fromJust . findTable (factTableName fact) $ tables
return $ dimsFromIds tables ++ dimsFromVals prefix (tableColumns table)
where
dimsFromIds tables =
flip mapMaybe (factColumns fact) $ \fcol -> case fcol of
DimId d _ -> findTable d tables
_ -> Nothing
2015-12-16 03:03:47 +05:30
dimsFromVals prefix tableColumns =
map (\(dim, cols) -> Table { tableName = prefix <> dim
, tableColumns = Column "id" "serial" NotNull : cols
, tableConstraints = [ PrimaryKey "id"
, UniqueKey (map columnName cols)
]
})
. Map.toList
. Map.mapWithKey (\dim ->
map (\col@Column {..} -> col { columnName = dimColumnName dim columnName })
. nub)
. Map.fromListWith (flip (++))
. mapMaybe (\fcol -> do
DimVal d col <- fcol
column <- findColumn col tableColumns
return (d, [ column ]))
. map Just
. factColumns
$ fact
2015-12-16 16:57:10 +05:30
extractAllDimensionTables :: Fact -> Reader Env [(Fact, Table)]
2015-12-16 03:03:47 +05:30
extractAllDimensionTables fact = do
2015-12-16 16:57:10 +05:30
myDims <- map (fact,) <$> extractDimensionTables fact
parentDims <- concat <$> mapM extract (factParentNames fact)
2015-12-16 16:57:10 +05:30
return . nubBy ((==) `on` snd) $ myDims ++ parentDims
where
extract fName = do
2015-12-16 16:57:10 +05:30
facts <- asks envFacts
2015-12-16 03:03:47 +05:30
extractAllDimensionTables . fromJust . findFact fName $ facts