示例#1
0
        void BuildParentHierarchy(SelectQuery selectQuery)
        {
            foreach (var table in selectQuery.From.Tables)
            {
                if (table.Source is SelectQuery s)
                {
                    RegisterHierachry(selectQuery, s, new HierarchyInfo(selectQuery, HierarchyType.From, selectQuery));

                    foreach (var setOperator in s.SetOperators)
                    {
                        RegisterHierachry(selectQuery, setOperator.SelectQuery, new HierarchyInfo(selectQuery, HierarchyType.SetOperator, setOperator));
                        BuildParentHierarchy(setOperator.SelectQuery);
                    }

                    BuildParentHierarchy(s);
                }

                foreach (var joinedTable in table.Joins)
                {
                    if (joinedTable.Table.Source is SelectQuery joinQuery)
                    {
                        RegisterHierachry(selectQuery, joinQuery,
                                          new HierarchyInfo(selectQuery, HierarchyType.Join, joinedTable));
                        BuildParentHierarchy(joinQuery);
                    }
                }
            }

            var items = new List <IQueryElement>
            {
                selectQuery.GroupBy,
                selectQuery.Having,
                selectQuery.Where,
                selectQuery.OrderBy
            };

            items.AddRange(selectQuery.Select.Columns);
            if (!selectQuery.Where.IsEmpty)
            {
                items.Add(selectQuery.Where);
            }

            foreach (var item in items)
            {
                IQueryElement parent = null;
                new QueryVisitor().VisitParentFirst(item, e =>
                {
                    if (e is SelectQuery q)
                    {
                        RegisterHierachry(selectQuery, q, new HierarchyInfo(selectQuery, HierarchyType.InnerQuery, parent));
                        BuildParentHierarchy(q);
                        return(false);
                    }

                    parent = e;

                    return(true);
                });
            }
        }
示例#2
0
 static void SetNonQueryParameter(IQueryElement element)
 {
     if (element.ElementType == QueryElementType.SqlParameter)
     {
         ((SqlParameter)element).IsQueryParameter = false;
     }
 }
示例#3
0
        static bool IsAggregationFunction(IQueryElement expr)
        {
            var func = expr as SqlFunction;

            if (func != null)
            {
                switch (func.Name)
                {
                case "Count":
                case "Average":
                case "Min":
                case "Max":
                case "Sum": return(true);

                default: return(false);
                }
            }

            var sqlExpr = expr as SqlExpression;

            if (sqlExpr != null)
            {
                return(sqlExpr.SqlFlags.HasFlag(SqlFlags.Aggregate));
            }

            return(false);
        }
示例#4
0
        public override bool IsParameterDependedElement(IQueryElement element)
        {
            if (base.IsParameterDependedElement(element))
            {
                return(true);
            }

            switch (element.ElementType)
            {
            case QueryElementType.ExprExprPredicate:
            {
                var expr = (SqlPredicate.ExprExpr)element;

                // Oracle saves empty string as null to database, so we need predicate modification before sending query
                //
                if ((expr.Operator == SqlPredicate.Operator.Equal ||
                     expr.Operator == SqlPredicate.Operator.NotEqual ||
                     expr.Operator == SqlPredicate.Operator.GreaterOrEqual ||
                     expr.Operator == SqlPredicate.Operator.LessOrEqual) && expr.WithNull == true)
                {
                    if (expr.Expr1.SystemType == typeof(string) && expr.Expr1.CanBeEvaluated(true))
                    {
                        return(true);
                    }
                    if (expr.Expr2.SystemType == typeof(string) && expr.Expr2.CanBeEvaluated(true))
                    {
                        return(true);
                    }
                }
                break;
            }
            }

            return(false);
        }
        public override bool IsParameterDependedElement(IQueryElement element)
        {
            if (base.IsParameterDependedElement(element))
            {
                return(true);
            }

            switch (element.ElementType)
            {
            case QueryElementType.LikePredicate:
            {
                var like = (SqlPredicate.Like)element;
                if (like.Expr2.ElementType != QueryElementType.SqlValue)
                {
                    return(true);
                }
                break;
            }

            case QueryElementType.SearchStringPredicate:
            {
                var containsPredicate = (SqlPredicate.SearchString)element;
                if (containsPredicate.Expr2.ElementType != QueryElementType.SqlValue)
                {
                    return(true);
                }

                return(false);
            }
            }

            return(false);
        }
