deep_preloader 1.0.1 → 1.1.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 +4 -4
- data/.github/workflows/gem-push.yml +31 -0
- data/.github/workflows/test.yml +50 -0
- data/.gitignore +1 -0
- data/gemfiles/{activerecord_6_0_beta.gemfile → activerecord_6_1.gemfile} +1 -1
- data/gemfiles/activerecord_7_0.gemfile +8 -0
- data/lib/deep_preloader/abstract_spec.rb +4 -0
- data/lib/deep_preloader/polymorphic_spec.rb +5 -1
- data/lib/deep_preloader/spec.rb +3 -3
- data/lib/deep_preloader/version.rb +1 -1
- data/lib/deep_preloader.rb +41 -34
- data/nix/generate.rb +42 -0
- data/shell.nix +11 -0
- metadata +9 -5
- data/.circleci/config.yml +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4d52fcac4fc5b9b0768ecb6dd0c9db5e8ddee7f0ae8d9475ca3364fceb38b9b
|
4
|
+
data.tar.gz: a41e279ad07e928fdb36a55c3ba33cacc0e3d4137bc09863b234f5b6ca7be256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 400bfd0eb4d794f3d1b1074e422788a27114dfd8d606dbc8334a08c8cfb31e02e39e55bc02cd13132419238c2d09921a73f8f8ad989b40244d4504dccc3a00c7
|
7
|
+
data.tar.gz: 1eb00d062a73b0d5d8ae94451ee638db04f616f9c535c5154f4db855d048d16604ea129620f0f81708980933c83b845a309bc0a1eb7df1aa54ea74c8f001a9a9
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Publish Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "master" ]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Build + Publish
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
contents: read
|
13
|
+
packages: write
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v3
|
17
|
+
- name: Set up Ruby 2.7
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.7
|
21
|
+
|
22
|
+
- name: Publish to RubyGems
|
23
|
+
run: |
|
24
|
+
mkdir -p $HOME/.gem
|
25
|
+
touch $HOME/.gem/credentials
|
26
|
+
chmod 0600 $HOME/.gem/credentials
|
27
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
28
|
+
gem build *.gemspec
|
29
|
+
gem push *.gem
|
30
|
+
env:
|
31
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
name: Run Tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches: "**"
|
6
|
+
|
7
|
+
permissions:
|
8
|
+
contents: read
|
9
|
+
checks: write
|
10
|
+
pull-requests: write
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby-version: ['2.7', '3.1', '3.2']
|
20
|
+
include:
|
21
|
+
- ruby-version: '2.7'
|
22
|
+
bundle-gemfile: gemfiles/activerecord_5_2.gemfile
|
23
|
+
- ruby-version: '3.1'
|
24
|
+
bundle-gemfile: gemfiles/activerecord_6_1.gemfile
|
25
|
+
- ruby-version: '3.2'
|
26
|
+
bundle-gemfile: gemfiles/activerecord_7_0.gemfile
|
27
|
+
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
|
28
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.bundle-gemfile }}
|
29
|
+
steps:
|
30
|
+
- uses: actions/checkout@v3
|
31
|
+
- name: Set up Ruby
|
32
|
+
uses: ruby/setup-ruby@v1
|
33
|
+
with:
|
34
|
+
ruby-version: ${{ matrix.ruby-version }}
|
35
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
36
|
+
- name: Run tests
|
37
|
+
run: bundle exec rspec --profile 10 --format RspecJunitFormatter --out test_results/rspec.xml --format progress
|
38
|
+
- name: Upload result
|
39
|
+
uses: actions/upload-artifact@v3
|
40
|
+
if: always()
|
41
|
+
with:
|
42
|
+
name: rspec_${{ matrix.ruby-version }}.xml
|
43
|
+
path: test_results/rspec.xml
|
44
|
+
- name: Test Report
|
45
|
+
uses: dorny/test-reporter@v1
|
46
|
+
if: always()
|
47
|
+
with:
|
48
|
+
name: Rspec Tests - ${{ matrix.ruby-version }}
|
49
|
+
path: test_results/rspec.xml
|
50
|
+
reporter: java-junit
|
data/.gitignore
CHANGED
@@ -15,7 +15,11 @@ class DeepPreloader::PolymorphicSpec < DeepPreloader::AbstractSpec
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(specs_by_type = {})
|
18
|
-
@specs_by_type = specs_by_type
|
18
|
+
@specs_by_type = specs_by_type.transform_keys(&:to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
def polymorphic?
|
22
|
+
true
|
19
23
|
end
|
20
24
|
|
21
25
|
def for_type(clazz)
|
data/lib/deep_preloader/spec.rb
CHANGED
@@ -11,11 +11,11 @@ class DeepPreloader::Spec < DeepPreloader::AbstractSpec
|
|
11
11
|
end
|
12
12
|
when Hash
|
13
13
|
assoc_specs = data.each_with_object({}) do |(k, v), h|
|
14
|
-
h[k.
|
14
|
+
h[k.to_s] = parse(v)
|
15
15
|
end
|
16
16
|
self.new(assoc_specs)
|
17
17
|
when String, Symbol
|
18
|
-
self.new({ data.
|
18
|
+
self.new({ data.to_s => nil })
|
19
19
|
when DeepPreloader::AbstractSpec
|
20
20
|
data
|
21
21
|
when nil
|
@@ -26,7 +26,7 @@ class DeepPreloader::Spec < DeepPreloader::AbstractSpec
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def initialize(association_specs = {})
|
29
|
-
@association_specs = association_specs
|
29
|
+
@association_specs = association_specs.transform_keys(&:to_s)
|
30
30
|
end
|
31
31
|
|
32
32
|
def merge!(other)
|
data/lib/deep_preloader.rb
CHANGED
@@ -12,23 +12,7 @@ class DeepPreloader
|
|
12
12
|
worker = PreloadWorker.new(lock: lock)
|
13
13
|
spec = Spec.parse(spec) unless spec.is_a?(AbstractSpec)
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
case spec
|
18
|
-
when Spec
|
19
|
-
unless models_by_class.size == 1
|
20
|
-
raise ArgumentError.new("Provided multiple model types to non-polymorphic preload spec")
|
21
|
-
end
|
22
|
-
|
23
|
-
model_class, models = models_by_class.first
|
24
|
-
worker.add_associations_from_spec(models, model_class, spec)
|
25
|
-
when PolymorphicSpec
|
26
|
-
models_by_class.each do |model_class, models|
|
27
|
-
model_spec = spec.for_type(model_class)
|
28
|
-
next unless model_spec
|
29
|
-
worker.add_associations_from_spec(models, model_class, model_spec)
|
30
|
-
end
|
31
|
-
end
|
15
|
+
worker.add_associations_from_spec(models, spec)
|
32
16
|
|
33
17
|
worker.run!
|
34
18
|
models
|
@@ -40,23 +24,49 @@ class DeepPreloader
|
|
40
24
|
@worklist = {}
|
41
25
|
end
|
42
26
|
|
43
|
-
def add_associations_from_spec(models,
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
27
|
+
def add_associations_from_spec(models, spec)
|
28
|
+
models = Array.wrap(models)
|
29
|
+
|
30
|
+
# A polymorphic spec expects models of several types, and defines which
|
31
|
+
# associations to preload for each of them.
|
32
|
+
if spec.polymorphic?
|
33
|
+
# We expect models to be of different types, and to have different subspecs for each.
|
34
|
+
models_by_class = models.group_by(&:class)
|
35
|
+
|
36
|
+
models_by_class.each do |model_class, class_models|
|
37
|
+
model_spec = spec.for_type(model_class)
|
38
|
+
next unless model_spec
|
39
|
+
|
40
|
+
add_associations_from_spec(class_models, model_spec)
|
48
41
|
end
|
42
|
+
else
|
43
|
+
# A non-polymorphic spec implies that the models are all of the same type
|
44
|
+
model_class = models.first.class
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
unless models.all? { |m| m.is_a?(model_class) }
|
47
|
+
raise ArgumentError.new('Provided multiple model types to a non-polymorphic preload spec')
|
48
|
+
end
|
49
|
+
|
50
|
+
spec.association_specs.each do |association_name, child_spec|
|
51
|
+
association_reflection = model_class.reflect_on_association(association_name)
|
52
|
+
if association_reflection.nil?
|
53
|
+
raise ArgumentError.new("Preloading error: couldn't find association #{association_name} on model class #{model_class.name}")
|
54
|
+
end
|
55
|
+
|
56
|
+
# A polymorphic association links to many different model types
|
57
|
+
# (discriminated in the referrer), so must be loaded separately per
|
58
|
+
# target model type.
|
59
|
+
if association_reflection.polymorphic?
|
60
|
+
add_polymorphic_association(models, association_reflection, child_spec)
|
61
|
+
else
|
62
|
+
add_association(models, association_reflection, child_spec)
|
63
|
+
end
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
58
68
|
def run!
|
59
|
-
while
|
69
|
+
while @worklist.present?
|
60
70
|
context, entries = @worklist.shift
|
61
71
|
ActiveRecord::Base.logger&.debug("Preloading children in context #{context}") if DEBUG
|
62
72
|
|
@@ -96,12 +106,10 @@ class DeepPreloader
|
|
96
106
|
children = entry.children
|
97
107
|
child_spec = entry.child_spec
|
98
108
|
next unless child_spec && children.present?
|
99
|
-
child_class = children.first.class # children of a given parent are all of the same type
|
100
|
-
add_associations_from_spec(children, child_class, child_spec)
|
101
|
-
end
|
102
109
|
|
110
|
+
add_associations_from_spec(children, child_spec)
|
111
|
+
end
|
103
112
|
end
|
104
|
-
|
105
113
|
end
|
106
114
|
|
107
115
|
private
|
@@ -242,8 +250,9 @@ class DeepPreloader
|
|
242
250
|
target = targets
|
243
251
|
else
|
244
252
|
if targets.size > 1
|
245
|
-
raise RuntimeError.new(
|
253
|
+
raise RuntimeError.new('Internal preloader error: attempted to attach multiple children to a singular association')
|
246
254
|
end
|
255
|
+
|
247
256
|
target = targets.first
|
248
257
|
end
|
249
258
|
|
@@ -253,7 +262,6 @@ class DeepPreloader
|
|
253
262
|
association.loaded!
|
254
263
|
association.target = target
|
255
264
|
targets.each { |t| association.set_inverse_instance(t) }
|
256
|
-
targets
|
257
265
|
end
|
258
266
|
|
259
267
|
def parent_key_column
|
@@ -267,5 +275,4 @@ class DeepPreloader
|
|
267
275
|
end
|
268
276
|
end
|
269
277
|
end
|
270
|
-
|
271
278
|
end
|
data/nix/generate.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#! /usr/bin/env nix-shell
|
2
|
+
#! nix-shell -i ruby -p ruby -p bundler -p bundix
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# Bundix doesn't support `gemspec` directive in Gemfiles, as it doesn't copy the
|
6
|
+
# gemspec (and its dependencies) into the store.
|
7
|
+
# This workaround is from https://github.com/manveru/bundix/issues/10#issuecomment-405879379
|
8
|
+
|
9
|
+
require 'shellwords'
|
10
|
+
require 'uri'
|
11
|
+
|
12
|
+
def sh(*args)
|
13
|
+
warn args.shelljoin
|
14
|
+
system(*args) || raise
|
15
|
+
end
|
16
|
+
|
17
|
+
sh 'bundle', 'lock'
|
18
|
+
|
19
|
+
require 'fileutils'
|
20
|
+
require 'bundler'
|
21
|
+
|
22
|
+
lockfile = Bundler::LockfileParser.new(File.read('Gemfile.lock'))
|
23
|
+
gems = lockfile.specs.select { |spec| spec.source.is_a?(Bundler::Source::Rubygems) }
|
24
|
+
sources = [URI('https://rubygems.org/')] | gems.map(&:source).flat_map(&:remotes)
|
25
|
+
|
26
|
+
FileUtils.mkdir_p 'nix/gem'
|
27
|
+
Dir.chdir 'nix/gem' do
|
28
|
+
['Gemfile', 'Gemfile.lock', 'gemset.nix'].each do |f|
|
29
|
+
File.delete(f) if File.exist?(f)
|
30
|
+
end
|
31
|
+
|
32
|
+
File.open('Gemfile', 'w') do |gemfile|
|
33
|
+
sources.each { |source| gemfile.puts "source #{source.to_s.inspect}" }
|
34
|
+
gemfile.puts
|
35
|
+
|
36
|
+
gems.each do |gem|
|
37
|
+
gemfile.puts "gem #{gem.name.inspect}, #{gem.version.to_s.inspect}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
sh 'bundix', '-l'
|
42
|
+
end
|
data/shell.nix
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep_preloader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iKnow Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -171,7 +171,8 @@ executables: []
|
|
171
171
|
extensions: []
|
172
172
|
extra_rdoc_files: []
|
173
173
|
files:
|
174
|
-
- ".
|
174
|
+
- ".github/workflows/gem-push.yml"
|
175
|
+
- ".github/workflows/test.yml"
|
175
176
|
- ".gitignore"
|
176
177
|
- ".rspec"
|
177
178
|
- ".travis.yml"
|
@@ -184,12 +185,15 @@ files:
|
|
184
185
|
- bin/setup
|
185
186
|
- deep_preloader.gemspec
|
186
187
|
- gemfiles/activerecord_5_2.gemfile
|
187
|
-
- gemfiles/
|
188
|
+
- gemfiles/activerecord_6_1.gemfile
|
189
|
+
- gemfiles/activerecord_7_0.gemfile
|
188
190
|
- lib/deep_preloader.rb
|
189
191
|
- lib/deep_preloader/abstract_spec.rb
|
190
192
|
- lib/deep_preloader/polymorphic_spec.rb
|
191
193
|
- lib/deep_preloader/spec.rb
|
192
194
|
- lib/deep_preloader/version.rb
|
195
|
+
- nix/generate.rb
|
196
|
+
- shell.nix
|
193
197
|
homepage: http://github.com/iknow/deep_preloader
|
194
198
|
licenses:
|
195
199
|
- MIT
|
@@ -209,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
213
|
- !ruby/object:Gem::Version
|
210
214
|
version: '0'
|
211
215
|
requirements: []
|
212
|
-
rubygems_version: 3.
|
216
|
+
rubygems_version: 3.1.6
|
213
217
|
signing_key:
|
214
218
|
specification_version: 4
|
215
219
|
summary: Explicit preloader for ActiveRecord
|
data/.circleci/config.yml
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
version: 2.1
|
2
|
-
|
3
|
-
executors:
|
4
|
-
ruby:
|
5
|
-
parameters:
|
6
|
-
ruby-version:
|
7
|
-
type: string
|
8
|
-
default: "2.6"
|
9
|
-
gemfile:
|
10
|
-
type: string
|
11
|
-
default: "Gemfile"
|
12
|
-
docker:
|
13
|
-
- image: circleci/ruby:<< parameters.ruby-version >>
|
14
|
-
environment:
|
15
|
-
BUNDLE_JOBS: 3
|
16
|
-
BUNDLE_RETRY: 3
|
17
|
-
BUNDLE_PATH: vendor/bundle
|
18
|
-
RAILS_ENV: test
|
19
|
-
BUNDLE_GEMFILE: << parameters.gemfile >>
|
20
|
-
|
21
|
-
jobs:
|
22
|
-
test:
|
23
|
-
parameters:
|
24
|
-
ruby-version:
|
25
|
-
type: string
|
26
|
-
gemfile:
|
27
|
-
type: string
|
28
|
-
executor:
|
29
|
-
name: ruby
|
30
|
-
ruby-version: << parameters.ruby-version >>
|
31
|
-
gemfile: << parameters.gemfile >>
|
32
|
-
parallelism: 1
|
33
|
-
steps:
|
34
|
-
- checkout
|
35
|
-
|
36
|
-
- run:
|
37
|
-
# Remove the non-appraisal gemfile for safety: we never want to use it.
|
38
|
-
name: Prepare bundler
|
39
|
-
command: bundle -v
|
40
|
-
|
41
|
-
- run:
|
42
|
-
name: Compute a gemfile lock
|
43
|
-
command: bundle lock && cp "${BUNDLE_GEMFILE}.lock" /tmp/gem-lock
|
44
|
-
|
45
|
-
- restore_cache:
|
46
|
-
keys:
|
47
|
-
- deep_preloader-<< parameters.ruby-version >>-{{ checksum "/tmp/gem-lock" }}
|
48
|
-
- deep_preloader-
|
49
|
-
|
50
|
-
- run:
|
51
|
-
name: Bundle Install
|
52
|
-
command: bundle check || bundle install
|
53
|
-
|
54
|
-
- save_cache:
|
55
|
-
key: deep_preloader-<< parameters.ruby-version >>-{{ checksum "/tmp/gem-lock" }}
|
56
|
-
paths:
|
57
|
-
- vendor/bundle
|
58
|
-
|
59
|
-
- run:
|
60
|
-
name: Run rspec
|
61
|
-
command: bundle exec rspec --profile 10 --format RspecJunitFormatter --out test_results/rspec.xml --format progress
|
62
|
-
|
63
|
-
- store_test_results:
|
64
|
-
path: test_results
|
65
|
-
|
66
|
-
publish:
|
67
|
-
executor: ruby
|
68
|
-
steps:
|
69
|
-
- checkout
|
70
|
-
- run:
|
71
|
-
name: Setup Rubygems
|
72
|
-
command: |
|
73
|
-
mkdir ~/.gem &&
|
74
|
-
echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials &&
|
75
|
-
chmod 0600 ~/.gem/credentials
|
76
|
-
- run:
|
77
|
-
name: Publish to Rubygems
|
78
|
-
command: |
|
79
|
-
gem build deep_preloader.gemspec
|
80
|
-
gem push deep_preloader-*.gem
|
81
|
-
|
82
|
-
workflows:
|
83
|
-
version: 2.1
|
84
|
-
build:
|
85
|
-
jobs:
|
86
|
-
- test:
|
87
|
-
name: 'ruby 2.5 ActiveRecord 5.2'
|
88
|
-
ruby-version: "2.5"
|
89
|
-
gemfile: gemfiles/activerecord_5_2.gemfile
|
90
|
-
- test:
|
91
|
-
name: 'ruby 2.6 ActiveRecord 5.2'
|
92
|
-
ruby-version: "2.6"
|
93
|
-
gemfile: gemfiles/activerecord_5_2.gemfile
|
94
|
-
- test:
|
95
|
-
name: 'ruby 2.6 ActiveRecord 6.0-beta'
|
96
|
-
ruby-version: "2.6"
|
97
|
-
gemfile: gemfiles/activerecord_6_0_beta.gemfile
|
98
|
-
- publish:
|
99
|
-
filters:
|
100
|
-
branches:
|
101
|
-
only: master
|
102
|
-
tags:
|
103
|
-
ignore: /.*/
|