ringo/src/Ringo/Extractor/Internal.hs

87 lines
3.2 KiB
Haskell
Raw Normal View History

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
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 Data.Text (Text)
import Ringo.Types
import Ringo.Utils
dimColumnName :: Text -> ColumnName -> ColumnName
2015-12-16 03:03:47 +05:30
dimColumnName dimName columnName =
fromMaybe columnName . Text.stripPrefix (dimName <> "_") $ columnName
timeUnitColumnName :: Text -> ColumnName -> TimeUnit -> ColumnName
timeUnitColumnName dimIdColName colName timeUnit =
colName <> "_" <> timeUnitName timeUnit <> "_" <> dimIdColName
2015-12-16 16:57:10 +05:30
factDimFKIdColumnName :: Text -> Text -> TableName -> ColumnName
factDimFKIdColumnName dimPrefix dimIdColName dimTableName =
fromMaybe dimTableName (Text.stripPrefix dimPrefix dimTableName) <> "_" <> dimIdColName
2015-12-16 16:57:10 +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
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]
extractDimensionTables fact = do
settings <- asks envSettings
2015-12-16 03:03:47 +05:30
tables <- asks envTables
let table = fromJust . findTable (factTableName fact) $ tables
return $ dimsFromIds tables ++ dimsFromVals settings (tableColumns table)
where
dimsFromIds tables =
flip mapMaybe (factColumns fact) $ \fcol -> case fcol of
DimId d _ -> findTable d tables
_ -> Nothing
dimsFromVals Settings {..} tableColumns =
map (\(dim, cols) ->
Table { tableName = settingDimPrefix <> dim
, tableColumns =
Column settingDimTableIdColumnName settingDimTableIdColumnType NotNull : cols
, tableConstraints = [ PrimaryKey settingDimTableIdColumnName
, 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