Module: ActiveRecord::Refined::AST::Predications
- Included in:
- Aggregate, Arithmetic, Bitwise, BitwiseNot, Case, Cast, Column, DatetimeValueFunction, Extract, Function, JsonPath, JsonSet, Over, Value
- Defined in:
- lib/active_record/refined/ast.rb
Overview
Predicate builders shared by symbols, qualified columns and expressions. Imported into the Symbol refinement with Refinement#import_methods, so every method must be defined with def.
Instance Method Summary collapse
- #!=(other) ⇒ Object
- #!~(pattern) ⇒ Object
- #<(other) ⇒ Object
- #<=(other) ⇒ Object
-
#==(other) ⇒ Object
and != mean SQL = and <>, and = NULL is never true there, so nil is rejected rather than silently rewritten to IS NULL.
- #=~(pattern) ⇒ Object
- #>(other) ⇒ Object
- #>=(other) ⇒ Object
- #between?(min, max) ⇒ Boolean
-
#bury(*path, value) ⇒ Object
What dig reads, bury sets: the last argument is the value and the rest are the path to it.
-
#casecmp?(value) ⇒ Boolean
Case-insensitive equality, folded on both sides rather than left to the collation, so it means the same thing on every adapter.
-
#contains?(value) ⇒ Boolean
Whether the document holds what is given, which SQL calls containment.
-
#dig(*path) ⇒ Object
Reading inside a JSON document, by the name of what Hash does.
- #dig_json(*path) ⇒ Object
-
#distinct_from?(value) ⇒ Boolean
Null-safe comparison: unlike = and <>, these treat NULL as a value, so not_distinct_from? is the one equality that may take nil.
- #end_with?(*suffixes) ⇒ Boolean
- #false? ⇒ Boolean
- #ilike?(pattern) ⇒ Boolean
- #in?(values) ⇒ Boolean
- #include?(substring) ⇒ Boolean
- #intersect?(elements) ⇒ Boolean
-
#key?(key) ⇒ Boolean
Whether the key is there at all, as Hash#key? asks.
- #like?(pattern) ⇒ Boolean
-
#member?(element) ⇒ Boolean
The array comparisons carry the meaning of their Ruby namesakes.
- #not_between?(min, max) ⇒ Boolean
- #not_distinct_from?(value) ⇒ Boolean
- #not_false? ⇒ Boolean
- #not_ilike?(pattern) ⇒ Boolean
- #not_in?(values) ⇒ Boolean
- #not_like?(pattern) ⇒ Boolean
- #not_null? ⇒ Boolean
- #not_true? ⇒ Boolean
-
#null? ⇒ Boolean
!negates any predicate, so these are here for the four that SQL spells for itself: IS NOT NULL rather than NOT (... IS NULL), and likewise NOT IN and NOT LIKE. - #start_with?(*prefixes) ⇒ Boolean
- #subset?(elements) ⇒ Boolean
- #superset?(elements) ⇒ Boolean
-
#true? ⇒ Boolean
IS TRUE and IS FALSE differ from a comparison against the literal in what they make of NULL:
flag = TRUEis itself NULL there, and a NULL predicate selects nothing, while these two answer false. -
#when(value = nil, &block) ⇒ Object
CASE with this as the operand, compared against each
when::age.when(10).then(1).else(0).
Instance Method Details
#!=(other) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/active_record/refined/ast.rb', line 49 def !=(other) if other.nil? raise ArgumentError, "!= does not take nil; use !null? instead" end Comparison.new(self, :!=, other) end |
#!~(pattern) ⇒ Object
76 77 78 |
# File 'lib/active_record/refined/ast.rb', line 76 def !~(pattern) Match.new(self, pattern, negated: true) end |
#<(other) ⇒ Object
64 65 66 |
# File 'lib/active_record/refined/ast.rb', line 64 def <(other) Comparison.new(self, :<, other) end |
#<=(other) ⇒ Object
68 69 70 |
# File 'lib/active_record/refined/ast.rb', line 68 def <=(other) Comparison.new(self, :<=, other) end |
#==(other) ⇒ Object
and != mean SQL = and <>, and = NULL is never true there, so nil
is rejected rather than silently rewritten to IS NULL. null? builds its node directly and stays clear of this check.
42 43 44 45 46 47 |
# File 'lib/active_record/refined/ast.rb', line 42 def ==(other) if other.nil? raise ArgumentError, "== does not take nil; use null? instead" end Comparison.new(self, :==, other) end |
#=~(pattern) ⇒ Object
72 73 74 |
# File 'lib/active_record/refined/ast.rb', line 72 def =~(pattern) Match.new(self, pattern) end |
#>(other) ⇒ Object
56 57 58 |
# File 'lib/active_record/refined/ast.rb', line 56 def >(other) Comparison.new(self, :>, other) end |
#>=(other) ⇒ Object
60 61 62 |
# File 'lib/active_record/refined/ast.rb', line 60 def >=(other) Comparison.new(self, :>=, other) end |
#between?(min, max) ⇒ Boolean
121 122 123 |
# File 'lib/active_record/refined/ast.rb', line 121 def between?(min, max) In.new(self, min..max) end |
#bury(*path, value) ⇒ Object
What dig reads, bury sets: the last argument is the value and the rest are the path to it. The document comes back changed rather than being written anywhere, which update_all is for.
230 231 232 |
# File 'lib/active_record/refined/ast.rb', line 230 def bury(*path, value) JsonSet.new(self, path, value) end |
#casecmp?(value) ⇒ Boolean
Case-insensitive equality, folded on both sides rather than left to the collation, so it means the same thing on every adapter.
154 155 156 157 158 159 160 |
# File 'lib/active_record/refined/ast.rb', line 154 def casecmp?(value) if value.nil? raise ArgumentError, "casecmp? does not take nil; use null? instead" end Comparison.new(Function.new("LOWER", [self]), :==, Function.new("LOWER", [value])) end |
#contains?(value) ⇒ Boolean
Whether the document holds what is given, which SQL calls containment. SQLite has no equivalent.
236 237 238 |
# File 'lib/active_record/refined/ast.rb', line 236 def contains?(value) JsonContains.new(self, value) end |
#dig(*path) ⇒ Object
Reading inside a JSON document, by the name of what Hash does. A string or symbol steps into an object, an integer into an array, and what comes back is the value rather than the JSON, since that is what a comparison wants. dig_json keeps it JSON, for a document to be dug into further or compared whole.
219 220 221 |
# File 'lib/active_record/refined/ast.rb', line 219 def dig(*path) JsonPath.new(self, path) end |
#dig_json(*path) ⇒ Object
223 224 225 |
# File 'lib/active_record/refined/ast.rb', line 223 def dig_json(*path) JsonPath.new(self, path, as_json: true) end |
#distinct_from?(value) ⇒ Boolean
Null-safe comparison: unlike = and <>, these treat NULL as a value, so not_distinct_from? is the one equality that may take nil.
164 165 166 |
# File 'lib/active_record/refined/ast.rb', line 164 def distinct_from?(value) DistinctFrom.new(self, value, negated: true) end |
#end_with?(*suffixes) ⇒ Boolean
179 180 181 182 183 184 |
# File 'lib/active_record/refined/ast.rb', line 179 def end_with?(*suffixes) if suffixes.empty? raise ArgumentError, "end_with? needs at least one suffix" end Like.any(self, suffixes.map {|suffix| "%#{Like.escape(suffix)}" }) end |
#false? ⇒ Boolean
105 106 107 |
# File 'lib/active_record/refined/ast.rb', line 105 def false? TruthValue.new(self, false) end |
#ilike?(pattern) ⇒ Boolean
144 145 146 |
# File 'lib/active_record/refined/ast.rb', line 144 def ilike?(pattern) Like.new(self, pattern, nil, case_sensitive: false) end |
#in?(values) ⇒ Boolean
113 114 115 |
# File 'lib/active_record/refined/ast.rb', line 113 def in?(values) In.new(self, values) end |
#include?(substring) ⇒ Boolean
186 187 188 |
# File 'lib/active_record/refined/ast.rb', line 186 def include?(substring) Like.new(self, "%#{Like.escape(substring)}%", Like::ESCAPE) end |
#intersect?(elements) ⇒ Boolean
210 211 212 |
# File 'lib/active_record/refined/ast.rb', line 210 def intersect?(elements) ArrayPredicate.new(self, :"&&", ArrayPredicate.elements(elements, "intersect?")) end |
#key?(key) ⇒ Boolean
Whether the key is there at all, as Hash#key? asks. Hash has has_key? too; one name is enough, and this is the one Ruby's own style prefers.
243 244 245 |
# File 'lib/active_record/refined/ast.rb', line 243 def key?(key) JsonHasKey.new(self, key) end |
#like?(pattern) ⇒ Boolean
136 137 138 |
# File 'lib/active_record/refined/ast.rb', line 136 def like?(pattern) Like.new(self, pattern) end |
#member?(element) ⇒ Boolean
The array comparisons carry the meaning of their Ruby namesakes. member? is Enumerable's element test, so an Array argument is rejected rather than quietly meaning something Array#member? does not; whole-array comparisons go by the Set and Array names.
194 195 196 197 198 199 200 |
# File 'lib/active_record/refined/ast.rb', line 194 def member?(element) if element.is_a?(::Array) || element.is_a?(::Set) raise ArgumentError, "member? takes a single element; use superset? to require every element" end ArrayPredicate.new(self, :"@>", [element]) end |
#not_between?(min, max) ⇒ Boolean
125 126 127 |
# File 'lib/active_record/refined/ast.rb', line 125 def not_between?(min, max) In.new(self, min..max, negated: true) end |
#not_distinct_from?(value) ⇒ Boolean
168 169 170 |
# File 'lib/active_record/refined/ast.rb', line 168 def not_distinct_from?(value) DistinctFrom.new(self, value) end |
#not_false? ⇒ Boolean
109 110 111 |
# File 'lib/active_record/refined/ast.rb', line 109 def not_false? TruthValue.new(self, false, negated: true) end |
#not_ilike?(pattern) ⇒ Boolean
148 149 150 |
# File 'lib/active_record/refined/ast.rb', line 148 def not_ilike?(pattern) Like.new(self, pattern, nil, case_sensitive: false, negated: true) end |
#not_in?(values) ⇒ Boolean
117 118 119 |
# File 'lib/active_record/refined/ast.rb', line 117 def not_in?(values) In.new(self, values, negated: true) end |
#not_like?(pattern) ⇒ Boolean
140 141 142 |
# File 'lib/active_record/refined/ast.rb', line 140 def not_like?(pattern) Like.new(self, pattern, negated: true) end |
#not_null? ⇒ Boolean
88 89 90 |
# File 'lib/active_record/refined/ast.rb', line 88 def not_null? Comparison.new(self, :!=, nil) end |
#not_true? ⇒ Boolean
101 102 103 |
# File 'lib/active_record/refined/ast.rb', line 101 def not_true? TruthValue.new(self, true, negated: true) end |
#null? ⇒ Boolean
! negates any predicate, so these are here for the four that SQL
spells for itself: IS NOT NULL rather than NOT (... IS NULL), and
likewise NOT IN and NOT LIKE. They mean the same thing either way,
including when the column is NULL; what they save is the reading.
84 85 86 |
# File 'lib/active_record/refined/ast.rb', line 84 def null? Comparison.new(self, :==, nil) end |
#start_with?(*prefixes) ⇒ Boolean
172 173 174 175 176 177 |
# File 'lib/active_record/refined/ast.rb', line 172 def start_with?(*prefixes) if prefixes.empty? raise ArgumentError, "start_with? needs at least one prefix" end Like.any(self, prefixes.map {|prefix| "#{Like.escape(prefix)}%" }) end |
#subset?(elements) ⇒ Boolean
206 207 208 |
# File 'lib/active_record/refined/ast.rb', line 206 def subset?(elements) ArrayPredicate.new(self, :"<@", ArrayPredicate.elements(elements, "subset?")) end |
#superset?(elements) ⇒ Boolean
202 203 204 |
# File 'lib/active_record/refined/ast.rb', line 202 def superset?(elements) ArrayPredicate.new(self, :"@>", ArrayPredicate.elements(elements, "superset?")) end |
#true? ⇒ Boolean
IS TRUE and IS FALSE differ from a comparison against the literal in
what they make of NULL: flag = TRUE is itself NULL there, and a
NULL predicate selects nothing, while these two answer false. So the
difference shows in the negations: not_true? keeps the NULL rows
that !(:flag == true) drops.
97 98 99 |
# File 'lib/active_record/refined/ast.rb', line 97 def true? TruthValue.new(self, true) end |
#when(value = nil, &block) ⇒ Object
CASE with this as the operand, compared against each when:
:age.when(10).then(1).else(0). The other shape, where each when
carries its own condition, starts at case_when.
132 133 134 |
# File 'lib/active_record/refined/ast.rb', line 132 def when(value = nil, &block) Case.new(self).when(value, &block) end |