예제 #1
0
        public IParseResult TryLoadRegexPattern(string regex)
        {
            _wasInitialised     = false;
            _expressionMetaData = null;
            _regularExpression  = null;

            if (_replaceWildCards)
            {
                regex = regex.ReplaceRegexWildCards();
            }

            regex = regex.TrimStart(SpecialCharacters.StartsWith).TrimEnd(SpecialCharacters.EndsWith);
            var result = new RegularExpressionFactory(_alphabet, _random, MaxCharClassInverseLength)
                         .TryGetRegularExpression(regex, out var expression);

            if (!result.IsSuccess)
            {
                return(result);
            }

            _regularExpression  = expression;
            _expressionMetaData = result.Value;
            _wasInitialised     = true;

            return(new SuccessParseResult());
        }
예제 #2
0
        public static void UpdateWith(this ExpressionMetaData oldValue, ExpressionMetaData newValue)
        {
            if (oldValue == null || newValue == null)
            {
                return;
            }

            oldValue.HasComplement   = oldValue.HasComplement || newValue.HasComplement;
            oldValue.HasIntersection = oldValue.HasIntersection || newValue.HasIntersection;
        }
예제 #3
0
        private string TranslateOneToMany(string functionName, MemberExpression memberExpression, LambdaExpression fieldExpression, LambdaExpression filterExpression)
        {
            if (!string.IsNullOrEmpty(TranslateMember(memberExpression))) // this shouldn't return any SQL
            {
                throw new SqlExpressionTranslatorException(memberExpression.ToString());
            }

            var relation = GetRelation(memberExpression.Expression, memberExpression.Member.Name);

            if (relation == null)
            {
                throw new SqlExpressionTranslatorException(memberExpression.ToString());
            }

            if (fieldExpression != null && filterExpression != null && fieldExpression.Parameters[0] != filterExpression.Parameters[0])
            {
                throw new SqlExpressionTranslatorException(null);
            }

            var iterator = fieldExpression != null ? fieldExpression.Parameters[0] : filterExpression != null ? filterExpression.Parameters[0] : Expression.Parameter(relation.ElementType);

            LambdaExpression relationExpression = CreateToManyFilterExpression(relation, memberExpression.Expression, filterExpression, iterator);

            var template = _toManyTemplates[functionName];

            if (template == null)
            {
                throw new NotSupportedException(functionName);
            }

            var alias = SqlNameGenerator.NextTableAlias();

            _metaData[iterator] = new ExpressionMetaData {
                Iterator = iterator, Relation = relation, Schema = relation.ForeignSchema
            };

            _relationAliases[iterator] = new Dictionary <object, string> {
                { relation, alias }
            };

            _subQueries.Push(new SubQuery());

            string sqlFields = Translate(fieldExpression);
            string sqlWhere  = Translate(relationExpression);
            string sqlJoins  = (Joins.Count > 0) ? string.Join(" ", Joins.Select(join => join.ToSql(_sqlDialect))) : null;

            _subQueries.Pop();

            return(string.Format(template,
                                 sqlFields,
                                 _sqlDialect.QuoteTable(relation.ForeignSchema.MappedName) + " " + alias, sqlJoins ?? "",
                                 sqlWhere
                                 ));
        }
        public void UpdateWith_SetsHasIntersectionToTrue_WhenNewValueIsTrue()
        {
            var oldValue = new ExpressionMetaData();
            var newValue = new ExpressionMetaData {
                HasIntersection = true
            };

            oldValue.UpdateWith(newValue);

            Assert.IsTrue(oldValue.HasIntersection);
        }
        public void UpdateWith_SetsHasComplementToTrue_WhenNewValueIsTrue()
        {
            var oldValue = new ExpressionMetaData();
            var newValue = new ExpressionMetaData {
                HasComplement = true
            };

            oldValue.UpdateWith(newValue);

            Assert.IsTrue(oldValue.HasComplement);
        }
        public void UpdateWith_LeavesHasComplementTrue_WhenOldValueIsTrueButNewValueIsFalse()
        {
            var oldValue = new ExpressionMetaData {
                HasComplement = true
            };
            var newValue = new ExpressionMetaData {
                HasComplement = false
            };

            oldValue.UpdateWith(newValue);

            Assert.IsTrue(oldValue.HasComplement);
        }
        public void UpdateWith_LeavesHasIntersectionTrue_WhenOldValueIsTrueButNewValueIsFalse()
        {
            var oldValue = new ExpressionMetaData {
                HasIntersection = true
            };
            var newValue = new ExpressionMetaData {
                HasIntersection = false
            };

            oldValue.UpdateWith(newValue);

            Assert.IsTrue(oldValue.HasIntersection);
        }