示例#6
0
        public static bool TryEvaluateExpression(this IQueryElement expr, EvaluationContext context, out object?result)
        {
            var info = expr.TryEvaluateExpression(context);

            result = info.Value;
            return(info.IsEvaluated);
        }
示例#7
0
 void AddVisited(IQueryElement element, IQueryElement?newElement)
 {
     if (!VisitedElements.ContainsKey(element))
     {
         VisitedElements[element] = newElement;
     }
 }
示例#8
0
 public void VisitAll(IQueryElement element, Action <IQueryElement> action)
 {
     _visitedElements.Clear();
     _all     = true;
     _action2 = action;
     Visit2(element);
 }
示例#9
0
 static void ClearQueryParameter(IQueryElement element)
 {
     if (element is SqlParameter p && p.IsQueryParameter)
     {
         p.IsQueryParameter = false;
     }
 }
示例#10
0
        public IQueryResult Execute(string dbName, IQueryElement queryTree)
        {
            try
            {
                var db = _storage.GetDatabases().SingleOrDefault(d => d.Name == dbName);
                if (db == null)
                {
                    return new DTOQueryResult()
                           {
                               QueryResultType = ResultType.StringResult,
                               StringOutput    = "Database named '" + dbName + "' not exists!"
                           }
                }
                ;

                queryTree = _queryOptimizer.OptimizeQueryPlan(queryTree, new QueryParameters());
                var executer = new EngineExecuter(db, _storage,
                                                  (s, level) => _logger.Log(Name, s, level));
                return(executer.Execute(queryTree));
            }
            catch (Exception ex)
            {
                return(new DTOQueryResult()
                {
                    QueryResultType = ResultType.StringResult, StringOutput = ex.ToString()
                });
            }
        }
示例#11
0
 static bool ContainsTable(ISqlTableSource table, IQueryElement sql)
 {
     return(null != QueryVisitor.Find(sql, e =>
                                      e == table ||
                                      e.ElementType == QueryElementType.SqlField && table == ((SqlField)e).Table ||
                                      e.ElementType == QueryElementType.Column && table == ((SelectQuery.Column)e).Parent));
 }
示例#12
0
 public static bool IsMutable(this IQueryElement expr)
 {
     if (expr.CanBeEvaluated(false))
     {
         return(false);
     }
     return(expr.CanBeEvaluated(true));
 }
示例#13
0
 public void Add(IQueryElement element)
 {
     if (!elements.ContainsKey(element.ElementType))
     {
         elements.Add(element.ElementType, new HashSet <IQueryElement>());
     }
     elements[element.ElementType].Add(element);
 }
		private bool SearchSelectClause(IQueryElement element)
		{
			if (element.ElementType != QueryElementType.SelectClause) return true;

			new QueryVisitor().VisitParentFirst(element, SetNonQueryParameterInSelectClause);

			return false;
		}
示例#15
0
        public static void FindParentFirst(IQueryElement element, Func <IQueryElement, IQueryElement> action)
        {
            var visited = new HashSet <object>();

            var resultList = new LinkedList <IQueryElement>();

            SearchEngine <IQueryElement> .Current.Find(element, resultList,
                                                       new ApplyWhileFalseStrategy <IQueryElement, IQueryElement>(), visited, action);
        }
示例#16
0
        public static TElementType FindFirstOrDefault <TElementType>(IQueryElement element,
                                                                     Func <TElementType, bool> action)
            where TElementType : class, IQueryElement
        {
            Func <TElementType, TElementType> resultFunc = queryElement => action(queryElement)
                ? queryElement
                : null;

            return(FindFirstOrDefault(element, resultFunc));
        }
示例#17
0
 private static bool ContainsTable(ISqlTableSource table, IQueryElement sql)
 {
     return(null !=
            QueryVisitor.FindFirstOrDefault <IQueryExpression>(
                sql,
                e =>
                e == table ||
                e.ElementType == EQueryElementType.SqlField && table == ((ISqlField)e).Table ||
                e.ElementType == EQueryElementType.Column && table == ((IColumn)e).Parent));
 }
