better_seeder 0.2.2.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58577f255f87b959dca2b8d422ebf59f8a450ac857b05e5b9b46af1cfcd4fc9e
4
- data.tar.gz: 6c4022a220f744d03209ec5ce45c6344f328e2dbe1c46b9a7e6ae9ca323133f1
3
+ metadata.gz: 20203d64e75c796bd405cb5caaabeb697ee4cd64b2a21770cc2703efaaedf815
4
+ data.tar.gz: 8b218cd82cc8950284fa4fe0468443481760e092161c9a96f9ea2b0ae9974c28
5
5
  SHA512:
6
- metadata.gz: 8f322c8907aa1db395c3a231823080c50d4825f63f1d89d8dfa52784d0e686fa064b6c57cf8c6fafc830fc650741ca8853c7fb6c45fb248ef31b16c0f94de972
7
- data.tar.gz: c9d8b6d14f21db93507ac0a5b856dd832f367fe6aab97043cf7dcb6310043b37fd79ca4a6e86a6a2a2b7368c250f0ccebb0e7e797153d06a1e5687efc2a72130
6
+ metadata.gz: f193936be5c4bb4416bc27b2cdbb869c10c8dbe4a8d3046d63cc0ffd1af4e31edd7e0e613ab1828913df5a64fd225523211a158662b783491022a2109233ccb4
7
+ data.tar.gz: 806324afb167aa6376f8c5dbf5fbe13083f4bcc9ec1e89c8bcbb46b021f5c29b27318580b63e2dacc42d4bfb3bf54d22afde05142acecd6a49aee82a23c561ae
@@ -2,15 +2,17 @@
2
2
 
3
3
  module BetterSeeder
4
4
  class Configuration
5
- attr_accessor :log_language, :structure_path, :preload_path
5
+ attr_accessor :log_language, :log_level, :structure_path, :preload_path
6
6
 
7
7
  def initialize
8
8
  if defined?(Rails) && Rails.respond_to?(:root)
9
9
  @log_language = :en
10
+ @log_level = :info
10
11
  @structure_path = Rails.root.join('db', 'seed', 'structure')
11
12
  @preload_path = Rails.root.join('db', 'seed', 'preload')
12
13
  else
13
14
  @log_language = :en
15
+ @log_level = :info
14
16
  @structure_path = File.join(Dir.pwd, 'db', 'seed', 'structure')
15
17
  @preload_path = File.join(Dir.pwd, 'db', 'seed', 'preload')
16
18
  end
@@ -1,116 +1,133 @@
1
1
  module BetterSeeder
2
2
  module Farms
3
3
  class Farmer
