sequel-select-order-clauses 0.1.0 → 0.2.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
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23c244348f2b9b13024c0efadd677d4b6277bd32
|
4
|
+
data.tar.gz: 4579d5faa4e299881cce4e77c0d98306ba00f968
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afa8d9d6a552aad12cbb589e02d91ffe6fbd51ce3bd96a5a5d7722e681a04acf1aceb480881877eee6dca95658306899a971a3cef5e2a9ddeb383d5ad51ebd8e
|
7
|
+
data.tar.gz: 2f075bb2aa65d3ce7593861af10213de199ba0ead4fa827562348aac0869e83f07a3854152e46c45c4b76e1f64675bded6ec174904f4e5f469a5bffd29afcaf8
|
@@ -5,66 +5,83 @@ require 'sequel/extensions/select_order_clauses/version'
|
|
5
5
|
|
6
6
|
module Sequel
|
7
7
|
module SelectOrderClauses
|
8
|
+
def select_order
|
9
|
+
return self unless order = @opts[:order]
|
10
|
+
|
11
|
+
cached_dataset(:_select_order_ds) do
|
12
|
+
select(
|
13
|
+
*order.map.with_index { |o, index|
|
14
|
+
Sequel.as(
|
15
|
+
normalize_expression(unwrap_order_expression(o)),
|
16
|
+
"order_#{index}".to_sym,
|
17
|
+
)
|
18
|
+
}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
8
23
|
def append_order_as_selection
|
9
24
|
return self unless order = @opts[:order]
|
10
25
|
return self if @opts[:order_info]
|
11
26
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
# Try to figure out which of the select expressions is going to
|
25
|
-
# correspond to this order expression. This heuristic may not be
|
26
|
-
# perfect, but do our best and raise an error if we find more than one
|
27
|
-
# selection.
|
28
|
-
expression_selects =
|
29
|
-
selections.select do |s|
|
30
|
-
selection_satisfies_expression?(s, exp)
|
31
|
-
end
|
27
|
+
cached_dataset(:_append_order_as_selection_ds) do
|
28
|
+
# Note that since we're iterating over the order to return a modified
|
29
|
+
# version of this dataset, we can't modify the order in this method and
|
30
|
+
# remain sensible.
|
31
|
+
ds = self
|
32
|
+
|
33
|
+
selections = extract_selections(ds).map { |s| normalize_selection(s) }
|
34
|
+
|
35
|
+
order_info =
|
36
|
+
order.map.with_index do |o, index|
|
37
|
+
exp = normalize_expression(unwrap_order_expression(o))
|
38
|
+
dir = extract_direction(o)
|
32
39
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
# Try to figure out which of the select expressions is going to
|
41
|
+
# correspond to this order expression. This heuristic may not be
|
42
|
+
# perfect, but do our best and raise an error if we find more than one
|
43
|
+
# selection.
|
44
|
+
expression_selects =
|
45
|
+
selections.select do |s|
|
46
|
+
selection_satisfies_expression?(s, exp)
|
47
|
+
end
|
48
|
+
|
49
|
+
name =
|
50
|
+
case expression_selects.length
|
51
|
+
when 0 then nil
|
52
|
+
when 1
|
53
|
+
expression_select = expression_selects.first
|
54
|
+
|
55
|
+
# Once we have the SELECT expression that matches our ORDER BY
|
56
|
+
# expression, we just extract its name so that we'll be able to
|
57
|
+
# figure out how we sorted records later on. The exception is if
|
58
|
+
# the matching SELECT expression is "table".* - in that case
|
59
|
+
# we'll need to get the name from the ORDER BY expression.
|
60
|
+
target_expression =
|
61
|
+
if expression_select.is_a?(Sequel::SQL::ColumnAll)
|
62
|
+
exp
|
63
|
+
else
|
64
|
+
expression_select
|
65
|
+
end
|
66
|
+
|
67
|
+
extract_expression_name(target_expression)
|
68
|
+
else
|
69
|
+
raise "Found more than one selection in #{inspect} that matched the expression #{exp.inspect}: #{expression_selects.inspect}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# After all that, we still might not have been able to get a name.
|
73
|
+
# In that case, just append the ORDER BY expression to the SELECT
|
74
|
+
# clause with a special alias that we'll use later.
|
75
|
+
unless name
|
76
|
+
name = "order_#{index}".to_sym
|
77
|
+
ds = ds.select_append(Sequel.as(exp, name))
|
54
78
|
end
|
55
79
|
|
56
|
-
|
57
|
-
# In that case, just append the ORDER BY expression to the SELECT
|
58
|
-
# clause with a special alias that we'll use later.
|
59
|
-
unless name
|
60
|
-
name = "order_#{index}".to_sym
|
61
|
-
ds = ds.select_append(Sequel.as(exp, name))
|
80
|
+
{name: name, direction: dir}.freeze
|
62
81
|
end
|
63
82
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
ds.clone(order_info: order_info)
|
83
|
+
ds.clone(order_info: order_info.freeze)
|
84
|
+
end
|
68
85
|
end
|
69
86
|
|
70
87
|
private
|
@@ -5,6 +5,35 @@ class SelectOrderClausesSpec < Minitest::Spec
|
|
5
5
|
assert Sequel::SelectOrderClauses::VERSION.is_a?(String)
|
6
6
|
end
|
7
7
|
|
8
|
+
describe "select_order" do
|
9
|
+
def assert_select_order(ds:, selects:)
|
10
|
+
initial = ds
|
11
|
+
final = ds.select_order
|
12
|
+
|
13
|
+
assert_equal selects, final.opts[:select]
|
14
|
+
|
15
|
+
# Make sure that dataset is cached.
|
16
|
+
assert_equal final.object_id, ds.select_order.object_id
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should select only the order clauses" do
|
20
|
+
assert_select_order(
|
21
|
+
ds: User.dataset,
|
22
|
+
selects: nil,
|
23
|
+
)
|
24
|
+
|
25
|
+
assert_select_order(
|
26
|
+
ds: User.dataset.order_by(Sequel.desc(:id)),
|
27
|
+
selects: [Sequel.as(:id, :order_0)],
|
28
|
+
)
|
29
|
+
|
30
|
+
assert_select_order(
|
31
|
+
ds: User.dataset.order_by(Sequel.desc(:id), :other_column),
|
32
|
+
selects: [Sequel.as(:id, :order_0), Sequel.as(:other_column, :order_1)],
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
8
37
|
describe "append_order_as_selection" do
|
9
38
|
def assert_order_append(ds:, selects_to_append:, order_names:)
|
10
39
|
initial = ds
|
@@ -15,6 +44,9 @@ class SelectOrderClausesSpec < Minitest::Spec
|
|
15
44
|
order_info = final.opts.fetch(:order_info)
|
16
45
|
|
17
46
|
assert_equal order_names, order_info.map { |h| h.fetch(:name) }
|
47
|
+
|
48
|
+
# Make sure that dataset is cached.
|
49
|
+
assert_equal final.object_id, ds.append_order_as_selection.object_id
|
18
50
|
end
|
19
51
|
|
20
52
|
it "should do nothing to queries without order_by clauses" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-select-order-clauses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Hanks
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|