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
53 54 55 56 57 58 |
# File 'lib/active_record/refined/ast.rb', line 53 def !=(other) if other.nil? raise ArgumentError, "!= does not take nil; use !null? instead" end Comparison.new(self, :!=, other) end |
#!~(pattern) ⇒ Object
80 81 82 |
# File 'lib/active_record/refined/ast.rb', line 80 def !~(pattern) Match.new(self, pattern, negated: true) end |
#<(other) ⇒ Object
68 69 70 |
# File 'lib/active_record/refined/ast.rb', line 68 def <(other) Comparison.new(self, :<, other) end |
#<=(other) ⇒ Object
72 73 74 |
# File 'lib/active_record/refined/ast.rb', line 72 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.
46 47 48 49 50 51 |
# File 'lib/active_record/refined/ast.rb', line 46 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) end |
#>(other) ⇒ Object
60 61 62 |
# File 'lib/active_record/refined/ast.rb', line 60 def >(other) Comparison.new(self, :>, other) end |
#>=(other) ⇒ Object
64 65 66 |
# File 'lib/active_record/refined/ast.rb', line 64 def >=(other) Comparison.new(self, :>=, other) end |
#between?(min, max) ⇒ Boolean
125 126 127 |
# File 'lib/active_record/refined/ast.rb', line 125 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.
234 235 236 |
# File 'lib/active_record/refined/ast.rb', line 234 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.
158 159 160 161 162 163 164 |
# File 'lib/active_record/refined/ast.rb', line 158 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.
240 241 242 |
# File 'lib/active_record/refined/ast.rb', line 240 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.
223 224 225 |
# File 'lib/active_record/refined/ast.rb', line 223 def dig(*path) JsonPath.new(self, path) end |
#dig_json(*path) ⇒ Object
227 228 229 |
# File 'lib/active_record/refined/ast.rb', line 227 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.
168 169 170 |
# File 'lib/active_record/refined/ast.rb', line 168 def distinct_from?(value) DistinctFrom.new(self, value, negated: true) end |
#end_with?(*suffixes) ⇒ Boolean
183 184 185 186 187 188 |
# File 'lib/active_record/refined/ast.rb', line 183 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
109 110 111 |
# File 'lib/active_record/refined/ast.rb', line 109 def false? TruthValue.new(self, false) end |
#ilike?(pattern) ⇒ Boolean
148 149 150 |
# File 'lib/active_record/refined/ast.rb', line 148 def ilike?(pattern) Like.new(self, pattern, nil, case_sensitive: false) end |
#in?(values) ⇒ Boolean
117 118 119 |
# File 'lib/active_record/refined/ast.rb', line 117 def in?(values) In.new(self, values) end |
#include?(substring) ⇒ Boolean
190 191 192 |
# File 'lib/active_record/refined/ast.rb', line 190 def include?(substring) Like.new(self, "%#{Like.escape(substring)}%", Like::ESCAPE) end |
#intersect?(elements) ⇒ Boolean
214 215 216 |
# File 'lib/active_record/refined/ast.rb', line 214 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.
247 248 249 |
# File 'lib/active_record/refined/ast.rb', line 247 def key?(key) JsonHasKey.new(self, key) end |
#like?(pattern) ⇒ Boolean
140 141 142 |
# File 'lib/active_record/refined/ast.rb', line 140 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.
198 199 200 201 202 203 204 |
# File 'lib/active_record/refined/ast.rb', line 198 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
129 130 131 |
# File 'lib/active_record/refined/ast.rb', line 129 def not_between?(min, max) In.new(self, min..max, negated: true) end |
#not_distinct_from?(value) ⇒ Boolean
172 173 174 |
# File 'lib/active_record/refined/ast.rb', line 172 def not_distinct_from?(value) DistinctFrom.new(self, value) end |
#not_false? ⇒ Boolean
113 114 115 |
# File 'lib/active_record/refined/ast.rb', line 113 def not_false? TruthValue.new(self, false, negated: true) end |
#not_ilike?(pattern) ⇒ Boolean
152 153 154 |
# File 'lib/active_record/refined/ast.rb', line 152 def not_ilike?(pattern) Like.new(self, pattern, nil, case_sensitive: false, negated: true) end |
#not_in?(values) ⇒ Boolean
121 122 123 |
# File 'lib/active_record/refined/ast.rb', line 121 def not_in?(values) In.new(self, values, negated: true) end |
#not_like?(pattern) ⇒ Boolean
144 145 146 |
# File 'lib/active_record/refined/ast.rb', line 144 def not_like?(pattern) Like.new(self, pattern, negated: true) end |
#not_null? ⇒ Boolean
92 93 94 |
# File 'lib/active_record/refined/ast.rb', line 92 def not_null? Comparison.new(self, :!=, nil) end |
#not_true? ⇒ Boolean
105 106 107 |
# File 'lib/active_record/refined/ast.rb', line 105 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.
88 89 90 |
# File 'lib/active_record/refined/ast.rb', line 88 def null? Comparison.new(self, :==, nil) end |
#start_with?(*prefixes) ⇒ Boolean
176 177 178 179 180 181 |
# File 'lib/active_record/refined/ast.rb', line 176 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
210 211 212 |
# File 'lib/active_record/refined/ast.rb', line 210 def subset?(elements) ArrayPredicate.new(self, :"<@", ArrayPredicate.elements(elements, "subset?")) end |
#superset?(elements) ⇒ Boolean
206 207 208 |
# File 'lib/active_record/refined/ast.rb', line 206 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.
101 102 103 |
# File 'lib/active_record/refined/ast.rb', line 101 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.
136 137 138 |
# File 'lib/active_record/refined/ast.rb', line 136 def when(value = nil, &block) Case.new(self).when(value, &block) end |