internal void SetGraphIndex(DbNode node) { if (node.Index == 0) { node.ChangeIndex(GetNewIndex()); } }
private static void TranslateGraphDeclareTable(DbNode node, Designer root, out StringBuilder nodeTableVar) { var nodeTableVarName = GetTableVarName(node.Index); nodeTableVar = Text.GenerateSql(200) .Append(Text.Declare).S() .Append(nodeTableVarName).Append(Text._As_).Append(Text.Table).S() .Append(Text.LeftBracket); // add columns of all keys // note: // We add all keys in order to assure that all join or where relations will be properly built. bool first = true; foreach (var column in node.Map.GetKeys()) { var nullableDef = column.IsNullable ? Text.Null : Text.NotNull; if (!first) { nodeTableVar.AppendComma().S(); } nodeTableVar.Append(column.Name.Sql).S().Append(column.DataType.Build()).S().Append(nullableDef); first = false; } nodeTableVar.Append(Text.RightBracket) .Terminate(); root.TryAddVariableOrThrow(new Variable(new DataType(DT.TableVariable), nodeTableVarName), Text.Method.DesignTable, false); }
internal Relation AddGraphPair(DB3 foreignKey, DbNode predecessorNode, DbNode relatedNode, Link link) { SetRX(relatedNode); // We need to replace foreignKey with the invoker's one. // attention: // This is needed because the default foreign key is the first column. Since it is allowed // that any column represents the foreign key, the user's foreign key must be replaced with // the default one in order to fit the graph invoker's default foreign key. DB3 invokerForeignKey; GraphPair pair; Relation relation; if (link.IsFKTable(predecessorNode.NodeID)) // => predecessor node is FK, related node is REFERENCE { invokerForeignKey = _GetInvokerForeignKey(link, foreignKey, out relation); pair = new GraphPair(invokerForeignKey, relatedNode.NodeID, predecessorNode.RX, relatedNode.RX); } else { invokerForeignKey = _GetInvokerForeignKey(link, foreignKey, out relation); pair = new GraphPair(invokerForeignKey, predecessorNode.NodeID, relatedNode.RX, predecessorNode.RX); } _graphPairs.Add(pair); return(relation); }
Chainer ISemantic.Translate(SemqContext context, DbNode predecessor) { if (context == null) { throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException, "context = null", "InternalNode.ISemantic.Translate"); } if (predecessor == null) { throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException, "predecessor = null", "InternalNode.ISemantic.Translate"); } context.SetIndex(this); var from = GetDesigner().From(new Table(Map.Name, new AliasAs(Index))); if (!((IPredicate)this).HasPredicate) { return(from); } var predicate = ((IPredicate)this).Predicates[0]; var relation = DbMapping.GetRelation(predecessor.SynonymOrThis.NodeID, NodeID, DB3.Default); var relationExpression = relation.BuildRelation(predecessor.SynonymOrThis.NodeID, predecessor.Index, Index).E(); if (predicate.PredicateType == PredicateType.Cartesian) { var innerNode = ((ISemantic)predicate).Subject; context.SetIndex(innerNode); innerNode.QueryRoot = context.Subject; var innerJoinAs = from .InnerJoin((IOpenView)innerNode) .As(innerNode.Index); var joinRelation = DbMapping.GetRelation(NodeID, innerNode.SynonymOrThis.NodeID, DB3.Default); var joinExpression = joinRelation.BuildRelation(NodeID, Index, innerNode.Index).E(); var on = innerJoinAs .On(joinExpression); if (IsFinalizeable) { return(on.Where(relationExpression)); } else { return(on); } } else { return((Chainer)from.WhereExists( (INonSelectView) ((ISemantic)predicate).Translate(context, this), true) .AndWhere(relationExpression, true)); } }
// set the node's index internal void SetIndex(DbNode node) { // only assign new index if index is not already set if (node.Index == 0) { node.ChangeIndex(GetNewIndex()); } }
private static bool CheckSelfPredicate(DbNode currentNode, DbNode innerNode) { if (!(innerNode.Equals(currentNode) && innerNode.Next != null)) { return(false); } return(true); }
/// <summary> /// Determines whether this node is equal to the specified node. /// </summary> /// <param name="nodeToCompare">Is a specified node to be compared with.</param> public bool Equals(DbNode nodeToCompare) { if (nodeToCompare == null) { return(false); } return(NodeID.Equals(nodeToCompare.NodeID)); }
internal static Connectable GetConnectable(Assembly client, DbNode node, Chainer prev) { if (prev is Connectable) { return((Connectable)prev); } return(GetConnectable(client, prev, ConnectionManager.GetConnectionData(client, null, node, prev))); }
internal static void ProcessSelfPredicate(SemqContext context, DbNode currentNode, Predicate predicate, ref Chainer query) { if (predicate.PredicateType == PredicateType.Maximized) { ProcessMaximized(context, predicate, ref query); } else { ProcessExpressionSQL(currentNode, predicate, ref query); } }
/// <summary> /// Sets the inner node of the graph instance. /// </summary> /// <param name="context">A semantic context.</param> /// <param name="innerNode">The inner node.</param> protected void SetInnerNode(SemqContext context, DbNode innerNode) { if (context == null) { throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException, "context = null", "DbGraphBase.SetInnerNode"); } _innerNode = innerNode; context.SetGraphIndex(_innerNode); }
internal DbGraph(IGraph graph, DbNode relatedNode) : this(graph) { relatedNode.CheckWithAndThrow("relatedNode", Text.Method.With); _predecessorNode = ((IGraph)graph).Subject; ((IGraph)this).Translate = (context, predecessor) => { SetInnerNode(context, relatedNode); Translate.TranslateGraphNode(this, context, _predecessorNode, relatedNode, true); }; }
// Process a node chain S.S2...Sn by placing the consecutive node S2 into the predicate of a subject S: // S.S2 => S.P(S2) internal static void ConvertChainIntoPredicate(DbNode currentNode) { if (currentNode.Next == null) { return; } var next = currentNode.BreakChain(); var predicate = new Predicate(currentNode, PredicateType.Existential, true, LogicalOperator.And, (ISemantic)next, null, true); ((IPredicate)currentNode).Predicates.Add(predicate); }
/// <summary> /// Initializes a new instance of the DbNode class. /// </summary> /// <param name="prev">The previous node.</param> protected DbNode(DbNode prev) { if (prev != null) { _root = prev.Root; prev._next = this; _prev = prev; } else { _root = this; } }
internal DbGraph(DbNode node, DbNode relatedNode) : this(node.Root) { node = node.Root; relatedNode.CheckWithAndThrow("relatedNode", Text.Method.With); _predecessorNode = node; ((IGraph)this).Translate = (context, predecessor) => { context.SetGraphIndex(node); SetInnerNode(context, relatedNode); Translate.TranslateGraphNode(this, context, _predecessorNode, relatedNode, true); }; }
internal DbGraph(IGraph graph, IGraph relatedGraph) : this(graph) { CheckNullAndThrow(Arg(() => relatedGraph, relatedGraph)); _predecessorNode = ((IGraph)graph).Subject; InnerGraph = relatedGraph; ((IGraph)this).Translate = (context, predecessor) => { var innerNode = GetInnerNode(context); Translate.TranslateGraphNode(this, context, _predecessorNode, innerNode); Translate.TranslateGraph(relatedGraph.Root, context, this); }; }
internal static void CheckWithAndThrow(this DbNode node, string argument, string method) { if (node == null) { throw new QueryTalkException("Common.CheckTable", QueryTalkExceptionType.ArgumentNull, String.Format("{0} = null", argument), method); } if (!(node is ITable)) { throw new QueryTalkException("Common.CheckTable", QueryTalkExceptionType.InvalidWith, String.Format("{0} = {1}", argument, DbMapping.GetNodeName(node.NodeID)), method); } }
// Applies the joining of the nodes along the joinable node chain. // note: // Joining can be applied only on pure nodes without the predicates. // Otherwise the predicates could contain the joinable node chains // which would lead into the mixture of semantical and SQL query language. internal static Chainer Join(DbNode rootNode) { Chainer query = null; var node = rootNode; int ix = 1; // index of a table in joining // move along the graph while (node != null) { // check for predicates if (((IPredicate)node).HasPredicate) { node.Mapper.Throw(QueryTalkExceptionType.InvalidJoin, null, Text.Method.NodeChainJoin); } // check if node has a FK var fk = ((IRelation)node).FK; // isolate node & get next node var next = node.BreakChain(); // .From if (query == null) { query = Designer.GetNewDesigner(rootNode.Name, true, true) .From((IOpenView)node).As(ix); } // .InnerJoin else { // add .By for FK if (!fk.IsDefault) { var fkColumn = new DbColumn(new InternalNode(fk.TableID), fk); query = ((IInnerJoin)query).InnerJoin((IOpenView)node).As(ix).By(fkColumn.Of(ix - 1)); } else { query = ((IInnerJoin)query).InnerJoin((IOpenView)node); } } node = next; ++ix; } ; return(query); }
internal static Chainer CreateQueryFromSubject(DbNode currentNode) { if (currentNode is IFunction) { var arguments = ((IFunction)currentNode).Arguments; DbMapping.PrepareFunctionArguments(arguments, currentNode); return(currentNode.GetDesigner() .From(currentNode.Map.Name.PassUdf( ((IFunction)currentNode).Arguments), currentNode) .As(currentNode.Index)); } // table else { if (currentNode.IsSynonym) { if (currentNode.SynonymQuery is IOpenView) { return(currentNode.GetDesigner().From((IOpenView)currentNode.SynonymQuery, currentNode) .As(currentNode.Index)); } // View else { return(currentNode.GetDesigner().From((View)currentNode.SynonymQuery, currentNode) .As(currentNode.Index)); } } else { if (currentNode.Row != null) { var row = currentNode.Row; return(currentNode.GetDesigner() .From(currentNode.Map.Name, currentNode).As(currentNode.Index) .Where(DbMapping.GetNodeMap(row.NodeID) .BuildRKExpression(row.GetOriginalRKValues(), currentNode.Index))); } else { return(currentNode.GetDesigner() .From(currentNode.Map.Name, currentNode) .As(currentNode.Index)); } } } }
internal DbNode TrySetNode() { if (_node == null) { CheckLoadableAndThrow(Text.Method.ConnectBy); _node = ((INode)this).Node; _node.Row = this; } // allow reusability _node.CanBeReused(); _node.ChangeIndex(0); _node.Mapper.GetRoot().ClearForReuse(); return(_node); }
internal void AddNode(DbNode node) { if (!node.IsAdded) { if (RootSubject != null) { RootSubject.Nodes.Add(node); } else { Subject.Nodes.Add(node); } } node.IsAdded = true; }
internal DbGraph(DbNode node, IGraph relatedGraph) : this(node.Root) { node = node.Root; CheckNullAndThrow(Arg(() => relatedGraph, relatedGraph)); _predecessorNode = node; InnerGraph = relatedGraph; ((IGraph)this).Translate = (context, predecessor) => { context.SetGraphIndex((DbNode)node); var innerNode = GetInnerNode(context); Translate.TranslateGraphNode(this, context, _predecessorNode, innerNode); Translate.TranslateGraph(relatedGraph.Root, context, this); }; }
// common method for processing the connection data internal static ConnectionData GetConnectionData(Assembly client, ConnectBy connectBy, // explicitly given query key DbNode node, // database object bound to database map key (very likely to be given) Chainer chainObject) // chain object that is very likely to have no connection data (except when .ConnectBy is called inside the compilable) { ConnectionKey connectionKey = null; if (connectBy != null) { connectionKey = ((IConnectable)connectBy).ConnectionKey; } else if (node != null) { connectionKey = ((IConnectable)node).ConnectionKey; if (connectionKey != null) { ((IConnectable)node).ResetConnectionKey(); // always clean it up after the getter provide the ConnectionKey } } else if (chainObject != null) { var root = chainObject.GetRoot(); // root: in cases when connection data is stored into compilable object // example: // s.River.Select().ConnectBy().Go() if (root.ConnectionKey != null) { connectionKey = root.ConnectionKey; root.ConnectionKey = null; } // root.Node: in cases when the compilable is based on the mapped object // example: // s.River.Select().Go() else if (root.Node != null) { connectionKey = ((IConnectable)root.Node).ConnectionKey; if (connectionKey != null) { ((IConnectable)root.Node).ResetConnectionKey(); // always clean it up after the getter provide the ConnectionKey } } } return(ConnectionManager.InvokeConnectionFunc(client, connectionKey)); }
internal DbTable <T> TrySetNode <T>() where T : DbRow { if (_node == null) { CheckLoadableAndThrow(Text.Method.With); _node = ((INode <T>) this).Node; _node.Row = this; } // allow reusability _node.CanBeReused(); _node.ChangeIndex(0); _node.Mapper.GetRoot().ClearForReuse(); return((DbTable <T>)_node); }
// ctor: Maximized internal Predicate( DbNode subject, MaximizationType maximizationType, bool sign, LogicalOperator logicalOperator, OrderingArgument maximizedExpression, long top = 1) { DbMapping.CheckNullAndThrow(subject); if (maximizedExpression == null) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.ArgumentNull, "maximized expression = null", Text.Method.HavingMaxMin); } // check expression DbColumn type if (maximizedExpression.ArgType == typeof(DbColumn)) { var column = (DbColumn)maximizedExpression.Original; if (column.Parent != null && column.Parent.Prev != null) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.InvalidHavingPredicateArgument, String.Format("node = {0}", column.Parent), Text.Method.HavingMaxMin); } // column parent must be the same as the subject if (!column.Parent.Equals(subject)) { throw new QueryTalkException("Predicate.ctor", QueryTalkExceptionType.InvalidHavingPredicateArgument, String.Format("node = {0}{1} subject = {2}", column.Parent, Environment.NewLine, subject), Text.Method.HavingMaxMin); } } Subject = subject; Sign = sign; LogicalOperator = logicalOperator; PredicateType = Wall.PredicateType.Maximized; MaximizedType = maximizationType; MaximizedExpression = maximizedExpression; MaximizedTop = top; IsFinalizeable = true; subject.IsFinalizeable = true; }
internal Column[] GetColumnsByDatabaseOrder(string alias, DbNode node) { List <Column> columns = new List <Column>(); foreach (var map in SortedColumnsByDatabaseOrder) { if (alias != null) { columns.Add(new DbColumn(node, map.ID, true).Of(alias)); } else { columns.Add(new DbColumn(node, map.ID, true)); } } return(columns.ToArray()); }
// break the chain between the node and the next node // attention: // This method provokes serious problems in case of reusability because the subject of the predicate gets replaced with its successor. // For this reason in order to support reusability the root.Replace method must be used after every execution. internal DbNode BreakChain() { DbNode next = null; if (_next != null) { next = _next; next.RootWithBrokenChain = this.RootWithBrokenChain ?? this._root; next._prevBroken = next._prev; next._prev = null; next._rootBroken = next._root; next._root = next; } _nextBroken = _next; _next = null; return(next); }
private void _RecoverChain() { // recover chain if (_prevBroken != null) { _prev = _prevBroken; _prevBroken = null; } if (_nextBroken != null) { _next = _nextBroken; _nextBroken = null; } if (_rootBroken != null) { _root = _rootBroken; _rootBroken = null; } }
internal static void TranslateGraphNode(IGraph graph, SemqContext context, DbNode predecessor, DbNode node, bool isLeafNode = false) { var isSubject = (predecessor == null); node = node.Root; context.SetGraphIndex(node); Chainer translatedNode; Designer root; if (isSubject) { root = new InternalRoot(node); } else { root = context.TranslatedGraph.GetRoot(); node.IsFinalizeable = false; } // translate node only // important: // The node should be translated before the graph processing begins in order that to obtain the appropriate index. translatedNode = ((ISemantic)node).Translate(context, predecessor); StringBuilder nodeTableVar = null; // create table variable storage except for the last leaf node which does not need a table variable if (!isLeafNode) { TranslateGraphDeclareTable(node, root, out nodeTableVar); } // finish the node query translation as part of a graph if (isSubject) { TranslateGraphSubject(context, node, root, translatedNode, nodeTableVar); } else { TranslateGraphRelated(graph, context, predecessor, node, translatedNode, nodeTableVar); } }
internal static void ThrowInvalidQuantifierException( Predicate predicate, DbNode subject, ISemantic predicateSentence, DbNode intermediate, string predicateExpression) { DbNode predicateNode = null; if (predicateSentence != null) { predicateNode = (predicateSentence.Subject != null) ? predicateSentence.Subject : null; } if (intermediate != null) { throw new QueryTalkException("Translate.ThrowInvalidQuantifierException", QueryTalkExceptionType.QuantifierDisallowed, String.Format("subject = {0}{1} predicate node (intermediate) = {5}{1} given predicate node = {2}{1} predicate expression = {3}{1} quantifier = {4}", subject != null ? DbMapping.GetNodeName(subject.NodeID).Sql : Text.NotAvailable, Environment.NewLine, predicateNode != null ? DbMapping.GetNodeName(predicateNode.NodeID).Sql : Text.NotAvailable, predicateExpression != null ? predicateExpression : Text.NotAvailable, predicate.Quantifier != null ? predicate.Quantifier.QuantifierType.ToString() : Text.NotAvailable, intermediate.Name), Text.Method.PredicateMethod).SetExtra("Pay attention to the intermediate predicate node which was provided by the library since the subject and the given predicate node are not related directly to each other."); } else { throw new QueryTalkException("Translate.ThrowInvalidQuantifierException", QueryTalkExceptionType.QuantifierDisallowed, String.Format("subject = {0}{1} predicate node = {2}{1} predicate expression = {3}{1} quantifier = {4}", subject != null ? DbMapping.GetNodeName(subject.NodeID).Sql : Text.NotAvailable, Environment.NewLine, predicateNode != null ? DbMapping.GetNodeName(predicateNode.NodeID).Sql : Text.NotAvailable, predicateExpression != null ? predicateExpression : Text.NotAvailable, predicate.Quantifier != null ? predicate.Quantifier.QuantifierType.ToString() : Text.NotAvailable), Text.Method.PredicateMethod); } }
internal static void Finalize(DbNode predecessor, DbNode currentNode, ref Chainer query) { if (!currentNode.IsFinalizeable) { return; } predecessor = predecessor.SetSynonymOrThis(); currentNode = currentNode.SetSynonymOrThis(); var foreignKey = currentNode.GetFK(); var relation = DbMapping.GetRelation(currentNode.NodeID, predecessor.NodeID, foreignKey); var relationExpression = relation.BuildRelation(currentNode.NodeID, currentNode.Index, predecessor.Index).E(); if (query is ConditionChainer) { query = ((ConditionChainer)query).AndWhere(relationExpression, true); } else { query = ((IWhere)query).Where(relationExpression, true); } }