4
- # Genera dati fittizi per il modello specificato utilizzando il file di structure.
5
- #
6
- # Opzioni attese (Hash):
7
- # :model => Nome del modello come stringa, es. 'Media::Participant'
8
- # :count => Numero di record da generare (default: 10)
9
- #
10
- # Se la classe di structure definisce il metodo `unique_keys` (che deve restituire un array di array,
11
- # es. [[:media_id, :creator_id], [:role]]), verrà controllato che ogni record generato sia univoco,
12
- # sia in memoria (tra quelli generati in questa esecuzione) che rispetto ai dati già presenti nel database.
13
- # Se il record è duplicato, verrà rigenerato.
14
- #
15
- # Se la classe di structure definisce il metodo `seed_schema`, il record verrà validato tramite Dry-schema.
16
- #
17
- # @return [Array<Hash>] Array di record validati e univoci generati
18
- def self.generate(options = {})
19
- model_name = options[:model] or raise ArgumentError, "Missing :model option"
20
- count = options[:count] || 10
21
-
22
- # Costruisce il percorso del file di structure.
23
- # Ad esempio, per il modello "Media::Participant", il file atteso sarà:
24
- # "db/seed/structure/media/participant_structure.rb"
25
- structure_file = File.expand_path(
26
- File.join(BetterSeeder.configuration.structure_path, "#{model_name.underscore}_structure.rb"),
27
- Dir.pwd
28
- )
29
- raise "Structure file not found: #{structure_file}" unless File.exist?(structure_file)
30
-
31
- # Carica il file di structure.
32
- load structure_file
33
-
34
- # Costruisce il nome della classe di structure: semplice concatenazione.
35
- # Es: "Media::Participant" => "Media::ParticipantStructure"
36
- structure_class_name = "#{model_name}Structure"
37
- begin
38
- structure_class = Object.const_get(structure_class_name)
39
- rescue error
40
- message = "Structure class not found: #{structure_class_name}"
41
- BetterSeeder::Utils.logger(message: message)
42
- raise error
4
+
5
+ class << self
6
+ def generate(options = {})
7
+ model_name = options[:model] or raise ArgumentError, "Missing :model option"
8
+ count = options[:count] || 10
9
+
10
+ # Costruisce il percorso del file di structure.
11
+ structure_file = File.expand_path(
12
+ File.join(BetterSeeder.configuration.structure_path, "#{model_name.underscore}_structure.rb"),
13
+ Dir.pwd
14
+ )
15
+ raise "Structure file not found: #{structure_file}" unless File.exist?(structure_file)
16
+
17
+ # Carica il file di structure.
18
+ load structure_file
19
+
20
+ # Costruisce il nome della classe di structure: es. "Media::Participant" => "Media::ParticipantStructure"
21
+ structure_class_name = "#{model_name}Structure"
22
+ begin
23
+ structure_class = Object.const_get(structure_class_name)
24
+ rescue error
25
+ message = "Structure class not found: #{structure_class_name}"
26
+ BetterSeeder::Utils.logger(message: message)
27
+ raise error
28
+ end
29
+
30
+ generated_records = []
31
+
32
+ while generated_records.size < count
33
+ new_record = nil
34
+ loop do
35
+ new_record = build_record(model_name, structure_class)
36
+ new_record = inject_parent_keys(model_name, new_record, structure_class)
37
+ break if validate_record(new_record, structure_class) &&
38
+ !record_exists?(model_name, new_record, structure_class, generated_records)
39
+ end
40
+ generated_records.push(new_record)
41
+ end
42
+
43
+ generated_records
43
44
  end
44
45
 
45
- generation_rules = structure_class.structure
46
- raise "Structure must be a Hash" unless generation_rules.is_a?(Hash)
47
-
48
- # Recupera lo schema per la validazione, se definito.
49
- schema = structure_class.respond_to?(:seed_schema) ? structure_class.seed_schema : nil
50
-
51
- # Gestione dei vincoli di unicità.
52
- # Se il metodo unique_keys è definito, lo si aspetta come array di array,
53
- # ad esempio: [[:media_id, :creator_id], [:role]]
54
- unique_key_sets = structure_class.respond_to?(:unique_keys) ? structure_class.unique_keys : []
55
- # Pre-carica i valori già presenti nel database per ciascun gruppo di colonne.
56
- unique_sets = unique_key_sets.map do |cols|
57
- existing_keys = Set.new
58
- # Usa pluck per recuperare le colonne specificate dal modello.
59
- # Se il gruppo è di una sola colonna, pluck restituirà un array di valori; se multi, un array di array.
60
- db_rows = Object.const_get(model_name).pluck(*cols)
61
- db_rows.each do |row|
62
- composite_key = cols.size == 1 ? row.to_s : row.join("_")
63
- existing_keys.add(composite_key)
46
+ private
47
+
48
+ def record_exists?(model_name, record, structure_class, generated_records)
49
+ # Se non è definito il metodo unique_keys, non eseguiamo il controllo
50
+ return false unless structure_class.respond_to?(:unique_keys)
51
+ unique_key_sets = structure_class.unique_keys
52
+ return false if unique_key_sets.empty?
53
+
54
+ # Determina il modello associato: si assume che il nome del modello sia
55
+ # dato dalla rimozione della stringa "Structure" dal nome della classe di structure.
56
+ model_class_name = structure_class.to_s.sub(/Structure$/, '')
57
+ model_class = Object.const_get(model_class_name)
58
+
59
+ # Per ogni set di chiavi uniche, costruiamo le condizioni della query
60
+ unique_key_sets.each do |key_set|
61
+ conditions = {}
62
+ key_set.each do |col|
63
+ conditions[col] = record[col]
64
+ end
65
+ # Se esiste un record nel database che soddisfa le condizioni, restituisce true.
66
+ return true if generated_records.find do |record|
67
+ conditions.all? { |key, value| record[key] == value }
68
+ end.present?
69
+ return true if model_class.where(conditions).exists?
64
70
  end
