2016-01-01 20:57:54 +05:30
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
{-# LANGUAGE TupleSections #-}
|
|
|
|
{-# LANGUAGE CPP #-}
|
2016-02-03 16:00:39 +05:30
|
|
|
{-# LANGUAGE GADTs #-}
|
2015-12-15 18:22:51 +05:30
|
|
|
module Ringo.Extractor.Internal where
|
|
|
|
|
|
|
|
import qualified Data.Map as Map
|
|
|
|
import qualified Data.Text as Text
|
|
|
|
|
2015-12-18 02:37:17 +05:30
|
|
|
#if MIN_VERSION_base(4,8,0)
|
|
|
|
#else
|
|
|
|
import Control.Applicative ((<$>))
|
|
|
|
#endif
|
|
|
|
|
2016-06-22 17:10:14 +05:30
|
|
|
import Control.Monad.Reader (Reader, asks)
|
2015-12-16 16:57:10 +05:30
|
|
|
import Data.Function (on)
|
2015-12-19 11:55:08 +05:30
|
|
|
import Data.Maybe (mapMaybe, fromMaybe, fromJust, catMaybes)
|
2015-12-15 18:22:51 +05:30
|
|
|
import Data.Monoid ((<>))
|
2015-12-30 12:21:41 +05:30
|
|
|
import Data.List (nub, nubBy, find)
|
2015-12-18 01:00:32 +05:30
|
|
|
import Data.Text (Text)
|
2015-12-15 18:22:51 +05:30
|
|
|
|
2016-06-22 17:10:14 +05:30
|
|
|
import Ringo.Types.Internal
|
2015-12-30 12:21:41 +05:30
|
|
|
|
|
|
|
findTable :: TableName -> [Table] -> Maybe Table
|
|
|
|
findTable tName = find ((== tName) . tableName)
|
|
|
|
|
|
|
|
findFact :: TableName -> [Fact] -> Maybe Fact
|
|
|
|
findFact fName = find ((== fName) . factName)
|
|
|
|
|
|
|
|
findColumn :: ColumnName -> [Column] -> Maybe Column
|
|
|
|
findColumn cName = find ((== cName) . columnName)
|
2015-12-15 18:22:51 +05:30
|
|
|
|
2015-12-18 01:00:32 +05:30
|
|
|
dimColumnName :: Text -> ColumnName -> ColumnName
|
2015-12-16 03:03:47 +05:30
|
|
|
dimColumnName dimName columnName =
|
|
|
|
fromMaybe columnName . Text.stripPrefix (dimName <> "_") $ columnName
|
|
|
|
|
2016-06-23 12:29:18 +05:30
|
|
|
dimColumnMapping :: Text -> Fact -> TableName -> [(ColumnName, ColumnName)]
|
|
|
|
dimColumnMapping dimPrefix fact dimTableName =
|
|
|
|
[ (dimColumnName factColTargetTable factColTargetColumn, factColTargetColumn)
|
|
|
|
| FactColumn { factColType = DimVal {..}, ..} <- factColumns fact
|
|
|
|
, dimPrefix <> factColTargetTable == dimTableName ]
|
|
|
|
|
|
|
|
dimColumnMappings :: Text -> Fact -> [(TableName, [(ColumnName, ColumnName)])]
|
|
|
|
dimColumnMappings dimPrefix fact =
|
|
|
|
nub [ (dimTableName, dimColumnMapping dimPrefix fact dimTableName)
|
|
|
|
| FactColumn { factColType = DimVal {..}, ..} <- factColumns fact
|
|
|
|
, let dimTableName = dimPrefix <> factColTargetTable ]
|
|
|
|
|
2015-12-18 01:00:32 +05:30
|
|
|
timeUnitColumnName :: Text -> ColumnName -> TimeUnit -> ColumnName
|
|
|
|
timeUnitColumnName dimIdColName colName timeUnit =
|
|
|
|
colName <> "_" <> timeUnitName timeUnit <> "_" <> dimIdColName
|
2015-12-16 16:57:10 +05:30
|
|
|
|
2016-01-26 01:34:09 +05:30
|
|
|
factDimFKIdColumnName :: Text -> Text -> Fact -> Table -> [Table] -> ColumnName
|
|
|
|
factDimFKIdColumnName dimPrefix dimIdColName dimFact dimTable@Table { .. } tables =
|
|
|
|
if dimTable `elem` tables
|
2016-02-03 16:00:39 +05:30
|
|
|
then head [ factColTargetColumn
|
|
|
|
| FactColumn {factColType = DimId {..}, ..} <- factColumns dimFact
|
|
|
|
, factColTargetTable == tableName ]
|
2016-01-26 01:34:09 +05:30
|
|
|
else fromMaybe tableName (Text.stripPrefix dimPrefix tableName) <> "_" <> dimIdColName
|
2015-12-16 16:57:10 +05:30
|
|
|
|
2015-12-18 01:00:32 +05:30
|
|
|
extractedFactTableName :: Text -> Text -> TableName -> TimeUnit -> TableName
|
|
|
|
extractedFactTableName factPrefix factInfix factName timeUnit =
|
|
|
|
factPrefix <> factName <> factInfix <> timeUnitName timeUnit
|
2015-12-16 16:57:10 +05:30
|
|
|
|
2015-12-18 01:00:32 +05:30
|
|
|
idColTypeToFKIdColType :: Text -> Text
|
|
|
|
idColTypeToFKIdColType typ = case Text.toLower typ of
|
|
|
|
"serial" -> "integer"
|
|
|
|
"smallserial" -> "smallint"
|
|
|
|
"bigserial" -> "bigint"
|
|
|
|
_ -> typ
|
2015-12-16 16:57:10 +05:30
|
|
|
|
2015-12-16 03:03:47 +05:30
|
|
|
extractDimensionTables :: Fact -> Reader Env [Table]
|
2016-06-22 17:10:14 +05:30
|
|
|
extractDimensionTables fact = do
|
2015-12-18 01:00:32 +05:30
|
|
|
settings <- asks envSettings
|
2015-12-16 03:03:47 +05:30
|
|
|
tables <- asks envTables
|
|
|
|
let table = fromJust . findTable (factTableName fact) $ tables
|
2015-12-18 01:00:32 +05:30
|
|
|
return $ dimsFromIds tables ++ dimsFromVals settings (tableColumns table)
|
2015-12-15 18:22:51 +05:30
|
|
|
where
|
2016-02-03 16:00:39 +05:30
|
|
|
dimsFromIds tables =
|
|
|
|
catMaybes [ findTable factColTargetTable tables
|
|
|
|
| FactColumn {factColType = DimId {..}} <- factColumns fact ]
|
2015-12-15 18:22:51 +05:30
|
|
|
|
2015-12-18 01:00:32 +05:30
|
|
|
dimsFromVals Settings {..} tableColumns =
|
|
|
|
map (\(dim, cols) ->
|
|
|
|
Table { tableName = settingDimPrefix <> dim
|
|
|
|
, tableColumns =
|
|
|
|
Column settingDimTableIdColumnName settingDimTableIdColumnType NotNull : cols
|
|
|
|
, tableConstraints = [ PrimaryKey settingDimTableIdColumnName
|
|
|
|
, UniqueKey (map columnName cols)
|
|
|
|
]
|
|
|
|
})
|
2015-12-15 18:22:51 +05:30
|
|
|
. Map.toList
|
2015-12-18 13:20:35 +05:30
|
|
|
. Map.mapWithKey
|
2015-12-28 18:09:02 +05:30
|
|
|
(\dim -> map (\col -> col { columnName = dimColumnName dim (columnName col)
|
|
|
|
, columnNullable = NotNull
|
|
|
|
})
|
|
|
|
. nub)
|
2015-12-15 18:22:51 +05:30
|
|
|
. Map.fromListWith (flip (++))
|
|
|
|
. mapMaybe (\fcol -> do
|
2016-02-03 16:00:39 +05:30
|
|
|
FactColumn {factColType = DimVal {..}, ..} <- fcol
|
|
|
|
column <- findColumn factColTargetColumn tableColumns
|
|
|
|
return (factColTargetTable, [ column ]))
|
2015-12-15 18:22:51 +05:30
|
|
|
. 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
|
2015-12-15 18:22:51 +05:30
|
|
|
parentDims <- concat <$> mapM extract (factParentNames fact)
|
2015-12-16 16:57:10 +05:30
|
|
|
return . nubBy ((==) `on` snd) $ myDims ++ parentDims
|
2015-12-15 18:22:51 +05:30
|
|
|
where
|
2016-06-22 17:10:14 +05:30
|
|
|
extract fName = asks envFacts >>= extractAllDimensionTables . fromJust . findFact fName
|