class Arel::SelectManager

Public Class Methods

new(engine, table = nil) click to toggle source
Calls superclass method Arel::TreeManager.new
# File lib/arel/select_manager.rb, line 5
def initialize engine, table = nil
  super(engine)
  @ast   = Nodes::SelectStatement.new
  @ctx    = @ast.cores.last
  from table
end

Public Instance Methods

as(other) click to toggle source
# File lib/arel/select_manager.rb, line 46
def as other
  create_table_alias grouping(@ast), Nodes::SqlLiteral.new(other)
end
constraints() click to toggle source
# File lib/arel/select_manager.rb, line 22
def constraints
  @ctx.wheres
end
distinct(value = true) click to toggle source
# File lib/arel/select_manager.rb, line 144
def distinct(value = true)
  if value
    @ctx.set_quantifier = Arel::Nodes::Distinct.new
  else
    @ctx.set_quantifier = nil
  end
end
except(other) click to toggle source
# File lib/arel/select_manager.rb, line 186
def except other
  Nodes::Except.new ast, other.ast
end
Also aliased as: minus
exists() click to toggle source

Produces an Arel::Nodes::Exists node

# File lib/arel/select_manager.rb, line 42
def exists
  Arel::Nodes::Exists.new @ast
end
from(table) click to toggle source
# File lib/arel/select_manager.rb, line 83
def from table
  table = Nodes::SqlLiteral.new(table) if String === table
  # FIXME: this is a hack to support
  # test_with_two_tables_in_from_without_getting_double_quoted
  # from the AR tests.

  case table
  when Nodes::Join
    @ctx.source.right << table
  else
    @ctx.source.left = table
  end

  self
end
froms() click to toggle source
# File lib/arel/select_manager.rb, line 99
def froms
  @ast.cores.map { |x| x.from }.compact
end
group(*columns) click to toggle source
# File lib/arel/select_manager.rb, line 72
def group *columns
  columns.each do |column|
    # FIXME: backwards compat
    column = Nodes::SqlLiteral.new(column) if String === column
    column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column

    @ctx.groups.push Nodes::Group.new column
  end
  self
end
having(*exprs) click to toggle source
# File lib/arel/select_manager.rb, line 116
def having *exprs
  @ctx.having = Nodes::Having.new(collapse(exprs, @ctx.having))
  self
end
initialize_copy(other) click to toggle source
Calls superclass method Arel::TreeManager#initialize_copy
# File lib/arel/select_manager.rb, line 12
def initialize_copy other
  super
  @ctx = @ast.cores.last
end
intersect(other) click to toggle source
# File lib/arel/select_manager.rb, line 182
def intersect other
  Nodes::Intersect.new ast, other.ast
end
join(relation, klass = Nodes::InnerJoin) click to toggle source
# File lib/arel/select_manager.rb, line 103
def join relation, klass = Nodes::InnerJoin
  return self unless relation

  case relation
  when String, Nodes::SqlLiteral
    raise if relation.blank?
    klass = Nodes::StringJoin
  end

  @ctx.source.right << create_join(relation, nil, klass)
  self
end
join_sources() click to toggle source
# File lib/arel/select_manager.rb, line 228
def join_sources
  @ctx.source.right
end
join_sql() click to toggle source
# File lib/arel/select_manager.rb, line 214
def join_sql
  return nil if @ctx.source.right.empty?

  sql = visitor.dup.extend(Visitors::JoinSql).accept @ctx
  Nodes::SqlLiteral.new sql
end
joins(manager) click to toggle source
# File lib/arel/select_manager.rb, line 236
def joins manager
  if $VERBOSE
    warn "joins is deprecated and will be removed in 4.0.0"
    warn "please remove your call to joins from #{caller.first}"
  end
  manager.join_sql
end
limit() click to toggle source
# File lib/arel/select_manager.rb, line 17
def limit
  @ast.limit && @ast.limit.expr
end
Also aliased as: taken
limit=(limit)
Alias for: take
lock(locking = Arel.sql('FOR UPDATE')) click to toggle source
# File lib/arel/select_manager.rb, line 50
def lock locking = Arel.sql('FOR UPDATE')
  case locking
  when true
    locking = Arel.sql('FOR UPDATE')
  when Arel::Nodes::SqlLiteral
  when String
    locking = Arel.sql locking
  end

  @ast.lock = Nodes::Lock.new(locking)
  self
