예제 #1
0
        private void AutoJoin(JoinChainer source)
        {
            if (!source.HasNode)
            {
                throw JoinerException(source, (TableChainer)null, QueryTalkExceptionType.InvalidJoinTable);
            }

            bool         found  = false;
            TableChainer target = null;
            var          ix     = _targets.Count - 1;

            while (ix >= 0)
            {
                target = _targets[ix];
                if (CheckAutoTarget(source, target))
                {
                    found = true;
                    break;
                }
                --ix;
            }

            if (!found)
            {
                throw JoinerAutoJoinFailedException(source);
            }

            var expression = _GetMappedExpression(source, target, DB3.Default);

            _InjectOn(source, expression);
            source.AppendJoinGraph(target.JoinGraph);
        }
예제 #2
0
        private Expression AliasByJoin(JoinChainer source, ByArgument arg)
        {
            var target = _GetTargetByAlias(source, arg.Alias, true);

            if (!source.HasNode || !target.HasNode)
            {
                throw JoinerException(source, target, QueryTalkExceptionType.InvalidJoinTable);
            }

            var expression = _GetMappedExpression(source, target, DB3.Default);

            source.AppendJoinGraph(target.JoinGraph);

            return(expression);
        }
예제 #3
0
        private TableChainer _GetTargetByAlias(JoinChainer source, string alias, bool hasNodeCheck)
        {
            foreach (var target in _targets)
            {
                if (target.Alias.Name.EqualsCS(alias))
                {
                    if (hasNodeCheck && !target.HasNode)
                    {
                        throw JoinerException(source, alias, QueryTalkExceptionType.JoinTargetNotMapped);
                    }

                    return(target);
                }
            }

            throw JoinerException(source, alias, QueryTalkExceptionType.JoinTargetNotFound);
        }
예제 #4
0
        private void ByJoin(JoinChainer source)
        {
            Expression expression = null;
            Expression part       = null;

            var i = 0;

            foreach (var arg in source.ByArguments)
            {
                switch (arg.JoinType)
                {
                case ByType.Alias:
                    part = AliasByJoin(source, arg);
                    break;

                case ByType.NonMappedColumn:
                    part = NonMappedByJoin(source, arg);
                    break;

                case ByType.MappedColumn:
                    part = MappedByJoin(source, arg);
                    break;
                }

                if (i == 0)
                {
                    expression = part;
                }
                else
                {
                    expression = expression.And(part);
                }

                ++i;
            }

            _InjectOn(source, expression);
        }
예제 #5
0
        private TableChainer _InjectJoinBy(DbNode node, string alias)
        {
            Chainer last = _tables[_tables.Count - 1];
            Chainer next;

            // skip .As
            if (last.Next is AliasAs)
            {
                last = last.Next;
            }

            // skip .On/.By
            if (last.Next is OnChainer || last.Next is ByChainer)
            {
                last = last.Next;
            }

            next = last.Next;

            // inject .Join.By
            var nodeToInsert = new InternalNode(node);

            // pass FK to support multiple relations in column graph - !
            ((IRelation)nodeToInsert).FK = node.GetFK();

            var by = ((ISemqJoin)last).Join(nodeToInsert).By(alias);

            by.SetNext(next);

            // add injected
            JoinChainer source = (JoinChainer)_tables[_tables.Count - 1];

            _targets.Add(source);
            ByJoin(source);

            return(source);
        }
예제 #6
0
        private static void _InjectOn(JoinChainer source, Expression expression)
        {
            Chainer prevOfOn = source;
            Chainer nextOfOn;

            // skip .As
            if (source.Next is AliasAs)
            {
                prevOfOn = source.Next;
            }

            nextOfOn = prevOfOn.Next;

            // skip .By
            if (nextOfOn is ByChainer)
            {
                nextOfOn = nextOfOn.Next;
            }

            // inject .On
            var on = ((IOn)prevOfOn).On(expression);

            on.SetNext(nextOfOn);
        }
예제 #7
0
 private Expression NonMappedByJoin(JoinChainer source, ByArgument arg)
 {
     _GetTargetByAlias(source, arg.Alias, false);
     return(_GetNonMappedExpression(arg, source.Alias.Name));
 }