65
- { columns: cols, set: existing_keys }
71
+
72
+ false
66
73
  end
67
74
 
68
- generated_records = []
69
- progressbar = ProgressBar.create(total: count, format: '%a %B %p%% %t')
70
- attempts = 0
75
+ def build_record(model_name, structure_class)
76
+ generation_rules = structure_class.structure
77
+ raise "Structure must be a Hash" unless generation_rules.is_a?(Hash)
71
78
 
72
- # Continua a generare record finché non si raggiunge il numero richiesto.
73
- while generated_records.size < count
74
- attempts += 1
75
79
  record = {}
76
80
  generation_rules.each do |attribute, rule|
77
- # Ogni rule è un array: [tipo, generatore]
81
+ # Ogni rule è un array nel formato [tipo, generatore]
78
82
  generator = rule[1]
79
83
  value = generator.respond_to?(:call) ? generator.call : generator
80
84
  record[attribute] = value
81
85
  end
82
86
 
83
- # Se è definito uno schema, valida il record.
84
- if schema
85
- result = schema.call(record)
86
- unless result.success?
87
- message = "[ERROR] Record validation failed for #{model_name}: #{result.errors.to_h}"
88
- BetterSeeder::Utils.logger(message: message)
89
- progressbar.increment
90
- next # Rigenera il record se la validazione fallisce.
91
- end
92
- end
87
+ record
88
+ end
93
89
 
94
- # Controlla i vincoli di unicità: verifica che il record non sia già presente
95
- duplicate = unique_sets.any? do |unique_set|
96
- composite_key = unique_set[:columns].map { |col| record[col].to_s }.join("_")
97
- unique_set[:set].include?(composite_key)
98
- end
99
- next if duplicate
90
+ def inject_parent_keys(model_name, record, structure_class)
91
+ config = structure_class.respond_to?(:seed_config) ? structure_class.seed_config : {}
92
+ parents_spec = config[:parents]
93
+ return record unless parents_spec && !parents_spec.empty?
94
+
95
+ parents_spec.each do |parent_config|
96
+ parent_model = parent_config[:model]
97
+ column = parent_config[:column]
100
98
 
101
- # Aggiorna le strutture per il controllo di unicità con il nuovo record.
102
- unique_sets.each do |unique_set|
103
- composite_key = unique_set[:columns].map { |col| record[col].to_s }.join("_")
104
- unique_set[:set].add(composite_key)
99
+ # Tenta di ottenere un record del parent dal pool BetterSeeder.generated_records se disponibile.
100
+ # Usiamo il nome del modello come chiave nel pool.
101
+ pool_key = parent_model.to_s
102
+ parent_record = if defined?(BetterSeeder.generated_records) &&
103
+ BetterSeeder.generated_records[pool_key] &&
104
+ !BetterSeeder.generated_records[pool_key].empty?
105
+ BetterSeeder.generated_records[pool_key].sample
106
+ else
107
+ BetterSeeder.generated_records[pool_key] = parent_model.all
108
+ BetterSeeder.generated_records[pool_key].sample
109
+ end
110
+
111
+ raise "Parent record not found for #{parent_model}" unless parent_record
112
+
113
+ # Inietta nel record la chiave esterna indicata nella configurazione.
114
+ # binding.pry if model_name == "Media::Participant"
115
+ record[column] = parent_record[:id]
105
116
  end