end
locked() click to toggle source
# File lib/arel/select_manager.rb, line 63
def locked
  @ast.lock
end
minus(other)
Alias for: except
offset() click to toggle source
# File lib/arel/select_manager.rb, line 26
def offset
  @ast.offset && @ast.offset.expr
end
offset=(amount)
Alias for: skip
on(*exprs) click to toggle source
# File lib/arel/select_manager.rb, line 67
def on *exprs
  @ctx.source.right.last.right = Nodes::On.new(collapse(exprs))
  self
end
order(*expr) click to toggle source
# File lib/arel/select_manager.rb, line 152
def order *expr
  # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
  @ast.orders.concat expr.map { |x|
    String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
  }
  self
end
order_clauses() click to toggle source
# File lib/arel/select_manager.rb, line 221
def order_clauses
  visitor = Visitors::OrderClauses.new(@engine.connection)
  visitor.accept(@ast).map { |x|
    Nodes::SqlLiteral.new x
  }
end
orders() click to toggle source
# File lib/arel/select_manager.rb, line 160
def orders
  @ast.orders
end
project(*projections) click to toggle source
# File lib/arel/select_manager.rb, line 127
def project *projections
  # FIXME: converting these to SQLLiterals is probably not good, but
  # rails tests require it.
  @ctx.projections.concat projections.map { |x|
    [Symbol, String].include?(x.class) ? SqlLiteral.new(x.to_s) : x
  }
  self
end
projections() click to toggle source
# File lib/arel/select_manager.rb, line 136
def projections
  @ctx.projections
end
projections=(projections) click to toggle source
# File lib/arel/select_manager.rb, line 140
def projections= projections
  @ctx.projections = projections
end
skip(amount) click to toggle source
# File lib/arel/select_manager.rb, line 30
def skip amount
  if amount
    @ast.offset = Nodes::Offset.new(amount)
  else
    @ast.offset = nil
  end
  self
end
Also aliased as: offset=
source() click to toggle source
# File lib/arel/select_manager.rb, line 232
def source
  @ctx.source
end
take(limit) click to toggle source
# File lib/arel/select_manager.rb, line 202
def take limit
  if limit
    @ast.limit = Nodes::Limit.new(limit)
    @ctx.top   = Nodes::Top.new(limit)
  else
    @ast.limit = nil
    @ctx.top   = nil
  end
  self
end
Also aliased as: limit=
taken()
Alias for: limit
union(operation, other = nil) click to toggle source
# File lib/arel/select_manager.rb, line 171
def union operation, other = nil
  if other
    node_class = Nodes.const_get("Union#{operation.to_s.capitalize}")
  else
    other = operation
    node_class = Nodes::Union
  end

  node_class.new self.ast, other.ast
end
where_sql() click to toggle source
# File lib/arel/select_manager.rb, line 164
def where_sql
  return if @ctx.wheres.empty?

  viz = Visitors::WhereSql.new @engine.connection
  Nodes::SqlLiteral.new viz.accept @ctx
end
window(name) click to toggle source
# File lib/arel/select_manager.rb, line 121
def window name
  window = Nodes::NamedWindow.new(name)
  @ctx.windows.push window
  window
end
with(*subqueries) click to toggle source
# File lib/arel/select_manager.rb, line 191
def with *subqueries
  if subqueries.first.is_a? Symbol
    node_class = Nodes.const_get("With#{subqueries.shift.to_s.capitalize}")
  else
    node_class = Nodes::With
  end
  @ast.with = node_class.new(subqueries.flatten)

  self
end

Private Instance Methods

collapse(exprs, existing = nil) click to toggle source
# File lib/arel/select_manager.rb, line 263
def collapse exprs, existing = nil
  exprs = exprs.unshift(existing.expr) if existing
  exprs = exprs.compact.map { |expr|
    if String === expr
      # FIXME: Don't do this automatically
      Arel.sql(expr)
    else
      expr
    end
  }

  if exprs.length == 1
    exprs.first
  else
    create_and exprs
  end
end