order_query 0.3.0 → 0.3.1
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/CHANGES.md +7 -1
- data/MIT-LICENSE +1 -1
- data/README.md +7 -8
- data/lib/order_query/{condition.rb → column.rb} +6 -13
- data/lib/order_query/space.rb +13 -8
- data/lib/order_query/sql/{condition.rb → column.rb} +6 -6
- data/lib/order_query/sql/order_by.rb +5 -5
- data/lib/order_query/sql/where.rb +31 -37
- data/lib/order_query/version.rb +1 -1
- data/lib/order_query.rb +3 -3
- data/spec/order_query_spec.rb +9 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be66ba349bb0a4819d39ee8f01d8bfa12e82177e
|
4
|
+
data.tar.gz: 56637889ea73d1f90e70dcd72e09431eb357f1e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8f9fe60869ae746f9d095dfc549f651b994ded8b75875cd60761e9e7683cdcb6968834916ae6eb881b3dc684f26220adf4e873948923b8e41daee90b11d6671
|
7
|
+
data.tar.gz: b068a5d7bcc50af28dbdff396adca897f8f502640fcad0f162f1ea9ee4424c9a9cf1afde85837261908bd984a9339bbb6fdce50477d0aa9ed99b394cabf2e53a
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
## 0.3.1
|
2
|
+
|
3
|
+
* Automatically add primary key when there is no unique column for the order
|
4
|
+
* Remove `complete` option
|
5
|
+
* Fix Rubinius compatibility
|
6
|
+
|
1
7
|
## 0.3.0
|
2
8
|
|
3
|
-
* `order_query` now accepts
|
9
|
+
* `order_query` now accepts columns as varargs. Array form is still supported.
|
4
10
|
* `order_by` renamed to `seek`
|
5
11
|
|
6
12
|
## 0.2.1
|
data/MIT-LICENSE
CHANGED
@@ -6,7 +6,7 @@ a copy of this software and associated documentation files (the
|
|
6
6
|
without limitation the rights to use, copy, modify, merge, publish,
|
7
7
|
distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following
|
9
|
+
the following columns:
|
10
10
|
|
11
11
|
The above copyright notice and this permission notice shall be
|
12
12
|
included in all copies or substantial portions of the Software.
|
data/README.md
CHANGED
@@ -12,12 +12,12 @@ It uses [keyset pagination](http://use-the-index-luke.com/no-offset) to achieve
|
|
12
12
|
Add to Gemfile:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
gem 'order_query', '~> 0.3.
|
15
|
+
gem 'order_query', '~> 0.3.1'
|
16
16
|
```
|
17
17
|
|
18
18
|
## Usage
|
19
19
|
|
20
|
-
Define named order
|
20
|
+
Define named order columns with `order_query`:
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
class Post < ActiveRecord::Base
|
@@ -29,7 +29,7 @@ class Post < ActiveRecord::Base
|
|
29
29
|
end
|
30
30
|
```
|
31
31
|
|
32
|
-
Order query accepts a list of order
|
32
|
+
Order query accepts a list of order columns as varargs or one array, each one specified as:
|
33
33
|
|
34
34
|
```ruby
|
35
35
|
[<attribute name>, (attribute values in order), (:asc or :desc), (options hash)]
|
@@ -40,7 +40,6 @@ Available options:
|
|
40
40
|
| option | description |
|
41
41
|
|------------|----------------------------------------------------------------------------|
|
42
42
|
| unique | Unique attribute. Default: `true` for primary key, `false` otherwise. |
|
43
|
-
| complete | Specified attribute values are the only possible values. Default: `true`. |
|
44
43
|
| sql | Customize attribute value SQL |
|
45
44
|
|
46
45
|
|
@@ -87,9 +86,9 @@ post = posts.find(42)
|
|
87
86
|
post.order_home(posts) #=> #<OrderQuery::Point>
|
88
87
|
```
|
89
88
|
|
90
|
-
### Dynamic
|
89
|
+
### Dynamic columns
|
91
90
|
|
92
|
-
Query with dynamic order
|
91
|
+
Query with dynamic order columns using the `seek(*spec)` class method:
|
93
92
|
|
94
93
|
```ruby
|
95
94
|
space = Post.visible.seek([:id, :desc]) #=> #<OrderQuery::Space>
|
@@ -124,7 +123,7 @@ class Post < ActiveRecord::Base
|
|
124
123
|
[:priority, %w(high medium low)],
|
125
124
|
# A method and custom SQL can be used instead of an attribute
|
126
125
|
[:valid_votes_count, :desc, sql: '(votes - suspicious_votes)'],
|
127
|
-
# Default sort order for non-array
|
126
|
+
# Default sort order for non-array columns is :asc, just like SQL
|
128
127
|
[:updated_at, :desc],
|
129
128
|
# pass unique: true for unique attributes to get more optimized queries
|
130
129
|
# unique is true by default for primary_key
|
@@ -153,7 +152,7 @@ ORDER BY
|
|
153
152
|
LIMIT 1
|
154
153
|
```
|
155
154
|
|
156
|
-
The actual query is a bit different because `order_query` wraps the top-level `OR` with a (redundant) non-strict
|
155
|
+
The actual query is a bit different because `order_query` wraps the top-level `OR` with a (redundant) non-strict column `x0' AND (x0 OR ...)`
|
157
156
|
for [performance reasons](https://github.com/glebm/order_query/issues/3).
|
158
157
|
This can be disabled with `OrderQuery.wrap_top_level_or = false`.
|
159
158
|
|
@@ -1,13 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require 'order_query/sql/
|
2
|
+
require 'order_query/sql/column'
|
3
3
|
module OrderQuery
|
4
|
-
# An order
|
5
|
-
class
|
4
|
+
# An order column (sort column)
|
5
|
+
class Column
|
6
6
|
attr_reader :name, :order, :order_enum, :options
|
7
7
|
delegate :column_name, :quote, to: :@sql
|
8
8
|
|
9
|
-
# @option spec [String] :unique Mark the attribute as unique to avoid redundant
|
10
|
-
# @option spec [String] :complete Mark the condition's domain as complete to avoid redundant conditions (only for array conditions)
|
9
|
+
# @option spec [String] :unique Mark the attribute as unique to avoid redundant columns
|
11
10
|
def initialize(spec, scope)
|
12
11
|
spec = spec.dup
|
13
12
|
options = spec.extract_options!
|
@@ -24,18 +23,13 @@ module OrderQuery
|
|
24
23
|
complete: true
|
25
24
|
)
|
26
25
|
@unique = @options[:unique]
|
27
|
-
@
|
28
|
-
@sql = SQL::Condition.new(self, scope)
|
26
|
+
@sql = SQL::Column.new(self, scope)
|
29
27
|
end
|
30
28
|
|
31
29
|
def unique?
|
32
30
|
@unique
|
33
31
|
end
|
34
32
|
|
35
|
-
def complete?
|
36
|
-
@complete
|
37
|
-
end
|
38
|
-
|
39
33
|
# @param [Object] value
|
40
34
|
# @param [:before, :after] side
|
41
35
|
# @return [Array] valid order values before / after passed (depending on the side)
|
@@ -54,7 +48,7 @@ module OrderQuery
|
|
54
48
|
end
|
55
49
|
else
|
56
50
|
# default to all if current is not in sort order values
|
57
|
-
|
51
|
+
[]
|
58
52
|
end
|
59
53
|
end
|
60
54
|
|
@@ -63,7 +57,6 @@ module OrderQuery
|
|
63
57
|
@name,
|
64
58
|
(@order_enum.inspect if order_enum),
|
65
59
|
('unique' if @unique),
|
66
|
-
('complete' if order_enum && complete?),
|
67
60
|
(column_name if options[:sql]),
|
68
61
|
{desc: '▼', asc: '▲'}[@order]
|
69
62
|
].compact
|
data/lib/order_query/space.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
require 'order_query/
|
1
|
+
require 'order_query/column'
|
2
2
|
require 'order_query/sql/order_by'
|
3
3
|
module OrderQuery
|
4
4
|
# Order specification and a scope
|
5
5
|
class Space
|
6
|
-
# @return [Array<OrderQuery::
|
7
|
-
attr_reader :
|
6
|
+
# @return [Array<OrderQuery::Column>]
|
7
|
+
attr_reader :columns
|
8
8
|
|
9
9
|
# @param [ActiveRecord::Relation] base_scope
|
10
10
|
# @param [Array<Array<Symbol,String>>, OrderQuery::Spec] order_spec
|
11
11
|
def initialize(base_scope, order_spec)
|
12
12
|
@base_scope = base_scope
|
13
|
-
@
|
14
|
-
|
13
|
+
@columns = order_spec.map { |cond_spec| Column.new(cond_spec, base_scope) }
|
14
|
+
# add primary key if columns are not unique
|
15
|
+
unless @columns.last.unique?
|
16
|
+
raise ArgumentError.new('Unique column must be last') if @columns.detect(&:unique?)
|
17
|
+
@columns << Column.new([base_scope.primary_key], base_scope)
|
18
|
+
end
|
19
|
+
@order_by_sql = SQL::OrderBy.new(@columns)
|
15
20
|
end
|
16
21
|
|
17
22
|
# @return [Point]
|
@@ -19,12 +24,12 @@ module OrderQuery
|
|
19
24
|
Point.new(record, self)
|
20
25
|
end
|
21
26
|
|
22
|
-
# @return [ActiveRecord::Relation] scope ordered by
|
27
|
+
# @return [ActiveRecord::Relation] scope ordered by columns
|
23
28
|
def scope
|
24
29
|
@scope ||= @base_scope.order(@order_by_sql.build)
|
25
30
|
end
|
26
31
|
|
27
|
-
# @return [ActiveRecord::Relation] scope ordered by
|
32
|
+
# @return [ActiveRecord::Relation] scope ordered by columns in reverse
|
28
33
|
def scope_reverse
|
29
34
|
@scope_reverse ||= @base_scope.order(@order_by_sql.build_reverse)
|
30
35
|
end
|
@@ -42,7 +47,7 @@ module OrderQuery
|
|
42
47
|
delegate :count, :empty?, to: :@base_scope
|
43
48
|
|
44
49
|
def inspect
|
45
|
-
"#<OrderQuery::Space @
|
50
|
+
"#<OrderQuery::Space @columns=#{@columns.inspect} @base_scope=#{@base_scope.inspect}>"
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module OrderQuery
|
2
2
|
module SQL
|
3
|
-
class
|
4
|
-
attr_reader :
|
3
|
+
class Column
|
4
|
+
attr_reader :column, :scope
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(column, scope)
|
7
|
+
@column = column
|
8
8
|
@scope = scope
|
9
9
|
end
|
10
10
|
|
11
11
|
def column_name
|
12
12
|
@column_name ||= begin
|
13
|
-
sql =
|
13
|
+
sql = column.options[:sql]
|
14
14
|
if sql
|
15
15
|
sql.respond_to?(:call) ? sql.call : sql
|
16
16
|
else
|
17
|
-
connection.quote_table_name(scope.table_name) + '.' + connection.quote_column_name(
|
17
|
+
connection.quote_table_name(scope.table_name) + '.' + connection.quote_column_name(column.name)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module OrderQuery
|
2
2
|
module SQL
|
3
3
|
class OrderBy
|
4
|
-
# @param [Array<
|
5
|
-
def initialize(
|
6
|
-
@
|
4
|
+
# @param [Array<Column>]
|
5
|
+
def initialize(columns)
|
6
|
+
@columns = columns
|
7
7
|
end
|
8
8
|
|
9
9
|
# @return [String]
|
@@ -20,10 +20,10 @@ module OrderQuery
|
|
20
20
|
|
21
21
|
# @return [Array<String>]
|
22
22
|
def order_by_sql_clauses
|
23
|
-
@
|
23
|
+
@columns.map { |cond| column_clause cond }
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def column_clause(cond)
|
27
27
|
dir_sql = sort_direction_sql cond.order
|
28
28
|
col_sql = cond.column_name
|
29
29
|
if cond.order_enum
|
@@ -7,13 +7,13 @@ module OrderQuery
|
|
7
7
|
|
8
8
|
# @param [OrderQuery::Point] point
|
9
9
|
def initialize(point)
|
10
|
-
@point
|
11
|
-
@
|
10
|
+
@point = point
|
11
|
+
@columns = point.space.columns
|
12
12
|
end
|
13
13
|
|
14
|
-
# Join
|
14
|
+
# Join column pairs with OR, and nest within each other with AND
|
15
15
|
# @param [:before or :after] side
|
16
|
-
# @return [query, parameters] WHERE
|
16
|
+
# @return [query, parameters] WHERE columns matching records strictly before / after this one
|
17
17
|
# sales < 5 OR
|
18
18
|
# sales = 5 AND (
|
19
19
|
# invoice < 3 OR
|
@@ -21,14 +21,14 @@ module OrderQuery
|
|
21
21
|
# ... ))
|
22
22
|
def build(side)
|
23
23
|
# generate pairs of terms such as sales < 5, sales = 5
|
24
|
-
|
25
|
-
[where_side(
|
24
|
+
terms = @columns.map { |col|
|
25
|
+
[where_side(col, side, true), where_tie(col)].reject { |x| x == WHERE_IDENTITY }
|
26
26
|
}
|
27
27
|
# group pairwise with OR, and nest with AND
|
28
|
-
query = foldr_terms
|
28
|
+
query = foldr_terms terms.map { |pair| join_terms 'OR'.freeze, *pair }, 'AND'.freeze
|
29
29
|
if ::OrderQuery.wrap_top_level_or
|
30
30
|
# wrap in a redundant AND clause for performance
|
31
|
-
query = wrap_top_level_or query,
|
31
|
+
query = wrap_top_level_or query, terms, side
|
32
32
|
end
|
33
33
|
query
|
34
34
|
end
|
@@ -44,7 +44,7 @@ module OrderQuery
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
# joins terms with an operator
|
47
|
+
# joins terms with an operator, empty terms are skipped
|
48
48
|
# @return [query, parameters]
|
49
49
|
def join_terms(op, *terms)
|
50
50
|
[terms.map(&:first).reject(&:empty?).join(" #{op} "), terms.map(&:second).reduce([], :+)]
|
@@ -63,61 +63,55 @@ module OrderQuery
|
|
63
63
|
# (sales < 5 OR
|
64
64
|
# (sales = 5 AND ...)))
|
65
65
|
# Read more at https://github.com/glebm/order_query/issues/3
|
66
|
-
def wrap_top_level_or(query,
|
67
|
-
|
68
|
-
if
|
69
|
-
(
|
70
|
-
|
71
|
-
join_terms 'AND'.freeze, redundant_cond, wrap_term_with_parens(query)
|
66
|
+
def wrap_top_level_or(query, terms, side)
|
67
|
+
top_term_i = terms.index(&:present?)
|
68
|
+
if top_term_i && terms[top_term_i].length == 2 &&
|
69
|
+
(cond = where_side(@columns[top_term_i], side, false)) != WHERE_IDENTITY
|
70
|
+
join_terms 'AND'.freeze, cond, wrap_term_with_parens(query)
|
72
71
|
else
|
73
72
|
query
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
77
|
-
# @return [query, params] tie-breaker unless
|
78
|
-
def where_tie(
|
79
|
-
if
|
76
|
+
# @return [query, params] tie-breaker unless column is unique
|
77
|
+
def where_tie(col)
|
78
|
+
if col.unique?
|
80
79
|
WHERE_IDENTITY
|
81
80
|
else
|
82
|
-
where_eq(
|
81
|
+
where_eq(col)
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
86
85
|
# @param [:before or :after] side
|
87
|
-
# @return [query, params] return query
|
88
|
-
def where_side(
|
89
|
-
if
|
90
|
-
|
91
|
-
if cond.complete? && values.length == cond.order_enum.length
|
92
|
-
WHERE_IDENTITY
|
93
|
-
else
|
94
|
-
where_in cond, values
|
95
|
-
end
|
86
|
+
# @return [query, params] return query fragment for column values before / after the current one
|
87
|
+
def where_side(col, side, strict = true, value = point.value(col))
|
88
|
+
if col.order_enum
|
89
|
+
where_in col, col.enum_side(value, side, strict)
|
96
90
|
else
|
97
|
-
where_ray
|
91
|
+
where_ray col, value, side, strict
|
98
92
|
end
|
99
93
|
end
|
100
94
|
|
101
|
-
def where_in(
|
95
|
+
def where_in(col, values)
|
102
96
|
case values.length
|
103
97
|
when 0
|
104
98
|
WHERE_IDENTITY
|
105
99
|
when 1
|
106
|
-
where_eq
|
100
|
+
where_eq col, values[0]
|
107
101
|
else
|
108
|
-
["#{
|
102
|
+
["#{col.column_name} IN (?)".freeze, [values]]
|
109
103
|
end
|
110
104
|
end
|
111
105
|
|
112
|
-
def where_eq(
|
113
|
-
[%Q(#{
|
106
|
+
def where_eq(col, value = point.value(col))
|
107
|
+
[%Q(#{col.column_name} = ?).freeze, [value]]
|
114
108
|
end
|
115
109
|
|
116
|
-
def where_ray(
|
110
|
+
def where_ray(col, from, mode, strict = true)
|
117
111
|
ops = %w(< >)
|
118
112
|
ops = ops.reverse if mode == :after
|
119
|
-
op = {asc: ops[0], desc: ops[1]}[
|
120
|
-
["#{
|
113
|
+
op = {asc: ops[0], desc: ops[1]}[col.order || :asc]
|
114
|
+
["#{col.column_name} #{op}#{'=' unless strict} ?".freeze, [from]]
|
121
115
|
end
|
122
116
|
|
123
117
|
WHERE_IDENTITY = [''.freeze, [].freeze].freeze
|
data/lib/order_query/version.rb
CHANGED
data/lib/order_query.rb
CHANGED
@@ -66,10 +66,10 @@ module OrderQuery
|
|
66
66
|
scope name, -> {
|
67
67
|
send(space_method).scope
|
68
68
|
}
|
69
|
-
scope
|
69
|
+
scope "#{name}_reverse", -> {
|
70
70
|
send(space_method).scope_reverse
|
71
71
|
}
|
72
|
-
define_singleton_method "#{name}_at", ->
|
72
|
+
define_singleton_method "#{name}_at", ->(record) {
|
73
73
|
send(space_method).at(record)
|
74
74
|
}
|
75
75
|
define_method(name) { |scope = nil|
|
@@ -81,6 +81,6 @@ module OrderQuery
|
|
81
81
|
class << self
|
82
82
|
attr_accessor :wrap_top_level_or
|
83
83
|
end
|
84
|
-
# Wrap top-level or with an AND and a redundant
|
84
|
+
# Wrap top-level or with an AND and a redundant column for performance
|
85
85
|
self.wrap_top_level_or = true
|
86
86
|
end
|
data/spec/order_query_spec.rb
CHANGED
@@ -9,7 +9,7 @@ end
|
|
9
9
|
class Post < ActiveRecord::Base
|
10
10
|
include OrderQuery
|
11
11
|
order_query :order_list,
|
12
|
-
[:pinned, [true, false]
|
12
|
+
[:pinned, [true, false]],
|
13
13
|
[:published_at, :desc],
|
14
14
|
[:id, :desc]
|
15
15
|
end
|
@@ -21,7 +21,8 @@ end
|
|
21
21
|
# Advanced model
|
22
22
|
class Issue < ActiveRecord::Base
|
23
23
|
DISPLAY_ORDER = [
|
24
|
-
[:
|
24
|
+
[:pinned, [true, false]],
|
25
|
+
[:priority, %w(high medium low)],
|
25
26
|
[:valid_votes_count, :desc, sql: '(votes - suspicious_votes)'],
|
26
27
|
[:updated_at, :desc],
|
27
28
|
[:id, :desc]
|
@@ -63,9 +64,11 @@ describe 'OrderQuery' do
|
|
63
64
|
t = Time.now
|
64
65
|
datasets = [
|
65
66
|
[
|
67
|
+
['high', 5, 0, t, true],
|
68
|
+
['high', 5, 1, t, true],
|
66
69
|
['high', 5, 0, t],
|
70
|
+
['high', 5, 0, t - 1.day],
|
67
71
|
['high', 5, 1, t],
|
68
|
-
['high', 5, 1, t - 1.day],
|
69
72
|
['medium', 10, 0, t],
|
70
73
|
['medium', 10, 5, t - 12.hours],
|
71
74
|
['low', 30, 0, t + 1.day]
|
@@ -85,7 +88,7 @@ describe 'OrderQuery' do
|
|
85
88
|
datasets.each_with_index do |ds, i|
|
86
89
|
it "is ordered correctly (test data #{i})" do
|
87
90
|
issues = ds.map do |attr|
|
88
|
-
Issue.new(priority: attr[0], votes: attr[1], suspicious_votes: attr[2], updated_at: attr[3])
|
91
|
+
Issue.new(priority: attr[0], votes: attr[1], suspicious_votes: attr[2], updated_at: attr[3], pinned: attr[4] || false)
|
89
92
|
end
|
90
93
|
issues.shuffle.reverse_each(&:save!)
|
91
94
|
expect(Issue.display_order.to_a).to eq(issues)
|
@@ -161,7 +164,7 @@ describe 'OrderQuery' do
|
|
161
164
|
end
|
162
165
|
end
|
163
166
|
|
164
|
-
it '#seek falls back to scope when order
|
167
|
+
it '#seek falls back to scope when order column is missing self' do
|
165
168
|
a = create_issue(priority: 'medium')
|
166
169
|
b = create_issue(priority: 'high')
|
167
170
|
expect(a.seek(Issue.display_order, [[:priority, ['wontfix', 'askbob']], [:id, :desc]]).next).to eq(b)
|
@@ -176,6 +179,7 @@ describe 'OrderQuery' do
|
|
176
179
|
self.verbose = false
|
177
180
|
|
178
181
|
create_table :issues do |t|
|
182
|
+
t.column :pinned, :boolean, null: false, default: false
|
179
183
|
t.column :priority, :string
|
180
184
|
t.column :votes, :integer
|
181
185
|
t.column :suspicious_votes, :integer
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: order_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gleb Mazovetskiy
|
@@ -78,10 +78,10 @@ files:
|
|
78
78
|
- README.md
|
79
79
|
- Rakefile
|
80
80
|
- lib/order_query.rb
|
81
|
-
- lib/order_query/
|
81
|
+
- lib/order_query/column.rb
|
82
82
|
- lib/order_query/point.rb
|
83
83
|
- lib/order_query/space.rb
|
84
|
-
- lib/order_query/sql/
|
84
|
+
- lib/order_query/sql/column.rb
|
85
85
|
- lib/order_query/sql/order_by.rb
|
86
86
|
- lib/order_query/sql/where.rb
|
87
87
|
- lib/order_query/version.rb
|