DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
FetchStatementNode.cs
Go to the documentation of this file.
1 using System;
2 using System.Linq;
3 
4 using Deveel.Data.Sql.Cursors;
6 
7 namespace Deveel.Data.Sql.Parser {
9  public string Direction { get; private set; }
10 
11  public string CursorName { get; private set; }
12 
13  public IExpressionNode Position { get; private set; }
14 
15  public IExpressionNode Into { get; private set; }
16 
17  protected override ISqlNode OnChildNode(ISqlNode node) {
18  if (node.NodeName == "direction_opt") {
19  GetDirection(node);
20  } else if (node is IdentifierNode) {
21  CursorName = ((IdentifierNode) node).Text;
22  } else if (node.NodeName == "into_opt") {
23  GetInto(node);
24  }
25 
26  return base.OnChildNode(node);
27  }
28 
29  private void GetDirection(ISqlNode node) {
30  var childNode = node.ChildNodes.FirstOrDefault();
31  if (childNode == null)
32  return;
33 
34  childNode = childNode.ChildNodes.FirstOrDefault();
35  if (childNode == null)
36  throw new SqlParseException();
37 
38  if (String.Equals(childNode.NodeName, "NEXT", StringComparison.OrdinalIgnoreCase) ||
39  String.Equals(childNode.NodeName, "PRIOR", StringComparison.OrdinalIgnoreCase) ||
40  String.Equals(childNode.NodeName, "FIRST", StringComparison.OrdinalIgnoreCase) ||
41  String.Equals(childNode.NodeName, "LAST", StringComparison.OrdinalIgnoreCase)) {
42  Direction = childNode.NodeName.ToUpper();
43  } else if (String.Equals(childNode.NodeName, "ABSOLUTE", StringComparison.OrdinalIgnoreCase) ||
44  String.Equals(childNode.NodeName, "RELATIVE", StringComparison.OrdinalIgnoreCase)) {
45  var positionNode = childNode.ChildNodes.FirstOrDefault();
46  if (positionNode == null)
47  throw new SqlParseException("The position expression if required in an ABSOLUTE or RELATIVE fetch.");
48 
49  var expression = positionNode as IExpressionNode;
50  if (expression == null)
51  throw new SqlParseException();
52 
53  Direction = childNode.NodeName.ToUpper();
54  Position = expression;
55  }
56  }
57 
58  private void GetInto(ISqlNode node) {
59  foreach (var childNode in node.ChildNodes) {
60  if (childNode is IExpressionNode) {
61  Into = childNode as IExpressionNode;
62  break;
63  }
64  }
65  }
66 
67  private static bool TryParseDirection(string s, out FetchDirection direction) {
68 #if PCL
69  return Enum.TryParse(s, true, out direction);
70 #else
71  try {
72  direction = (FetchDirection) Enum.Parse(typeof (FetchDirection), s, true);
73  return true;
74  } catch (Exception) {
75  direction = new FetchDirection();
76  return false;
77  }
78 #endif
79  }
80 
81  protected override void BuildStatement(StatementBuilder builder) {
82  FetchDirection direction;
83  if (!TryParseDirection(Direction, out direction))
84  throw new InvalidOperationException();
85 
86  var statement = new FetchStatement(CursorName, direction);
87  if (Into != null)
88  statement.IntoReference = ExpressionBuilder.Build(Into);
89  if (Position != null)
90  statement.PositionExpression = ExpressionBuilder.Build(Position);
91 
92  builder.Statements.Add(statement);
93  }
94  }
95 }
This is a simple identifier within a SQL grammar.
Defines the contract for nodes in an AST model for a SQL grammar analysis and parsing.
Definition: ISqlNode.cs:25
string NodeName
Gets the name of the node analyzed from the parser.
Definition: ISqlNode.cs:29
static SqlExpression Build(IExpressionNode node)
override void BuildStatement(StatementBuilder builder)
ICollection< IStatement > Statements
IEnumerable< ISqlNode > ChildNodes
Gets a read-only enumeration of the children nodes, if any.
Definition: ISqlNode.cs:39
override ISqlNode OnChildNode(ISqlNode node)
During the initialization of the node from the parser, this method is called for every child node add...
static bool TryParseDirection(string s, out FetchDirection direction)
An error that occurs when compiling a input string into a SQL object.
This interface acts like a marker that indicates if a ISqlNode represents a SQL expression.