class EachSQL

Enumerable EachSQL object.

Public Class Methods

new(type, delimiter = ';') click to toggle source

@param type RDBMS type: :default|:mysql|:oracle|:postgres @param delimiter Script delimiter.

# File lib/each_sql/each_sql.rb, line 9
def initialize type, delimiter = ';'
  @type   = type
  @data   = ''
  @sqls   = []

  self.delimiter = delimiter
end

Public Instance Methods

<<(input) click to toggle source

Appends the given String to the buffer. @param input String to append

# File lib/each_sql/each_sql.rb, line 32
def << input
  if input
    @data << input.sub(/\A#{[65279].pack('U*')}/, '') # BOM (FIXME)
  end
  self
end
clear() click to toggle source

Clears the buffer @return [EachSQL]

# File lib/each_sql/each_sql.rb, line 41
def clear
  @data = ''
  self
end
delimiter() click to toggle source

@return Current delimiter.

# File lib/each_sql/each_sql.rb, line 26
def delimiter
  @delim
end
delimiter=(delim) click to toggle source

@param delim SQL delimiter @return

# File lib/each_sql/each_sql.rb, line 19
def delimiter= delim
  @delim = delim
  @parser = EachSQL::Parser.parser_for @type, delim
  self
end
each() { |sql| ... } click to toggle source

Parses the buffer and enumerates through the executable blocks. @yield [String] @return [NilClass]

# File lib/each_sql/each_sql.rb, line 70
def each
  return enum_for(:each) unless block_given?

  result = shift
  sqls   = (result[:sqls] + result[:leftover]).
            map { |sql| strip_sql(sql) }.
            reject(&:empty?)
  sqls.each do |sql|
    yield sql
  end
end
empty?() click to toggle source

Return is the buffer is empty @return [Boolean]

# File lib/each_sql/each_sql.rb, line 63
def empty?
  @data.gsub(/\s/, '').empty?
end
shift() click to toggle source

Parses current buffer and returns the result in Hash. :sqls is an Array of processed executable SQL blocks, :leftover is the unparsed trailing data @return [Hash]

# File lib/each_sql/each_sql.rb, line 50
def shift
  result   = @parser.parse @data
  @data    = result.captures[:leftover].join
  leftover = strip_sql(@data)
  {
    :sqls =>
      result.captures[:execution_block].map { |b| strip_sql b },
    :leftover => leftover.empty? ? nil : leftover
  }
end

Private Instance Methods

strip_sql(sql) click to toggle source
# File lib/each_sql/each_sql.rb, line 83
def strip_sql sql
  # Preprocess
  case @type
  when :oracle
    sql = sql.sub(/\A[\s\/]+/, '').sub(/[\s\/]+\Z/, '')
  end

  # FIXME: Infinite loop?
  # sql = sql.gsub(
  #         /
  #          (?:
  #            (?:\A(?:#{Regexp.escape @delim}|[\s]+)+)
  #            |
  #            (?:(?:#{Regexp.escape @delim}|[\s]+)+\Z)
  #          )+
  #         /x, '')
  prev_sql = nil
  delim = Regexp.escape @delim
  while prev_sql != sql
    prev_sql = sql
    sql = sql.strip.sub(/\A(?:#{delim})+/, '').sub(/(?:#{delim})+\Z/, '')
  end

  # Postprocess
  case @type
  when :oracle
    if sql =~ /\bend(\s+\S+)?\Z/i
      sql = sql + ';'
    end
  end

  sql
end