class Seaquel::Statement

Root node for an sql statement.

Attributes

expression_convertor[R]
fields[R]
from[R]
group_by[R]
having[R]
joins[R]
limit[R]
offset[R]
order_by[R]
project[R]

These are overwritten, not appended to.

set[R]
target[R]
values[R]
where[R]

Public Class Methods

new(expression_convertor) click to toggle source
# File lib/seaquel/statement.rb, line 34
def initialize expression_convertor
  @expression_convertor = expression_convertor

  @from = list()
  @project = list()
  @order_by = list()
  @where = AST::JoinOp.new(:and, [])
  @set = list()
  @values = list()
  @fields = column_list()
  @joins = []
  @having = AST::JoinOp.new(:and, [])
  @group_by = list()
end

Public Instance Methods

convert(exp) click to toggle source

Turns an expression into SQL

# File lib/seaquel/statement.rb, line 95
def convert exp
  expression_convertor.sql(exp).toplevel
end
join(tables) click to toggle source

Produces a join clause and adds it to the joins list.

@param tables [Array<Object>] a list of tables to join to @return [Join] Join subobject.

# File lib/seaquel/statement.rb, line 73
def join tables
  join = Join.new(tables)
  joins << join

  join
end
set_limit(n) click to toggle source
# File lib/seaquel/statement.rb, line 49
def set_limit n
  @limit = n
end
set_offset(n) click to toggle source
# File lib/seaquel/statement.rb, line 52
def set_offset n
  @offset = n
end
set_target(table) click to toggle source
# File lib/seaquel/statement.rb, line 64
def set_target table
  @target = table
end
set_type(type) click to toggle source

Allows to determine the type of statement generated.

@param type [{:update, :select, :delete}]

# File lib/seaquel/statement.rb, line 60
def set_type type
  @type = type
end
to_s(variant=:compact) click to toggle source
# File lib/seaquel/statement.rb, line 80
def to_s variant=:compact
  case @type 
    when :update
      generate_update(variant)
    when :insert
      generate_insert(variant)
    when :delete
      generate_delete(variant)
  else
    generate_select(variant)
  end
end

Private Instance Methods

column_list() click to toggle source
# File lib/seaquel/statement.rb, line 105
def column_list
  AST::ColumnList.new
end
generate_delete(variant) click to toggle source

Generates SQL for a DELETE statement.

# File lib/seaquel/statement.rb, line 119
def generate_delete variant
  parts = []
  parts << "DELETE"

  unless from.empty?
    parts << 'FROM'
    parts << convert(from)
  end

  unless joins.empty?
    joins.each do |join|
      parts << join.convert(
        self # as #convert
      )
    end
  end

  unless where.empty?
    parts << 'WHERE'
    parts << convert(where)
  end

  parts.join(' ')      
end
generate_insert(variant) click to toggle source

Generates SQL for an INSERT statement.

# File lib/seaquel/statement.rb, line 146
def generate_insert variant
  parts = []
  parts << "INSERT"

  if target
    parts << "INTO"
    parts << convert(target)
  end

  unless values.empty?
    if fields.empty?
      # If you are inserting data to all the columns, the column names can be
      # omitted.
      parts << 'VALUES'
      parts << values.
        map { |value_list| 
          parens(convert(value_list)) }.
        join(', ')
    else
      # A field list must be produced
      # assert: !values.empty? && !fields.empty?

      parts << parens(convert(fields))
      parts << 'VALUES'
      parts << values.
          map { |value_list| 
            raise InvalidStatement, "Field list in INSERT statement doesn't match value list (#{fields.size} fields and #{value_list.size} values)." \
              unless fields.size == value_list.size

            parens(convert(value_list)) }.
          join(', ')
    end
  end

  parts.join(' ')
end
generate_select(variant) click to toggle source

Generates SQL for a SELECT statement.

# File lib/seaquel/statement.rb, line 185
def generate_select variant
  parts = []
  parts << "SELECT"

  if project.empty?
    parts << '*'
  else
    parts << convert(project)
  end

  unless from.empty?
    parts << 'FROM'
    parts << convert(from) 
  end

  unless joins.empty?
    joins.each do |join|
      parts << join.convert(
        self # as #convert
      )
    end
  end

  unless where.empty?
    parts << 'WHERE'
    parts << convert(where)
  end

  unless group_by.empty?
    parts << 'GROUP BY'
    parts << convert(group_by)
  end

  unless having.empty?
    parts << 'HAVING'
    parts << convert(having)
  end

  unless order_by.empty?
    parts << 'ORDER BY'
    parts << convert(order_by)
  end

  if offset
    parts << 'OFFSET'
    parts << convert(offset)
  end

  if limit 
    parts << 'LIMIT'
    parts << convert(limit)
  end

  parts.join(' ')
end
generate_update(variant) click to toggle source

Generates SQL for an UPDATE statement.

# File lib/seaquel/statement.rb, line 243
def generate_update variant 
  parts = []
  parts << 'UPDATE'
  parts << convert(target)

  unless set.empty?
    parts << 'SET'
    parts << convert(set)
  end

  unless where.empty?
    parts << 'WHERE'
    parts << convert(where)
  end

  parts.join(' ')
end
list() click to toggle source

Produces an empty list.

# File lib/seaquel/statement.rb, line 102
def list
  AST::List.new
end
parens(str) click to toggle source

Wraps str in parenthesises.

Example:

parens('foo') # => '(foo)'
# File lib/seaquel/statement.rb, line 113
def parens str
  "(#{str})"
end