top_n_loader 1.0.0 → 1.0.3
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/.github/workflows/test.yml +22 -0
- data/.rubocop.yml +16 -0
- data/Gemfile.lock +49 -34
- data/README.md +1 -1
- data/Rakefile +6 -1
- data/bin/console +2 -2
- data/gemfiles/Gemfile-rails-6.0 +8 -0
- data/gemfiles/Gemfile-rails-7.0 +8 -0
- data/lib/top_n_loader/sql_builder.rb +104 -51
- data/lib/top_n_loader/version.rb +1 -1
- data/lib/top_n_loader.rb +13 -9
- data/top_n_loader.gemspec +2 -1
- metadata +27 -10
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d905751360ae053d80faa6332daad7e5fce710c2b44031483d71018e15d67c1a
|
|
4
|
+
data.tar.gz: dc175dd9e135880cb26c1c81c2784500e8ee0950dda9b03a39799af6d0b98710
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb24707fdea8d9162a87b6960cce21ee38d5f9c5ab8cadee549a97518e0da9c1f1fea5e2c6ae50b0b1db0171d868ec5cb2c5f3c058b8e1cefba14491b058d2ec
|
|
7
|
+
data.tar.gz: a69198a3697ebc97e49c5c36d71103b9c8afb837b1416a7668e0190323042b3af51af3cd14bd1e22351646f271b825e385db53a80bb8090f3baf34e6e47626d4
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
strategy:
|
|
6
|
+
fail-fast: false
|
|
7
|
+
matrix:
|
|
8
|
+
ruby: [ '2.7', '3.0', '3.1' ]
|
|
9
|
+
gemfiles:
|
|
10
|
+
- gemfiles/Gemfile-rails-6.0
|
|
11
|
+
- gemfiles/Gemfile-rails-7.0
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v2
|
|
15
|
+
- uses: ruby/setup-ruby@v1
|
|
16
|
+
with:
|
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
|
18
|
+
- run: |
|
|
19
|
+
sudo apt-get update
|
|
20
|
+
sudo apt-get install -y libsqlite3-dev
|
|
21
|
+
- run: bundle install --gemfile ${{ matrix.gemfiles }} --jobs 4 --retry 3
|
|
22
|
+
- run: bundle exec --gemfile ${{ matrix.gemfiles }} rake
|
data/.rubocop.yml
ADDED
data/Gemfile.lock
CHANGED
|
@@ -1,45 +1,59 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
top_n_loader (1.0.
|
|
4
|
+
top_n_loader (1.0.3)
|
|
5
5
|
activerecord
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (
|
|
11
|
-
activesupport (=
|
|
12
|
-
activerecord (
|
|
13
|
-
activemodel (=
|
|
14
|
-
activesupport (=
|
|
15
|
-
|
|
16
|
-
activesupport (5.2.3)
|
|
10
|
+
activemodel (7.0.3)
|
|
11
|
+
activesupport (= 7.0.3)
|
|
12
|
+
activerecord (7.0.3)
|
|
13
|
+
activemodel (= 7.0.3)
|
|
14
|
+
activesupport (= 7.0.3)
|
|
15
|
+
activesupport (7.0.3)
|
|
17
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
|
-
i18n (>=
|
|
19
|
-
minitest (
|
|
20
|
-
tzinfo (~>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
i18n (1.6.0)
|
|
17
|
+
i18n (>= 1.6, < 2)
|
|
18
|
+
minitest (>= 5.1)
|
|
19
|
+
tzinfo (~> 2.0)
|
|
20
|
+
ast (2.4.2)
|
|
21
|
+
concurrent-ruby (1.1.10)
|
|
22
|
+
docile (1.4.0)
|
|
23
|
+
i18n (1.10.0)
|
|
26
24
|
concurrent-ruby (~> 1.0)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
minitest (5.16.1)
|
|
26
|
+
parallel (1.22.1)
|
|
27
|
+
parser (3.1.2.0)
|
|
28
|
+
ast (~> 2.4.1)
|
|
29
|
+
rainbow (3.1.1)
|
|
30
|
+
rake (13.0.6)
|
|
31
|
+
regexp_parser (2.5.0)
|
|
32
|
+
rexml (3.2.5)
|
|
33
|
+
rubocop (1.31.0)
|
|
34
|
+
parallel (~> 1.10)
|
|
35
|
+
parser (>= 3.1.0.0)
|
|
36
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
37
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
38
|
+
rexml (>= 3.2.5, < 4.0)
|
|
39
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
|
40
|
+
ruby-progressbar (~> 1.7)
|
|
41
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
42
|
+
rubocop-ast (1.18.0)
|
|
43
|
+
parser (>= 3.1.1.0)
|
|
44
|
+
rubocop-rubycw (0.1.6)
|
|
45
|
+
rubocop (~> 1.0)
|
|
46
|
+
ruby-progressbar (1.11.0)
|
|
47
|
+
simplecov (0.21.2)
|
|
48
|
+
docile (~> 1.1)
|
|
49
|
+
simplecov-html (~> 0.11)
|
|
50
|
+
simplecov_json_formatter (~> 0.1)
|
|
51
|
+
simplecov-html (0.12.3)
|
|
52
|
+
simplecov_json_formatter (0.1.4)
|
|
53
|
+
sqlite3 (1.4.4)
|
|
54
|
+
tzinfo (2.0.4)
|
|
55
|
+
concurrent-ruby (~> 1.0)
|
|
56
|
+
unicode-display_width (2.2.0)
|
|
43
57
|
|
|
44
58
|
PLATFORMS
|
|
45
59
|
ruby
|
|
@@ -47,11 +61,12 @@ PLATFORMS
|
|
|
47
61
|
DEPENDENCIES
|
|
48
62
|
bundler
|
|
49
63
|
minitest
|
|
50
|
-
pry
|
|
51
64
|
rake
|
|
65
|
+
rubocop
|
|
66
|
+
rubocop-rubycw
|
|
52
67
|
simplecov
|
|
53
68
|
sqlite3
|
|
54
69
|
top_n_loader!
|
|
55
70
|
|
|
56
71
|
BUNDLED WITH
|
|
57
|
-
1.
|
|
72
|
+
2.1.4
|
data/README.md
CHANGED
data/Rakefile
CHANGED
data/bin/console
CHANGED
|
@@ -9,71 +9,92 @@ module TopNLoader::SQLBuilder
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def self.top_n_association_sql(klass, target_klass, relation, limit:, order_mode:, order_key:)
|
|
12
|
+
limit = limit.to_i
|
|
12
13
|
parent_table = klass.table_name
|
|
13
14
|
joins = klass.joins relation.to_sym
|
|
14
15
|
target_table = target_klass.table_name
|
|
16
|
+
nullable = nullable_column? target_klass, order_key
|
|
15
17
|
if target_table == klass.table_name
|
|
16
18
|
target_table = "#{joins.joins_values.first.to_s.pluralize}_#{target_table}"
|
|
17
19
|
end
|
|
18
20
|
join_sql = joins.to_sql.match(/FROM.+/)[0]
|
|
19
|
-
|
|
21
|
+
parent_primary_key = "#{qt parent_table}.#{q klass.primary_key}"
|
|
22
|
+
target_order_key = "#{qt target_table}.#{q order_key}"
|
|
23
|
+
target_primary_key = "#{qt target_table}.#{q target_klass.primary_key}"
|
|
24
|
+
top_n_key, top_n_alias, t_join_cond = limit == 1 ? [
|
|
25
|
+
target_primary_key, :top_n_primary_key, "#{target_primary_key} = top_n_primary_key"
|
|
26
|
+
] : [
|
|
27
|
+
target_order_key, :top_n_order_key, compare_cond(target_order_key, order_mode, includes_nil: nullable)
|
|
28
|
+
]
|
|
29
|
+
order_columns = limit == 1 ? [target_order_key, target_primary_key].uniq : [target_order_key]
|
|
30
|
+
order_cond = order_columns.map {|column| "#{column} #{order_mode.to_s.upcase}"}.join(', ')
|
|
31
|
+
<<~SQL.squish
|
|
20
32
|
SELECT #{qt target_table}.*, top_n_group_key
|
|
21
33
|
#{join_sql}
|
|
22
34
|
INNER JOIN
|
|
23
35
|
(
|
|
24
|
-
SELECT T.#{q klass.primary_key}
|
|
36
|
+
SELECT T.#{q klass.primary_key} AS top_n_group_key,
|
|
25
37
|
(
|
|
26
|
-
SELECT #{
|
|
38
|
+
SELECT #{top_n_key}
|
|
27
39
|
#{join_sql}
|
|
28
|
-
WHERE #{
|
|
29
|
-
ORDER BY #{
|
|
30
|
-
LIMIT 1 OFFSET #{limit
|
|
31
|
-
) AS
|
|
32
|
-
FROM #{qt parent_table}
|
|
40
|
+
WHERE #{parent_primary_key} = T.#{q klass.primary_key}
|
|
41
|
+
ORDER BY #{order_cond}
|
|
42
|
+
LIMIT 1#{" OFFSET #{limit - 1}" if limit != 1}
|
|
43
|
+
) AS #{top_n_alias}
|
|
44
|
+
FROM #{qt parent_table} AS T WHERE T.#{q klass.primary_key} IN (?)
|
|
33
45
|
) T
|
|
34
|
-
ON #{
|
|
35
|
-
|
|
36
|
-
T.last_value IS NULL
|
|
37
|
-
OR #{qt target_table}.#{q order_key} #{{ asc: :<=, desc: :>= }[order_mode]} T.last_value
|
|
38
|
-
OR #{qt target_table}.#{q order_key} is NULL
|
|
39
|
-
)
|
|
40
|
-
)
|
|
46
|
+
ON #{parent_primary_key} = T.top_n_group_key AND #{t_join_cond}
|
|
47
|
+
SQL
|
|
41
48
|
end
|
|
42
49
|
|
|
43
|
-
|
|
44
50
|
def self.top_n_group_sql(klass:, group_column:, group_keys:, condition:, limit:, order_mode:, order_key:)
|
|
45
|
-
|
|
46
|
-
group_key_table = value_table(:T, :top_n_group_key, group_keys)
|
|
51
|
+
limit = limit.to_i
|
|
47
52
|
table_name = klass.table_name
|
|
48
53
|
sql = condition_sql klass, condition
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
group_key_nullable = group_keys.include?(nil) && nullable_column?(klass, group_column)
|
|
55
|
+
order_key_nullable = nullable_column? klass, order_key
|
|
56
|
+
group_key_table = value_table :T, :top_n_group_key, group_keys
|
|
57
|
+
table_order_key = "#{qt table_name}.#{q order_key}"
|
|
58
|
+
join_cond = equals_cond "#{qt table_name}.#{q group_column}", includes_nil: group_key_nullable
|
|
59
|
+
table_primary_key = "#{qt table_name}.#{q klass.primary_key}"
|
|
60
|
+
top_n_key, top_n_alias, t_join_cond = limit == 1 ? [
|
|
61
|
+
table_primary_key, :top_n_primary_key, "#{table_primary_key} = top_n_primary_key"
|
|
62
|
+
] : [
|
|
63
|
+
table_order_key, :top_n_order_key,
|
|
64
|
+
"#{compare_cond table_order_key, order_mode, includes_nil: order_key_nullable}#{" WHERE #{sql}" if sql}"
|
|
65
|
+
]
|
|
66
|
+
order_columns = limit == 1 ? [table_order_key, table_primary_key].uniq : [table_order_key]
|
|
67
|
+
order_cond = order_columns.map {|column| "#{column} #{order_mode.to_s.upcase}"}.join(', ')
|
|
68
|
+
<<~SQL.squish
|
|
55
69
|
SELECT #{qt table_name}.*, top_n_group_key
|
|
56
70
|
FROM #{qt table_name}
|
|
57
71
|
INNER JOIN
|
|
58
72
|
(
|
|
59
73
|
SELECT top_n_group_key,
|
|
60
74
|
(
|
|
61
|
-
SELECT #{
|
|
62
|
-
WHERE #{join_cond}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
) AS last_value
|
|
75
|
+
SELECT #{top_n_key} FROM #{qt table_name}
|
|
76
|
+
WHERE #{join_cond}#{" AND #{sql}" if sql}
|
|
77
|
+
ORDER BY #{order_cond}
|
|
78
|
+
LIMIT 1#{" OFFSET #{limit - 1}" if limit != 1}
|
|
79
|
+
) AS #{top_n_alias}
|
|
67
80
|
FROM #{group_key_table}
|
|
68
81
|
) T
|
|
69
|
-
ON #{join_cond}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
ON #{join_cond} AND #{t_join_cond}
|
|
83
|
+
SQL
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.equals_cond(column, includes_nil:, t_column: 'T.top_n_group_key')
|
|
87
|
+
cond = "#{column} = #{t_column}"
|
|
88
|
+
includes_nil ? "(#{cond} OR (#{column} IS NULL AND #{t_column} IS NULL))" : cond
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.compare_cond(column, order_mode, includes_nil:, t_column: 'T.top_n_order_key')
|
|
92
|
+
op = order_mode == :asc ? '<=' : '>='
|
|
93
|
+
if includes_nil && (nil_first? ? order_mode == :asc : order_mode == :desc)
|
|
94
|
+
"(#{column} #{op} #{t_column} OR #{column} IS NULL OR #{t_column} IS NULL)"
|
|
95
|
+
else
|
|
96
|
+
"(#{column} #{op} #{t_column} OR #{t_column} IS NULL)"
|
|
97
|
+
end
|
|
77
98
|
end
|
|
78
99
|
|
|
79
100
|
def self.q(name)
|
|
@@ -84,24 +105,56 @@ module TopNLoader::SQLBuilder
|
|
|
84
105
|
ActiveRecord::Base.connection.quote_table_name name
|
|
85
106
|
end
|
|
86
107
|
|
|
108
|
+
def self.nullable_column?(klass, column)
|
|
109
|
+
klass.column_for_attribute(column).null
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.type_values(values)
|
|
113
|
+
return [nil, values] if sqlite?
|
|
114
|
+
groups = values.group_by { _1.is_a?(Time) || _1.is_a?(DateTime) ? 0 : _1.is_a?(Date) ? 1 : 2 }
|
|
115
|
+
type = groups[0] ? :TIMESTAMP : groups[1] ? :DATE : nil
|
|
116
|
+
[type, groups.sort.flat_map(&:last)]
|
|
117
|
+
end
|
|
118
|
+
|
|
87
119
|
def self.value_table(table, column, values)
|
|
88
|
-
|
|
89
|
-
|
|
120
|
+
type, values = type_values values
|
|
121
|
+
if postgres?
|
|
122
|
+
values_value_table table, column, values, type
|
|
90
123
|
else
|
|
91
|
-
union_value_table
|
|
124
|
+
union_value_table table, column, values, type
|
|
92
125
|
end
|
|
93
126
|
end
|
|
94
127
|
|
|
95
|
-
def self.
|
|
128
|
+
def self.values_table_batch_size
|
|
129
|
+
sqlite? ? 200 : 1000
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.nil_first?
|
|
133
|
+
!postgres?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.adapter_name
|
|
137
|
+
ActiveRecord::Base.connection.adapter_name
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.postgres?
|
|
141
|
+
adapter_name == 'PostgreSQL'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.sqlite?
|
|
145
|
+
adapter_name == 'SQLite'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def self.union_value_table(table, column, values, type)
|
|
96
149
|
sanitize_sql_array [
|
|
97
|
-
"(SELECT ? AS #{column}#{' UNION SELECT ?' * (values.size - 1)}) AS #{table}",
|
|
150
|
+
"(SELECT #{"#{type} " if type}? AS #{column}#{' UNION SELECT ?' * (values.size - 1)}) AS #{table}",
|
|
98
151
|
*values
|
|
99
152
|
]
|
|
100
153
|
end
|
|
101
154
|
|
|
102
|
-
def self.values_value_table(table, column, values)
|
|
155
|
+
def self.values_value_table(table, column, values, type)
|
|
103
156
|
sanitize_sql_array [
|
|
104
|
-
"(VALUES #{
|
|
157
|
+
"(VALUES (#{"#{type} " if type}?) #{', (?)' * (values.size - 1)}) AS #{table} (#{column})",
|
|
105
158
|
*values
|
|
106
159
|
]
|
|
107
160
|
end
|
|
@@ -122,12 +175,12 @@ module TopNLoader::SQLBuilder
|
|
|
122
175
|
sql_binds = begin
|
|
123
176
|
case value
|
|
124
177
|
when NilClass
|
|
125
|
-
|
|
178
|
+
"#{q key} IS NULL"
|
|
126
179
|
when Range
|
|
127
180
|
if value.exclude_end?
|
|
128
|
-
[
|
|
181
|
+
["#{q key} >= ? AND #{q key} < ?", value.begin, value.end]
|
|
129
182
|
else
|
|
130
|
-
[
|
|
183
|
+
["#{q key} BETWEEN ? AND ?", value.begin, value.end]
|
|
131
184
|
end
|
|
132
185
|
when Hash
|
|
133
186
|
raise ArgumentError, '' unless value.keys == [:not]
|
|
@@ -135,12 +188,12 @@ module TopNLoader::SQLBuilder
|
|
|
135
188
|
when Enumerable
|
|
136
189
|
array = value.to_a
|
|
137
190
|
if array.include? nil
|
|
138
|
-
[
|
|
191
|
+
["(#{q key} IS NULL OR #{q key} IN (?))", array.reject(&:nil?)]
|
|
139
192
|
else
|
|
140
|
-
[
|
|
193
|
+
["#{q key} IN (?)", array]
|
|
141
194
|
end
|
|
142
195
|
else
|
|
143
|
-
[
|
|
196
|
+
["#{q key} = ?", value]
|
|
144
197
|
end
|
|
145
198
|
end
|
|
146
199
|
sanitize_sql_array sql_binds
|
data/lib/top_n_loader/version.rb
CHANGED
data/lib/top_n_loader.rb
CHANGED
|
@@ -10,7 +10,7 @@ module TopNLoader
|
|
|
10
10
|
return Hash.new { [] } if ids.empty? || limit.zero?
|
|
11
11
|
klass = base_klass.reflect_on_association(relation.to_sym).klass
|
|
12
12
|
order_option = { limit: limit, **parse_order(klass, order) }
|
|
13
|
-
sql = SQLBuilder.top_n_association_sql base_klass, klass, relation, order_option
|
|
13
|
+
sql = SQLBuilder.top_n_association_sql base_klass, klass, relation, **order_option
|
|
14
14
|
records = klass.find_by_sql([sql, ids])
|
|
15
15
|
format_result(records, klass: klass, **order_option)
|
|
16
16
|
end
|
|
@@ -25,14 +25,18 @@ module TopNLoader
|
|
|
25
25
|
limit: limit,
|
|
26
26
|
**parse_order(klass, order)
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
keys = keys.uniq
|
|
29
|
+
batch_size = keys.size.fdiv(keys.size.fdiv(SQLBuilder.values_table_batch_size).ceil).ceil
|
|
30
|
+
records = keys.each_slice(batch_size).flat_map do |batch_keys|
|
|
31
|
+
klass.find_by_sql(
|
|
32
|
+
SQLBuilder.top_n_group_sql(
|
|
33
|
+
group_keys: batch_keys,
|
|
34
|
+
condition: condition,
|
|
35
|
+
**options
|
|
36
|
+
)
|
|
33
37
|
)
|
|
34
|
-
|
|
35
|
-
format_result records, options
|
|
38
|
+
end
|
|
39
|
+
format_result records, **options
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
private
|
|
@@ -74,7 +78,7 @@ module TopNLoader
|
|
|
74
78
|
existings, blanks = grouped_records.partition { |o| o[order_key] }
|
|
75
79
|
existings.sort_by! { |o| [o[order_key], o[primary_key]] }
|
|
76
80
|
blanks.sort_by! { |o| o[primary_key] }
|
|
77
|
-
ordered = blanks + existings
|
|
81
|
+
ordered = SQLBuilder.nil_first? ? blanks + existings : existings + blanks
|
|
78
82
|
ordered.reverse! if order_mode == :desc
|
|
79
83
|
ordered.take limit
|
|
80
84
|
end
|
data/top_n_loader.gemspec
CHANGED
|
@@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
|
|
11
11
|
spec.summary = %q{load top n records for each group}
|
|
12
12
|
spec.description = %q{load top n records for each group}
|
|
13
|
+
spec.homepage = "https://github.com/tompng/#{spec.name}"
|
|
13
14
|
spec.license = "MIT"
|
|
14
15
|
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -21,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
21
22
|
|
|
22
23
|
spec.add_dependency "activerecord"
|
|
23
24
|
|
|
24
|
-
%w[bundler rake minitest sqlite3
|
|
25
|
+
%w[bundler rake minitest sqlite3 simplecov rubocop rubocop-rubycw].each do |gem_name|
|
|
25
26
|
spec.add_development_dependency gem_name
|
|
26
27
|
end
|
|
27
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: top_n_loader
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tompng
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-07-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -81,7 +81,7 @@ dependencies:
|
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: simplecov
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - ">="
|
|
@@ -95,7 +95,21 @@ dependencies:
|
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
98
|
+
name: rubocop
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rubocop-rubycw
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
100
114
|
requirements:
|
|
101
115
|
- - ">="
|
|
@@ -115,8 +129,9 @@ executables: []
|
|
|
115
129
|
extensions: []
|
|
116
130
|
extra_rdoc_files: []
|
|
117
131
|
files:
|
|
132
|
+
- ".github/workflows/test.yml"
|
|
118
133
|
- ".gitignore"
|
|
119
|
-
- ".
|
|
134
|
+
- ".rubocop.yml"
|
|
120
135
|
- Gemfile
|
|
121
136
|
- Gemfile.lock
|
|
122
137
|
- LICENSE.txt
|
|
@@ -124,15 +139,17 @@ files:
|
|
|
124
139
|
- Rakefile
|
|
125
140
|
- bin/console
|
|
126
141
|
- bin/setup
|
|
142
|
+
- gemfiles/Gemfile-rails-6.0
|
|
143
|
+
- gemfiles/Gemfile-rails-7.0
|
|
127
144
|
- lib/top_n_loader.rb
|
|
128
145
|
- lib/top_n_loader/sql_builder.rb
|
|
129
146
|
- lib/top_n_loader/version.rb
|
|
130
147
|
- top_n_loader.gemspec
|
|
131
|
-
homepage:
|
|
148
|
+
homepage: https://github.com/tompng/top_n_loader
|
|
132
149
|
licenses:
|
|
133
150
|
- MIT
|
|
134
151
|
metadata: {}
|
|
135
|
-
post_install_message:
|
|
152
|
+
post_install_message:
|
|
136
153
|
rdoc_options: []
|
|
137
154
|
require_paths:
|
|
138
155
|
- lib
|
|
@@ -147,8 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
147
164
|
- !ruby/object:Gem::Version
|
|
148
165
|
version: '0'
|
|
149
166
|
requirements: []
|
|
150
|
-
rubygems_version: 3.
|
|
151
|
-
signing_key:
|
|
167
|
+
rubygems_version: 3.3.3
|
|
168
|
+
signing_key:
|
|
152
169
|
specification_version: 4
|
|
153
170
|
summary: load top n records for each group
|
|
154
171
|
test_files: []
|