106
117
 
107
- generated_records << record
108
- progressbar.increment
118
+ record
119
+ end
120
+
121
+ def validate_record(record, structure_class)
122
+ return true unless structure_class.respond_to?(:seed_schema_validation)
123
+
124
+ schema = structure_class.seed_schema_validation
125
+ result = schema.call(record)
126
+ return true if result.success?
127
+
128
+ raise result.errors.to_h
109
129
  end
110
130
 
111
- message = "[INFO] Generated #{generated_records.size} unique records for #{model_name} after #{attempts} attempts."
112
- BetterSeeder::Utils.logger(message: message)
113
- generated_records
114
131
  end
115
132
  end
116
133
  end
@@ -2,21 +2,36 @@
2
2
 
3
3
  module BetterSeeder
4
4
  module Utils
5
- # Trasforma un nome di classe in snake_case.
6
- # Esempio: "Campaigns::Campaign" => "campaigns_campaign"
7
- def self.transform_class_name(class_name)
8
- elements = class_name.split("::").map(&:underscore)
9
- # Aggiunge "_structure.rb" all'ultimo elemento
10
- elements[-1] = "#{elements[-1]}_structure.rb"
11
- elements.join("/")
12
- end
13
5
 
14
- def self.logger(message: nil)
15
- if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
16
- Rails.logger.info message
17
- else
18
- puts message
6
+ class << self
7
+ # Trasforma un nome di classe in snake_case.
8
+ # Esempio: "Campaigns::Campaign" => "campaigns_campaign"
9
+ def transform_class_name(class_name)
10
+ elements = class_name.split("::").map(&:underscore)
11
+ # Aggiunge "_structure.rb" all'ultimo elemento
12
+ elements[-1] = "#{elements[-1]}_structure.rb"
13
+ elements.join("/")
14
+ end
15
+
16
+ def logger(message: nil)
17
+ if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
18
+ Rails.logger.info message
19
+ else
20
+ puts message
21
+ end
19
22
  end
23
+
24
+ def log_level_setup
25
+ level = case BetterSeeder.configuration.log_level
26
+ when :debug then Logger::DEBUG
27
+ when :info then Logger::INFO
28
+ when :error then Logger::ERROR
29
+ else Logger::DEBUG
30
+ end
31
+
32
+ ActiveRecord::Base.logger.level = level
33
+ end
34
+
20
35
  end
21
36
  end
22
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BetterSeeder
4
- VERSION = "0.2.2.1"
4
+ VERSION = "0.2.3"
5
5
  end
data/lib/better_seeder.rb CHANGED
@@ -14,17 +14,31 @@ module BetterSeeder
14
14
 
15
15
  def initialize
16
16
  if defined?(Rails) && Rails.respond_to?(:root)
17
- @log_language = :en
17
+ @log_language = :en
18
+ @log_level = :info
18
19
  @structure_path = Rails.root.join('db', 'seed', 'structure')
19
- @preload_path = Rails.root.join('db', 'seed', 'preload')
20
+ @preload_path = Rails.root.join('db', 'seed', 'preload')
20
21
  else
21
- @log_language = :en
22
+ @log_language = :en
23
+ @log_level = :info
22
24
  @structure_path = File.join(Dir.pwd, 'db', 'seed', 'structure')
23
- @preload_path = File.join(Dir.pwd, 'db', 'seed', 'preload')
25
+ @preload_path = File.join(Dir.pwd, 'db', 'seed', 'preload')
24
26
  end
25
27
  end
26
28
  end
27
29
 