示例#18
0
 private static void FindOnceInternal <TElementType>(IQueryElement element, LinkedList <TElementType> resultList,
                                                     HashSet <object> visited)
     where TElementType : class, IQueryElement
 {
     if (element != null)
     {
         SearchEngine <IQueryElement> .Current.Find(element, resultList, new ChildrenFirstStrategy <TElementType>(),
                                                    visited);
     }
 }
示例#19
0
        public bool TryGetValue(IQueryElement expr, [MaybeNullWhen(false)] out EvaluationInfo?info)
        {
            if (_evaluationCache == null)
            {
                info = null;
                return(false);
            }

            return(_evaluationCache.TryGetValue(expr, out info));
        }
示例#20
0
        public static bool?EvaluateBoolExpression(this IQueryElement expr, EvaluationContext context, bool?defaultValue = null)
        {
            var evaluated = expr.EvaluateExpression(context);

            if (evaluated is bool boolValue)
            {
                return(boolValue);
            }

            return(defaultValue);
        }
示例#21
0
        public override QueryDTO Execute(QueryParameters parameters)
        {
            IQueryElement classNameElement = Element(ElementType.CLASS_NAME);
            QueryDTO      classResult      = classNameElement.Execute(parameters);

            if (classResult.Result != null)
            {
                return(classResult);
            }
            var objectClass = classResult.QueryClass;

            if (objectClass.Interface)
            {
                return(new QueryDTO
                {
                    Result = new DTOQueryResult()
                    {
                        QueryResultType = ResultType.StringResult,
                        StringOutput = cantCreateObjectLabel
                    }
                });
            }
            List <Property> propeteries = parameters.Database.Schema.ClassProperties(objectClass);

            var oid     = new Oid(Guid.NewGuid(), parameters.Database.DatabaseId.Dli);
            var toStore = new Storable {
                Oid = oid
            };

            foreach (var attrToSet in AllElements(ElementType.OBJECT_INITIALIZATION_ELEMENT))
            {
                parameters.Subquery = new QueryDTO {
                    Value = toStore, AdditionalValue = propeteries
                };

                var attributeResult = attrToSet.Execute(parameters);
                if (attributeResult.Result != null)
                {
                    return(attributeResult);
                }
            }

            parameters.Storage.Save(parameters.Database.DatabaseId, toStore);
            parameters.Log("New object saved with id: " + oid, MessageLevel.QueryExecution);
            return(new QueryDTO()
            {
                Result = new DTOQueryResult
                {
                    NextResult = null,
                    QueryResultType = ResultType.StringResult,
                    StringOutput = "New object saved with id: " + oid
                }
            });
        }
示例#22
0
        private bool SearchSelectClause(IQueryElement element)
        {
            if (element.ElementType != QueryElementType.SelectClause)
            {
                return(true);
            }

            new QueryVisitor().VisitParentFirst(element, SetNonQueryParameterInSelectClause);

            return(false);
        }
示例#23
0
 static void SetQueryParameter(IQueryElement element)
 {
     if (element.ElementType == QueryElementType.SqlParameter)
     {
         var p = (SqlParameter)element;
         if (p.SystemType == null || p.SystemType.IsScalar(false))
         {
             p.IsQueryParameter = false;
         }
     }
 }
示例#24
0
 static void EnforceBinaryParameters(IQueryElement element)
 {
     if (element.ElementType == QueryElementType.SqlParameter)
     {
         var p = (SqlParameter)element;
         if (p.SystemType == typeof(byte[]) || p.SystemType == typeof(Binary))
         {
             p.IsQueryParameter = true;
         }
     }
 }
示例#25
0
        public static bool NeedsEqual(IQueryElement ex)
        {
            switch (ex.ElementType)
            {
            case QueryElementType.SqlParameter:
            case QueryElementType.SqlField:
            case QueryElementType.Column:
            case QueryElementType.SqlFunction: return(true);
            }

            return(false);
        }
