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



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 54

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 and 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
  return select_node
end

.parse_limit_clause(tokens) ⇒ Object



79
80
81
82
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 79

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

.parse_offset_clause(tokens) ⇒ Object



84
85
86
87
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 84

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

Instance Method Details

#to_sql(options = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/active_record/turntable/sql_tree_patch.rb', line 40

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
  return sql
end