30
+ # Definisce un hash che fungerà da pool per memorizzare i record generati per ciascun modello.
31
+ @generated_records = {}
32
+
33
+ def self.generated_records
34
+ @generated_records
35
+ end
36
+
37
+ def self.store_generated_record(model_name, record)
38
+ @generated_records[model_name.to_s] ||= []
39
+ @generated_records[model_name.to_s] << record
40
+ end
41
+
28
42
  # Restituisce l'istanza globale di configurazione. Se non esiste, viene creata con i valori di default.
29
43
  def self.configuration
30
44
  @configuration ||= Configuration.new
@@ -47,6 +61,7 @@ module BetterSeeder
47
61
  # Metodo install che crea l'initializer di BetterSeeder in config/initializers
48
62
  # con le seguenti impostazioni:
49
63
  # - log_language: lingua da usare per i log (es. :en, :it)
64
+ # - log_level: livello di logging nell'output dei dati del seeder (:debug, :info, :error)
50
65
  # - structure_path: percorso dove sono memorizzati i file di structure (default: Rails.root/db/seed/structure)
51
66
  # - preload_path: percorso dove verranno salvati i file esportati (default: Rails.root/db/seed/preload)
52
67
  def self.install
@@ -60,6 +75,7 @@ module BetterSeeder
60
75
  # This file was generated by BetterSeeder.install
61
76
  BetterSeeder.configure do |config|
62
77
  config.log_language = :en
78
+ config.log_level = :error
63
79
  config.structure_path = Rails.root.join('db', 'seed', 'structure')
64
80
  config.preload_path = Rails.root.join('db', 'seed', 'preload')
65
81
  end
@@ -94,9 +110,15 @@ module BetterSeeder
94
110
  # - Se abilitato, i record vengono caricati nel database e successivamente esportati nel formato richiesto
95
111
  # - Vengono raccolte statistiche e loggato il tempo totale di esecuzione
96
112
  def self.magic(config)
113
+ previous_log_level = ActiveRecord::Base.logger.level
114
+ BetterSeeder::Utils.log_level_setup
115
+
116
+ message = "[LOGGER] previous log level: #{previous_log_level}, actual log level: #{ActiveRecord::Base.logger.level}"
117
+ BetterSeeder::Utils.logger(message: message)
118
+
97
119
  start_time = Time.now
98
- stats = {} # Statistiche: modello => numero di record caricati
99
- parent_loaded_records = {} # Per memorizzare i record creati per i modelli parent
120
+ stats = {} # Statistiche: modello => numero di record caricati
121
+ parent_loaded_records = {} # Per memorizzare i record creati per i modelli parent
100
122
 
101
123
  ActiveRecord::Base.transaction do
102
124
  export_type = config[:configurations][:export_type]
@@ -106,11 +128,12 @@ module BetterSeeder
106
128
  end
107
129
  end
108
130
 
131
+ ActiveRecord::Base.logger.level = previous_log_level
109
132
  total_time = Time.now - start_time
110
133
  log_statistics(stats, total_time)
111
134
  end
112
135
 
113
- def self.generate_structure(model_name: )
136
+ def self.generate_structure(model_name:)
114
137
  BetterSeeder::Builders::Structure.generate(model_name)
115
138
  end
116
139
 
@@ -146,12 +169,17 @@ module BetterSeeder
146
169
  # Recupera la configurazione specifica dal file di structure tramite il metodo seed_config.
147
170
  # Se non definito, vengono usati dei valori di default.
148
171
  seed_config = structure_class.respond_to?(:seed_config) ? structure_class.seed_config : {}
