order_query 0.4.1 → 0.5.0

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
- SHA1:
3
- metadata.gz: 01cd918d06d860206e938baf5f500446132bdbd6
4
- data.tar.gz: 39882d3d3d1fb272f88597ed281973618b6f293c
2
+ SHA256:
3
+ metadata.gz: 140bea826457d9ad046a701da89e0073ca15f6631d3e996b5b44ba01fc7a7910
4
+ data.tar.gz: aae7c51f4c0c607455b92efa36ca71c2df86b0b7b49c022a94bb209452a6bc4e
5
5
  SHA512:
6
- metadata.gz: 8b23735d7393e0bc5e8842e644deb06f22618b50e68ed5537c1755c3e6dd88858189104d18cef2279d15fa9fc158dc8a3470570f980b13f929187e80be30d5d8
7
- data.tar.gz: a40ec816d36f311647c37515adf8866151505a4205b5c46e0d42f22f47c1f9ef7816a290df711876157bfefe25849065ddb86aff1d5bf4b3f1967ae1d187560e
6
+ metadata.gz: f3c6db46a213cd3acc4cddc7f9f35247ec7ac6c986005b2d4e9185128b2f8c12ec585230c879e5a911c9c4ff097b00eda7dd530f04f78e242715c0bcda27ed5d
7
+ data.tar.gz: 6171c2a35660bb8595bfae88e159cb65cafb93039ebd032b8257d5564e99dbedf51c6044d78df8382497b1d74c6a2493a155647ba7c68115c925a6fb2bf1a8a1
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.5.0
2
+
3
+ * Rails 6 now supported.
4
+ * Fixes support for `nil`s with explicit order, when a `nil` is neither
5
+ the first nor the last element of the explicit order,
6
+ e.g. `status: ['assigned', nil, 'fixed']`.
7
+ [#93b08877](https://github.com/glebm/order_query/commit/93b08877790a0ff02eea0d835def6ff3c40a83da)
8
+
1
9
  ## 0.4.1
2
10
 
3
11
  * If a column had a `nulls:` option and there were multiple records with `NULL`,
data/Gemfile CHANGED
@@ -2,11 +2,5 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gemspec
6
-
7
- # TODO: remove these lines and update spec/gemfiles/rails_5_2.gemfile once
8
- # Rails 5.2 is out.
9
- gem 'activerecord', '~> 5.2.0.rc1'
10
- gem 'activesupport', '~> 5.2.0.rc1'
11
-
12
- eval_gemfile './shared.gemfile'
5
+ eval_gemfile 'spec/gemfiles/rails_6_0.gemfile'
6
+ eval_gemfile 'rubocop.gemfile'
data/README.md CHANGED
@@ -11,7 +11,7 @@ This gem finds the next or previous record(s) relative to the current one effici
11
11
  Add to Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'order_query', '~> 0.4.1'
14
+ gem 'order_query', '~> 0.5.0'
15
15
  ```
16
16
 
17
17
  ## Usage
@@ -38,8 +38,9 @@ module OrderQuery
38
38
  "extra arguments: #{vals_and_or_dir.map(&:inspect) * ', '}"
39
39
  end
40
40
  @unique = unique.nil? ? (name.to_s == scope.primary_key) : unique
41
- if @order_enum && (@order_enum[0].nil? || @order_enum[-1].nil?)
41
+ if @order_enum&.include?(nil)
42
42
  fail ArgumentError, '`nulls` cannot be set if a value is null' if nulls
43
+
43
44
  @nullable = true
44
45
  @nulls = if @order_enum[0].nil?
45
46
  @direction == :desc ? :first : :last
@@ -87,7 +88,7 @@ module OrderQuery
87
88
  # @example for [:difficulty, ['Easy', 'Normal', 'Hard']]:
88
89
  # enum_side('Normal', :after) #=> ['Hard']
89
90
  # enum_side('Normal', :after, false) #=> ['Normal', 'Hard']
90
- def enum_side(value, side, strict = true)
91
+ def enum_side(value, side, strict = true) # rubocop:disable Metrics/AbcSize
91
92
  ord = order_enum
92
93
  pos = ord.index(value)
93
94
  if pos
@@ -22,6 +22,7 @@ module OrderQuery
22
22
  if @columns.detect(&:unique?)
23
23
  fail ArgumentError, 'Unique column must be last'
24
24
  end
25
+
25
26
  @columns << Column.new(base_scope, base_scope.primary_key)
26
27
  end
27
28
  @order_by_sql = SQL::OrderBy.new(@columns)
@@ -51,6 +51,7 @@ module OrderQuery
51
51
  if optimize_enum_bools_nil?(col)
52
52
  return optimize_enum_bools_nil(col, reverse)
53
53
  end
54
+
54
55
  clauses = []
55
56
  with_nulls = false
56
57
  if col.order_enum.include?(nil)
@@ -69,6 +70,7 @@ module OrderQuery
69
70
  def needs_null_sort?(col, reverse,
70
71
  nulls_direction = col.nulls_direction(reverse))
71
72
  return false unless col.nullable?
73
+
72
74
  nulls_direction != col.default_nulls_direction(reverse)
73
75
  end
74
76
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OrderQuery
4
- VERSION = '0.4.1'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -4,7 +4,18 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec path: '../../'
6
6
 
7
- gem 'activerecord', '~> 5.0.5'
8
- gem 'activesupport', '~> 5.0.5'
7
+ gem 'activerecord', '~> 5.0.6'
8
+ gem 'activesupport', '~> 5.0.6'
9
+
10
+ platforms :mri, :rbx do
11
+ # https://github.com/rails/rails/blob/v5.0.6/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L4
12
+ gem 'mysql2', '< 0.5'
13
+
14
+ # https://github.com/rails/rails/blob/v5.0.6/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L2
15
+ gem 'pg', '~> 0.18'
16
+
17
+ # https://github.com/rails/rails/blob/v5.0.6/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L7
18
+ gem 'sqlite3', '~> 1.3.6'
19
+ end
9
20
 
10
21
  eval_gemfile '../../shared.gemfile'
@@ -7,4 +7,15 @@ gemspec path: '../../'
7
7
  gem 'activerecord', '~> 5.1.3'
8
8
  gem 'activesupport', '~> 5.1.3'
9
9
 
10
+ platforms :mri, :rbx do
11
+ # https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L4
12
+ gem 'mysql2', '< 0.5'
13
+
14
+ # https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L2
15
+ gem 'pg', '>= 0.18', '< 2.0'
16
+
17
+ # https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L10
18
+ gem 'sqlite3', '~> 1.3.6'
19
+ end
20
+
10
21
  eval_gemfile '../../shared.gemfile'
@@ -4,7 +4,18 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec path: '../../'
6
6
 
7
- gem 'activerecord', '~> 5.2.0.rc1'
8
- gem 'activesupport', '~> 5.2.0.rc1'
7
+ gem 'activerecord', '~> 5.2.3'
8
+ gem 'activesupport', '~> 5.2.3'
9
+
10
+ platforms :mri, :rbx do
11
+ # https://github.com/rails/rails/blob/v5.2.3/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
12
+ gem 'mysql2', '>= 0.4.4', '< 0.6.0'
13
+
14
+ # https://github.com/rails/rails/blob/v5.2.3/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
15
+ gem 'pg', '>= 0.18', '< 2.0'
16
+
17
+ # https://github.com/rails/rails/blob/v5.2.3/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L12
18
+ gem 'sqlite3', '~> 1.3', '>= 1.3.6'
19
+ end
9
20
 
10
21
  eval_gemfile '../../shared.gemfile'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec path: '../../'
6
+
7
+ gem 'activerecord', '~> 5.2.3'
8
+ gem 'activesupport', '~> 5.2.3'
9
+
10
+ platforms :mri, :rbx do
11
+ # https://github.com/rails/rails/blob/v6.0.0/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
12
+ gem 'sqlite3', '~> 1.4'
13
+
14
+ # https://github.com/rails/rails/blob/v6.0.0/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
15
+ gem 'pg', '>= 0.18', '< 2.0'
16
+
17
+ # https://github.com/rails/rails/blob/v6.0.0/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
18
+ gem 'mysql2', '>= 0.4.4'
19
+ end
20
+
21
+ eval_gemfile '../../shared.gemfile'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ eval_gemfile '../../rubocop.gemfile'
@@ -221,20 +221,27 @@ RSpec.describe 'OrderQuery' do
221
221
  end
222
222
 
223
223
  context 'nil in string enum' do
224
+ display = ->(issue) { "##{issue.id}-#{issue.priority || 'NULL'}" }
224
225
  priorities = [nil, 'low', 'medium', 'high']
225
- let!(:issues) { priorities.map { |p| create_issue(priority: p) } }
226
- priorities.permutation do |p|
227
- it "works for #{p} (desc)" do
228
- scope = Issue.seek([:priority, p]).scope
229
- actual = scope.all.map(&:priority)
230
- expected = p
231
- expect(actual).to eq(expected), scope.to_sql
226
+ let!(:issues) do
227
+ priorities.flat_map do |p|
228
+ [create_issue(priority: p), create_issue(priority: p)]
232
229
  end
233
- it "works for #{p} (asc)" do
234
- scope = Issue.seek([:priority, p, :asc]).scope
235
- actual = scope.all.map(&:priority)
236
- expected = p.reverse
237
- expect(actual).to eq(expected), scope.to_sql
230
+ end
231
+ priorities.permutation do |perm|
232
+ it "works for #{perm} (desc)" do
233
+ expect_order(
234
+ Issue.seek([:priority, perm]),
235
+ issues.sort_by { |x| [perm.index(x.priority), x.id] },
236
+ &display
237
+ )
238
+ end
239
+ it "works for #{perm} (asc)" do
240
+ expect_order(
241
+ Issue.seek([:priority, perm, :asc]),
242
+ issues.sort_by { |x| [perm.index(x.priority), -x.id] }.reverse,
243
+ &display
244
+ )
238
245
  end
239
246
  end
240
247
  end
@@ -340,69 +347,33 @@ RSpec.describe 'OrderQuery' do
340
347
  end
341
348
 
342
349
  context 'nil in boolean enum' do
350
+ display = ->(post) { "##{post.id}-#{post.pinned || 'NULL'}" }
343
351
  states = [nil, false, true]
344
- let!(:posts) { states.map { |state| create_post(pinned: state) } }
345
- states.permutation do |p|
346
- it "works for #{p} (desc)" do
347
- scope = Post.seek([:pinned, p]).scope
348
- actual = scope.all.map(&:pinned)
349
- expected = p
350
- expect(actual).to eq(expected), scope.to_sql
352
+ let!(:posts) do
353
+ states.flat_map do |state|
354
+ [create_post(pinned: state), create_post(pinned: state)]
355
+ end
356
+ end
357
+ states.permutation do |perm|
358
+ it "works for #{perm} (desc)" do
359
+ expect_order(
360
+ Post.seek([:pinned, perm]),
361
+ posts.sort_by { |x| [perm.index(x.pinned), x.id] },
362
+ &display
363
+ )
351
364
  end
352
- it "works for #{p} (asc)" do
353
- scope = Post.seek([:pinned, p, :asc]).scope
354
- actual = scope.all.map(&:pinned)
355
- expected = p.reverse
356
- expect(actual).to eq(expected), scope.to_sql
365
+ it "works for #{perm} (asc)" do
366
+ expect_order(
367
+ Post.seek([:pinned, perm, :asc]),
368
+ posts.sort_by { |x| [-perm.index(x.pinned), x.id] },
369
+ &display
370
+ )
357
371
  end
358
372
  end
359
373
  end
360
374
 
361
375
  context 'nil published_at' do
362
- # rubocop:disable Metrics/AbcSize
363
-
364
- def expect_next(space, post, next_post)
365
- point = space.at(post)
366
- actual = point.next
367
- failure_message =
368
- "expected: #{post.title}.next == #{next_post.title}\n" \
369
- " got: #{actual ? actual.title : 'nil'}\n" \
370
- " all: #{space.scope.all.map(&:title)}\n" \
371
- " sql: #{space.at(post).after.limit(1).to_sql}"
372
- expect(actual ? actual.title : nil).to eq(next_post.title),
373
- failure_message
374
- end
375
-
376
- def expect_prev(space, post, prev_post)
377
- point = space.at(post)
378
- actual = point.previous
379
- failure_message =
380
- "expected: #{post.title}.previous == #{prev_post.title}\n" \
381
- " got: #{actual ? actual.title : 'nil'}\n" \
382
- " all: #{space.scope.all.map(&:title)}\n" \
383
- " sql: #{space.at(post).before.limit(1).to_sql}"
384
- expect(actual ? actual.title : nil).to eq(prev_post.title),
385
- failure_message
386
- end
387
-
388
- def expect_order(space, ordered)
389
- actual = space.scope.all.map(&:title)
390
- expected = ordered.map(&:title)
391
- failure_message =
392
- "expected: #{expected * ', '}\n"\
393
- " got: #{actual * ', '}\n"\
394
- " sql: #{space.scope.to_sql}"
395
- expect(actual).to eq(expected), failure_message
396
-
397
- ordered.each_cons(2) do |post, next_post|
398
- expect_next space, post, next_post
399
- expect_prev space, next_post, post
400
- end
401
- expect_next space, ordered.last, ordered.first
402
- expect_prev space, ordered.first, ordered.last
403
- end
404
-
405
- # rubocop:enable Metrics/AbcSize
376
+ display = ->(post) { post.title }
406
377
 
407
378
  let! :null_1 do
408
379
  Post.create!(title: 'null_1', published_at: nil).reload
@@ -419,22 +390,22 @@ RSpec.describe 'OrderQuery' do
419
390
 
420
391
  it 'orders nulls first (desc)' do
421
392
  space = Post.seek([:published_at, :desc, nulls: :first])
422
- expect_order space, [null_1, null_2, older, newer]
393
+ expect_order space, [null_1, null_2, older, newer], &display
423
394
  end
424
395
 
425
396
  it 'orders nulls first (asc)' do
426
397
  space = Post.seek([:published_at, :asc, nulls: :first])
427
- expect_order space, [null_1, null_2, newer, older]
398
+ expect_order space, [null_1, null_2, newer, older], &display
428
399
  end
429
400
 
430
401
  it 'orders nulls last (desc)' do
431
402
  space = Post.seek([:published_at, :desc, nulls: :last])
432
- expect_order space, [older, newer, null_1, null_2]
403
+ expect_order space, [older, newer, null_1, null_2], &display
433
404
  end
434
405
 
435
406
  it 'orders nulls last (asc)' do
436
407
  space = Post.seek([:published_at, :asc, nulls: :last])
437
- expect_order space, [newer, older, null_1, null_2]
408
+ expect_order space, [newer, older, null_1, null_2], &display
438
409
  end
439
410
  end
440
411
 
@@ -8,7 +8,7 @@ if ENV['COVERAGE'] && !%w[rbx jruby].include?(RUBY_ENGINE)
8
8
  end
9
9
  require 'order_query'
10
10
 
11
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+ require_relative './support/order_expectation'
12
12
 
13
13
  require 'fileutils'
14
14
  FileUtils.mkpath 'log' unless File.directory? 'log'
@@ -35,3 +35,7 @@ else
35
35
  fail "Unknown DB adapter #{adapter}. "\
36
36
  'Valid adapters are: mysql2, postgresql, sqlite3.'
37
37
  end
38
+
39
+ RSpec.configure do |c|
40
+ c.include OrderExpectations
41
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrderExpectations
4
+ # rubocop:disable Metrics/AbcSize
5
+
6
+ def expect_next(space, record, next_record, &display)
7
+ point = space.at(record)
8
+ actual = point.next
9
+ failure_message =
10
+ "expected: next(#{display[record]}) == #{display[next_record]}\n" \
11
+ " got: #{actual ? display[actual] : 'nil'}\n" \
12
+ " all: #{space.scope.all.map(&display)}\n" \
13
+ " sql: #{space.at(record).after.limit(1).to_sql}"
14
+ expect(actual ? display[actual] : nil).to eq(display[next_record]),
15
+ failure_message
16
+ end
17
+
18
+ def expect_prev(space, record, prev_record, &display)
19
+ point = space.at(record)
20
+ actual = point.previous
21
+ failure_message =
22
+ "expected: previous(#{display[record]}) == #{display[prev_record]}\n" \
23
+ " got: #{actual ? display[actual] : 'nil'}\n" \
24
+ " all: #{space.scope.all.map(&display)}\n" \
25
+ " sql: #{space.at(record).before.limit(1).to_sql}"
26
+ expect(actual ? display[actual] : nil).to eq(display[prev_record]),
27
+ failure_message
28
+ end
29
+
30
+ def expect_order(space, ordered, &display)
31
+ all_actual = space.scope.all.map(&display)
32
+ all_expected = ordered.map(&display)
33
+ failure_message =
34
+ "expected: #{all_expected * ', '}\n"\
35
+ " got: #{all_actual * ', '}\n"\
36
+ " sql: #{space.scope.to_sql}"
37
+ expect(all_actual).to eq(all_expected), failure_message
38
+
39
+ ordered.each_cons(2) do |record, next_record|
40
+ expect_next space, record, next_record, &display
41
+ expect_prev space, next_record, record, &display
42
+ end
43
+ expect_next space, ordered.last, ordered.first, &display
44
+ expect_prev space, ordered.first, ordered.last, &display
45
+ end
46
+
47
+ # rubocop:enable Metrics/AbcSize
48
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: order_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Mazovetskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-21 00:00:00.000000000 Z
11
+ date: 2019-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '5.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.0'
22
+ version: '7.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '5.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.0'
32
+ version: '7.0'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '5.0'
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '6.0'
42
+ version: '7.0'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: '5.0'
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '6.0'
52
+ version: '7.0'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: rake
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -78,20 +78,6 @@ dependencies:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
80
  version: '3.4'
81
- - !ruby/object:Gem::Dependency
82
- name: rubocop
83
- requirement: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - "~>"
86
- - !ruby/object:Gem::Version
87
- version: 0.53.0
88
- type: :development
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - "~>"
93
- - !ruby/object:Gem::Version
94
- version: 0.53.0
95
81
  - !ruby/object:Gem::Dependency
96
82
  name: simplecov
97
83
  requirement: !ruby/object:Gem::Requirement
@@ -131,8 +117,11 @@ files:
131
117
  - spec/gemfiles/rails_5_0.gemfile
132
118
  - spec/gemfiles/rails_5_1.gemfile
133
119
  - spec/gemfiles/rails_5_2.gemfile
120
+ - spec/gemfiles/rails_6_0.gemfile
121
+ - spec/gemfiles/rubocop.gemfile
134
122
  - spec/order_query_spec.rb
135
123
  - spec/spec_helper.rb
124
+ - spec/support/order_expectation.rb
136
125
  homepage: https://github.com/glebm/order_query
137
126
  licenses:
138
127
  - MIT
@@ -146,21 +135,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
135
  requirements:
147
136
  - - ">="
148
137
  - !ruby/object:Gem::Version
149
- version: '0'
138
+ version: 2.3.0
150
139
  required_rubygems_version: !ruby/object:Gem::Requirement
151
140
  requirements:
152
141
  - - ">="
153
142
  - !ruby/object:Gem::Version
154
143
  version: '0'
155
144
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.6.13
145
+ rubygems_version: 3.0.6
158
146
  signing_key:
159
147
  specification_version: 4
160
148
  summary: Find next / previous Active Record(s) in one query
161
149
  test_files:
162
150
  - spec/order_query_spec.rb
163
151
  - spec/spec_helper.rb
152
+ - spec/support/order_expectation.rb
164
153
  - spec/gemfiles/rails_5_1.gemfile
165
154
  - spec/gemfiles/rails_5_2.gemfile
155
+ - spec/gemfiles/rubocop.gemfile
166
156
  - spec/gemfiles/rails_5_0.gemfile
157
+ - spec/gemfiles/rails_6_0.gemfile