order_as_specified 1.5 → 1.6
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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -15
- data/.travis.yml +33 -20
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -1
- data/README.md +4 -1
- data/RELEASING.md +14 -0
- data/lib/order_as_specified.rb +25 -7
- data/lib/order_as_specified/version.rb +1 -1
- data/order_as_specified.gemspec +3 -4
- data/spec/config/database.yml +6 -0
- data/spec/config/test_setup_migration.rb +1 -0
- data/spec/mysql_spec.rb +16 -0
- data/spec/postgresql_spec.rb +0 -2
- data/spec/shared/order_as_specified_examples.rb +56 -2
- data/spec/spec_helper.rb +3 -2
- metadata +14 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 119668cc688124610b87036f0f929c0fbcc35ef4acea5e1c2a1cdc48c1101241
|
4
|
+
data.tar.gz: a17df8766bfe178cac883311d8ba4b165b4e43a9c4afd1d8e4b8af0e099d5010
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a53e19dc18fb420fbf88f1fb535b46a0a5c5b13a84158c237a350243f8cfefa5f78ae048087bcc939ea7ecab12e4b7aec5c62bae7960d921a83704f9a53a45e
|
7
|
+
data.tar.gz: 0ca1d4697d3634f442edb58173cf4d7f6199571ae1a69415cb6cb2d8b93079ff588023e5549f99ca998979cfeff93ee3ea1f2f0810afd90c8501df829d41e104
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,17 +1,5 @@
|
|
1
|
-
|
2
|
-
-
|
1
|
+
inherit_from:
|
2
|
+
- https://raw.githubusercontent.com/panorama-ed/code-conventions/master/rubocop.yml
|
3
3
|
|
4
4
|
AllCops:
|
5
|
-
TargetRubyVersion: 2.
|
6
|
-
|
7
|
-
AbcSize:
|
8
|
-
Enabled: false
|
9
|
-
|
10
|
-
DotPosition:
|
11
|
-
EnforcedStyle: trailing
|
12
|
-
|
13
|
-
MethodLength:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
StringLiterals:
|
17
|
-
EnforcedStyle: double_quotes
|
5
|
+
TargetRubyVersion: 2.4 # Keep this in sync with .travis.yml
|
data/.travis.yml
CHANGED
@@ -1,28 +1,41 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.5
|
3
|
+
- 2.6
|
4
|
+
- 2.5
|
5
|
+
- 2.4 # Keep this in sync with .rubocop.yml
|
6
|
+
# We test up to the latest version of Ruby here, and test these Ruby versions
|
7
|
+
# against all support ActiveRecord versions. One test will be "duplicated"
|
8
|
+
# below when we calculate code coverage, but I don't know how to avoid that and
|
9
|
+
# still test all combinations of Ruby and ActiveRecord.
|
5
10
|
before_script:
|
6
|
-
|
7
|
-
|
8
|
-
- chmod +x ./cc-test-reporter
|
9
|
-
- ./cc-test-reporter before-build
|
11
|
+
- psql -c 'create database order_as_specified_test;' -U postgres
|
12
|
+
- mysql -e 'CREATE DATABASE order_as_specified_test;'
|
10
13
|
script:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
addons:
|
16
|
-
postgresql: "9.3"
|
14
|
+
- bundle exec rspec
|
15
|
+
services:
|
16
|
+
- mysql
|
17
|
+
- postgresql
|
17
18
|
env:
|
18
|
-
global:
|
19
|
-
CC_TEST_REPORTER_ID=781c439d68cbb928316deaec1c7136f98423e1db87238f99cbc95183de94df9e
|
20
19
|
matrix:
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
- ACTIVERECORD_VERSION="~> 5.2.0"
|
21
|
+
- ACTIVERECORD_VERSION="~> 5.1.0"
|
22
|
+
- ACTIVERECORD_VERSION="~> 5.0.0"
|
23
|
+
matrix:
|
24
|
+
include:
|
25
|
+
- rvm: 2.6
|
26
|
+
script:
|
27
|
+
- bundle exec rspec
|
28
|
+
- gem install --no-document rubocop rubocop-rspec-focused && rubocop
|
29
|
+
env:
|
30
|
+
- CODE_COVERAGE=true
|
31
|
+
- ACTIVERECORD_VERSION="~> 5.2.0"
|
32
|
+
branches:
|
33
|
+
only:
|
34
|
+
# We always run tests for PRs. This prevents running PR tests twice (once "for
|
35
|
+
# the PR" and once "for the branch"), though we do want tests to run always
|
36
|
+
# run on master.
|
37
|
+
- master
|
24
38
|
notifications:
|
25
39
|
email: false
|
26
|
-
|
27
|
-
|
28
|
-
secure: pLL6WXsWnvigZNgcYYwr0el3AG3WbRXOV4zAoBx/pAD/y51/KOjWboUO5szOqIicdSBJTIY5el7wK4uUi5elseumjl1jvOQSG7izvCGzDekuJuOTj9f6MdLtigbIaWO5/NWtXw0/JGHDQJpB4HyOv1mGAjQ3Y6MKxMNv+RUsgRI=
|
40
|
+
slack:
|
41
|
+
secure: lVaScxPymqeYlTh+KlprWDK+O18BkQTyNSBTfzsLFzWF3Dy+p1rp2aeh0AhuLVYQDrlmFZ7cDMZ1ZYDyV2Y6lLtt+4ii7rATagI8R9WUVYb90C97tu1M6v5tpIjoTEOLx9hGc66heyvq1hNCKXbTqsqmrD69FYdjuXnOfrIs6J4=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# Unreleased (`master`)
|
2
|
+
|
3
|
+
# 1.6
|
4
|
+
|
5
|
+
We are dropping official support for Ruby 2.3 and below, though they may
|
6
|
+
continue to work.
|
7
|
+
|
8
|
+
This release adds support for ordering by `Range`s. Big thanks to
|
9
|
+
[Karl-Aksel Puulmann](https://github.com/macobo) for adding this functionality!
|
10
|
+
|
1
11
|
# 1.5
|
2
12
|
|
3
13
|
This release improves performance by switching to use `CASE` statements. Huge
|
data/Gemfile
CHANGED
@@ -5,4 +5,6 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in order_as_specified.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
|
8
|
+
if ENV["TRAVIS"] == "true" && ENV["ACTIVERECORD_VERSION"]
|
9
|
+
gem "activerecord", ENV["ACTIVERECORD_VERSION"]
|
10
|
+
end
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
[](https://codecov.io/gh/panorama-ed/order_as_specified)
|
2
|
+
[](https://travis-ci.com/panorama-ed/order_as_specified)
|
3
|
+
[](http://inch-ci.org/github/panorama-ed/order_as_specified)
|
4
|
+
[](http://badge.fury.io/rb/order_as_specified)
|
2
5
|
|
3
6
|
# OrderAsSpecified
|
4
7
|
|
data/RELEASING.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Releasing
|
2
|
+
|
3
|
+
## These are steps for the maintainer to take to release a new version of this gem.
|
4
|
+
|
5
|
+
1. Create a new branch for bumping the version.
|
6
|
+
1. On the new branch, update the VERSION constant in `lib/order_as_specified/version.rb`.
|
7
|
+
1. Update the Changelog.
|
8
|
+
1. Commit the change: `git add -A && git commit -m 'Bump to vX.X'`.
|
9
|
+
1. Add a tag: `git tag -am "vX.X" vX.X`.
|
10
|
+
1. Push the branch and tag: `git push --follow-tags`
|
11
|
+
1. Make a PR.
|
12
|
+
1. Merge the PR.
|
13
|
+
1. Push to rubygems: `gem build order_as_specified.gemspec && gem push *.gem && rm *.gem`
|
14
|
+
1. Celebrate!
|
data/lib/order_as_specified.rb
CHANGED
@@ -18,15 +18,15 @@ module OrderAsSpecified
|
|
18
18
|
table = connection.quote_table_name(params[:table])
|
19
19
|
attribute = connection.quote_column_name(params[:attribute])
|
20
20
|
|
21
|
-
# We have to explicitly quote for now because SQL sanitization for ORDER BY
|
22
|
-
# queries isn't in less current versions of Rails.
|
23
|
-
# See: https://github.com/rails/rails/pull/13008
|
24
|
-
db_connection = ActiveRecord::Base.connection
|
25
21
|
conditions = params[:values].map do |value|
|
26
22
|
raise OrderAsSpecified::Error, "Cannot order by `nil`" if value.nil?
|
27
23
|
|
28
|
-
|
29
|
-
|
24
|
+
if value.is_a? Range
|
25
|
+
range_clause("#{table}.#{attribute}", value)
|
26
|
+
else
|
27
|
+
# Sanitize each value to reduce the risk of SQL injection.
|
28
|
+
"#{table}.#{attribute}=#{quote(value)}"
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
32
|
when_queries = conditions.map.with_index do |cond, index|
|
@@ -53,7 +53,9 @@ module OrderAsSpecified
|
|
53
53
|
# @param hash [Hash] the ActiveRecord-style arguments, such as:
|
54
54
|
# { other_objects: { id: [1, 5, 3] } }
|
55
55
|
def extract_params(hash, table = table_name)
|
56
|
-
|
56
|
+
unless hash.size == 1
|
57
|
+
raise OrderAsSpecified::Error, "Could not parse params"
|
58
|
+
end
|
57
59
|
|
58
60
|
key, val = hash.first
|
59
61
|
|
@@ -67,4 +69,20 @@ module OrderAsSpecified
|
|
67
69
|
}
|
68
70
|
end
|
69
71
|
end
|
72
|
+
|
73
|
+
def range_clause(col, range)
|
74
|
+
if range.first >= range.last
|
75
|
+
raise OrderAsSpecified::Error, "Range needs to be increasing"
|
76
|
+
end
|
77
|
+
|
78
|
+
op = range.exclude_end? ? "<" : "<="
|
79
|
+
"#{col} >= #{quote(range.first)} AND #{col} #{op} #{quote(range.last)}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def quote(value)
|
83
|
+
# We have to explicitly quote for now because SQL sanitization for ORDER BY
|
84
|
+
# queries isn't in less current versions of Rails.
|
85
|
+
# See: https://github.com/rails/rails/pull/13008
|
86
|
+
ActiveRecord::Base.connection.quote(value)
|
87
|
+
end
|
70
88
|
end
|
data/order_as_specified.gemspec
CHANGED
@@ -23,11 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "activerecord", ">= 5.0.0"
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler"
|
26
|
+
spec.add_development_dependency "codecov"
|
27
|
+
spec.add_development_dependency "mysql2"
|
26
28
|
spec.add_development_dependency "pg"
|
27
29
|
spec.add_development_dependency "rspec"
|
28
30
|
spec.add_development_dependency "rspec-rails"
|
29
|
-
spec.add_development_dependency "
|
30
|
-
spec.add_development_dependency "rubocop-rspec-focused"
|
31
|
-
spec.add_development_dependency "simplecov"
|
32
|
-
spec.add_development_dependency "sqlite3"
|
31
|
+
spec.add_development_dependency "sqlite3", "~> 1.3.13"
|
33
32
|
end
|
data/spec/config/database.yml
CHANGED
data/spec/mysql_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "shared/order_as_specified_examples"
|
5
|
+
require "config/test_setup_migration"
|
6
|
+
|
7
|
+
RSpec.describe "MySQL" do
|
8
|
+
before :all do
|
9
|
+
ActiveRecord::Base.establish_connection(:mysql_test)
|
10
|
+
TestSetupMigration.migrate(:up)
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) { ActiveRecord::Base.remove_connection }
|
14
|
+
|
15
|
+
include_examples ".order_as_specified"
|
16
|
+
end
|
data/spec/postgresql_spec.rb
CHANGED
@@ -4,7 +4,6 @@ require "spec_helper"
|
|
4
4
|
require "shared/order_as_specified_examples"
|
5
5
|
require "config/test_setup_migration"
|
6
6
|
|
7
|
-
# rubocop:disable Metrics/BlockLength
|
8
7
|
RSpec.describe "PostgreSQL" do
|
9
8
|
before :all do
|
10
9
|
ActiveRecord::Base.establish_connection(:postgresql_test)
|
@@ -68,4 +67,3 @@ RSpec.describe "PostgreSQL" do
|
|
68
67
|
end
|
69
68
|
end
|
70
69
|
end
|
71
|
-
# rubocop:enable Metrics/BlockLength
|
@@ -4,7 +4,6 @@ require "support/application_record"
|
|
4
4
|
require "support/test_class"
|
5
5
|
require "support/association_test_class"
|
6
6
|
|
7
|
-
# rubocop:disable Metrics/BlockLength
|
8
7
|
RSpec.shared_examples ".order_as_specified" do
|
9
8
|
# Clean up after each test. This is a lot lighter for these few tests than
|
10
9
|
# trying to wrangle with RSpec-Rails to get transactional tests to work.
|
@@ -81,6 +80,54 @@ RSpec.shared_examples ".order_as_specified" do
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
83
|
+
context "when the order is a range" do
|
84
|
+
subject do
|
85
|
+
TestClass.order_as_specified(number_field: ranges).order(:number_field)
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:ranges) { [(3..4), (0..2)] }
|
89
|
+
let(:numbers) { [0, 1, 2, 3, 4] }
|
90
|
+
|
91
|
+
let!(:test_objects) do
|
92
|
+
numbers.each do |i|
|
93
|
+
TestClass.create(number_field: i)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "sorts according to range" do
|
98
|
+
expect(subject.map(&:number_field)).to eq [
|
99
|
+
*numbers.drop(3),
|
100
|
+
*numbers.take(3)
|
101
|
+
]
|
102
|
+
end
|
103
|
+
|
104
|
+
context "exclusive ranges" do
|
105
|
+
let(:numbers) { [0, 1, 2, 3, 4, 0.9, 1.5] }
|
106
|
+
|
107
|
+
let(:ranges) { [(1...2), (0...1), (2...5)] }
|
108
|
+
|
109
|
+
it "sorts according to range" do
|
110
|
+
expect(subject.map(&:number_field)).to eq [
|
111
|
+
1,
|
112
|
+
1.5,
|
113
|
+
0,
|
114
|
+
0.9,
|
115
|
+
2,
|
116
|
+
3,
|
117
|
+
4
|
118
|
+
]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "reverse ranges" do
|
123
|
+
let(:ranges) { [(5..0)] }
|
124
|
+
|
125
|
+
it "raises an error" do
|
126
|
+
expect { subject }.to raise_error(OrderAsSpecified::Error)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
84
131
|
context "with another table name specified" do
|
85
132
|
subject do
|
86
133
|
TestClass.
|
@@ -149,5 +196,12 @@ RSpec.shared_examples ".order_as_specified" do
|
|
149
196
|
expect(sql).to include(pattern)
|
150
197
|
end
|
151
198
|
end
|
199
|
+
|
200
|
+
context "invalid hash input" do
|
201
|
+
subject { TestClass.order_as_specified({}) }
|
202
|
+
|
203
|
+
it "raises an error" do
|
204
|
+
expect { subject }.to raise_error(OrderAsSpecified::Error)
|
205
|
+
end
|
206
|
+
end
|
152
207
|
end
|
153
|
-
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
if ENV["TRAVIS"] == "true"
|
3
|
+
if ENV["TRAVIS"] == "true" && ENV["CODE_COVERAGE"] == "true"
|
4
4
|
require "simplecov"
|
5
|
-
|
5
|
+
require "codecov"
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
6
7
|
SimpleCov.start do
|
7
8
|
# Omit the spec directory from being counted in code coverage calculations.
|
8
9
|
add_filter "/spec/"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: order_as_specified
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Evelyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: codecov
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: mysql2
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,21 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop
|
70
|
+
name: pg
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
@@ -95,7 +81,7 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: rspec
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - ">="
|
@@ -109,7 +95,7 @@ dependencies:
|
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
98
|
+
name: rspec-rails
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
101
|
- - ">="
|
@@ -126,16 +112,16 @@ dependencies:
|
|
126
112
|
name: sqlite3
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
|
-
- - "
|
115
|
+
- - "~>"
|
130
116
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
117
|
+
version: 1.3.13
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
|
-
- - "
|
122
|
+
- - "~>"
|
137
123
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
124
|
+
version: 1.3.13
|
139
125
|
description: Obtain ActiveRecord results with a custom ordering with no need to store
|
140
126
|
anything in the database.
|
141
127
|
email:
|
@@ -151,12 +137,14 @@ files:
|
|
151
137
|
- Gemfile
|
152
138
|
- LICENSE.txt
|
153
139
|
- README.md
|
140
|
+
- RELEASING.md
|
154
141
|
- lib/order_as_specified.rb
|
155
142
|
- lib/order_as_specified/error.rb
|
156
143
|
- lib/order_as_specified/version.rb
|
157
144
|
- order_as_specified.gemspec
|
158
145
|
- spec/config/database.yml
|
159
146
|
- spec/config/test_setup_migration.rb
|
147
|
+
- spec/mysql_spec.rb
|
160
148
|
- spec/order_as_specified_spec.rb
|
161
149
|
- spec/postgresql_spec.rb
|
162
150
|
- spec/shared/order_as_specified_examples.rb
|
@@ -192,6 +180,7 @@ summary: Add arbitrary ordering to ActiveRecord queries.
|
|
192
180
|
test_files:
|
193
181
|
- spec/config/database.yml
|
194
182
|
- spec/config/test_setup_migration.rb
|
183
|
+
- spec/mysql_spec.rb
|
195
184
|
- spec/order_as_specified_spec.rb
|
196
185
|
- spec/postgresql_spec.rb
|
197
186
|
- spec/shared/order_as_specified_examples.rb
|