Adds validation check for duplicate dimensions.

pull/1/head
Abhinav Sarkar 2016-06-23 12:29:18 +05:30
parent 6c87c59eb4
commit 207b11bee1
No known key found for this signature in database
GPG Key ID: 7C9166A6F5465AD5
5 changed files with 51 additions and 18 deletions

View File

@ -35,6 +35,18 @@ dimColumnName :: Text -> ColumnName -> ColumnName
dimColumnName dimName columnName = dimColumnName dimName columnName =
fromMaybe columnName . Text.stripPrefix (dimName <> "_") $ columnName fromMaybe columnName . Text.stripPrefix (dimName <> "_") $ columnName
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 ]
timeUnitColumnName :: Text -> ColumnName -> TimeUnit -> ColumnName timeUnitColumnName :: Text -> ColumnName -> TimeUnit -> ColumnName
timeUnitColumnName dimIdColName colName timeUnit = timeUnitColumnName dimIdColName colName timeUnit =
colName <> "_" <> timeUnitName timeUnit <> "_" <> dimIdColName colName <> "_" <> timeUnitName timeUnit <> "_" <> dimIdColName

View File

@ -7,7 +7,7 @@ import qualified Data.Map as Map
import qualified Data.Text as Text import qualified Data.Text as Text
import Database.HsSqlPpp.Syntax (ScalarExpr) import Database.HsSqlPpp.Syntax (ScalarExpr)
import Data.List (find) import Data.List (find, nub)
import Data.Monoid ((<>)) import Data.Monoid ((<>))
import Data.Text (Text) import Data.Text (Text)
@ -15,12 +15,6 @@ import Ringo.Extractor.Internal
import Ringo.Generator.Sql import Ringo.Generator.Sql
import Ringo.Types import Ringo.Types
dimColumnMapping :: Text -> Fact -> TableName -> [(ColumnName, ColumnName)]
dimColumnMapping dimPrefix fact dimTableName =
[ (dimColumnName factColTargetTable factColTargetColumn, factColTargetColumn)
| FactColumn { factColType = DimVal {..}, ..} <- factColumns fact
, dimPrefix <> factColTargetTable == dimTableName ]
coalesceColumn :: TypeDefaults -> TableName -> Column -> ScalarExpr coalesceColumn :: TypeDefaults -> TableName -> Column -> ScalarExpr
coalesceColumn defaults tName Column{..} = coalesceColumn defaults tName Column{..} =
if columnNullable == Null if columnNullable == Null

View File

@ -3,13 +3,32 @@
{-# LANGUAGE Rank2Types #-} {-# LANGUAGE Rank2Types #-}
module Ringo.Types module Ringo.Types
( ColumnName, ColumnType, TableName ( ColumnName
, Nullable(..), Column(..), TableConstraint(..), Table(..) , ColumnType
, TimeUnit(..), timeUnitName, timeUnitToSeconds , TableName
, Fact(..), FactColumnType(..), FactColumn(..), factSourceColumnName , Nullable(..)
, Settings(..), defSettings , Column(..)
, ValidationError(..), TypeDefaults , TableConstraint(..)
, Env, envTables, envFacts, envSettings, envTypeDefaults, , Table(..)
TablePopulationMode(..), Dependencies) where , TimeUnit(..)
, timeUnitName
, timeUnitToSeconds
, Fact(..)
, FactColumnKind(..)
, FactColumnType(..)
, FactColumn(..)
, factSourceColumnName
, Settings(..)
, defSettings
, ValidationError(..)
, TypeDefaults
, Env
, envTables
, envFacts
, envSettings
, envTypeDefaults
, TablePopulationMode(..)
, Dependencies
) where
import Ringo.Types.Internal import Ringo.Types.Internal

View File

@ -161,6 +161,7 @@ data ValidationError = MissingTable !TableName
| MissingColumn !TableName !ColumnName | MissingColumn !TableName !ColumnName
| DuplicateColumn !TableName !ColumnName | DuplicateColumn !TableName !ColumnName
| MissingTimeColumn !TableName | MissingTimeColumn !TableName
| DuplicateDimension !TableName
| MissingNotNullConstraint !TableName !ColumnName | MissingNotNullConstraint !TableName !ColumnName
| MissingTypeDefault !Text | MissingTypeDefault !Text
deriving (Eq, Show) deriving (Eq, Show)

View File

@ -15,8 +15,9 @@ import Control.Applicative ((<$>))
#endif #endif
import Control.Monad.Reader (Reader, ask, runReader) import Control.Monad.Reader (Reader, ask, runReader)
import Data.Function (on)
import Data.Maybe (isJust, fromJust) import Data.Maybe (isJust, fromJust)
import Data.List (nub, group, sort) import Data.List (nub, group, groupBy, sort)
import Ringo.Extractor.Internal import Ringo.Extractor.Internal
import Ringo.Types import Ringo.Types
@ -92,7 +93,7 @@ validateFact Fact {..} = do
_ -> [] _ -> []
validateEnv :: [Table] -> [Fact] -> Settings -> TypeDefaults -> Either [ValidationError] Env validateEnv :: [Table] -> [Fact] -> Settings -> TypeDefaults -> Either [ValidationError] Env
validateEnv tables facts settings typeDefaults = validateEnv tables facts settings@Settings {..} typeDefaults =
flip runReader (RawEnv tables facts settings typeDefaults) $ do flip runReader (RawEnv tables facts settings typeDefaults) $ do
tableVs <- concat <$> mapM validateTable tables tableVs <- concat <$> mapM validateTable tables
factVs <- concat <$> mapM validateFact facts factVs <- concat <$> mapM validateFact facts
@ -101,7 +102,13 @@ validateEnv tables facts settings typeDefaults =
let dupColVs = [ DuplicateColumn tableName col let dupColVs = [ DuplicateColumn tableName col
| Table{..} <- tables | Table{..} <- tables
, col <- findDups . map columnName $ tableColumns ] , col <- findDups . map columnName $ tableColumns ]
let vs = nub $ tableVs ++ factVs ++ dupTableVs ++ dupFactVs ++ dupColVs let dupDimVs = facts
>>- concatMap (dimColumnMappings settingDimPrefix)
>>> sort
>>> groupBy ((==) `on` fst)
>>> filter (map snd >>> nub >>> length >>> (/= 1))
>>> map (head >>> fst >>> DuplicateDimension)
vs = nub $ tableVs ++ factVs ++ dupTableVs ++ dupFactVs ++ dupColVs ++ dupDimVs
if null vs if null vs
then return . Right $ Env tables facts settings typeDefaults then return . Right $ Env tables facts settings typeDefaults
else return . Left $ vs else return . Left $ vs