예제 #8
0
        private string ProcessRelation(Expression fullExpression, Expression leftExpression, string memberName)
        {
            if (leftExpression.NodeType == ExpressionType.Convert)
            {
                leftExpression = ((UnaryExpression)leftExpression).Operand;
            }

            var parentMetaData = _metaData[leftExpression];

            if (parentMetaData != null)
            {
                if (_metaData.ContainsKey(fullExpression))
                {
                    return(null); // relation already visited
                }
                var iterator = GetRootIterator(parentMetaData.Iterator);

                var relation  = parentMetaData.Schema.Relations[memberName];
                var leftAlias = _relationAliases[iterator][parentMetaData.Key];

                if (relation != null && relation.IsToOne)
                {
                    if (!_relationAliases[iterator].ContainsKey(relation))
                    {
                        var sqlJoin = new SqlJoinDefinition(
                            new SqlJoinPart(parentMetaData.Schema, relation.LocalField, leftAlias),
                            new SqlJoinPart(relation.ForeignSchema, relation.ForeignField, SqlNameGenerator.NextTableAlias())
                            );

                        CurrentQuery.Joins.Add(sqlJoin);

                        _relationAliases[iterator][relation] = sqlJoin.Right.Alias;
                    }

                    _metaData[fullExpression] = new ExpressionMetaData {
                        Iterator = iterator, Relation = relation, Schema = relation.ForeignSchema
                    };
                }
                else if (relation == null)
                {
                    return(leftAlias + "." + (_schema.FieldsByFieldName[memberName]?.MappedName ?? memberName));
                }
            }

            return(null);
        }
예제 #9
0
        private void PrepareForNewExpression(ParameterExpression rootIterator, string tableAlias, TableSchema schema)
        {
            if (_rootIterator == null)
            {
                _rootIterator = rootIterator;

                _relationAliases[rootIterator] = new Dictionary <object, string> {
                    { schema, tableAlias }
                };
            }

            _metaData[rootIterator] = new ExpressionMetaData
            {
                Relation = null,
                Iterator = rootIterator,
                Schema   = schema
            };

            _rootIterators[rootIterator] = _rootIterator; // make additional root iterators equivalent to first one
        }
예제 #10
0
        private string TranslateOneToMany(string functionName, MemberExpression memberExpression, LambdaExpression fieldExpression, LambdaExpression filterExpression)
        {
            if (!string.IsNullOrEmpty(TranslateMember(memberExpression))) // this shouldn't return any SQL
                throw new SqlExpressionTranslatorException(memberExpression.ToString());

            var relation = GetRelation(memberExpression.Expression, memberExpression.Member.Name);

            if (relation == null)
                throw new SqlExpressionTranslatorException(memberExpression.ToString());

            if (fieldExpression != null && filterExpression != null && fieldExpression.Parameters[0] != filterExpression.Parameters[0])
                throw new SqlExpressionTranslatorException(null);

            var iterator = fieldExpression != null ? fieldExpression.Parameters[0] : filterExpression != null ? filterExpression.Parameters[0] : Expression.Parameter(relation.ElementType);

            LambdaExpression relationExpression = CreateToManyFilterExpression(relation, memberExpression.Expression, filterExpression, iterator);

            var template = _toManyTemplates[functionName];

            if (template == null)
                throw new NotSupportedException(functionName);

            var alias = SqlNameGenerator.NextTableAlias();

            _metaData[iterator] = new ExpressionMetaData { Iterator = iterator, Relation = relation, Schema = relation.ForeignSchema };

            _relationAliases[iterator] = new Dictionary<object, string> { { relation, alias } };

            _subQueries.Push(new SubQuery());

            string sqlFields = Translate(fieldExpression);
            string sqlWhere = Translate(relationExpression);
            string sqlJoins = (Joins.Count > 0) ? string.Join(" ", Joins.Select(join => join.ToSql(_sqlDialect))) : null;

            _subQueries.Pop();

            return string.Format(template,
                                    sqlFields,
                                    _sqlDialect.QuoteTable(relation.ForeignSchema.MappedName) + " " + alias, sqlJoins ?? "",
                                    sqlWhere
                                );
        }
예제 #11
0
        private string ProcessRelation(Expression fullExpression, Expression leftExpression, string memberName)
        {
            var parentMetaData = _metaData[leftExpression];

            if (parentMetaData != null)
            {
                if (_metaData.ContainsKey(fullExpression))
                    return null; // relation already visited

                var iterator = GetRootIterator(parentMetaData.Iterator);

                var relation = parentMetaData.Schema.Relations[memberName];
                var leftAlias = _relationAliases[iterator][parentMetaData.Key];

                if (relation != null && relation.IsToOne)
                {
                    if (!_relationAliases[iterator].ContainsKey(relation))
                    {
                        var sqlJoin = new SqlJoinDefinition(
                            new SqlJoinPart(parentMetaData.Schema, relation.LocalField, leftAlias),
                            new SqlJoinPart(relation.ForeignSchema, relation.ForeignField, SqlNameGenerator.NextTableAlias())
                            );

                        CurrentQuery.Joins.Add(sqlJoin);

                        _relationAliases[iterator][relation] = sqlJoin.Right.Alias;
                    }

                    _metaData[fullExpression] = new ExpressionMetaData { Iterator = iterator, Relation = relation, Schema = relation.ForeignSchema };
                }
                else if (relation == null)
                {
                    return leftAlias + "." + memberName;
                }
            }

            return null;
        }
예제 #12
0
        private void PrepareForNewExpression(ParameterExpression rootIterator, string tableAlias, OrmSchema schema)
        {
            if (_rootIterator == null)
            {
                _rootIterator = rootIterator;

                _relationAliases[rootIterator] = new Dictionary<object, string> { { schema, tableAlias } };
            }

            _metaData[rootIterator] = new ExpressionMetaData
            {
                Relation = null,
                Iterator = rootIterator,
                Schema = schema
            };

            _rootIterators[rootIterator] = _rootIterator; // make additional root iterators equivalent to first one
        }