Class: SqlBeautifier::Condition
- Defined in:
- lib/sql_beautifier/condition.rb
Constant Summary collapse
- NOT_PREFIX_PATTERN =
%r{\Anot([[:space:]]+)}i
Class Method Summary collapse
- .build(conjunction, condition_text) ⇒ Object
- .flatten_group_into!(flattened, group_condition, outer_conjunction) ⇒ Object
- .flatten_same_conjunction_groups(conditions) ⇒ Object
- .flattenable_into_conjunction?(condition, outer_conjunction) ⇒ Boolean
- .format(text, indent_width: 0) ⇒ Object
- .parse_all(text) ⇒ Object
- .parse_condition_group(condition_text) ⇒ Object
- .render_all(conditions, indent_width:) ⇒ Object
- .unwrap_not_prefix_parens(text) ⇒ Object
- .unwrap_single_condition(condition_text) ⇒ Object
Instance Method Summary collapse
Class Method Details
.build(conjunction, condition_text) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sql_beautifier/condition.rb', line 68 def self.build(conjunction, condition_text) unwrapped = unwrap_single_condition(condition_text) inner_conditions = parse_condition_group(unwrapped) if inner_conditions children = inner_conditions.map do |inner_conjunction, inner_text| build(inner_conjunction, inner_text) end new(conjunction: conjunction, children: children) else new(conjunction: conjunction, expression: unwrapped) end end |
.flatten_group_into!(flattened, group_condition, outer_conjunction) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/sql_beautifier/condition.rb', line 158 def self.flatten_group_into!(flattened, group_condition, outer_conjunction) group_condition.children.each_with_index do |child, inner_index| new_conjunction = begin if flattened.empty? nil elsif inner_index.zero? group_condition.conjunction || outer_conjunction else outer_conjunction end end flattened << new(conjunction: new_conjunction, expression: child.expression, children: child.children) end end |
.flatten_same_conjunction_groups(conditions) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/sql_beautifier/condition.rb', line 131 def self.flatten_same_conjunction_groups(conditions) return conditions if conditions.length <= 1 outer_conjunction = conditions[1]&.conjunction return conditions unless outer_conjunction return conditions unless conditions.drop(1).all? { |condition| condition.conjunction == outer_conjunction } flattened = [] conditions.each do |condition| if condition.group? && flattenable_into_conjunction?(condition, outer_conjunction) flatten_group_into!(flattened, condition, outer_conjunction) else flattened << condition end end flattened end |
.flattenable_into_conjunction?(condition, outer_conjunction) ⇒ Boolean
151 152 153 154 155 156 |
# File 'lib/sql_beautifier/condition.rb', line 151 def self.flattenable_into_conjunction?(condition, outer_conjunction) return false unless condition.group? inner_conjunction = condition.children[1]&.conjunction inner_conjunction == outer_conjunction && condition.children.drop(1).all? { |child| child.conjunction == outer_conjunction } end |
.format(text, indent_width: 0) ⇒ Object
11 12 13 14 15 16 |
# File 'lib/sql_beautifier/condition.rb', line 11 def self.format(text, indent_width: 0) conditions = parse_all(text) return conditions.first.expression if conditions.length <= 1 && conditions.first&.leaf? render_all(conditions, indent_width: indent_width) end |
.parse_all(text) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/sql_beautifier/condition.rb', line 18 def self.parse_all(text) raw_pairs = Tokenizer.split_top_level_conditions(text) conditions = raw_pairs.map do |conjunction, condition_text| build(conjunction, condition_text) end flatten_same_conjunction_groups(conditions) end |
.parse_condition_group(condition_text) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/sql_beautifier/condition.rb', line 118 def self.parse_condition_group(condition_text) return unless condition_text trimmed = condition_text.strip return unless Tokenizer.outer_parentheses_wrap_all?(trimmed) inner_content = Util.strip_outer_parentheses(trimmed) inner_conditions = Tokenizer.split_top_level_conditions(inner_content) return unless inner_conditions.length > 1 inner_conditions end |
.render_all(conditions, indent_width:) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/sql_beautifier/condition.rb', line 27 def self.render_all(conditions, indent_width:) indentation = Util.whitespace(indent_width) lines = [] conditions.each_with_index do |condition, index| rendered = condition.render(indent_width: indent_width) line = begin if index.zero? "#{indentation}#{rendered}" else "#{indentation}#{condition.conjunction} #{rendered}" end end lines << line end lines.join("\n") end |
.unwrap_not_prefix_parens(text) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/sql_beautifier/condition.rb', line 97 def self.unwrap_not_prefix_parens(text) prefix_match = text.match(NOT_PREFIX_PATTERN) return text unless prefix_match remainder = text[prefix_match[0].length..] unwrapped_remainder = remainder while Tokenizer.outer_parentheses_wrap_all?(unwrapped_remainder) inner_content = Util.strip_outer_parentheses(unwrapped_remainder) inner_conditions = Tokenizer.split_top_level_conditions(inner_content) break if inner_conditions.length > 1 unwrapped_remainder = inner_content end return text if unwrapped_remainder == remainder "not #{unwrapped_remainder}" end |
.unwrap_single_condition(condition_text) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/sql_beautifier/condition.rb', line 83 def self.unwrap_single_condition(condition_text) output = condition_text.strip while Tokenizer.outer_parentheses_wrap_all?(output) inner_content = Util.strip_outer_parentheses(output) inner_conditions = Tokenizer.split_top_level_conditions(inner_content) break if inner_conditions.length > 1 output = inner_content end unwrap_not_prefix_parens(output) end |
Instance Method Details
#group? ⇒ Boolean
52 53 54 |
# File 'lib/sql_beautifier/condition.rb', line 52 def group? !leaf? end |
#leaf? ⇒ Boolean
48 49 50 |
# File 'lib/sql_beautifier/condition.rb', line 48 def leaf? @children.nil? end |
#render(indent_width:) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/sql_beautifier/condition.rb', line 56 def render(indent_width:) return InList.format_in_text(@expression, base_indent: indent_width) if leaf? inline_version = render_inline return inline_version if inline_version.length <= SqlBeautifier.config_for(:inline_group_threshold) inner_output = self.class.render_all(@children, indent_width: indent_width + 4) closing_indentation = Util.whitespace(indent_width) "(\n#{inner_output}\n#{closing_indentation})" end |