Пример #1
0
        /// <summary>
        /// Generate compares for type codes
        /// </summary>
        /// <param name="mappingNode"></param>
        /// <param name="columnName"></param>
        /// <param name="value"></param>
        public OnCompareExpression(MappingNode mappingNode, string columnName, int value)
            : base(null, 0, 0)
        {
            Class fkParentClass = mappingNode as Class;

            if (fkParentClass != null)
            {
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(fkParentClass, columnName), 0, 0));
                Add(new NumberExpression(value, 0, 0), "=");
                return;
            }
            MappingTable mappingTable = mappingNode as MappingTable;

            if (mappingTable != null)
            {
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(mappingTable, columnName), 0, 0));
                Add(new NumberExpression(value, 0, 0), "=");
                return;
            }
            else
            {
                throw new ArgumentException("OnCompareExpression: Unexpected mapping node type", "mappingNode");
            }
        }
Пример #2
0
        public OnCompareExpression(MappingNode mappingNode, OidColumn oidColumn, ForeignKeyColumn fkColumn)
            : base(null, 0, 0)
        {
            Class fkParentClass = mappingNode as Class;

            if (fkParentClass != null)
            {
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(oidColumn), 0, 0));
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(fkParentClass, fkColumn), 0, 0), "=");
                return;
            }
            MappingTable mappingTable = mappingNode as MappingTable;

            if (mappingTable != null)
            {
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(oidColumn), 0, 0));
                Add(new RawIdentifierExpression(QualifiedColumnName.Get(mappingTable, fkColumn), 0, 0), "=");
                return;
            }
            else
            {
                throw new ArgumentException("OnCompareExpression: Unexpected mapping node type", "mappingNode");
            }
        }