149
- file_name = seed_config[:file_name] || "#{model_name.underscore}_seed"
150
- excluded_columns = seed_config.dig(:columns, :excluded) || []
151
- generate_data = seed_config.fetch(:generate_data, true)
152
- count = seed_config[:count] || 10
153
- load_data = seed_config.fetch(:load_data, true)
154
- parent = seed_config[:parent] # nil oppure valore (o array) per modelli child
172
+ file_name = seed_config[:file_name] || "#{model_name.underscore}_seed"
173
+ excluded_columns = if export_type.to_s.downcase != 'sql'
174
+ seed_config.dig(:columns, :excluded) || []
175
+ else
176
+ []
177
+ end
178
+ generate_data = seed_config.fetch(:generate_data, true)
179
+ count = seed_config[:count] || 10
180
+ load_data = seed_config.fetch(:load_data, true)
181
+ parent = seed_config[:parent] # nil oppure valore (o array) per modelli child
182
+ superclass = seed_config[:superclass] # nil oppure valore (o array) per modelli child
155
183
 
156
184
  # Log per indicare se il modello è parent o child.
157
185
  message = if parent.nil?
@@ -170,74 +198,54 @@ module BetterSeeder
170
198
  raise Object.const_get(model_name)
171
199
  end
172
200
 
173
- # Recupera o genera i record.
174
- records = if generate_data
175
- Farms::Farmer.generate(model: model_name, count: count)
176
- else
177
- model_class.all.map(&:attributes)
178
- end
179
-
180
- # Rimuove le colonne escluse.
181
- processed_records = records.map do |record|
182
- record.reject { |key, _| excluded_columns.include?(key.to_sym) }
201
+ # Se abilitato, carica i record nel database.
202
+ if load_data && File.exist?("#{BetterSeeder.configuration.preload_path.to_s}/#{seed_config[:file_name]}.sql")
203
+ load_data_from_file(seed_config)
204
+ stats[model_name] = model_class.all.count
205
+ else
206
+ if generate_data
207
+ records = Farms::Farmer.generate(model: model_name, count: count)
208
+ total_records = records.size
209
+ stats[model_name] = total_records
210
+ created_records = load_records_into_db(model_class, records, total_records, model_name, superclass)
211
+ # Se il modello è parent, salva i record creati per poterli utilizzare in seguito per i modelli child.
212
+ parent_loaded_records[model_name] = created_records if parent.nil?
213
+ else
214
+ model_class.all.map(&:attributes)
215
+ end
183
216
  end
184
217
 
185
- # Se il modello è child, inietta le foreign key.
186
- if parent
187
- Array(parent).each do |parent_model_name|
188
- parent_records = parent_loaded_records[parent_model_name]
189
- if parent_records.nil? || parent_records.empty?
190
- message = "[ERROR] No loaded records found for parent model #{parent_model_name}. Cannot assign foreign key for #{model_name}."
191
- BetterSeeder::Utils.logger(message: message)
192
- else
193
- # Il nome della foreign key è ottenuto prendendo l'ultima parte del nome del modello padre,
194
- # trasformandola in minuscolo e in forma singolare, e aggiungendo "_id".
195
- foreign_key = parent_model_name.split("::").last.underscore.singularize + "_id"
196
- processed_records.each do |record|
197
- record[foreign_key] = parent_records.sample.id
198
- end
199
- end
218
+ # Rimuove le colonne escluse.
219
+ unless BetterSeeder.generated_records[(superclass || model_name).to_s].nil?
220
+ processed_records = BetterSeeder.generated_records[(superclass || model_name).to_s]
221
+ processed_records = processed_records.map do |campaign|
222
+ campaign.attributes.except(*excluded_columns.map(&:to_s))
200
223
  end
201
- end
202
224
 
203
- # Se abilitato, carica i record nel database.
204
- if load_data
205
- total_records = processed_records.size
206
- stats[model_name] = total_records
207
- created_records = load_records_into_db(model_class, processed_records, total_records, model_name)
208
- # Se il modello è parent, salva i record creati per poterli utilizzare in seguito per i modelli child.
209
- parent_loaded_records[model_name] = created_records if parent.nil?
210
- else
211
- stats[model_name] = 0
225
+ # Esporta i record nel formato richiesto.
226
+ export_records(model_class, processed_records, export_type, file_name)
212
227
  end
213
-
214
- # Esporta i record nel formato richiesto.
215
- export_records(model_class, processed_records, export_type, file_name)
216
228
  end
