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: 0b010f558103980a1604be1c1e9eaa84c7f357e7
4
- data.tar.gz: ee47dd9e0ea2aef8d8c3997e2cd48d37a2beb326
3
+ metadata.gz: 23c244348f2b9b13024c0efadd677d4b6277bd32
4
+ data.tar.gz: 4579d5faa4e299881cce4e77c0d98306ba00f968
5
5
  SHA512:
6
- metadata.gz: a3123d4161d388842ea289034b50b79546b0751033038085e6e900a3f9618c804d236b73752f0454aa95d63dbc4a8e7888329dd727394c3e8c31f665f54f126d
7
- data.tar.gz: e4f1887ec9d649f5e8140bd4b924739df3e6220d55089cc38b959b5228d7a1c497eb9c91afa5faddbe2f206877bdf29e6cd70f10a6e655676adf51ff5ede8184
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
- # Note that since we're iterating over the order to return a modified
13
- # version of this dataset, we can't modify the order in this method and
14
- # remain sensible.
15
- ds = self
16
-
17
- selections = extract_selections(ds).map { |s| normalize_selection(s) }
18
-
19
- order_info =
20
- order.map.with_index do |o, index|
21
- exp = normalize_expression(unwrap_order_expression(o))
22
- dir = extract_direction(o)
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
- name =
34
- case expression_selects.length
35
- when 0 then nil
36
- when 1
37
- expression_select = expression_selects.first
38
-
39
- # Once we have the SELECT expression that matches our ORDER BY
40
- # expression, we just extract its name so that we'll be able to
41
- # figure out how we sorted records later on. The exception is if
42
- # the matching SELECT expression is "table".* - in that case
43
- # we'll need to get the name from the ORDER BY expression.
44
- target_expression =
45
- if expression_select.is_a?(Sequel::SQL::ColumnAll)
46
- exp
47
- else
48
- expression_select
49
- end
50
-
51
- extract_expression_name(target_expression)
52
- else
53
- raise "Found more than one selection in #{inspect} that matched the expression #{exp.inspect}: #{expression_selects.inspect}"
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
- # After all that, we still might not have been able to get a name.
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
- {name: name, direction: dir}
65
- end
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sequel
4
4
  module SelectOrderClauses
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -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.1.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-09-05 00:00:00.000000000 Z
11
+ date: 2017-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler