deep_preloader 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92fe99d9c1c0a4b426c9827491057c3604e5b511c61c749701de5c65da7d4825
4
- data.tar.gz: efab30b69e968a8a6f45e000da724189808a91dfedb6279930daeb0058ab3557
3
+ metadata.gz: a4d52fcac4fc5b9b0768ecb6dd0c9db5e8ddee7f0ae8d9475ca3364fceb38b9b
4
+ data.tar.gz: a41e279ad07e928fdb36a55c3ba33cacc0e3d4137bc09863b234f5b6ca7be256
5
5
  SHA512:
6
- metadata.gz: 4fed23d8d1df1c47f8665298594adf7741243551f207462eabd74e64e86ead26a977ec39df17d791c0c88f09b22e1958d6120b65820c14b51b313b0cc29e0d7c
7
- data.tar.gz: a94f34a7290e83b7f26cbbcdba8ad51445bfd9f1474e2d9ba8f01449196b51a8e44789c8d81114c91a7e647af194331002fe1a1e48c9dedcfab1999ef9fdfc16
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
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  gemfiles/*.gemfile.lock
11
+ /nix/gem
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rspec_junit_formatter"
6
- gem "activerecord", "~> 6.0.0.beta"
6
+ gem "activerecord", "~> 6.1.0"
7
7
 
8
8
  gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rspec_junit_formatter"
6
+ gem "activerecord", "~> 7.0.0"
7
+
8
+ gemspec path: "../"
@@ -2,4 +2,8 @@ class DeepPreloader::AbstractSpec
2
2
  def for_type(clazz)
3
3
  raise ArgumentError.new("Cannot type dispatch on non-polymorphic preload spec #{self.inspect}")
4
4
  end
5
+
6
+ def polymorphic?
7
+ false
8
+ end
5
9
  end
@@ -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)
@@ -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.to_sym] = parse(v)
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.to_sym => nil })
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)
@@ -1,3 +1,3 @@
1
1
  class DeepPreloader
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -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
- models_by_class = Array.wrap(models).group_by(&:class)
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, model_class, spec)
44
- spec.association_specs.each do |association_name, child_spec|
45
- association_reflection = model_class.reflect_on_association(association_name)
46
- if association_reflection.nil?
47
- raise ArgumentError.new("Preloading error: couldn't find association #{association_name} on model class #{model_class.name}")
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
- if association_reflection.polymorphic?
51
- add_polymorphic_association(models, association_reflection, child_spec)
52
- else
53
- add_association(models, association_reflection, child_spec)
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(@worklist.present?)
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("Internal preloader error: attempted to attach multiple children to a singular association")
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
@@ -0,0 +1,11 @@
1
+ with (import <nixpkgs> {});
2
+ let
3
+ env = bundlerEnv {
4
+ name = "bundler-env";
5
+ gemdir = ./nix/gem;
6
+ ruby = ruby_3_0;
7
+ };
8
+ in stdenv.mkDerivation {
9
+ name = "shell";
10
+ buildInputs = [ env ];
11
+ }
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.1
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: 2019-05-21 00:00:00.000000000 Z
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
- - ".circleci/config.yml"
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/activerecord_6_0_beta.gemfile
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.0.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: /.*/