示例#26
0
 public IQueryElement Remove(IQueryElement element)
 {
     if (elements.ContainsKey(element.ElementType))
     {
         Boolean exists = elements[element.ElementType].Remove(element);
         if (exists)
         {
             return(element);
         }
     }
     return(null);
 }
示例#27
0
        public override int Cost(QueryParameters parameters)
        {
            IQueryElement classNameElement = Element(ElementType.CLASS_NAME);
            QueryDTO      classResult      = classNameElement.Execute(parameters);

            if (classResult.QueryClass.ClassId == null)
            {
                throw new ApplicationException("Unknow Class");
            }
            return(Index.Value == null?parameters.ServerSchemaStats.GetClassObjectNumber(parameters.Database.DatabaseId, classResult.QueryClass.ClassId) :
                       parameters.IndexMechanism.GetAvarageObjectFindCost(Index.Key, parameters.ServerSchemaStats.GetClassObjectNumber(parameters.Database.DatabaseId, classResult.QueryClass.ClassId)));
        }
示例#28
0
 static void SetQueryParameter(IQueryElement element)
 {
     if (element.ElementType == QueryElementType.SqlParameter)
     {
         var sqlParameter = (SqlParameter)element;
         if (!(sqlParameter.Type.SystemType == null) && !sqlParameter.Type.SystemType.IsScalar(false))
         {
             return;
         }
         sqlParameter.IsQueryParameter = false;
     }
 }
示例#29
0
        public override QueryDTO Execute(QueryParameters parameters)
        {
            IQueryElement          leftElement  = Element(ElementType.LEFT_OPERAND);
            IQueryElement          rightElement = Element(ElementType.RIGHT_OPERAND);
            IQueryElement          operation    = Element(ElementType.OPERATOR);
            Func <IStorable, bool> expression   = delegate(IStorable databaseObject)
            {
                QueryDTO subquery = new QueryDTO {
                    QueryClass = parameters.Subquery.QueryClass, QueryObjects = new List <IStorable> {
                        databaseObject
                    }
                };
                QueryParameters singleParameter = new QueryParameters {
                    Database = parameters.Database, Storage = parameters.Storage, Subquery = subquery
                };
                var      left  = leftElement.Execute(singleParameter).Value;
                var      right = rightElement.Execute(singleParameter).Value;
                QueryDTO comparisionSubquery = new QueryDTO {
                    Value = left, AdditionalValue = right
                };
                QueryParameters comparisionParameter = new QueryParameters {
                    Subquery = comparisionSubquery
                };
                return((Boolean)operation.Execute(comparisionParameter).Value);
            };

            try
            {
                IEnumerable <IStorable> objects = parameters.Subquery.QueryObjects;

                QueryDTO query = new QueryDTO()
                {
                    QueryClass   = parameters.Subquery.QueryClass,
                    QueryObjects = objects.Where(obj => expression(obj)).ToList()
                };

                return(query);
            }
            catch (NoClassPropertyException exc)
            {
                new DTOQueryResult {
                };
                DTOQueryResult errorResult = new DTOQueryResult
                {
                    NextResult      = null,
                    QueryResultType = ResultType.StringResult,
                    StringOutput    = "Unknown propertyName: " + exc.PropertyName
                };
                return(new QueryDTO {
                    Result = errorResult
                });
            }
        }
