mensa 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca5c6f3fab08895527058f4cbb70a55608297da85a234c2476d120be6de13882
4
- data.tar.gz: f09da64e3c8dfaaf1917e1097845171aa29fab13c18285d3802278d5a7d8bfc9
3
+ metadata.gz: 9bf52a653e507bed6b1fe67a162dfa882b8dab27aa377b3d883e3da45f67f727
4
+ data.tar.gz: da0c8e7b5c349f4f5bd8c4358797a5eec1327ecf1171dc6de7158b0cc9cfbee4
5
5
  SHA512:
6
- metadata.gz: 2f9ff2a45fd5d5784a31ee7e96d45b683bc16aecb53947eb6a942f5764d175fcbbc16303103ad3c46f71a571da8c5a8b5e8af9fa82000fdd8bbd025694108263
7
- data.tar.gz: 9948a29ea8daee96c71466b33d3e63e4a7dd20496247edf36740c779cf2b2743fbfdedf92f03a391abe5d43544aa32f25825b340b6fb8a8f471bb66432107dda
6
+ metadata.gz: 0c9e920e4760b45ea4d3ecb2f4e09745a84bc1830e70a3a2085fba4b5511411df65b607fecc9e11ec827811a71848d8a4f66c1be7f0a71b61a77d4100b3b5c99
7
+ data.tar.gz: b86ee152657699c2739acda33e9b24afcd04e2360a2f034c2d20b27bb2aaa7d5ba53b1677ea0cef76fa238e179c05eec5194fc268069a1c0fda06d7a761ac10e
data/.shipkit.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- previous_version: 0.7.1
2
+ previous_version: 0.7.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.3
4
+
5
+ - **Behaviour change:** the `matches` and `does_not_match` filters now do a
6
+ case-insensitive "contains" (`ILIKE '%value%'`), the same way search does.
7
+ Before, they passed the value to `LIKE` as it was, so `matches "LLC"` only
8
+ found rows that were exactly `LLC`. The value is taken literally, so saved
9
+ views that relied on typing `%` or `_` wildcards now match a literal `%` or
10
+ `_`. `does_not_match` now also returns rows where the column is NULL.
11
+ Attributes without a `type` are cast to text for the comparison.
12
+
3
13
  ## 0.7.2
4
14
 
5
15
  - The verifier's report only lists failures and warnings. `-v`/`--verbose` (or
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mensa (0.7.1)
4
+ mensa (0.7.2)
5
5
  csv
6
6
  importmap-rails
7
7
  pagy (>= 43)
data/README.md CHANGED
@@ -187,6 +187,11 @@ The operators are `is`, `isnt`, `matches`, `does_not_match`, `gt`, `gteq`, `lt`,
187
187
  | boolean, uuid, enums and other types | `is`, `isnt` |
188
188
  | jsonb, json | none (json also has no `is_duplicate`) |
189
189
 
190
+ `matches` finds rows where the column contains the value anywhere, ignoring case
191
+ (`ILIKE '%value%'`), and `does_not_match` finds the others, including rows where the
192
+ column is empty (NULL). The value is taken literally: `%`, `_` and `\` are matched as
193
+ characters, not as wildcards. A blank value matches only empty strings.
194
+
190
195
  `matches` and `does_not_match` are left out when the filter has a `collection`, and
191
196
  `is_current` is only offered when `Current` has a method named after the column.
192
197
 
@@ -14,7 +14,7 @@ module Mensa
14
14
  config_reader :multiple
15
15
  config_reader :having?
16
16
 
17
- # Types that LIKE works on, nil is an attribute without a type
17
+ # Types that ILIKE works on, nil is an attribute without a type
18
18
  TEXT_TYPES = [:string, :text, :citext, nil].freeze
19
19
  # Types with a meaningful order, for gt, gteq, lt and lteq
20
20
  RANGE_TYPES = %i[integer bigint float decimal money date datetime timestamp timestamptz time interval].freeze
@@ -139,9 +139,12 @@ module Mensa
139
139
  hash[:value] = Current.public_send(column.name)
140
140
  "#{col} = :value"
141
141
  when :matches
142
- "#{col} LIKE :value"
142
+ hash[:value] = contains_pattern(hash[:value])
143
+ "#{text_col(col)} ILIKE :value"
143
144
  when :does_not_match
144
- "#{col} NOT LIKE :value"
145
+ # Rows without a value don't contain it either
146
+ hash[:value] = contains_pattern(hash[:value])
147
+ "(#{col} IS NULL OR #{text_col(col)} NOT ILIKE :value)"
145
148
  when :is
146
149
  hash[:value].is_a?(Array) ? "#{col} IN (:value)" : "#{col} = :value"
147
150
  when :isnt
@@ -280,6 +283,23 @@ module Mensa
280
283
  record_scope.having("#{column_sql} IN (#{duplicate_values_scope.to_sql})")
281
284
  end
282
285
 
286
+ # A case-insensitive "contains" pattern, with %, _ and \ in the value
287
+ # matched literally. A blank value is compared as it is, like `is` does,
288
+ # so it doesn't turn into '%%' and match everything.
289
+ def contains_pattern(value)
290
+ return value if value.to_s.empty?
291
+
292
+ "%#{ActiveRecord::Base.sanitize_sql_like(value.to_s)}%"
293
+ end
294
+
295
+ # An attribute without a type may not be text in SQL (e.g. a count), cast
296
+ # it like search does. Typed columns are compared as they are, so an
297
+ # explicit `matches` on e.g. a boolean still fails (and the verifier
298
+ # reports it).
299
+ def text_col(col)
300
+ column.type.nil? ? "CAST(#{col} AS text)" : col
301
+ end
302
+
283
303
  # Unused at the moment
284
304
  def normalize(query)
285
305
  query
data/lib/mensa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mensa
2
- VERSION = "0.7.2"
2
+ VERSION = "0.7.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mensa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom de Grunt