Exemplo n.º 1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="firstIsType"></param>
        /// <param name="isInConstraint"></param>
        /// <param name="lastIsAttribute"></param>
        /// <param name="overrideId">True, if the Path is into a constraint and queried an attribute through Reference 
        /// (Person[Brother.MyKind.Name = 'nice'])</param>
        public void ConvertToSQL(Path path, bool firstIsType, bool isInConstraint, bool lastIsAttribute, bool overrideId)
        {
            int index = 0;

            // Process the first entity
            if (firstIsType)
            {
                Identifier ident = path.Identifiers[index++];

                //	Exception management : entity mapping
                EntityMapping entityMapping = _Mapping.Entities[ident.Value, true];

                // Save entity mapping current context
                entityMappingContext.Push(entityMapping);

                entityModelContext.Push(_Model.GetEntity(ident.Value, true));

                ProcessEntity(ident, false);
            }

            // Restore the first entity context
            EntityMapping firstMapping = (EntityMapping)entityMappingContext.Peek();
            Table firstTable = (Table)tableContext.Peek();

            // Process references
            int lastIndex = lastIsAttribute ? path.Identifiers.Count - 1 : path.Identifiers.Count;
            bool isFirstReference = true;
            ArrayList collEpression = new ArrayList();

            int stackCount = entityMappingContext.Count;

            Evaluant.Uss.Models.Entity previousEntityModel = (Evaluant.Uss.Models.Entity)entityModelContext.Peek();

            for (; index < lastIndex; index++)
            {
                Identifier ident = path.Identifiers[index];

                UnionStatement childrenSubExp = new UnionStatement();
                //childrenSubExp.TableAlias = ident.Value;

                Evaluant.Uss.Models.Reference reference =
                    _Model.GetReference(previousEntityModel.Type, ident.Value, true);

                //	ident.Value isn't a reference but an attribute
                if (_Model.GetReference(previousEntityModel.Type, ident.Value) == null &&
                    _Model.GetAttribute(previousEntityModel.Type, ident.Value) != null)
                {
                    EntityMapping tmpMap = _Mapping.Entities[previousEntityModel.Type];
                    entityMappingContext.Push(tmpMap);

                    entityModelContext.Push(_Model.GetEntity(previousEntityModel.Type));

                    continue;
                }

                Evaluant.Uss.Models.Entity currentModel = previousEntityModel;	//Model.GetEntity(previousEntityModel.Type);
                while (_Model.GetParent(currentModel) != null && reference == null)
                {
                    currentModel = Model.GetParent(currentModel);

                    //	ident.Value isn't a reference but an attribute
                    if (_Model.GetReference(currentModel.Type, ident.Value) == null &&
                        _Model.GetAttribute(currentModel.Type, ident.Value) != null)
                        continue;

                    reference = _Model.GetReference(currentModel.Type, ident.Value);
                    if (reference != null)
                        break;
                }

                // Restore parent context
                EntityMapping parentMapping = index == 0 && isInConstraint ? (EntityMapping)entityMappingContext.Peek() : (EntityMapping)entityMappingContext.Pop();
                Evaluant.Uss.Models.Entity parentModel =
                    index == 0 && isInConstraint ? (Evaluant.Uss.Models.Entity)entityModelContext.Peek() : (Evaluant.Uss.Models.Entity)entityModelContext.Pop();

                string cType = reference.ChildType;
                previousEntityModel = _Model.GetEntity(cType, true);

                Table parentTable = (Table)tableContext.Pop();
                SelectStatement parentQuery = (SelectStatement)queryContext.Pop();

                //	Get tree for reference.ChildType
                IList childrenSubTypes = _Model.GetTree(cType);

                // Get all fullname attributes
                StringCollection attributes = new StringCollection();
                attributes.AddRange(_Model.GetFullAttributesNames(cType));

                Hashtable subQueries = new Hashtable();

                foreach (Evaluant.Uss.Models.Entity child in childrenSubTypes)
                {
                    if (_Mapping.Entities[child.Type] == null)
                        continue;

                    string refName = ident.Value;

                    ReferenceMapping referenceMapping = parentMapping.References[refName];

                    Evaluant.Uss.Models.Entity current = Model.GetEntity(parentMapping.Type);
                    if (referenceMapping == null)
                    {
                        while (_Model.GetParent(current) != null)
                        {
                            current = Model.GetParent(current);
                            referenceMapping = _Mapping.Entities[current.Type].References[refName];
                            if (referenceMapping != null)
                                break;
                        }
                    }

                    if (referenceMapping == null)
                        throw new MappingNotFoundException(String.Format("Reference [{0}] not found in Type [{1}]", ident.Value, parentMapping.Type));

                    RuleMappingCollection ruleMapping = referenceMapping.Rules;

                    // Save child mapping context
                    EntityMapping childMapping = _Mapping.Entities[child.Type];
                    entityMappingContext.Push(childMapping);

                    entityModelContext.Push(_Model.GetEntity(child.Type));

                    // Process child mapping reference
                    ProcessEntity(ident, true);

                    // Restore child context
                    Table childTable = (Table)tableContext.Pop();
                    SelectStatement childQuery = (SelectStatement)queryContext.Pop();
                    childQuery.TableAlias = childTable.TableAlias;
                    childQuery.SelectList = new ExpressionCollection();

                    // Begin to the first INNER JOIN 
                    Table righFirstTableJoinTable = null;

                    // la référence précedente a une contrainte avec Attribute Table de type INNER JOIN
                    if (isFirstReference && parentTable.GetType() == typeof(JoinedTable))
                        righFirstTableJoinTable = parentQuery;

                        // la référence précedente suit une autre référence de type INNER JOIN
                    else if (!isFirstReference && parentTable.GetType() == typeof(JoinedTable))
                    {
                        righFirstTableJoinTable = parentTable;
                        foreach (ILogicExpression exp in parentQuery.WhereClause.SearchCondition)
                        {
                            childQuery.WhereClause.SearchCondition.Add(exp);
                        }
                    }


                        // autre cas
                    else if (parentTable.GetType() == typeof(TableSource))
                    {
                        righFirstTableJoinTable = parentTable;
                        // Ajoute les clauses Wheres de la table courante
                        if (!isInConstraint)
                            foreach (ILogicExpression exp in parentQuery.WhereClause.SearchCondition)
                            {
                                childQuery.WhereClause.SearchCondition.Add(exp);
                            }
                    }
                    else
                    {
                        righFirstTableJoinTable = parentTable;
                        if (righFirstTableJoinTable.TableAlias == null || righFirstTableJoinTable.TableAlias == string.Empty)
                            righFirstTableJoinTable.TableAlias = refName;
                    }

                    Table leftFirstJoinTable = ruleMapping.Count != 1 ? new TableSource(ruleMapping[0], ruleMapping[0].ChildTable, "rule" + index) : childTable;

                    string parentFieldTable = righFirstTableJoinTable.TableAlias;

                    for (int indexId = 0; indexId < referenceMapping.EntityParent.Ids.Count; indexId++)
                    {
                        PrimaryKeyMapping pmk = referenceMapping.EntityParent.Ids[indexId];

                        string idfield = string.Empty;
                        if (righFirstTableJoinTable.GetType() == typeof(TableSource))
                            idfield = referenceMapping.EntityParent.GetIdField(pmk);
                        else
                            idfield = referenceMapping.EntityParent.GetIdFieldAs(pmk);

                        string alias = GetParentIdAlias(referenceMapping.EntityParent, pmk.Field);
                        childQuery.SelectList.Add(new Column(ruleMapping[0], parentFieldTable, idfield, alias));
                    }

                    // Multiple Key
                    foreach (PrimaryKeyMapping pkm in childMapping.Ids)
                        childQuery.SelectList.Add(new Column(ruleMapping[ruleMapping.Count - 1], childQuery.TableAlias, childMapping.GetIdField(pkm), childMapping.GetIdFieldAs(pkm)));


                    // adds all foreign keys contained in the current table that will be used by the next reference
                    if (index + 1 < lastIndex)
                    {
                        Identifier nextIdent = path.Identifiers[index + 1];
                        Models.Entity type = child;

                        while (_Mapping.Entities[type.Type].References[nextIdent.Value] == null)
                            type = Model.GetEntity(type.Inherit, true);

                        if (_Mapping.Entities[type.Type].References[nextIdent.Value] == null)
                            break;

                        RuleMappingCollection rules = _Mapping.Entities[type.Type].References[nextIdent.Value].Rules;

                        if (rules.Count == 1
                            && rules[0].ParentField != referenceMapping.EntityParent.IdFields
                            && rules[0].ParentField != childMapping.IdFields)
                        {
                            foreach (string parentField in rules[0].ParentField.Split(SqlMapperProvider.IDSEP))
                                childQuery.SelectList.Add(new Column(rules[0], childQuery.TableAlias, parentField, parentField));


                        }
                    }

                    // specify relation role name
                    if (!string.IsNullOrEmpty(referenceMapping.DiscriminatorField))
                    {
                        childQuery.WhereClause.SearchCondition.Add(
                            new BinaryLogicExpression(
                            new Column(referenceMapping, leftFirstJoinTable.TableAlias, referenceMapping.DiscriminatorField),
                            BinaryLogicOperator.Equals,
                            new Constant(referenceMapping.DiscriminatorValue, DbType.AnsiString)
                            ));
                    }

                    // inner join on index table FK_Parent
                    JoinedTable firstJoinTable = new JoinedTable(leftFirstJoinTable, TypeJoinedTable.Inner, righFirstTableJoinTable);
                    firstJoinTable.TableAlias = leftFirstJoinTable.TableAlias;

                    for (int indexId = 0; indexId < ruleMapping[0].ParentFields.Length; indexId++)
                    {
                        string childField = ruleMapping[0].ChildFields[indexId];
                        string parentField = ruleMapping[0].ParentFields[indexId];
                        string idField = parentMapping.Ids.Count > indexId ? parentMapping.Ids[indexId].Field : string.Empty;

                        string parentid = ruleMapping[0].GetParentFieldAs();
                        if (righFirstTableJoinTable.GetType() == typeof(TableSource) || (ruleMapping.Count == 1 && parentField != idField))
                            parentid = parentField;

                        firstJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                            new Column(ruleMapping[0], righFirstTableJoinTable.TableAlias, parentid),
                            BinaryLogicOperator.Equals,
                            new Column(ruleMapping[0], leftFirstJoinTable.TableAlias, childField)));
                    }

                    if (!string.IsNullOrEmpty(childMapping.DiscriminatorField))
                    {
                        BinaryLogicExpression discriminator = new BinaryLogicExpression(
                            new Column(childMapping, childQuery.TableAlias, childMapping.DiscriminatorField),
                            BinaryLogicOperator.Equals,
                            new Constant(childMapping.DiscriminatorValue, DbType.AnsiStringFixedLength)
                            );
                        childQuery.WhereClause.SearchCondition.Add(discriminator);
                    }

                    if (ruleMapping.Count == 1)
                        childQuery.FromClause.Add(firstJoinTable);

                    // Fin Construction du premier INNER JOIN 
                    if (isInConstraint && ruleMapping.Count == 1 && index == 0)
                    {
                        // Restore the first entity context
                        Table mainTable = (Table)tableContext.Peek();

                        if (ruleMapping[0].ParentFields.Length > 1)
                        {
                            MultipledKey parentKey = new MultipledKey(ruleMapping[0]);
                            MultipledKey childKey = new MultipledKey(ruleMapping[0]);
                            foreach (string key in ruleMapping[0].ParentFields)
                            {
                                parentKey.Collection.Add(new Column(ruleMapping[0], firstTable.TableAlias, key));       // parent table/column link
                                childKey.Collection.Add(new Column(ruleMapping[0], mainTable.TableAlias, key));        // child table/column link   
                            }
                            linkTableContext.Push(parentKey);       // parent table/column link
                            linkTableContext.Push(childKey);        // child table/column link
                        }
                        else
                        {
                            linkTableContext.Push(new Column(ruleMapping[0], firstTable.TableAlias, ruleMapping[0].ParentField));       // parent table/column link
                            linkTableContext.Push(new Column(ruleMapping[0], mainTable.TableAlias, ruleMapping[0].ParentField));        // child table/column link
                        }
                    }

                    tableContext.Push(firstJoinTable);

                    for (int i = 1; i < ruleMapping.Count; i++)
                    {
                        firstJoinTable = (JoinedTable)tableContext.Pop();

                        JoinedTable lastJoinTable = null;

                        // la référence courante possède une contrainte qui est de type INNER JOIN
                        if (ident.Constraint != null && childTable.GetType() == typeof(JoinedTable))
                        {
                            SelectStatement query = new SelectStatement(referenceMapping);
                            query.TableAlias = childTable.TableAlias;

                            lastJoinTable = new JoinedTable(childQuery, TypeJoinedTable.Inner, firstJoinTable);
                            lastJoinTable.TableAlias = childQuery.TableAlias;
                            lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                                new Column(ruleMapping[i], childQuery.TableAlias, ruleMapping[i].ChildField),
                                BinaryLogicOperator.Equals,
                                new Column(ruleMapping[i], leftFirstJoinTable.TableAlias, ruleMapping[i].ParentField)));


                            query.SelectList.Add(new Column(childMapping.Ids[0], childQuery.TableAlias, childMapping.GetIdField(childMapping.Ids[0])));

                            childQuery = query;
                            tableContext.Push(lastJoinTable);
                        }
                        else
                        {
                            Table leftTable = i == ruleMapping.Count - 1 ? childTable : new TableSource(ruleMapping[i], ruleMapping[i].ChildTable, String.Concat("rule", index + i));
                            Table rightTable = firstJoinTable;

                            lastJoinTable = new JoinedTable(leftTable, TypeJoinedTable.Inner, rightTable);
                            lastJoinTable.TableAlias = leftTable.TableAlias;

                            // inner join on index table FK_Child
                            lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                                new Column(ruleMapping[i], leftTable.TableAlias, ruleMapping[i].ChildField),
                                BinaryLogicOperator.Equals,
                                new Column(ruleMapping[i], rightTable.TableAlias, ruleMapping[i].ParentField)));

                            tableContext.Push(lastJoinTable);
                        }

                        // it's a last rule
                        if (i == ruleMapping.Count - 1)
                        {
                            lastJoinTable = (JoinedTable)tableContext.Pop();

                            if (isInConstraint && index == lastIndex - 1)
                            {
                                // Restore the first entity context
                                EntityMapping mainMapping = (EntityMapping)entityMappingContext.Peek();
                                Table mainTable = (Table)tableContext.Peek();

                                string parentField = firstMapping.GetIdField(firstMapping.Ids[0]);
                                if (path.Identifiers.Count > 1 && (!lastIsAttribute || overrideId))
                                    parentField = "ParentId";

                                linkTableContext.Push(new Column(firstMapping.Ids[0], parentTable.TableAlias, parentField));                // parent table/column link
                                linkTableContext.Push(new Column(firstMapping.Ids[0], mainTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0])));        // child table/column link
                            }

                            if (referenceMapping.DiscriminatorField != null && referenceMapping.Name != "*")
                            {
                                BinaryLogicExpression condition = new BinaryLogicExpression(
                                    new Column(referenceMapping, leftFirstJoinTable.TableAlias, referenceMapping.DiscriminatorField),
                                    BinaryLogicOperator.Equals,
                                    new Constant(ident.Value, DbType.AnsiString));

                                collEpression.Add(condition);
                            }

                            childQuery.FromClause.Add(lastJoinTable);
                            tableContext.Push(lastJoinTable);
                        }
                    }

                    childQuery.SelectList.Insert(0, new Constant(child.Type, DbType.AnsiString, TYPE_ALIAS));

                    int attributeTableIndex = 0;

                    foreach (string attName in attributes)
                    {
                        string attNameAlias = attName.Substring(attName.LastIndexOf(DOT) + 1);
                        string shortAttName = attNameAlias;

                        AttributeMapping am = childMapping.Attributes[shortAttName];

                        // if duplicated attribute name, add an incremented index at the end  (if not already done)
                        if (!_IsAliasColumnComputed)
                        {
                            foreach (string colName in _AliasColumnMapping.Values)
                            {
                                if (colName == shortAttName)
                                {
                                    if (!_AliasColumnMapping.Contains(attName))
                                    {
                                        attNameAlias += ++_AliasColumnIndexNumber;
                                        _AliasColumnMapping.Add(attName, attNameAlias);
                                    }
                                    else
                                        attNameAlias = _AliasColumnMapping[attName].ToString();
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // get the previous computed alias
                            attNameAlias = _AliasColumnMapping[attName].ToString();
                        }

                        if (am != null)
                        {
                            if (am.Table == childMapping.Table)
                            {
                                childQuery.SelectList.Add(new Column(am, childQuery.TableAlias, am.Field, attNameAlias));
                            }
                            if (am.Table != childMapping.Table && childMapping.Ids[0].Generator.Name == GeneratorMapping.GeneratorType.inherited)
                            {
                                //	Add the Left Join for parent attribute table

                                Table left = childQuery.FromClause[0];
                                Table right = new TableSource(am.ParentEntity.Ids[0], am.Table, string.Concat("a", attributeTableIndex++));

                                JoinedTable jt = new JoinedTable(left, TypeJoinedTable.LeftOuter, right);

                                jt.SearchConditions.Add(new BinaryLogicExpression(
                                    new Column(null, right.TableAlias, am.ParentField),
                                    BinaryLogicOperator.Equals,
                                    new Column(null, left.TableAlias, childMapping.GetIdField(childMapping.Ids[0]))
                                    ));

                                childQuery.FromClause[0] = jt;

                                childQuery.SelectList.Add(new Column(am, right.TableAlias, am.Field, attNameAlias));

                                //	Get the parent table and insert a clause and then we don't return the
                                //	records which have a record in a child table

                                string parentType = string.Empty;
                                if (_Model.GetParent(_Model.GetEntity(child.Type)) != null)
                                    parentType = _Model.GetParent(_Model.GetEntity(child.Type)).Type;

                                if (parentType == string.Empty)
                                    continue;

                                EntityMapping parentEntityMapping = _Mapping.Entities[parentType];

                                SelectStatement sel = (SelectStatement)subQueries[parentType];

                                SelectStatement exludeClause = new SelectStatement(null);
                                exludeClause.SelectedAllColumns = true;
                                exludeClause.FromClause.Add(new TableSource(childMapping, childMapping.Table));

                                exludeClause.WhereClause.SearchCondition.Add(new BinaryLogicExpression(
                                    new Column(parentEntityMapping.Ids[0], sel.TableAlias, parentEntityMapping.GetIdField(parentEntityMapping.Ids[0])),
                                    BinaryLogicOperator.Equals,
                                    new Column(childMapping.Ids[0], childMapping.Table, childMapping.GetIdField(childMapping.Ids[0]))));

                                ExistsPredicate ex = new ExistsPredicate(exludeClause);
                                UnaryLogicExpression ua = new UnaryLogicExpression(UnaryLogicOperator.Not, ex);

                                sel.WhereClause.SearchCondition.Add(ua);
                            }
                        }
                        else
                        {
                            childQuery.SelectList.Add(new Constant(DBNull.Value, DbType.AnsiStringFixedLength, attNameAlias));
                        }

                        // Store the correspondance between the alias/column name and the attribute name 
                        if (!_IsAliasColumnComputed && !_AliasColumnMapping.Contains(attName))
                            _AliasColumnMapping.Add(attName, attNameAlias);
                    }

                    //					entityMappingContext.Pop();
                    //					entityModelContext.Pop();
                    tableContext.Pop();

                    //childrenSubExp.SelectExpressions.Add(childQuery);
                    subQueries.Add(child.Type, childQuery);
                }

                foreach (SelectStatement sel in subQueries.Values)
                    childrenSubExp.SelectExpressions.Add(sel);

                childrenSubExp.TableAlias = parentQuery.TableAlias;

                if (parentQuery.SelectList.Count == 0)
                {
                    //parentQuery.SelectedAllColumns = true;
                }

                //isFirstReference = false;
                queryContext.Push(childrenSubExp);

                //entityMappingContext.Push(_Mapping.Entities.GetEntity(cType));

                //entityModelContext.Push(_Model.GetEntity(cType));

                //if(!isInConstraint)
                tableContext.Push(childrenSubExp);

                //				queryContext.Push(childQuery);
            }


            // if only one attribute
            if (lastIsAttribute && index == 0)
            {
                //FROM  [Course] as [e2] 
                //WHERE ([e2].[CourseId] = [e1].[CourseId])

                SelectStatement childQuery = (SelectStatement)queryContext.Pop();
                firstTable = (Table)tableContext.Pop();
                childQuery.FromClause.Add(firstTable);

                Table mainTable = (Table)tableContext.Peek();
                childQuery.WhereClause.SearchCondition.Add(
                        new BinaryLogicExpression(new Column(null, firstTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0])),
                        BinaryLogicOperator.Equals,
                        new Column(null, mainTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0]))));

                queryContext.Push(childQuery);
                tableContext.Push(firstTable);
            }

            if (isInConstraint)
            {
                int max = entityMappingContext.Count;
                if (lastIsAttribute)
                    max--;

                for (int i = max; i > stackCount; i--)
                {
                    entityMappingContext.Pop();
                    entityModelContext.Pop();
                }
            }
        }
