Class: SQLTree::Node::SelectQuery

Inherits:
Base
  • Object
show all
Defined in:
lib/sql_tree/node/select_query.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

[], #inspect, #quote_str, #quote_var

Constructor Details

#initializeSelectQuery

Returns a new instance of SelectQuery.



7
8
9
10
# File 'lib/sql_tree/node/select_query.rb', line 7

def initialize
  @distinct = false
  @select   = []
end

Instance Attribute Details

#distinctObject

Returns the value of attribute distinct.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def distinct
  @distinct
end

#fromObject

Returns the value of attribute from.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def from
  @from
end

#group_byObject

Returns the value of attribute group_by.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def group_by
  @group_by
end

#havingObject

Returns the value of attribute having.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def having
  @having
end

#limitObject

Returns the value of attribute limit.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def limit
  @limit
end

#order_byObject

Returns the value of attribute order_by.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def order_by
  @order_by
end

#selectObject

Returns the value of attribute select.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def select
  @select
end

#whereObject

Returns the value of attribute where.



5
6
7
# File 'lib/sql_tree/node/select_query.rb', line 5

def where
  @where
end

Class Method Details

.parse(tokens) ⇒ Object

Uses the provided initialized parser to parse a SELECT query.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/sql_tree/node/select_query.rb', line 25

def self.parse(tokens)
  select_node = self.new
  tokens.consume(SQLTree::Token::SELECT)

  if tokens.peek == SQLTree::Token::DISTINCT
    tokens.consume(SQLTree::Token::DISTINCT)
    select_node.distinct = true
  end

  select_node.select   = self.parse_select_clause(tokens)
  select_node.from     = self.parse_from_clause(tokens)   if tokens.peek == SQLTree::Token::FROM
  select_node.where    = self.parse_where_clause(tokens)  if tokens.peek == SQLTree::Token::WHERE
  if tokens.peek == SQLTree::Token::GROUP
    select_node.group_by = self.parse_group_clause(tokens)
    select_node.having   = self.parse_having_clause(tokens) if tokens.peek == SQLTree::Token::HAVING
  end
  select_node.order_by = self.parse_order_clause(tokens)  if tokens.peek == SQLTree::Token::ORDER
  return select_node
end

.parse_from_clause(tokens) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/sql_tree/node/select_query.rb', line 54

def self.parse_from_clause(tokens)
  tokens.consume(SQLTree::Token::FROM)
  sources = [SQLTree::Node::Source.parse(tokens)]
  while tokens.peek == SQLTree::Token::COMMA
    tokens.consume(SQLTree::Token::COMMA)
    sources << SQLTree::Node::Source.parse(tokens)
  end
  return sources
end

.parse_group_clause(tokens) ⇒ Object



69
70
71
72
73
74
75
76
77
78
# File 'lib/sql_tree/node/select_query.rb', line 69

def self.parse_group_clause(tokens)
  tokens.consume(SQLTree::Token::GROUP)
  tokens.consume(SQLTree::Token::BY)
  exprs = [SQLTree::Node::Expression.parse(tokens)]
  while tokens.peek == SQLTree::Token::COMMA
    tokens.consume(SQLTree::Token::COMMA)
    exprs << SQLTree::Node::Expression.parse(tokens)
  end
  return exprs
end

.parse_having_clause(tokens) ⇒ Object



80
81
82
83
# File 'lib/sql_tree/node/select_query.rb', line 80

def self.parse_having_clause(tokens)
  tokens.consume(SQLTree::Token::HAVING)
  SQLTree::Node::Expression.parse(tokens)
end

.parse_limit_clause(tokens) ⇒ Object



96
97
98
# File 'lib/sql_tree/node/select_query.rb', line 96

def self.parse_limit_clause(tokens)
  # TODO: implement me
end

.parse_order_clause(tokens) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/sql_tree/node/select_query.rb', line 85

def self.parse_order_clause(tokens)
  tokens.consume(SQLTree::Token::ORDER)
  tokens.consume(SQLTree::Token::BY)
  exprs = [SQLTree::Node::Ordering.parse(tokens)]
  while tokens.peek == SQLTree::Token::COMMA
    tokens.consume(SQLTree::Token::COMMA)
    exprs << SQLTree::Node::Ordering.parse(tokens)
  end
  return exprs
end

.parse_select_clause(tokens) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/sql_tree/node/select_query.rb', line 45

def self.parse_select_clause(tokens)
  expressions = [SQLTree::Node::SelectExpression.parse(tokens)]
  while tokens.peek == SQLTree::Token::COMMA
    tokens.consume(SQLTree::Token::COMMA)
    expressions << SQLTree::Node::SelectExpression.parse(tokens)
  end
  return expressions
end

.parse_where_clause(tokens) ⇒ Object



64
65
66
67
# File 'lib/sql_tree/node/select_query.rb', line 64

def self.parse_where_clause(tokens)
  tokens.consume(SQLTree::Token::WHERE)
  Expression.parse(tokens)
end

Instance Method Details

#to_sqlObject



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/sql_tree/node/select_query.rb', line 12

def to_sql
  raise "At least one SELECT expression is required" if self.select.empty?
  sql = (self.distinct) ? "SELECT DISTINCT " : "SELECT "
  sql << select.map { |s| s.to_sql }.join(', ')
  sql << " FROM "     << from.map { |f| f.to_sql }.join(', ')
  sql << " WHERE "    << where.to_sql if where
  sql << " GROUP BY " << group_by.map { |g| g.to_sql }.join(', ') if group_by
  sql << " ORDER BY " << order_by.map { |o| o.to_sql }.join(', ') if order_by
  sql << " HAVING "   << having.to_sql if having
  return sql
end