示例#30
0
        public override QueryDTO Execute(QueryParameters parameters)
        {
            IQueryElement classNameElement = Element(ElementType.CLASS_NAME);
            QueryDTO      classResult      = classNameElement.Execute(parameters);

            if (classResult.Result != null)
            {
                return(classResult);
            }
            var classToGet     = classResult.QueryClass;
            var classParameter = parameters.Database.Schema.ClassProperties(classToGet);
            var objs           = parameters.Storage.GetAll(parameters.Database.DatabaseId);

            objs = objs.Where(s => s.Properties.All(p => classParameter.Any(cp => cp.PropertyId.Id == p.Key.PropertyId.Id)));
            var selectDto = new QueryDTO {
                QueryClass = classToGet, QueryObjects = objs
            };

            parameters.Subquery = selectDto;

            if (TryGetElement(ElementType.WHERE, out IQueryElement searchCriteria))
            {
                QueryDTO whereDto = searchCriteria.Execute(parameters);
                if (whereDto.Result?.QueryResultType == ResultType.StringResult)
                {
                    return(whereDto);
                }
                objs = whereDto.QueryObjects;
                parameters.Subquery.QueryObjects = objs;
            }
            if (TryGetElement(ElementType.CLASS_PROPERTY, out IQueryElement property))
            {
                var propertyValueDto = property.Execute(parameters);
                if (propertyValueDto.Result?.QueryResultType == ResultType.StringResult)
                {
                    return(propertyValueDto);
                }
                objs = propertyValueDto.QueryObjects;
            }

            var getDto = new DTOQueryResult
            {
                NextResult      = null,
                QueryResultType = ResultType.ReferencesOnly,
                QueryResults    = objs.Select(o => o.Oid).ToList()
            };

            selectDto.Result       = getDto;
            selectDto.QueryClass   = classToGet;
            selectDto.QueryObjects = objs;
            return(selectDto);
        }
示例#31
0
 static void SetQueryParameter(IQueryElement element)
 {
     if (element is SqlParameter p)
     {
         // TimeSpan parameters created for IDS provider and must be converted to literal as IDS doesn't support
         // intervals explicitly
         if ((p.Type.SystemType == typeof(TimeSpan) || p.Type.SystemType == typeof(TimeSpan?)) &&
             p.Type.DataType != DataType.Int64)
         {
             p.IsQueryParameter = false;
         }
     }
 }
		private bool SetNonQueryParameterInSelectClause(IQueryElement element)
		{
			if (element.ElementType == QueryElementType.SqlParameter)
			{
				((SqlParameter)element).IsQueryParameter = false;
				return false;
			}

			if (element.ElementType == QueryElementType.SqlQuery)
			{
				new QueryVisitor().VisitParentFirst(element, SearchSelectClause);
				return false;
			}

			return true;
		}
 /// <summary>
 /// Joins specified queries using 'Or' logcal join.
 /// </summary>
 /// <param name="firstQueryElement">The first query element.</param>
 /// <param name="secondQueryElement">The second query element.</param>
 /// <returns>Returns joined IQueryElement.</returns>
 public static IQueryElement Or(this IQueryElement firstQueryElement, IQueryElement secondQueryElement)
 {
     return new Or(firstQueryElement, secondQueryElement);
 }
示例#34
0
		static void SetQueryParameter(IQueryElement element)
		{
			if (element.ElementType == QueryElementType.SqlParameter)
				((SqlParameter)element).IsQueryParameter = false;
		}
示例#35
0
		/// <summary>
		///     Wrapps the given <paramref name="command" /> into a new QueryPart by storing its QueryCommand statement and parameter
		/// </summary>
		/// <param name="command"></param>
		/// <param name="builder"></param>
		/// <returns></returns>
		public static GenericQueryPart FromCommand(IDbCommand command, IQueryElement builder)
		{
			return new GenericQueryPart(command.CommandText,
				command.Parameters.Cast<IDataParameter>().Select(s => new QueryParameter(s.ParameterName, s.Value)), builder);
		}
示例#36
0
        static bool IsAggregationFunction(IQueryElement expr)
        {
            if (expr is SqlFunction)
                switch (((SqlFunction)expr).Name)
                {
                    case "Count"   :
                    case "Average" :
                    case "Min"     :
                    case "Max"     :
                    case "Sum"     : return true;
                }

            return false;
        }
示例#37
0
 static bool ContainsTable(ISqlTableSource table, IQueryElement sql)
 {
     return null != new QueryVisitor().Find(sql, e =>
         e == table ||
         e.ElementType == QueryElementType.SqlField && table == ((SqlField)e).Table ||
         e.ElementType == QueryElementType.Column   && table == ((SelectQuery.Column)  e).Parent);
 }
示例#38
0
 /// <summary>
 /// Initializes a new instance of the <see cref="And"/> class.
 /// </summary>
 /// <param name="firstElement">The first element.</param>
 /// <param name="secondElement">The second element.</param>
 internal And(IQueryElement firstElement, IQueryElement secondElement)
 {
     _firstElement = firstElement;
     _secondElement = secondElement;
 }