Class: SqlBeautifier::TableReference

Inherits:
Base
  • Object
show all
Defined in:
lib/sql_beautifier/table_reference.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.derived_table_lookup_name_from(text) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sql_beautifier/table_reference.rb', line 65

def self.derived_table_lookup_name_from(text)
  stripped_text, _lateral = strip_lateral_prefix(text.strip)
  return unless stripped_text.start_with?(Constants::OPEN_PARENTHESIS)

  closing_position = Scanner.new(stripped_text).find_matching_parenthesis(0)
  return unless closing_position

  expression = stripped_text[0..closing_position]
  remaining_text = stripped_text[(closing_position + 1)..].strip
  derived_alias = extract_derived_table_alias(remaining_text)

  derived_alias || expression
end

.extract_derived_table_alias(remaining_text) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sql_beautifier/table_reference.rb', line 79

def self.extract_derived_table_alias(remaining_text)
  return if remaining_text.empty?

  words = remaining_text.split(Constants::WHITESPACE_REGEX)

  if words.first&.downcase == "as"
    words[1]
  else
    words.first
  end
end

.extract_explicit_alias(table_specification) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/sql_beautifier/table_reference.rb', line 44

def self.extract_explicit_alias(table_specification)
  words = table_specification.strip.split(Constants::WHITESPACE_REGEX).grep_v(CommentParser::SENTINEL_PATTERN)
  return nil if words.length < 2

  if words[1] == "as"
    words[2]
  else
    words[1]
  end
end

.parse(segment_text) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/sql_beautifier/table_reference.rb', line 10

def self.parse(segment_text)
  table_specification = table_specification_text(segment_text)
  stripped_specification, _lateral = strip_lateral_prefix(table_specification.strip)

  return parse_derived_table(stripped_specification) if stripped_specification.start_with?(Constants::OPEN_PARENTHESIS)

  table_name = Util.first_word(stripped_specification)
  return unless table_name

  new(name: table_name, explicit_alias: extract_explicit_alias(stripped_specification))
end

.parse_derived_table(table_specification) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/sql_beautifier/table_reference.rb', line 22

def self.parse_derived_table(table_specification)
  closing_position = Scanner.new(table_specification).find_matching_parenthesis(0)
  return unless closing_position

  expression = table_specification[0..closing_position]
  remaining = table_specification[(closing_position + 1)..].strip
  derived_alias = extract_derived_table_alias(remaining)

  new(
    name: derived_alias || expression,
    explicit_alias: derived_alias,
    derived_table_expression: expression
  )
end

.strip_lateral_prefix(text) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/sql_beautifier/table_reference.rb', line 55

def self.strip_lateral_prefix(text)
  stripped = text.strip

  if stripped.match?(Constants::LATERAL_PREFIX_PATTERN)
    [stripped.sub(Constants::LATERAL_PREFIX_PATTERN, ""), true]
  else
    [stripped, false]
  end
end

.table_specification_text(segment_text) ⇒ Object



37
38
39
40
41
42
# File 'lib/sql_beautifier/table_reference.rb', line 37

def self.table_specification_text(segment_text)
  on_keyword_position = Tokenizer.find_top_level_keyword(segment_text, "on")
  return segment_text.strip unless on_keyword_position

  segment_text[0...on_keyword_position].strip
end

Instance Method Details

#alias_name ⇒ Object



103
104
105
# File 'lib/sql_beautifier/table_reference.rb', line 103

def alias_name
  @explicit_alias || @assigned_alias
end

#assign_alias!(value) ⇒ Object



99
100
101
# File 'lib/sql_beautifier/table_reference.rb', line 99

def assign_alias!(value)
  @assigned_alias = value
end

#derived_table? ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/sql_beautifier/table_reference.rb', line 91

def derived_table?
  @derived_table_expression.present?
end

#formatted_name ⇒ Object



95
96
97
# File 'lib/sql_beautifier/table_reference.rb', line 95

def formatted_name
  Util.format_table_name(@name)
end

#render(trailing_sentinels: nil) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sql_beautifier/table_reference.rb', line 107

def render(trailing_sentinels: nil)
  formatted = begin
    if derived_table?
      alias_name ? "#{@derived_table_expression} #{alias_name}" : @derived_table_expression
    else
      alias_name ? "#{formatted_name} #{alias_name}" : formatted_name
    end
  end

  trailing_sentinels&.any? ? "#{formatted} #{trailing_sentinels.join(' ')}" : formatted
end