/// <inheritdoc cref="QueryTimeColumn.SetLookupStatus"/> public static void FindLookups(ISqlQueryBuilder qb) { //if there is only one table then user us selecting stuff from the lookup table only if (qb.TablesUsedInQuery.Count == 1) { return; } QueryTimeColumn.SetLookupStatus(qb.SelectColumns.ToArray(), qb.TablesUsedInQuery); }
/// <inheritdoc/> public void AddColumn(IColumn col) { QueryTimeColumn toAdd = new QueryTimeColumn(col); //if it is new, add it to the list if (!SelectColumns.Contains(toAdd)) { SelectColumns.Add(toAdd); SQLOutOfDate = true; } }
/// <summary> /// Populates _sql (SQL property) and resolves all parameters, filters containers etc. Basically Finalizes this query builder /// </summary> public void RegenerateSQL() { SelectColumns.Sort(); //things we discover below, set them all to default values again _pivotDimension = null; _axisAppliesToDimension = null; _axis = null; _isCohortIdentificationAggregate = false; ParameterManager.ClearNonGlobals(); if (_queryLevelParameterProvider != null) { ParameterManager.AddParametersFor(_queryLevelParameterProvider, ParameterLevel.QueryLevel); } TableInfo primary; TablesUsedInQuery = SqlQueryBuilderHelper.GetTablesUsedInQuery(this, out primary, _forceJoinsToTheseTables); var tables = _forceJoinsToTheseTables != null ? TablesUsedInQuery.Union(_forceJoinsToTheseTables).ToList() : TablesUsedInQuery; if (!tables.Any()) { throw new QueryBuildingException("No tables could be identified for the query. Try adding a column or a force join"); } //get the database language syntax based on the tables used in the query _syntaxHelper = SqlQueryBuilderHelper.GetSyntaxHelper(tables); //tell the count column what language it is if (_countColumn != null) { _isCohortIdentificationAggregate = _aggregateConfigurationIfAny != null && _aggregateConfigurationIfAny.IsCohortIdentificationAggregate; //if it is not a cic aggregate then make sure it has an alias e.g. count(*) AS MyCount. cic aggregates take extreme liberties with this field like passing in 'distinct chi' and '*' and other wacky stuff that is so not cool _countColumn.SetQuerySyntaxHelper(_syntaxHelper, !_isCohortIdentificationAggregate); } IAggregateHelper aggregateHelper = _syntaxHelper.AggregateHelper; if (_pivotID != -1) { try { _pivotDimension = SelectColumns.Single( qtc => qtc.IColumn is AggregateDimension && ((AggregateDimension)qtc.IColumn).ID == _pivotID); } catch (Exception e) { throw new QueryBuildingException("Problem occurred when trying to find PivotDimension ID " + _pivotID + " in SelectColumns list", e); } } foreach (AggregateDimension dimension in SelectColumns.Select(c => c.IColumn).Where(e => e is AggregateDimension)) { var availableAxis = dimension.AggregateContinuousDateAxis; if (availableAxis != null) { if (_axis != null) { throw new QueryBuildingException( "Multiple dimensions have an AggregateContinuousDateAxis within the same configuration (Dimensions " + _axisAppliesToDimension.GetRuntimeName() + " and " + dimension.GetRuntimeName() + ")"); } else { _axis = availableAxis; _axisAppliesToDimension = dimension; } } } if (_pivotDimension != null) { if (_pivotDimension.IColumn == _axisAppliesToDimension) { throw new QueryBuildingException("Column " + _pivotDimension.IColumn + " is both a PIVOT and has an AXIS configured on it, you cannot have both."); } } //work out all the filters Filters = SqlQueryBuilderHelper.GetAllFiltersUsedInContainerTreeRecursively(RootFilterContainer); //tell the manager about them ParameterManager.AddParametersFor(Filters); if (AggregateTopX != null) { SqlQueryBuilderHelper.HandleTopX(this, _syntaxHelper, AggregateTopX.TopX); } else { SqlQueryBuilderHelper.ClearTopX(this); } //if user wants to force join to some other tables that don't appear in the SELECT list, who are we to stop him! if (_forceJoinsToTheseTables != null) { foreach (TableInfo t in _forceJoinsToTheseTables) { if (!TablesUsedInQuery.Contains(t)) { TablesUsedInQuery.Add(t); ParameterManager.AddParametersFor(t); } //if user has force joined to a primary extraction table if (t.IsPrimaryExtractionTable) { if (primary == null) //we don't currently know the primary (i.e. none of the SELECT columns were from primary tables so use this table as primary) { primary = t; } else if (primary.ID == t.ID) //we know the primary already but it is the same table so thats fine { continue; } else { //this isn't fine throw new QueryBuildingException("You chose to FORCE a join to table " + t + " which is marked IsPrimaryExtractionTable but you have also selected a column called " + primary + " which is also an IsPrimaryExtractionTable (cannot have 2 different primary extraction tables)"); } } } } this.PrimaryExtractionTable = primary; SqlQueryBuilderHelper.FindLookups(this); JoinsUsedInQuery = SqlQueryBuilderHelper.FindRequiredJoins(this); var queryLines = new List <CustomLine>(); _sql = ""; ValidateDimensions(); //assuming we were not told to ignore the writing out of parameters! if (!DoNotWriteOutParameters) { foreach (ISqlParameter parameter in ParameterManager.GetFinalResolvedParametersList()) { queryLines.Add(new CustomLine(QueryBuilder.GetParameterDeclarationSQL(parameter), QueryComponent.VariableDeclaration)); } } CompileCustomLinesInStageAndAddToList(QueryComponent.VariableDeclaration, queryLines); //put the name in as SQL comments followed by the SQL e.g. the name of an AggregateConfiguration or whatever GetSelectSQL(queryLines); queryLines.Add(new CustomLine(SqlQueryBuilderHelper.GetFROMSQL(this), QueryComponent.FROM)); CompileCustomLinesInStageAndAddToList(QueryComponent.JoinInfoJoin, queryLines); queryLines.Add(new CustomLine(SqlQueryBuilderHelper.GetWHERESQL(this), QueryComponent.WHERE)); CompileCustomLinesInStageAndAddToList(QueryComponent.WHERE, queryLines); GetGroupBySQL(queryLines, aggregateHelper); queryLines = queryLines.Where(l => !string.IsNullOrWhiteSpace(l.Text)).ToList(); _sql = aggregateHelper.BuildAggregate(queryLines, _axis); }