217
229
 
218
230
  # Carica i record nel database, utilizzando una progress bar per monitorare il progresso.
219
231
  # I log delle query SQL vengono temporaneamente disabilitati.
220
232
  #
221
233
  # @return [Array<Object>] Array dei record creati (istanze ActiveRecord)
222
- def self.load_records_into_db(model_class, processed_records, total_records, model_name)
223
- created_records = []
234
+ def self.load_records_into_db(model_class, processed_records, total_records, model_name, superclass)
224
235
  progressbar = ProgressBar.create(total: total_records, format: '%a %B %p%% %t')
225
236
  message = "[INFO] Starting to load #{total_records} records for model #{model_name}..."
226
237
  BetterSeeder::Utils.logger(message: message)
227
238
 
228
- previous_level = ActiveRecord::Base.logger.level
229
- ActiveRecord::Base.logger.level = Logger::ERROR
230
-
231
239
  processed_records.each do |record|
232
240
  created = model_class.create!(record)
233
- created_records << created
241
+ BetterSeeder.store_generated_record(superclass || model_name, created)
234
242
  progressbar.increment
235
243
  end
236
244
 
237
- ActiveRecord::Base.logger.level = previous_level
238
245
  message = "[INFO] Finished loading #{total_records} records into model #{model_name}."
239
246
  BetterSeeder::Utils.logger(message: message)
240
- created_records
247
+
248
+ BetterSeeder.generated_records[model_name]
241
249
  end
242
250
 
243
251
  # Esporta i record nel formato specificato (json, csv, sql).
@@ -261,8 +269,8 @@ module BetterSeeder
261
269
 
262
270
  # Log finale con le statistiche raccolte e il tempo totale di esecuzione.
263
271
  def self.log_statistics(stats, total_time)
264
- stats_message = stats.map { |model, count| "#{model}: #{count} records" }.join(", ")
265
- message = "[INFO] Finished processing all models in #{total_time.round(2)} seconds. Statistics: #{stats_message}"
272
+ stats_message = stats.map { |model, count| "#{model}: #{count} records" }.join("\n")
273
+ message = "[INFO] Finished processing all models in #{total_time.round(2)} seconds. Statistics: \n#{stats_message}"
266
274
  BetterSeeder::Utils.logger(message: message)
267
275
  end
268
276
 
@@ -271,4 +279,29 @@ module BetterSeeder
271
279
  def self.transform_class_name(class_name)
272
280
  class_name.split("::").map(&:underscore).join("_")
273
281
  end
282
+
283
+ def self.load_data_from_file(seed_config)
284
+ config = seed_config
285
+ return unless config[:load_data] # Se load_data non è abilitato, esce senza fare nulla.
286
+
287
+ # Costruisce il nome del file di seed: ad esempio, se config[:file_name] è "my_model_seed",
288
+ # il file atteso sarà "my_model_seed_seed.sql".
289
+ seed_file_name = "#{config[:file_name]}.sql"
290
+ seed_file_path = File.join(BetterSeeder.configuration.preload_path, seed_file_name)
291
+
292
+ unless File.exist?(seed_file_path)
293
+ BetterSeeder::Utils.logger(message: "[WARN] Seed file not found: #{seed_file_path}")
294
+ return false
295
+ end
296
+
297
+ sql = File.read(seed_file_path)
298
+ begin
299
+ ActiveRecord::Base.connection.execute(sql)
300
+ BetterSeeder::Utils.logger(message: "[INFO] Loaded seed file: #{seed_file_path}")
301
+ true
302
+ rescue => e
303
+ BetterSeeder::Utils.logger(message: "[ERROR] Failed to load seed file: #{seed_file_path} - Error: #{e.message}")
304
+ false
305
+ end
306
+ end
274
307
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_seeder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - alessio_bussolari
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-10 00:00:00.000000000 Z
11
+ date: 2025-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffaker