Class: SQLTree::Node::SelectQuery

Inherits:
Base
  • Object
show all
Defined in:
lib/active_record/turntable/sql_tree_patch.rb

Direct Known Subclasses

SubQuery

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#quote_field_name

Class Method Details

.parse(tokens) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 104

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

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

  select_node.select   = parse_list(tokens, SQLTree::Node::SelectDeclaration)
  select_node.from     = self.parse_from_clause(tokens)   if SQLTree::Token::FROM === tokens.peek
  select_node.where    = self.parse_where_clause(tokens)  if SQLTree::Token::WHERE === tokens.peek
  if SQLTree::Token::GROUP === tokens.peek
    select_node.group_by = self.parse_group_clause(tokens)
    select_node.having   = self.parse_having_clause(tokens) if SQLTree::Token::HAVING === tokens.peek
  end
  select_node.order_by = self.parse_order_clause(tokens) if SQLTree::Token::ORDER === tokens.peek
  if SQLTree::Token::LIMIT === tokens.peek && (list = self.parse_limit_clause(tokens))
    select_node.offset = list.shift if list.size > 1
    select_node.limit  = list.shift
  end
  select_node.offset = self.parse_offset_clause(tokens) if SQLTree::Token::OFFSET === tokens.peek
  select_node
end

.parse_limit_clause(tokens) ⇒ Object



129
130
131
132
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 129

def self.parse_limit_clause(tokens)
  tokens.consume(SQLTree::Token::LIMIT)
  self.parse_list(tokens, SQLTree::Node::Expression)
end

.parse_offset_clause(tokens) ⇒ Object



134
135
136
137
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 134

def self.parse_offset_clause(tokens)
  tokens.consume(SQLTree::Token::OFFSET)
  Expression.parse(tokens)
end

Instance Method Details

#to_sql(options = {}) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 90

def to_sql(options = {})
  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(options) }.join(", ")
  sql << " FROM "     << from.map { |f| f.to_sql(options) }.join(", ") if from
  sql << " WHERE "    << where.to_sql(options) if where
  sql << " GROUP BY " << group_by.map { |g| g.to_sql(options) }.join(", ") if group_by
  sql << " ORDER BY " << order_by.map { |o| o.to_sql(options) }.join(", ") if order_by
  sql << " HAVING "   << having.to_sql(options) if having
  sql << " LIMIT "    << Array(limit).map { |f| f.to_sql(options) }.join(", ") if limit
  sql << " OFFSET "   << offset.to_sql(options) if offset
  sql
end