Пример #3
0
        private void AnnotateExpressionTree(OqlExpression expressionTree)
        {
            foreach (ParameterExpression parExp in expressionTree.GetAll(e => e is ParameterExpression).ToList())
            {
                if (Guid.Empty.Equals(parExp.ParameterValue) || DateTime.MinValue.Equals(parExp.ParameterValue))
                {
                    var parent = parExp.Parent;
                    if (parent.Operator == "=")
                    {
                        var i       = parent.Children.IndexOf(parExp);
                        var nullExp = new NamedConstantExpression("NULL", false, 0, 0);
                        parent.Children[i] = nullExp;
                        ((IManageExpression)nullExp).SetParent(parent);
                        parent.Operator = "IS";
                    }
                    if (parent.Operator == "<>")
                    {
                        var i       = parent.Children.IndexOf(parExp);
                        var nullExp = new NamedConstantExpression("NULL", true, 0, 0);
                        parent.Children[i] = nullExp;
                        ((IManageExpression)nullExp).SetParent(parent);
                        parent.Operator = "IS";
                    }
                }
            }

            foreach (IdentifierExpression exp in expressionTree.GetAll(e => e is IdentifierExpression).ToList())
            {
                string[] arr       = ((string)exp.Value).Split('.');
                string   fieldName = arr[arr.Length - 1];               // In case of embedded or value types this will be overwritten
                Relation relation;
                Class    parentClass = GetParentClass(exp, arr, out fieldName, out relation);

                if (fieldName == "oid")
                {
                    string[] oidColumns = (from c in parentClass.Oid.OidColumns select QualifiedColumnName.Get(c)).ToArray();
                    if (relation != null)
                    {
                        // In these cases we don't need the join to the table of the class owning the oid.
                        // It's sufficient to compare against the foreign keys stored in the owner class' table
                        // or in the mapping table
                        if (relation.MappingTable != null)
                        {
                            oidColumns = (from c in relation.MappingTable.ChildForeignKeyColumns select QualifiedColumnName.Get(relation.MappingTable, c)).ToArray();
                        }
                        else if (relation.Multiplicity == RelationMultiplicity.Element)
                        {
                            oidColumns = (from c in relation.ForeignKeyColumns select QualifiedColumnName.Get(c)).ToArray();
                        }
                    }

                    ParameterExpression parExp   = exp.Siblings[0] as ParameterExpression;
                    var isDirectSingleExpression = exp.Parent.Operator != "=" || oidColumns.Length == 1 && exp.Siblings[0] is ConstantExpression;                     // like "oid = 123"
                    if (parExp == null && !isDirectSingleExpression)
                    {
                        throw new QueryException(10010, $"Expression '{exp.ToString()}' resolves to an oid. It's sibling expression must be a ParameterExpression. But the sibling is {exp.Siblings[0]}");
                    }

                    object[] oidKeys = null;

                    if (!isDirectSingleExpression)
                    {
                        // split the ObjectId or an array into individual parameters
                        oidKeys = ExtractOidKeys(parExp);

                        // Now set the parameter value of the first column
                        if (oidKeys != null)
                        {
                            parExp.ParameterValue = oidKeys[0];
                        }
                    }

                    if (oidColumns.Length > 1 && exp.Children.Count == 0)
                    {
                        OqlExpression equalsExpression = exp.Parent;                          // Must be a = expression like 'xxx.oid = {0}'.
                        // We need some additional parameters for the additional columns.
                        MoveParameterExpression(expressionTree, parExp.Ordinal, oidColumns.Length - 1);

                        // Replace the parent expression with a new AND expression
                        OqlExpression andExpression = new OqlExpression(0, 0);
                        ((IManageExpression)andExpression).SetParent(equalsExpression.Parent);
                        equalsExpression.Parent.Children.Remove(equalsExpression);
                        equalsExpression.Parent.Add(andExpression);
                        // We need to set Parent and Child explicitly.
                        // See comment in IManageExpression.SetParent.
                        // Reuse the original equality expression as first child of the AND expression
                        ((IManageExpression)equalsExpression).SetParent(andExpression);
                        andExpression.Add(equalsExpression);
                        exp.SetAnnotation(anKey, oidColumns[0]);
                        int currentOrdinal = parExp.Ordinal;
                        // Now add the additional children of the AND expression
                        for (int i = 1; i < oidColumns.Length; i++)
                        {
                            OqlExpression newParent = equalsExpression.DeepClone;                             // equality expression and it's both children
                            andExpression.Add(newParent, "AND");
                            ((IManageExpression)newParent).SetParent(andExpression);
                            // Now patch the Annotation and a new parameter to the children
                            IdentifierExpression newIdentExp = (IdentifierExpression)newParent.Children.Where(e => e is IdentifierExpression).First();
                            newIdentExp.SetAnnotation(anKey, oidColumns[i]);
                            ParameterExpression newParExp = (ParameterExpression)newParent.Children.Where(e => e is ParameterExpression).First();
                            if (oidKeys != null)
                            {
                                newParExp.ParameterValue = oidKeys[i];
                            }
                            newParExp.Ordinal = ++currentOrdinal;
                        }
                    }
                    else
                    {
                        int index = 0;
                        if (exp.Children.Count > 0 && exp.Children[0] is IndexExpression)
                        {
                            index = (int)exp.Children[0].Value;
                        }
                        if (index >= oidColumns.Length)
                        {
                            throw new IndexOutOfRangeException("oid index exceeds oid column count");
                        }
                        exp.SetAnnotation(anKey, oidColumns[index]);
                    }
                }
                else
                {
                    Field field = parentClass.FindField(fieldName);
                    if (field != null)
                    {
                        exp.SetAnnotation(anKey, QualifiedColumnName.Get(field.Column));
                    }
                    else
                    {
                        Relation oneTooneRelation = parentClass.Relations.FirstOrDefault(r => r.Multiplicity == RelationMultiplicity.Element && (r.FieldName == fieldName || r.AccessorName == fieldName));
                        if (oneTooneRelation != null)
                        {
                            exp.SetAnnotation(anKey, QualifiedColumnName.Get(oneTooneRelation.ForeignKeyColumns.First()));
                        }

                        else
                        {
                            throw new Exception("Can't find Field mapping for " + fieldName + " in " + exp.Value);
                        }
                    }
                }
            }
        }