class RailsDbViews::DatabaseSymbol

Constants

COMMENTS
COMMENTS_SHARP
COMMENTS_TWO_DASH

It’s not very safe in case we start a line into a string with the characters – or #.

DIRECTIVE_START
SHARP_CHAR_DIRECTIVE_START
STRING_INTERPOLATION
TWO_DASH_DIRECTIVE_START

Attributes

inverse_of_required[RW]
marked_as_deleted[RW]
marked_as_deleted?[RW]
name[RW]
path[RW]
required[RW]
sql_content[RW]
status[RW]

Public Class Methods

new(file_path) click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 13
def initialize file_path
  @path = file_path
  @name = File.basename(file_path, ".*")

  @status = :none
  @required = []
  @marked_as_deleted = false
  @sql_content = File.read(@path)
  @inverse_of_required = []

  load_directives
end

Public Instance Methods

create!() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 65
def create!
  return if marked_as_deleted? || loaded?

  circular_reference_error if in_progress?

  self.status = Status::IN_PROGRESS

  required.each do |symbol_name|
    symbol = RailsDbViews::Factory.get(self.class, symbol_name)
    not_found_error(symbol_name) if symbol.nil?
    symbol.create!
  end

  ActiveRecord::Base.connection.execute(create_sql)

  self.status = Status::LOADED
end
create_sql() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 111
def create_sql
  raise NotImplementedError, "DatabaseSymbol should not be instanciated"
end
drop!() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 83
def drop!
  return if loaded?

  circular_reference_error if in_progress?

  self.status = Status::IN_PROGRESS

  # We start by the required one to delete first.
  inverse_of_required.each do |symbol_name|
    symbol = RailsDbViews::Factory.get(self.class, symbol_name)
    not_found_error(symbol_name) if symbol.nil?
    symbol.drop!
  end

  begin
    ActiveRecord::Base.connection.execute(drop_sql)
  rescue ActiveRecord::ActiveRecordError => e #Probably because the symbol doesn't exists yet.
    handle_error_on_drop
  end

  self.status = Status::LOADED
end
drop_sql() click to toggle source

Theses methods should be implemented in children objects.

# File lib/rails_db_views/database_symbol.rb, line 107
def drop_sql
  raise NotImplementedError, "DatabaseSymbol should not be instanciated"
end
handle_error_on_drop() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 115
def handle_error_on_drop
  raise NotImplementedError, "DatabaseSymbol should not be instanciated"
end
in_progress?() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 42
def in_progress?
  status == Status::IN_PROGRESS
end
loaded?() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 38
def loaded?
  status == Status::LOADED
end
mark_as_delete!() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 34
def mark_as_delete!
  @marked_as_deleted = true
end
process_inverse_of_required!() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 26
def process_inverse_of_required!
  @required.each do |name|
    required = RailsDbViews::Factory.get(self.class, name)
    not_found_error if required.nil?
    required.inverse_of_required << self.name
  end
end
process_string_interpolation(str) click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 51
def process_string_interpolation str
  str.gsub(STRING_INTERPOLATION) do |x|
    if $2 == '\\'
      $1[1..-1] #Rendering the whole expression because of escape char.
    else
      $2 + (TOPLEVEL_BINDING.eval($3)).to_s
    end
  end
end
uncommented_sql_content() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 61
def uncommented_sql_content
  process_string_interpolation(sql_content.split("\n").reject{|x| x=~ COMMENTS }.join("\n"))
end
unloaded?() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 46
def unloaded?
  status == Status::UNLOADED
end

Protected Instance Methods

circular_reference_error() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 129
def circular_reference_error
  raise RailsDbViews::CircularReferenceError, "Circular file reference! (file: #{path})"
end
load_directives() click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 137
def load_directives
  content_lines = sql_content.split("\n")

  directives = content_lines.map(&:strip).select{ |x| x =~ DIRECTIVE_START }.map{ |x|
      x.gsub(DIRECTIVE_START, "")
  }

  directives.each do |d|
    case d
    when /^require /
      self.required += d.split(/[ \t]+/)[1..-1]
    when /^delete(d?)/
      self.mark_as_delete!
    else
      raise RailsDbViews::IllegalDirective, "I don't know what to do with `#{d}` (in #{path})"
    end
  end

end
not_found_error(symbol_name) click to toggle source
# File lib/rails_db_views/database_symbol.rb, line 133
def not_found_error(symbol_name)
  raise RailsDbViews::SymbolNotFound, "#{self.class.name} `#{symbol_name}` referenced in file #{path} cannot be found..."
end