Exemplo n.º 2
0
        public override void Visit(Function function)
        {
            bool firstIsType = ((int)_ExprLevel.Peek() == EXPR);
            _ExprLevel.Push(_ExprLevel.Peek());

            ISQLExpression expression = null;

            EntityMapping entityMap = null;
            if (!firstIsType)
                entityMap = (EntityMapping)entityMappingContext.Peek();

            SelectStatement subQuery = new SelectStatement(entityMap);
            int lastIndex = function.Path.Identifiers.Count - 1;

            if (!firstIsType)
            {
                for (int index = 0; index < lastIndex; index++)
                {
                    string refName = function.Path.Identifiers[index].Value;
                    ReferenceMapping refeMap = entityMap.References[refName];

                    //	If refeMap == null, cannot find the reference in the child
                    //	Then try to get it from parent types
                    if (refeMap == null)
                    {
                        Evaluant.Uss.Models.Entity current = Model.GetEntity(entityMap.Type);
                        if (refeMap == null)
                        {
                            while (Model.GetParent(current) != null)
                            {
                                current = Model.GetParent(current);
                                refeMap = _Mapping.Entities[current.Type].References[refName];
                                if (refeMap != null)
                                {
                                    entityMap = refeMap.EntityParent;
                                    break;
                                }
                            }
                        }
                    }

                    if (refeMap == null)
                        throw new SqlMapperException(string.Concat("Cannot find the reference", refName, " from the entity ", entityMap.Type));

                    //entityMap = _Mapping.Entities[refeMap.EntityChild];
                }
            }

            Table currentTable = null;

            switch (function.Type)
            {
                case FunctionEnum.Average:
                    if (firstIsType)
                    {
                        subQuery = (SelectStatement)TransformToSql(function.Path, new string[0], new string[0], true); ;
                        subQuery.TableAlias = CreateUniqueTableAlias();
                        if (subQuery is UnionStatement)
                        {
                            SelectStatement select = new SelectStatement(null);
                            select.FromClause.Add(subQuery as Table);
                            subQuery = select;
                        }

                        tableContext.Push(subQuery as Table);
                        _IsFirstAttribute = true;
                        expression = ProcessAttributes((EntityMapping)entityMappingContext.Peek(), function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery.SelectList = new ExpressionCollection();
                        subQuery.SelectList.Add(new AggregateFunction(null, AggregateFunctionEnum.Avg, expression));
                        sqlExpressionContext.Push(subQuery);
                    }
                    else
                    {
                        currentTable = new TableSource(entityMap, ((TableSource)tableContext.Peek()).TableName, CreateUniqueTableAlias());
                        tableContext.Push(currentTable);
                        queryContext.Push(subQuery);

                        ConvertToSQL(function.Path, false, true, true);
                        expression = ProcessAttributes(entityMap, function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery = (SelectStatement)queryContext.Peek();

                        if (subQuery.GetType() == typeof(UnionStatement))
                        {
                            SelectStatement sel = new SelectStatement(null);

                            subQuery.TableAlias = CreateUniqueTableAlias();
                            sel.FromClause.Add(subQuery);

                            sel.SelectList = new ExpressionCollection();
                            sel.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Avg, expression));
                            sqlExpressionContext.Push(sel);
                        }
                        else
                        {
                            subQuery.SelectList = new ExpressionCollection();
                            subQuery.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Avg, expression));
                            sqlExpressionContext.Push(subQuery);
                        }

                        // link tables for inline views
                        ((SelectStatement)sqlExpressionContext.Peek()).WhereClause.SearchCondition.Add(new BinaryLogicExpression(new Column(null, subQuery.TableAlias, "ParentId"), BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));

                        tableContext.Pop();
                        queryContext.Pop();
                    }
                    break;
                case FunctionEnum.Count:
                    if (firstIsType)
                    {
                        subQuery = (SelectStatement)TransformToSql(function.Path, new string[0], null, false);
                        subQuery.TableAlias = CreateUniqueTableAlias();
                        if (subQuery is UnionStatement)
                        {
                            SelectStatement select = new SelectStatement(null);
                            select.FromClause.Add(subQuery as Table);
                            subQuery = select;
                        }

                        subQuery.SelectList = new ExpressionCollection();
                        subQuery.SelectList.Add(new AggregateFunction(null, AggregateFunctionEnum.Count, new Constant("*", DbType.StringFixedLength)));
                        sqlExpressionContext.Push(subQuery);
                    }
                    else
                    {
                        currentTable = new TableSource(entityMap, entityMap.Table, CreateUniqueTableAlias());
                        tableContext.Push(currentTable);
                        queryContext.Push(subQuery);

                        ConvertToSQL(function.Path, false, true, false);
                        currentTable = (Table)tableContext.Peek();
                        subQuery = (SelectStatement)queryContext.Peek();

                        if (subQuery.GetType() == typeof(UnionStatement))
                        {
                            SelectStatement sel = new SelectStatement(null);

                            subQuery.TableAlias = CreateUniqueTableAlias();
                            sel.FromClause.Add(subQuery);

                            sel.SelectList = new ExpressionCollection();
                            sel.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Count, new Constant("*", DbType.StringFixedLength)));
                            sqlExpressionContext.Push(sel);
                        }
                        else
                        {
                            subQuery.SelectList = new ExpressionCollection();
                            subQuery.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Count, new Constant("*", DbType.StringFixedLength)));
                            sqlExpressionContext.Push(subQuery);
                        }

                        // link tables for inline views
                        ((SelectStatement)sqlExpressionContext.Peek()).WhereClause.SearchCondition.Add(new BinaryLogicExpression(new Column(null, subQuery.TableAlias, "ParentId"), BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));

                        tableContext.Pop();
                        queryContext.Pop();
                    }
                    break;

                case FunctionEnum.Exists:
                    currentTable = new TableSource(entityMap, entityMap.Table, CreateUniqueTableAlias());
                    tableContext.Push(currentTable);
                    queryContext.Push(subQuery);

                    ConvertToSQL(function.Path, false, true, false);
                    subQuery = (SelectStatement)queryContext.Peek();

                    // the exists function just need ids fields 
                    // do not list attribute field to avoid problems with data type fields (text, ntext, image for sql server)

                    // Remove none needed selected item, according to the path

                    // no references: keep Type, Id (2 fields)
                    // references: keep Type, IdParent, Id (3 fields)
                    int keepFieldNb = (function.Path.Identifiers.Count == 1) ? 2 : 3;

                    if (subQuery is UnionStatement)
                    {
                        foreach (SelectStatement select in ((UnionStatement)subQuery).SelectExpressions)
                        {
                            for (int i = select.SelectList.Count - 1; i >= keepFieldNb; i--)
                                select.SelectList.RemoveAt(i);

                            // link tables for inline views
                            Column cLeft = linkTableContext.Pop() as Column;
                            Column cRight = linkTableContext.Pop() as Column;

                            if (cLeft is MultipledKey)
                            {
                                for (int index = 0; index < ((MultipledKey)cLeft).Collection.Count; index++)
                                {
                                    select.WhereClause.SearchCondition.Add(new BinaryLogicExpression(((MultipledKey)cLeft).Collection[index], BinaryLogicOperator.Equals, ((MultipledKey)cRight).Collection[index]));
                                }
                            }
                            else
                            {
                                select.WhereClause.SearchCondition.Add(new BinaryLogicExpression(cLeft, BinaryLogicOperator.Equals, cRight));
                            }
                        }
                    }
                    else
                    {
                        for (int i = subQuery.SelectList.Count - 1; i >= keepFieldNb; i--)
                            subQuery.SelectList.RemoveAt(i);

                        // link tables for inline views
                        subQuery.WhereClause.SearchCondition.Add(new BinaryLogicExpression(linkTableContext.Pop() as Column, BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));
                    }

                    subQuery.SelectedAllColumns = true;
                    expression = new ExistsPredicate(subQuery);
                    sqlExpressionContext.Push(expression);

                    tableContext.Pop();
                    queryContext.Pop();
                    break;

                case FunctionEnum.IsNull:
                    _IsFirstAttribute = true;
                    expression = new IsNullPredicate(ProcessAttributes(entityMap, function.Path.Identifiers[lastIndex].Value, false));
                    sqlExpressionContext.Push(expression);
                    break;

                case FunctionEnum.Max:
                    if (firstIsType)
                    {
                        subQuery = (SelectStatement)TransformToSql(function.Path, new string[0], new string[0], true);
                        subQuery.TableAlias = CreateUniqueTableAlias();
                        if (subQuery is UnionStatement)
                        {
                            SelectStatement select = new SelectStatement(null);
                            select.FromClause.Add(subQuery as Table);
                            subQuery = select;
                        }

                        tableContext.Push(subQuery as Table);
                        _IsFirstAttribute = true;
                        expression = ProcessAttributes((EntityMapping)entityMappingContext.Peek(), function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery.SelectList = new ExpressionCollection();
                        subQuery.SelectList.Add(new AggregateFunction(null, AggregateFunctionEnum.Max, expression));
                        sqlExpressionContext.Push(subQuery);
                    }
                    else
                    {
                        currentTable = new TableSource(entityMap, ((TableSource)tableContext.Peek()).TableName, CreateUniqueTableAlias());
                        tableContext.Push(currentTable);
                        queryContext.Push(subQuery);
                        entityMappingContext.Push(entityMap);
                        ConvertToSQL(function.Path, false, true, true);
                        
                        EntityMapping lastEM = (EntityMapping)entityMappingContext.Peek();

                        //entityModelContext.Pop();
                        entityModelContext.Peek();

                        expression = ProcessAttributes(lastEM, function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery = (SelectStatement)queryContext.Peek();

                        if (subQuery.GetType() == typeof(UnionStatement))
                        {
                            SelectStatement sel = new SelectStatement(null);

                            subQuery.TableAlias = CreateUniqueTableAlias();
                            sel.FromClause.Add(subQuery);

                            sel.SelectList = new ExpressionCollection();
                            sel.SelectList.Add(new AggregateFunction(lastEM, AggregateFunctionEnum.Max, expression));
                            sqlExpressionContext.Push(sel);
                        }
                        else
                        {
                            subQuery.SelectList = new ExpressionCollection();
                            subQuery.SelectList.Add(new AggregateFunction(lastEM, AggregateFunctionEnum.Max, expression));
                            sqlExpressionContext.Push(subQuery);
                        }

                        // link tables for inline views
                        if (linkTableContext.Count > 0)
                            ((SelectStatement)sqlExpressionContext.Peek()).WhereClause.SearchCondition.Add(
                                    new BinaryLogicExpression(new Column(null, subQuery.TableAlias, "ParentId"), BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));

                        tableContext.Pop();
                        queryContext.Pop();
                        entityMappingContext.Pop();
                    }
                    break;

                case FunctionEnum.Min:
                    if (firstIsType)
                    {
                        subQuery = (SelectStatement)TransformToSql(function.Path, new string[0], new string[0], true); ;
                        subQuery.TableAlias = CreateUniqueTableAlias();
                        if (subQuery is UnionStatement)
                        {
                            SelectStatement select = new SelectStatement(null);
                            select.FromClause.Add(subQuery as Table);
                            subQuery = select;
                        }

                        tableContext.Push(subQuery as Table);
                        _IsFirstAttribute = true;
                        expression = ProcessAttributes((EntityMapping)entityMappingContext.Peek(), function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery.SelectList = new ExpressionCollection();
                        subQuery.SelectList.Add(new AggregateFunction(null, AggregateFunctionEnum.Min, expression));
                        sqlExpressionContext.Push(subQuery);
                    }
                    else
                    {
                        currentTable = new TableSource(entityMap, ((TableSource)tableContext.Peek()).TableName, CreateUniqueTableAlias());
                        tableContext.Push(currentTable);
                        queryContext.Push(subQuery);

                        ConvertToSQL(function.Path, false, true, true);
                        expression = ProcessAttributes(entityMap, function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery = (SelectStatement)queryContext.Peek();

                        if (subQuery.GetType() == typeof(UnionStatement))
                        {
                            SelectStatement sel = new SelectStatement(null);

                            subQuery.TableAlias = CreateUniqueTableAlias();
                            sel.FromClause.Add(subQuery);

                            sel.SelectList = new ExpressionCollection();
                            sel.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Min, expression));
                            sqlExpressionContext.Push(sel);
                        }
                        else
                        {
                            subQuery.SelectList = new ExpressionCollection();
                            subQuery.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Min, expression));
                            sqlExpressionContext.Push(subQuery);
                        }

                        // link tables for inline views
                        ((SelectStatement)sqlExpressionContext.Peek()).WhereClause.SearchCondition.Add(new BinaryLogicExpression(new Column(null, subQuery.TableAlias, "ParentId"), BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));

                        tableContext.Pop();
                        queryContext.Pop();
                    }
                    break;

                case FunctionEnum.Sum:
                    if (firstIsType)
                    {
                        subQuery = (SelectStatement)TransformToSql(function.Path, new string[0], new string[0], true);
                        subQuery.TableAlias = CreateUniqueTableAlias();

                        if (subQuery is UnionStatement)
                        {
                            SelectStatement select = new SelectStatement(null);
                            select.FromClause.Add(subQuery as Table);
                            subQuery = select;
                        }

                        tableContext.Push(subQuery as Table);
                        _IsFirstAttribute = true;
                        expression = ProcessAttributes((EntityMapping)entityMappingContext.Peek(), function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery.SelectList = new ExpressionCollection();
                        subQuery.SelectList.Add(new AggregateFunction(null, AggregateFunctionEnum.Sum, expression));
                        sqlExpressionContext.Push(subQuery);
                    }
                    else
                    {
                        currentTable = new TableSource(entityMap, ((TableSource)tableContext.Peek()).TableName, CreateUniqueTableAlias());
                        tableContext.Push(currentTable);
                        queryContext.Push(subQuery);

                        ConvertToSQL(function.Path, false, true, true);
                        expression = ProcessAttributes(entityMap, function.Path.Identifiers[lastIndex].Value, false, true);

                        subQuery = (SelectStatement)queryContext.Peek();
                        if (subQuery.GetType() == typeof(UnionStatement))
                        {
                            SelectStatement sel = new SelectStatement(null);

                            subQuery.TableAlias = CreateUniqueTableAlias();
                            sel.FromClause.Add(subQuery);

                            sel.SelectList = new ExpressionCollection();
                            sel.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Sum, expression));
                            sqlExpressionContext.Push(sel);
                        }
                        else
                        {
                            subQuery.SelectList = new ExpressionCollection();
                            subQuery.SelectList.Add(new AggregateFunction(entityMap, AggregateFunctionEnum.Sum, expression));
                            sqlExpressionContext.Push(subQuery);
                        }

                        // link tables for inline views
                        ((SelectStatement)sqlExpressionContext.Peek()).WhereClause.SearchCondition.Add(new BinaryLogicExpression(new Column(null, subQuery.TableAlias, "ParentId"), BinaryLogicOperator.Equals, linkTableContext.Pop() as Column));

                        tableContext.Pop();
                        queryContext.Pop();
                    }
                    break;
            }

            _ExprLevel.Pop();
        }
