db_seed_dump 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 12060dc2ff4d43740982f7ba85591a5957be54061b5edb727a9a4b98d0f5eb0a
4
+ data.tar.gz: b82fc9a34b062e6fd4e74589d99c807037c8fb02c22a25613a2fb087672b62b6
5
+ SHA512:
6
+ metadata.gz: 71c7aa7db97b4a637146f3ca9022ff8e1379f0f91ed8096dd0ae9de5df05f971fd63ffec5d81cd49955e8bf5fd10bc52523398485985681a40fb127807444b94
7
+ data.tar.gz: 8ec68dead1f7db5ecc0e842d0f42216be36cfa5a790e29c8f7b8696f0132ab571762e637cb754771e62aaa968f721474db22c747a02ba4c6176288df65dd984c
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.rubocop.yml ADDED
@@ -0,0 +1,92 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-performance
5
+ - rubocop-rspec
6
+
7
+ Layout/LineLength:
8
+ Max: 120
9
+
10
+ Lint/MissingSuper:
11
+ Enabled: false
12
+
13
+ Style/FrozenStringLiteralComment:
14
+ Enabled: false
15
+
16
+ Style/Documentation:
17
+ Enabled: false
18
+
19
+ Style/MixinUsage:
20
+ Exclude:
21
+ - 'bin/setup'
22
+ - 'bin/update'
23
+ - 'db/seeds.rb'
24
+
25
+ Style/NonNilCheck:
26
+ IncludeSemanticChanges: true
27
+
28
+ Style/HashEachMethods:
29
+ Enabled: true
30
+
31
+ Style/HashTransformKeys:
32
+ Enabled: true
33
+
34
+ Style/HashTransformValues:
35
+ Enabled: true
36
+
37
+ Style/HashAsLastArrayItem:
38
+ Enabled: false
39
+
40
+ Metrics/BlockLength:
41
+ Exclude:
42
+ - 'spec/**/*.rb'
43
+ - 'config/environments/**/*.rb'
44
+ - 'config/routes.rb'
45
+ - 'db/seeds.rb'
46
+
47
+ Metrics/MethodLength:
48
+ CountAsOne:
49
+ - array
50
+ - hash
51
+ - heredoc
52
+
53
+ RSpec/MultipleMemoizedHelpers:
54
+ Enabled: false
55
+
56
+ RSpec/MultipleExpectations:
57
+ Enabled: false
58
+
59
+ RSpec/DescribeClass:
60
+ Exclude:
61
+ - 'spec/system/**/*'
62
+ - 'spec/views/**/*'
63
+
64
+ RSpec/AnyInstance:
65
+ Enabled: false
66
+
67
+ RSpec/DescribedClass:
68
+ SkipBlocks: true
69
+
70
+ RSpec/ExampleLength:
71
+ Max: 20
72
+ Exclude:
73
+ - 'spec/system/**/*'
74
+ - 'spec/requests/**/*'
75
+ - 'spec/views/**/*'
76
+
77
+ RSpec/InstanceVariable:
78
+ Exclude:
79
+ - 'spec/views/**/*'
80
+
81
+ RSpec/NestedGroups:
82
+ Max: 5
83
+
84
+ AllCops:
85
+ NewCops: enable
86
+ Exclude:
87
+ - 'bin/**/*'
88
+ - 'db_seed_dump.gemspec'
89
+
90
+ inherit_mode:
91
+ merge:
92
+ - Exclude
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,118 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1000`
3
+ # on 2021-09-23 15:39:08 UTC using RuboCop version 1.21.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'seed_dump.gemspec'
15
+
16
+ # Offense count: 1
17
+ # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches.
18
+ Lint/DuplicateBranch:
19
+ Exclude:
20
+ - 'lib/seed_dump/dump_methods.rb'
21
+
22
+ # Offense count: 3
23
+ Lint/UselessAssignment:
24
+ Exclude:
25
+ - 'lib/seed_dump/dump_methods/enumeration.rb'
26
+ - 'lib/seed_dump/environment.rb'
27
+ - 'spec/dump_methods_spec.rb'
28
+
29
+ # Offense count: 5
30
+ # Configuration parameters: IgnoredMethods, CountRepeatedAttributes, Max.
31
+ Metrics/AbcSize:
32
+ Exclude:
33
+ - 'lib/seed_dump/dump_methods.rb'
34
+ - 'lib/seed_dump/dump_methods/enumeration.rb'
35
+ - 'lib/seed_dump/environment.rb'
36
+ - 'spec/helpers.rb'
37
+
38
+ # Offense count: 1
39
+ # Configuration parameters: IgnoredMethods, Max.
40
+ Metrics/CyclomaticComplexity:
41
+ Exclude:
42
+ - 'lib/seed_dump/dump_methods.rb'
43
+
44
+ # Offense count: 6
45
+ # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
46
+ Metrics/MethodLength:
47
+ Exclude:
48
+ - 'lib/seed_dump/dump_methods.rb'
49
+ - 'lib/seed_dump/dump_methods/enumeration.rb'
50
+ - 'lib/seed_dump/environment.rb'
51
+ - 'spec/helpers.rb'
52
+
53
+ # Offense count: 1
54
+ # Configuration parameters: CountComments, Max, CountAsOne.
55
+ Metrics/ModuleLength:
56
+ Exclude:
57
+ - 'lib/seed_dump/dump_methods.rb'
58
+
59
+ # Offense count: 1
60
+ # Configuration parameters: IgnoredMethods, Max.
61
+ Metrics/PerceivedComplexity:
62
+ Exclude:
63
+ - 'lib/seed_dump/dump_methods.rb'
64
+
65
+ # Offense count: 1
66
+ RSpec/BeforeAfterAll:
67
+ Exclude:
68
+ - 'spec/environment_spec.rb'
69
+
70
+ # Offense count: 6
71
+ # Configuration parameters: Prefixes.
72
+ # Prefixes: when, with, without
73
+ RSpec/ContextWording:
74
+ Exclude:
75
+ - 'spec/dump_methods_spec.rb'
76
+
77
+ # Offense count: 2
78
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
79
+ # Include: **/*_spec*rb*, **/spec/**/*
80
+ RSpec/FilePath:
81
+ Exclude:
82
+ - 'spec/dump_methods_spec.rb'
83
+ - 'spec/environment_spec.rb'
84
+
85
+ # Offense count: 6
86
+ # Configuration parameters: AssignmentOnly.
87
+ RSpec/InstanceVariable:
88
+ Exclude:
89
+ - 'spec/dump_methods_spec.rb'
90
+
91
+ # Offense count: 1
92
+ # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
93
+ RSpec/VerifiedDoubles:
94
+ Exclude:
95
+ - 'spec/environment_spec.rb'
96
+
97
+ # Offense count: 1
98
+ # Configuration parameters: MinBodyLength.
99
+ Style/GuardClause:
100
+ Exclude:
101
+ - 'spec/helpers.rb'
102
+
103
+ # Offense count: 1
104
+ # Cop supports --auto-correct.
105
+ # Configuration parameters: Mode.
106
+ Style/StringConcatenation:
107
+ Exclude:
108
+ - 'lib/seed_dump/dump_methods.rb'
109
+
110
+ # Offense count: 8
111
+ # Cop supports --auto-correct.
112
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
113
+ # URISchemes: http, https
114
+ Layout/LineLength:
115
+ Exclude:
116
+ - 'Rakefile'
117
+ - 'seed_dump.gemspec'
118
+ - 'spec/dump_methods_spec.rb'
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '>= 4'
4
+ gem 'activesupport', '>= 4'
5
+ gem 'rgl'
6
+
7
+ group :development, :test do
8
+ gem 'activerecord-import', '~> 0.4'
9
+ gem 'byebug', '~> 11.0'
10
+ gem 'factory_bot', '~> 4.8.2'
11
+ gem 'rubocop', require: false
12
+ gem 'rubocop-performance', require: false
13
+ gem 'rubocop-rspec', require: false
14
+ end
15
+
16
+ group :development do
17
+ gem 'jeweler', '~> 2.0'
18
+ end
19
+
20
+ group :test do
21
+ gem 'database_cleaner', '~> 1.0'
22
+ gem 'rspec', '~> 3.7.0'
23
+ gem 'sqlite3', '~> 1.0'
24
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2021 Nick Flueckiger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ Seed Dump
2
+ ========
3
+
4
+ Seed Dump is a Rails 4 and 5 plugin that adds a rake task named `db:seed:dump`.
5
+
6
+ It allows you to create seed data files from the existing data in your database.
7
+
8
+ You can also use Seed Dump from the Rails console. See below for usage examples.
9
+
10
+ Installation
11
+ ------------
12
+
13
+ Add it to your Gemfile with:
14
+ ```ruby
15
+ gem 'seed_dump', git: 'git://github.com/renuo/seed_dump', branch: 'master'
16
+ ```
17
+
18
+ Documentation
19
+ -------------
20
+
21
+ This documentation is point to the develop branch of the repository.
22
+ For the documentation of the current release head to: https://github.com/renuo/seed_dump/blob/master/README.md.
23
+
24
+ Examples
25
+ --------
26
+
27
+ ### Rake task
28
+
29
+ Dump all data directly to `db/seeds.rb`:
30
+ ```sh
31
+ $ rake db:seed:dump
32
+ ```
33
+ Result:
34
+ ```ruby
35
+ Product.create!([
36
+ { category_id: 1, description: "Long Sleeve Shirt", name: "Long Sleeve Shirt" },
37
+ { category_id: 3, description: "Plain White Tee Shirt", name: "Plain T-Shirt" }
38
+ ])
39
+ User.create!([
40
+ { password: "123456", username: "test_1" },
41
+ { password: "234567", username: "test_2" }
42
+ ])
43
+ ```
44
+
45
+ Dump only data from the users table and dump a maximum of 1 record:
46
+ ```sh
47
+ $ rake db:seed:dump MODELS=User LIMIT=1
48
+ ```
49
+
50
+ Result:
51
+ ```ruby
52
+ User.create!([
53
+ { password: "123456", username: "test_1" }
54
+ ])
55
+ ```
56
+
57
+ Append to `db/seeds.rb` instead of overwriting it:
58
+ ```sh
59
+ rake db:seed:dump APPEND=true
60
+ ```
61
+
62
+ Use another output file instead of `db/seeds.rb`:
63
+ ```sh
64
+ rake db:seed:dump FILE=db/seeds/users.rb
65
+ ```
66
+
67
+ Exclude `name` and `age` from the dump:
68
+ ```sh
69
+ rake db:seed:dump EXCLUDE=name,age
70
+ ```
71
+
72
+ There are more options that can be set— see below for all of them.
73
+
74
+ ### Console
75
+
76
+ Output a dump of all User records:
77
+ ```ruby
78
+ irb(main):001:0> puts SeedDump.dump(User)
79
+ User.create!([
80
+ { password: "123456", username: "test_1" },
81
+ { password: "234567", username: "test_2" }
82
+ ])
83
+ ```
84
+
85
+ Write the dump to a file:
86
+ ```ruby
87
+ irb(main):002:0> SeedDump.dump(User, file: 'db/seeds.rb')
88
+ ```
89
+
90
+ Append the dump to a file:
91
+ ```ruby
92
+ irb(main):003:0> SeedDump.dump(User, file: 'db/seeds.rb', append: true)
93
+ ```
94
+
95
+ Exclude `name` and `age` from the dump:
96
+ ```ruby
97
+ irb(main):004:0> SeedDump.dump(User, exclude: [:name, :age])
98
+ ```
99
+
100
+ Options are specified as a Hash for the second argument.
101
+
102
+ In the console, any relation of ActiveRecord rows can be dumped (not individual objects though)
103
+ ```ruby
104
+ irb(main):001:0> puts SeedDump.dump(User.where(is_admin: false))
105
+ User.create!([
106
+ { password: "123456", username: "test_1", is_admin: false },
107
+ { password: "234567", username: "test_2", is_admin: false }
108
+ ])
109
+ ```
110
+
111
+ Options
112
+ -------
113
+
114
+ | Option | Values | Usage | Default |
115
+ |-----------------|---------------|----------------------------------------------------------------------------------------------------------------------------|---------------------------------|
116
+ | append | [true, false] | Set if the data should be appended to the file or overwritten | false |
117
+ | batch_size | [Integer] | Number of records written to the file at once. Decrease if you are running out of memory, Increase if too slow | 1000 |
118
+ | limit | [Integer] | Limits the number of entries dumped into the seeds file | no |
119
+ | file | [Path] | Sets the file path for the output seeds file | 'db/seeds.rb' |
120
+ | exclude | [Columns] | Exclude multiple attributes from the dump | [:id, :created_at, :updated_at] |
121
+ | import | [true, false] | Use the format for the [activerecord-import](https://github.com/zdennis/activerecord-import) gem | false |
122
+ | conditions | [] | Dump only specific records to the seeds. Can be set in the console with (e.g. `SeedDump.dump(User.where(state: :active))`) | None |
123
+ | models | [Models] | List of models that should be dumped to the seeds | All Models |
124
+ | models_excluded | [Models] | List of modles that should be excluded from the seeds dump | No Models excluded |
125
+ | insert_all | [true, false] | Set if the data should use insert_all instead of create! in the dump | false |
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = 'db_seed_dump'
8
+ gem.summary = '{Seed Dumper for Rails}'
9
+ gem.description = %{Dump (parts) of your database to db/seeds.rb to get a headstart creating a meaningful seeds.rb file}
10
+ gem.email = 'nick.flueckiger@renuo.ch'
11
+ gem.homepage = 'https://github.com/reno/seed_dump'
12
+ gem.authors = ['Rob Halff', 'Ryan Oblak', 'Nick Flueckiger']
13
+ gem.license = 'MIT'
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
18
+ end
19
+
20
+ require 'rdoc/task'
21
+ Rake::RDocTask.new do |rdoc|
22
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
23
+
24
+ rdoc.rdoc_dir = 'rdoc'
25
+ rdoc.title = "db_seed_dump #{version}"
26
+ rdoc.rdoc_files.include('README*')
27
+ rdoc.rdoc_files.include('lib/**/*.rb')
28
+ end
29
+
30
+ require 'rspec/core/rake_task'
31
+ RSpec::Core::RakeTask.new(:spec)
32
+ task default: :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/bin/fastcheck ADDED
@@ -0,0 +1 @@
1
+ bundle exec rubocop
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: db_seed_dump 1.0.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "db_seed_dump".freeze
9
+ s.version = "1.0.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Rob Halff".freeze, "Ryan Oblak".freeze, "Nick Flueckiger".freeze]
14
+ s.date = "2021-10-02"
15
+ s.description = "Dump (parts) of your database to db/seeds.rb to get a headstart creating a meaningful seeds.rb file".freeze
16
+ s.email = "nick.flueckiger@renuo.ch".freeze
17
+ s.executables = ["fastcheck".freeze]
18
+ s.extra_rdoc_files = [
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".rspec",
23
+ ".rubocop.yml",
24
+ ".rubocop_todo.yml",
25
+ "Gemfile",
26
+ "MIT-LICENSE",
27
+ "README.md",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "bin/fastcheck",
31
+ "db_seed_dump.gemspec",
32
+ "lib/seed_dump.rb",
33
+ "lib/seed_dump/dependency_unwrangler.rb",
34
+ "lib/seed_dump/dump_methods.rb",
35
+ "lib/seed_dump/dump_methods/enumeration.rb",
36
+ "lib/seed_dump/environment.rb",
37
+ "lib/seed_dump/railtie.rb",
38
+ "lib/tasks/seed_dump.rake",
39
+ "spec/dump_methods_spec.rb",
40
+ "spec/environment_spec.rb",
41
+ "spec/factories/another_samples.rb",
42
+ "spec/factories/samples.rb",
43
+ "spec/factories/yet_another_samples.rb",
44
+ "spec/helpers.rb",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = "https://github.com/reno/seed_dump".freeze
48
+ s.licenses = ["MIT".freeze]
49
+ s.rubygems_version = "3.2.22".freeze
50
+ s.summary = "{Seed Dumper for Rails}".freeze
51
+
52
+ if s.respond_to? :specification_version then
53
+ s.specification_version = 4
54
+ end
55
+
56
+ if s.respond_to? :add_runtime_dependency then
57
+ s.add_runtime_dependency(%q<activerecord>.freeze, [">= 4"])
58
+ s.add_runtime_dependency(%q<activesupport>.freeze, [">= 4"])
59
+ s.add_runtime_dependency(%q<rgl>.freeze, [">= 0"])
60
+ s.add_development_dependency(%q<activerecord-import>.freeze, ["~> 0.4"])
61
+ s.add_development_dependency(%q<byebug>.freeze, ["~> 11.0"])
62
+ s.add_development_dependency(%q<factory_bot>.freeze, ["~> 4.8.2"])
63
+ s.add_development_dependency(%q<rubocop>.freeze, [">= 0"])
64
+ s.add_development_dependency(%q<rubocop-performance>.freeze, [">= 0"])
65
+ s.add_development_dependency(%q<rubocop-rspec>.freeze, [">= 0"])
66
+ s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.0"])
67
+ else
68
+ s.add_dependency(%q<activerecord>.freeze, [">= 4"])
69
+ s.add_dependency(%q<activesupport>.freeze, [">= 4"])
70
+ s.add_dependency(%q<rgl>.freeze, [">= 0"])
71
+ s.add_dependency(%q<activerecord-import>.freeze, ["~> 0.4"])
72
+ s.add_dependency(%q<byebug>.freeze, ["~> 11.0"])
73
+ s.add_dependency(%q<factory_bot>.freeze, ["~> 4.8.2"])
74
+ s.add_dependency(%q<rubocop>.freeze, [">= 0"])
75
+ s.add_dependency(%q<rubocop-performance>.freeze, [">= 0"])
76
+ s.add_dependency(%q<rubocop-rspec>.freeze, [">= 0"])
77
+ s.add_dependency(%q<jeweler>.freeze, ["~> 2.0"])
78
+ end
79
+ end
80
+
@@ -0,0 +1,51 @@
1
+ require 'rgl/adjacency'
2
+ require 'rgl/topsort'
3
+
4
+ class SeedDump
5
+ class DependencyUnwrangler
6
+ def initialize(models)
7
+ @models = models
8
+ @graph = RGL::DirectedAdjacencyGraph.new
9
+ @evaluation_order = []
10
+ end
11
+
12
+ def evaluation_order
13
+ return [] if @models.empty?
14
+ return @evaluation_order unless @evaluation_order.empty?
15
+
16
+ build_graph unless graph_built?
17
+
18
+ @evaluation_order = @graph.topsort_iterator.to_a.reverse
19
+ @evaluation_order
20
+ end
21
+
22
+ private
23
+
24
+ def build_graph
25
+ @models.map do |model|
26
+ referents_by_model(model).each do |referent|
27
+ @graph.add_edge(model, referent)
28
+ end
29
+ end
30
+ end
31
+
32
+ def graph_built?
33
+ !@graph.edges.empty? && !@graph.vertices.empty?
34
+ end
35
+
36
+ def referents_by_model(model)
37
+ associations = model.reflect_on_all_associations(:belongs_to)
38
+ associations.map do |association|
39
+ association.options[:polymorphic] ? collect_polymorphic_deps(association) : association.klass
40
+ end.flatten
41
+ end
42
+
43
+ def collect_polymorphic_deps(association)
44
+ ActiveRecord::Base.descendants.select do |other_model|
45
+ other_model.reflect_on_all_associations(:has_many).any? do |has_many_association|
46
+ has_many_association.options[:as] == association.name
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,86 @@
1
+ class SeedDump
2
+ module DumpMethods
3
+ module Enumeration
4
+ def active_record_enumeration(records, _io, options)
5
+ # If the records don't already have an order,
6
+ # order them by primary key ascending.
7
+ if !records.respond_to?(:arel) || records.arel.orders.blank?
8
+ records.order("#{records.quoted_table_name}.#{records.quoted_primary_key} ASC")
9
+ end
10
+
11
+ num_of_batches, batch_size, last_batch_size = batch_params_from(records, options)
12
+
13
+ processed_entities = 0
14
+ # Loop through each batch
15
+ (1..num_of_batches).each do |batch_number|
16
+ record_strings = []
17
+
18
+ last_batch = (batch_number == num_of_batches)
19
+
20
+ cur_batch_size = if last_batch
21
+ last_batch_size
22
+ else
23
+ batch_size
24
+ end
25
+
26
+ processed_entities += cur_batch_size
27
+
28
+ # Loop through the records of the current batch
29
+ records.offset((batch_number - 1) * batch_size).limit(cur_batch_size).each do |record|
30
+ record_strings << dump_record(record, options)
31
+ end
32
+
33
+ should_split_file = split_file?(processed_entities, options)
34
+ processed_entities -= options[:file_split_limit] if should_split_file
35
+
36
+ yield record_strings, last_batch, should_split_file
37
+ end
38
+ end
39
+
40
+ def split_file?(processed_entities, options)
41
+ return false if options[:file_split_limit].nil?
42
+
43
+ (processed_entities / file_index_from(options)) >= options[:file_split_limit]
44
+ end
45
+
46
+ def enumerable_enumeration(records, _io, options)
47
+ num_of_batches, batch_size = batch_params_from(records, options)
48
+
49
+ record_strings = []
50
+
51
+ batch_number = 1
52
+
53
+ records.each_with_index do |record, i|
54
+ record_strings << dump_record(record, options)
55
+
56
+ last_batch = (i == records.length - 1)
57
+
58
+ next unless (record_strings.length == batch_size) || last_batch
59
+
60
+ yield record_strings, last_batch
61
+
62
+ record_strings = []
63
+ batch_number += 1
64
+ end
65
+ end
66
+
67
+ def batch_params_from(records, options)
68
+ batch_size = batch_size_from(options)
69
+
70
+ count = records.count
71
+
72
+ remainder = count % batch_size
73
+
74
+ [(count.to_f / batch_size).ceil, batch_size, (remainder.zero? ? batch_size : remainder)]
75
+ end
76
+
77
+ def batch_size_from(options)
78
+ options[:batch_size]&.to_i || 1000
79
+ end
80
+
81
+ def file_index_from(options)
82
+ options[:current_file_index]&.to_i || 1
83
+ end
84
+ end
85
+ end
86
+ end