sequel-select-order-clauses 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4596afa94f19b82c39ae79479131ff6c60643740
4
+ data.tar.gz: 1eb6f016f4d7ea86d33891dc3cb85b1e508b0f16
5
+ SHA512:
6
+ metadata.gz: 0dd46ee1b0e93733b06ba789868d0c0990433bf75cf530e8ea2afb6a33566194d3f62607549ba88827abe0aa9fbafae05561b92b7e72fc9b7b94f356e1fb0ed4
7
+ data.tar.gz: cb3caecd7a4132fb3fd74339b0d8c91d8894960a0b8dd6e5d82080c1385e65e534665a208d7ef69fd4ee6d8dbd35340b72b10806b443c4f3ad0f2f5229bed654
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'minitest', '5.5.1'
7
+ gem 'minitest-rg', '5.1.0'
8
+
9
+ gem 'pry'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Chris Hanks
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # Sequel::SelectOrderClauses
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ Dir["./tasks/*.rb"].sort.each &method(:require)
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel/extensions/select_order_clauses'
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel'
4
+ require 'sequel/extensions/select_order_clauses/version'
5
+
6
+ module Sequel
7
+ module SelectOrderClauses
8
+ def append_order_as_selection
9
+ return self unless order = @opts[:order]
10
+ return self if @opts[:order_info]
11
+
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
32
+
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}"
54
+ end
55
+
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))
62
+ end
63
+
64
+ {name: name, direction: dir}
65
+ end
66
+
67
+ ds.clone(order_info: order_info)
68
+ end
69
+
70
+ private
71
+
72
+ # Our inputs should have already been simplified and normalized to the
73
+ # extent possible, now the nitty-gritty of defining whatever equality
74
+ # logic we really need to for them.
75
+
76
+ # The question at hand: can we safely assume that this expression in the
77
+ # SELECT clause will always represent this expression in the ORDER BY?
78
+ def selection_satisfies_expression?(s, e)
79
+ case s
80
+ when Sequel::SQL::AliasedExpression
81
+ # Order expressions can be simple references to aliases, which is a
82
+ # pretty simple and useful case to check for. In other words:
83
+ # `SELECT function() AS my_value FROM table ORDER BY my_value`
84
+ if e.is_a?(Symbol) && s.aliaz == e
85
+ true
86
+ else
87
+ # Otherwise, see whether the expression being aliased does what we
88
+ # want. For example:
89
+ # `SELECT function() AS my_value FROM table ORDER BY function()`
90
+ selection_satisfies_expression?(normalize_selection(s.expression), e)
91
+ end
92
+ when Sequel::SQL::QualifiedIdentifier
93
+ # SELECT "table"."column"
94
+ case e
95
+ when Symbol
96
+ # SELECT "table"."column" FROM "table" ORDER BY "column"
97
+ s.column == e
98
+ when Sequel::SQL::QualifiedIdentifier
99
+ # SELECT "table"."column" FROM "table" ORDER BY "table"."column"
100
+ s == e
101
+ end
102
+ when Sequel::SQL::ColumnAll
103
+ # SELECT "table".*
104
+ case e
105
+ when Sequel::SQL::QualifiedIdentifier
106
+ # Satisfies any column anchored on that table...
107
+ s.table == e.table
108
+ when Symbol
109
+ # ...or a plain column reference that we can verify lives on this
110
+ # model. Note that m.columns.include?(e) would leave out
111
+ # lazy-loaded columns.
112
+ respond_to?(:model) &&
113
+ (m = model) &&
114
+ m.table_name == s.table &&
115
+ m.db_schema.has_key?(e)
116
+ end
117
+ else
118
+ # These values could be anything - functions, mathematical operations,
119
+ # literal SQL strings, etc. Just try for simple equality.
120
+ s == e
121
+ end
122
+ end
123
+
124
+ # In addition to the common normalization logic in normalize_expression(),
125
+ # which can be applied to expressions in either the SELECT or ORDER BY
126
+ # clauses, this method encapsulates an assumption that is safe to make
127
+ # about expressions in SELECT but not in ORDER BY, that a simple
128
+ # identifier (a symbol) on a single-source dataset must refer to a column
129
+ # in the table. In an ORDER BY clause it could also refer to an alias in
130
+ # the SELECT clause.
131
+ def normalize_selection(s)
132
+ s = normalize_expression(s)
133
+
134
+ case s
135
+ when Symbol
136
+ if joined_dataset?
137
+ s # Can't make any assumptions about the source table.
138
+ else
139
+ Sequel.qualify(first_source, s)
140
+ end
141
+ else
142
+ s
143
+ end
144
+ end
145
+
146
+ # Move more esoteric Sequel types to the baseline of symbols representing
147
+ # identifiers and QualifiedIdentifiers representing table-column pairs, so
148
+ # that it's easier for us to do comparisons without needing to define
149
+ # equality logic between every combination of classes in the Sequel AST.
150
+ def normalize_expression(expression)
151
+ case expression
152
+ when Symbol
153
+ # Take care of symbol notations like :table__column___alias.
154
+ table, column, aliaz =
155
+ Sequel.split_symbol(expression).map { |part| part&.to_sym }
156
+
157
+ exp = table ? Sequel.qualify(table, column) : column
158
+ exp = Sequel.as(exp, aliaz) if aliaz
159
+ exp
160
+ when Sequel::SQL::Identifier
161
+ # Identifier objects have their uses, but not here, where a symbol is
162
+ # just fine.
163
+ expression.value.to_sym
164
+ when Sequel::SQL::QualifiedIdentifier
165
+ t = expression.table
166
+ c = expression.column
167
+
168
+ if t.is_a?(Symbol) && c.is_a?(Symbol)
169
+ expression
170
+ else
171
+ Sequel::SQL::QualifiedIdentifier.new(
172
+ normalize_expression(t),
173
+ normalize_expression(c),
174
+ )
175
+ end
176
+ else
177
+ # Other arbitrary expressions can just be passed through.
178
+ expression
179
+ end
180
+ end
181
+
182
+ def extract_selections(ds)
183
+ if selections = ds.opts[:select]
184
+ return selections
185
+ end
186
+
187
+ if (froms = ds.opts[:from]) && froms.length == 1
188
+ from = unwrap_alias(froms.first)
189
+ if from.is_a?(Sequel::Dataset)
190
+ extract_selections(from)
191
+ end
192
+ end
193
+ end
194
+
195
+ def extract_expression_name(expression)
196
+ case expression
197
+ when Symbol
198
+ expression
199
+ when Sequel::SQL::AliasedExpression
200
+ expression.aliaz
201
+ when Sequel::SQL::Identifier
202
+ extract_expression_name(expression.value)
203
+ when Sequel::SQL::QualifiedIdentifier
204
+ extract_expression_name(expression.column)
205
+ end
206
+ end
207
+
208
+ def unwrap_order_expression(order)
209
+ case order
210
+ when Sequel::SQL::OrderedExpression
211
+ order.expression
212
+ else
213
+ order
214
+ end
215
+ end
216
+
217
+ def unwrap_alias(expression)
218
+ case expression
219
+ when Sequel::SQL::AliasedExpression
220
+ expression.expression
221
+ else
222
+ expression
223
+ end
224
+ end
225
+
226
+ def extract_direction(order)
227
+ case order
228
+ when Sequel::SQL::OrderedExpression
229
+ order.descending ? :desc : :asc
230
+ else
231
+ :asc
232
+ end
233
+ end
234
+ end
235
+
236
+ Dataset.register_extension(:select_order_clauses, SelectOrderClauses)
237
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel
4
+ module SelectOrderClauses
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sequel/extensions/select_order_clauses/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'sequel-select-order-clauses'
8
+ spec.version = Sequel::SelectOrderClauses::VERSION
9
+ spec.authors = ["Chris Hanks"]
10
+ spec.email = ['christopher.m.hanks@gmail.com']
11
+ spec.summary = %q{Select the order clauses in a dataset}
12
+ spec.description = %q{Simple support for selecting the order clauses in a dataset}
13
+ spec.homepage = 'https://github.com/chanks/sequel-select-order-clauses'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'sqlite3'
24
+
25
+ spec.add_dependency 'sequel', '~> 4.0'
26
+ end
@@ -0,0 +1,227 @@
1
+ require 'spec_helper'
2
+
3
+ class SelectOrderClausesSpec < Minitest::Spec
4
+ it "should have a version" do
5
+ assert Sequel::SelectOrderClauses::VERSION.is_a?(String)
6
+ end
7
+
8
+ describe "append_order_as_selection" do
9
+ def assert_order_append(ds:, selects_to_append:, order_names:)
10
+ initial = ds
11
+ final = ds.append_order_as_selection
12
+
13
+ assert_equal (initial.opts[:select] || []) + selects_to_append, final.opts[:select] || []
14
+
15
+ order_info = final.opts.fetch(:order_info)
16
+
17
+ assert_equal order_names, order_info.map { |h| h.fetch(:name) }
18
+ end
19
+
20
+ it "should do nothing to queries without order_by clauses" do
21
+ assert_equal User.dataset, User.dataset.append_order_as_selection
22
+ end
23
+
24
+ describe "for simple symbol columns" do
25
+ it "when they are missing" do
26
+ assert_order_append \
27
+ ds: User.dataset.select(:id).order_by(:description),
28
+ selects_to_append: [Sequel.as(:description, :order_0)],
29
+ order_names: [:order_0]
30
+
31
+ assert_order_append \
32
+ ds: User.dataset.select(:id).order_by(:fake_column),
33
+ selects_to_append: [Sequel.as(:fake_column, :order_0)],
34
+ order_names: [:order_0]
35
+ end
36
+
37
+ it "when they are present" do
38
+ assert_order_append \
39
+ ds: User.dataset.select(:id).order_by(:id),
40
+ selects_to_append: [],
41
+ order_names: [:id]
42
+
43
+ assert_order_append \
44
+ ds: User.dataset.select(:created_at).order_by(:created_at),
45
+ selects_to_append: [],
46
+ order_names: [:created_at]
47
+ end
48
+ end
49
+
50
+ describe "when the dataset has been made via #from_self" do
51
+ it "when they are present" do
52
+ assert_order_append \
53
+ ds: User.dataset.select(:id).from_self.order_by(:id),
54
+ selects_to_append: [],
55
+ order_names: [:id]
56
+
57
+ assert_order_append \
58
+ ds: User.dataset.select(:users__created_at).from_self.order_by(:created_at),
59
+ selects_to_append: [],
60
+ order_names: [:created_at]
61
+ end
62
+ end
63
+
64
+ describe "for qualified columns" do
65
+ it "when they are missing" do
66
+ assert_order_append \
67
+ ds: User.dataset.select(:id).order_by(Sequel.qualify(:other_table, :fake_column)),
68
+ selects_to_append: [Sequel.qualify(:other_table, :fake_column).as(:order_0)],
69
+ order_names: [:order_0]
70
+
71
+ assert_order_append \
72
+ ds: User.dataset.select(:id).order_by(:other_table__fake_column),
73
+ selects_to_append: [Sequel.qualify(:other_table, :fake_column).as(:order_0)],
74
+ order_names: [:order_0]
75
+ end
76
+
77
+ it "when they are present" do
78
+ assert_order_append \
79
+ ds: User.dataset.select(Sequel.qualify(:users, :id)).order_by(:id),
80
+ selects_to_append: [],
81
+ order_names: [:id]
82
+
83
+ assert_order_append \
84
+ ds: User.dataset.select(Sequel.qualify(:users, Sequel::SQL::Identifier.new(:id))).order_by(:id),
85
+ selects_to_append: [],
86
+ order_names: [:id]
87
+
88
+ assert_order_append \
89
+ ds: User.dataset.select(:id).order_by(Sequel.qualify(:users, :id)),
90
+ selects_to_append: [],
91
+ order_names: [:id]
92
+
93
+ assert_order_append \
94
+ ds: User.dataset.select(:created_at).order_by(:users__created_at),
95
+ selects_to_append: [],
96
+ order_names: [:created_at]
97
+ end
98
+ end
99
+
100
+ describe "for columns with aliases" do
101
+ it "should recognize that ORDER BY can take either the column name or its alias" do
102
+ assert_order_append \
103
+ ds: User.dataset.select(Sequel.as(:description, :des)).order_by(:des),
104
+ selects_to_append: [],
105
+ order_names: [:des]
106
+
107
+ assert_order_append \
108
+ ds: User.dataset.select(Sequel.as(:description, :des)).order_by(:description),
109
+ selects_to_append: [],
110
+ order_names: [:des]
111
+ end
112
+
113
+ it "that are also qualified" do
114
+ assert_order_append \
115
+ ds: User.dataset.select(Sequel.qualify(:users, :description).as(:des)).order_by(:description),
116
+ selects_to_append: [],
117
+ order_names: [:des]
118
+
119
+ assert_order_append \
120
+ ds: User.dataset.select(Sequel.qualify(:users, :description).as(:des)).order_by(:des),
121
+ selects_to_append: [],
122
+ order_names: [:des]
123
+
124
+ assert_order_append \
125
+ ds: User.dataset.select(Sequel.as(:description, :des)).order_by(Sequel.qualify(:users, :description)),
126
+ selects_to_append: [],
127
+ order_names: [:des]
128
+
129
+ assert_order_append \
130
+ ds: User.dataset.select(:created_at___c_at).order_by(:users__created_at),
131
+ selects_to_append: [],
132
+ order_names: [:c_at]
133
+
134
+ assert_order_append \
135
+ ds: User.dataset.select(Sequel.qualify(:users, :description).as(:des)).order_by(:description),
136
+ selects_to_append: [],
137
+ order_names: [:des]
138
+ end
139
+ end
140
+
141
+ describe "when ordering by arbitrary expressions" do
142
+ it "when they are missing" do
143
+ assert_order_append \
144
+ ds: User.dataset.select(:id).order_by{function(:column1, 2)},
145
+ selects_to_append: [Sequel.virtual_row{function(:column1, 2)}.as(:order_0)],
146
+ order_names: [:order_0]
147
+
148
+ assert_order_append \
149
+ ds: User.dataset.select(:id).order_by{column - 2},
150
+ selects_to_append: [Sequel.virtual_row{column - 2}.as(:order_0)],
151
+ order_names: [:order_0]
152
+
153
+ assert_order_append \
154
+ ds: User.dataset.select(:id).order_by(Sequel.lit('function(column1, 2)')),
155
+ selects_to_append: [Sequel.lit('function(column1, 2)').as(:order_0)],
156
+ order_names: [:order_0]
157
+ end
158
+
159
+ it "when they are present" do
160
+ assert_order_append \
161
+ ds: User.dataset.select{function(:column1, 2).as(:my_column)}.order_by{function(:column1, 2)},
162
+ selects_to_append: [],
163
+ order_names: [:my_column]
164
+ end
165
+
166
+ it "when they are present but don't have a name we can safely predict" do
167
+ assert_order_append \
168
+ ds: User.dataset.select{function(:column1, 2)}.order_by{function(:column1, 2)},
169
+ selects_to_append: [Sequel.virtual_row{function(:column1, 2)}.as(:order_0)],
170
+ order_names: [:order_0]
171
+ end
172
+ end
173
+
174
+ describe "when a selection includes a ColumnAll" do
175
+ describe "and is not connected to a model" do
176
+ it "when ordering by a column qualified to that table" do
177
+ assert_order_append \
178
+ ds: DB[:users].select_all(:users).order_by(Sequel.qualify(:users, :id)),
179
+ selects_to_append: [],
180
+ order_names: [:id]
181
+ end
182
+
183
+ it "when ordering by a column qualified to a different table" do
184
+ assert_order_append \
185
+ ds: DB[:users].select_all(:users).order_by(Sequel.qualify(:users_2, :id)),
186
+ selects_to_append: [Sequel.qualify(:users_2, :id).as(:order_0)],
187
+ order_names: [:order_0]
188
+ end
189
+
190
+ it "when ordering by an unqualified column" do
191
+ assert_order_append \
192
+ ds: DB[:users].select_all(:users).order_by(:id),
193
+ selects_to_append: [Sequel.as(:id, :order_0)],
194
+ order_names: [:order_0]
195
+ end
196
+
197
+ it "when ordering by an arbitrary expression" do
198
+ assert_order_append \
199
+ ds: DB[:users].select_all(:users).order_by{function(:column, 2)},
200
+ selects_to_append: [Sequel.virtual_row{function(:column, 2)}.as(:order_0)],
201
+ order_names: [:order_0]
202
+ end
203
+ end
204
+
205
+ describe "and is connected to a model so we can look up columns" do
206
+ it "when ordering by an unqualified column that is present in the table" do
207
+ assert_order_append \
208
+ ds: User.dataset.select_all(:users).order_by(:id),
209
+ selects_to_append: [],
210
+ order_names: [:id]
211
+
212
+ assert_order_append \
213
+ ds: User.dataset.select_all(:users).order_by(:description),
214
+ selects_to_append: [],
215
+ order_names: [:description]
216
+ end
217
+
218
+ it "when ordering by an unqualified column that is not present in the table" do
219
+ assert_order_append \
220
+ ds: User.dataset.select_all(:users).order_by(:fake_column),
221
+ selects_to_append: [Sequel.as(:fake_column, :order_0)],
222
+ order_names: [:order_0]
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,19 @@
1
+ require 'sequel'
2
+
3
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ Sequel::Database.extension :select_order_clauses
6
+
7
+ DB = Sequel.sqlite
8
+
9
+ DB.create_table :users do
10
+ primary_key :id
11
+ Time :created_at
12
+ String :description
13
+ end
14
+
15
+ class User < Sequel::Model; end
16
+
17
+ require 'pry'
18
+ require 'minitest/autorun'
19
+ require 'minitest/rg'
data/tasks/specs.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new :default do |t|
5
+ t.libs = ['spec']
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+
9
+ task :spec => :default
10
+ task :test => :default
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel-select-order-clauses
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Hanks
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sequel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ description: Simple support for selecting the order clauses in a dataset
70
+ email:
71
+ - christopher.m.hanks@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/sequel-select-order-clauses.rb
82
+ - lib/sequel/extensions/select_order_clauses.rb
83
+ - lib/sequel/extensions/select_order_clauses/version.rb
84
+ - sequel-select-order-clauses.gemspec
85
+ - spec/select_order_clauses_spec.rb
86
+ - spec/spec_helper.rb
87
+ - tasks/specs.rb
88
+ homepage: https://github.com/chanks/sequel-select-order-clauses
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.5.1
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Select the order clauses in a dataset
112
+ test_files:
113
+ - spec/select_order_clauses_spec.rb
114
+ - spec/spec_helper.rb