Exemplo n.º 3
0
        public override void Visit(ExistsPredicate predicate)
        {
            if (predicate.SubQuery is UnionStatement)
            {
                _Query.Append(OPENBRACE);
                bool firstElement = true;

                UnionStatement union = predicate.SubQuery as UnionStatement;
                foreach (SelectStatement select in union.SelectExpressions)
                {
                    if (!firstElement)
                        _Query.Append(OR);
                    _Query.Append(EXISTS).Append(OPENBRACE);
                    select.Accept(this);
                    _Query.Append(CLOSEBRACE);
                    firstElement = false;
                }
                _Query.Append(CLOSEBRACE);
            }
            else
            {
                _Query.Append(EXISTS).Append(OPENBRACE);
                predicate.SubQuery.Accept(this);
                _Query.Append(CLOSEBRACE);
            }
        }
Exemplo n.º 4
0
        public ISQLExpression TransformToSql(Path path, string[] attributes, string[] orderby, bool lastIsAttribute)
        {
            //	Get all the entity of the hierarchy (parent and children)

            string baseType = path.Identifiers[0].Value;

            IList tree = _Model.GetTree(baseType);

            _UserAttributes = new StringCollection();

            //	attributes == null => don't get attributes

            if (attributes != null)
            {
                //	Get the specified class and store all the inherited classes 
                Evaluant.Uss.Models.Entity parent = null;
                Evaluant.Uss.Models.EntityCollection parents = new Evaluant.Uss.Models.EntityCollection();

                if (path.Identifiers.Count == 1)
                    parent = _Model.GetEntity(path.Identifiers[0].Value);
                else
                {
                    string refName = path.Identifiers[path.Identifiers.Count - 1].Value;
                    string firstType = path.Identifiers[0].Value;
                    string lastType = firstType;
                    string nextRefName = string.Empty;

                    for (int i = 0; i < path.Identifiers.Count - 1; i++)
                    {
                        nextRefName = path.Identifiers[i + 1].Value;

                        //	The next identifier isn't a reference but an attribute
                        if (_Model.GetReference(lastType, nextRefName) == null &&
                            _Model.GetAttribute(lastType, nextRefName) != null)
                            continue;

                        lastType = _Model.GetReference(lastType, nextRefName, true).ChildType;
                    }
                    parent = _Model.GetEntity(lastType);
                }

                if (parent == null)
                    throw new Evaluant.Uss.Models.ModelElementNotFoundException(String.Format("The type [{0}] was not found. Check your metadata.", baseType));

                if (attributes.Length == 0)
                {
                    //	attributes.Length == 0 => get all attributes
                    _UserAttributes.AddRange(_Model.GetFullAttributesNames(parent.Type));
                }
                else
                {
                    //	attributes.Length > 0 => get the user defined attributes
                    foreach (string attName in attributes)
                    {
                        _UserAttributes.Add(_Model.GetFullAttributeName(attName, parent.Type));
                    }
                }
            }

            UnionStatement sqlQuery = new UnionStatement();

            //	Process each entity of the tree and put the corresponding sql query
            //	into a UnionStatement

            StringCollection processedTables = new StringCollection();

            _BaseType = path.Identifiers[0].Value;

            Hashtable expressions = new Hashtable();

            string commonIdField = string.Empty;

            foreach (Evaluant.Uss.Models.Entity entity in tree)
            {
                //	If the entity doesn't have a mapping => don't process it
                if (_Mapping.Entities[entity.Type] == null)
                    continue;

                path.Identifiers[0].Value = entity.Type;

                EntityMapping entityMapping = _Mapping.Entities[entity.Type];

                if (processedTables.Contains(entityMapping.Table))
                    continue;

                processedTables.Add(entityMapping.Table);

                _ExprLevel.Push(PATH);
                SelectStatement exp = (SelectStatement)TransformToSql(path, _UserAttributes, true, lastIsAttribute);
                _ExprLevel.Pop();

                // process alias name calculation only once  
                _IsAliasColumnComputed = true;

                expressions.Add(entity.Type, exp);

                string parentType = string.Empty;
                if (_Model.GetParent(_Model.GetEntity(entity.Type)) != null)
                    parentType = _Model.GetParent(_Model.GetEntity(entity.Type)).Type;

                if (parentType == string.Empty || entityMapping.Ids[0].Generator.Name != GeneratorMapping.GeneratorType.inherited || parentType != _BaseType)
                    continue;

                EntityMapping parentMapping = _Mapping.Entities[parentType];

                SelectStatement sel = (SelectStatement)expressions[parentType];

                SelectStatement exludeClause = new SelectStatement(null);
                exludeClause.SelectedAllColumns = true;
                exludeClause.FromClause.Add(new TableSource(entityMapping, entityMapping.Table));

                string parentIdField = parentMapping.GetIdField(parentMapping.Ids[0]);
                if (path.Identifiers.Count > 1)
                    parentIdField = "ParentId";

                exludeClause.WhereClause.SearchCondition.Add(new BinaryLogicExpression(
                    new Column(parentMapping.Ids[0], sel.TableAlias, parentIdField),
                    BinaryLogicOperator.Equals,
                    new Column(entityMapping.Ids[0], entityMapping.Table, entityMapping.GetIdField(entityMapping.Ids[0]))));

                ExistsPredicate ex = new ExistsPredicate(exludeClause);
                UnaryLogicExpression ua = new UnaryLogicExpression(UnaryLogicOperator.Not, ex);

                sel.WhereClause.SearchCondition.Add(ua);

                //sqlQuery.SelectExpressions.Add(exp);
            }


            //If there are many tables in the union statement, make the id fields aliases identical
            bool isFirstSelect = true;
            ArrayList idAliases = new ArrayList();
            foreach (ISQLExpression exp in expressions.Values)
            {
                SelectStatement innerSelect = (SelectStatement)exp;
                if (isFirstSelect)
                {
                    foreach (ISQLExpression innerExp in innerSelect.SelectList)
                    {
                        if (innerExp is Column && ((Column)innerExp).Alias.StartsWith(EntityMapping.PREFIX_ID))
                            idAliases.Add(((Column)innerExp).Alias);
                    }
                    isFirstSelect = false;
                }
                else
                {
                    int i = 0;
                    foreach (ISQLExpression innerExp in innerSelect.SelectList)
                    {
                        if (innerExp is Column && ((Column)innerExp).Alias.StartsWith(EntityMapping.PREFIX_ID))
                        {
                            if (idAliases.Count > i)
                                ((Column)innerExp).Alias = (string)idAliases[i];
                            else
                                throw new UniversalStorageException(string.Format("entity Id fields do not meet the one of its parent '{0}'", _BaseType));
                            i++;
                        }
                    }
                }

                //Add the SelectStatement to the unionStatement
                sqlQuery.SelectExpressions.Add(innerSelect);
            }

            if (entityMappingContext.Count == 0)
            {
                throw new MappingNotFoundException(String.Format("Type not found [{0}]", baseType));
            }

            EntityMapping em = (EntityMapping)entityMappingContext.Peek();

            if (orderby != null)
            {
                for (int i = 0; i < orderby.Length; i++)
                {
                    string order = orderby[i].Trim();
                    if (order != string.Empty)
                    {
                        bool isDesc = false;
                        OrderByClauseColumn col = null;
                        int indexOfDirection = 0;
                        if ((indexOfDirection = order.ToLower().IndexOf(" desc")) > 0)
                        {
                            order = order.Substring(0, indexOfDirection).Trim();
                            isDesc = true;
                        }
                        else if ((indexOfDirection = order.ToLower().IndexOf(" asc")) > 0)
                            order = order.Substring(0, indexOfDirection).Trim();

                        if (order == "Id")
                        {
                            col = new OrderByClauseColumn(em.GetIdField(em.Ids[0]), true);
                        }
                        else
                        {
                            AttributeMapping orderMapping = em.Attributes[order, true];
                            string orderColName = orderMapping.Name;
                            string fullAttributeName = _Model.GetFullAttributeName(orderMapping.Name, orderMapping.ParentEntity.Type);
                            if (_AliasColumnMapping.Contains(fullAttributeName))
                                orderColName = _AliasColumnMapping[fullAttributeName].ToString();

                            col = new OrderByClauseColumn(orderColName, isDesc);
                        }
                        sqlQuery.OrderByClause.Add(col);
                    }
                }
            }

            if (sqlQuery.OrderByClause.Count == 0 && !lastIsAttribute && orderby != null)
            {
                //  Id position = 1 if loading single Entity (Person or Person[Name = 'p1']
                //  Id position = 2 if loading referenced Entity (Person.Partners or Person[Name = 'p1'].Partners)
                int idPosition = (path.Identifiers.Count == 1) ? 1 : 2;
                if (idPosition == 2)
                    idPosition = _Mapping.Entities[path.Identifiers[0].Value].Ids.Count + 1;
                Column columnId = (Column)sqlQuery.SelectExpressions[0].SelectList[idPosition];
                // get the Id alias of the first SelectStatement in case of UnionStatement
                if (sqlQuery.SelectExpressions[0] is UnionStatement)
                {
                    columnId = (Column)((UnionStatement)sqlQuery.SelectExpressions[0]).SelectExpressions[0].SelectList[idPosition];
                }

                EntityMapping entityMap = null;
                if (columnId.TagMapping is PrimaryKeyMapping)
                    entityMap = ((PrimaryKeyMapping)columnId.TagMapping).ParentEntity;
                if (columnId.TagMapping is RuleMapping)
                {
                    if (idPosition == 2)
                        entityMap = _Mapping.Entities[((RuleMapping)columnId.TagMapping).ParentReference.EntityChild];
                    else
                        entityMap = ((RuleMapping)columnId.TagMapping).ParentReference.EntityParent;

                }

                if (entityMap != null)
                {
                    SelectStatement selectQuery = sqlQuery;
                    if (sqlQuery is UnionStatement && ((UnionStatement)sqlQuery).SelectExpressions.Count > 0)
                        selectQuery = ((UnionStatement)sqlQuery).SelectExpressions[0] as SelectStatement;
                    foreach (PrimaryKeyMapping pkm in entityMap.Ids)
                    {
                        OrderByClauseColumn orderCol = null;
                        foreach (ISQLExpression exp in selectQuery.SelectList)
                        {
                            if (exp is Column && exp.TagMapping == pkm)
                            {
                                Column col = exp as Column;
                                orderCol = new OrderByClauseColumn(col.Alias);
                                break;
                            }
                        }
                        if (orderCol == null)
                        {

                            AttributeMapping attribute = entityMap.Attributes.FindByField(pkm.Field);

                            string idFieldAlias = pkm.ParentEntity.GetIdFieldAs(pkm);

                            foreach (string alias in _AliasColumnMapping.Keys)
                            {
                                if (alias.Contains(".") && attribute != null)
                                {
                                    if (alias.Split('.')[1] == attribute.Name)
                                    {
                                        orderCol = new OrderByClauseColumn(_AliasColumnMapping[alias].ToString());
                                        break;
                                    }
                                }
                                else if (alias == idFieldAlias)
                                {
                                    orderCol = new OrderByClauseColumn(_AliasColumnMapping[alias].ToString());
                                    break;
                                }
                            }

                            if (orderCol == null)
                                orderCol = new OrderByClauseColumn(em.GetIdFieldAs(pkm));

                        }
                        if (orderCol != null)
                            sqlQuery.OrderByClause.Add(orderCol);
                    }
                }


            }

            return sqlQuery;
        }
Exemplo n.º 5
0
		public virtual void Visit(ExistsPredicate predicate)
		{
            _Query.Append(EXISTS).Append(OPENBRACE);
			predicate.SubQuery.Accept(this);
			_Query.Append(CLOSEBRACE);
		}