brick 1.0.154 → 1.0.155

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: 647f34b463dc92515c7eb04331726a808b5ea69dd2bbd6ef99c9d6c769868565
4
- data.tar.gz: 22ae7fa65845e65a7848f5cfff0fbb52a864b0161783c3f7d28cfb82ba1f88e5
3
+ metadata.gz: fceffbcf863eb9c03b64a0cb4420a33ded5eb7f3908b40b263a345ae9bf5c164
4
+ data.tar.gz: 81f9f96bd1463b8b7e7736ed4716bcf78609bae27485af4de15cb23ae12e27ee
5
5
  SHA512:
6
- metadata.gz: 84034f48010bd159804a19cb865a9cad04ba5efe89bb1e807a7031393d9a64a33d9ca9802f991565f4d73753df087d200099052dde59e4127c6b94370456ec09
7
- data.tar.gz: 57b3cca20e566ef0d4ac72a45f24b025feea45421417b23cbe7cb683877ac228463f5f348f931a6024b9cdf750dde6aa6c49293e1ae1a596a70a0d8f3c128d6c
6
+ metadata.gz: c41a59ca62c80012166225b0cf80505b81fe57ccdfeb92c4add7f227d6d4a9cc0c664aaf5209c31dabd54c3e471fe140fd3dc75bf1441bbed0fca67e9801ffd9
7
+ data.tar.gz: 83c874515b230b0b607da32e41366284b15e830ebd7f7022fb318db412fef94a0339495de54c9ab0277425af2635cc8ab235675074cbb50f703082979ebd28b5
data/lib/brick/config.rb CHANGED
@@ -380,6 +380,14 @@ module Brick
380
380
  @mutex.synchronize { @always_load_fields = field_set }
381
381
  end
382
382
 
383
+ def ignore_migration_fks
384
+ @mutex.synchronize { @ignore_migration_fks || [] }
385
+ end
386
+
387
+ def ignore_migration_fks=(relations)
388
+ @mutex.synchronize { @ignore_migration_fks = relations }
389
+ end
390
+
383
391
  # Add status page showing all resources and what files have been built out for them
384
392
  def add_status
385
393
  true
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 154
8
+ TINY = 155
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -1164,6 +1164,12 @@ ActiveSupport.on_load(:active_record) do
1164
1164
  mattr_accessor :default_timezone, instance_writer: false
1165
1165
  self.default_timezone = :utc
1166
1166
  end
1167
+
1168
+ unless respond_to?(:primary_abstract_class)
1169
+ def self.primary_abstract_class
1170
+ self.abstract_class = true
1171
+ end
1172
+ end
1167
1173
  end
1168
1174
 
1169
1175
  # Rails < 4.0 cannot do #find_by, #find_or_create_by, or do #pluck on multiple columns, so here are the patches:
@@ -123,21 +123,27 @@ module Brick
123
123
  built_schemas = {} # Track all built schemas so we can place an appropriate drop_schema command only in the first
124
124
  # migration in which that schema is referenced, thereby allowing rollbacks to function properly.
125
125
  versions_to_create = [] # Resulting versions to be used when updating the schema_migrations table
126
+ ar_base = Object.const_defined?(:ApplicationRecord) ? ApplicationRecord : Class.new(ActiveRecord::Base)
126
127
  # Start by making migrations for fringe tables (those with no foreign keys).
127
128
  # Continue layer by layer, creating migrations for tables that reference ones already done, until
128
129
  # no more migrations can be created. (At that point hopefully all tables are accounted for.)
129
130
  while (fringe = chosen.reject do |tbl|
131
+ snag_fks = []
130
132
  snags = ::Brick.relations.fetch(tbl, nil)&.fetch(:fks, nil)&.select do |_k, v|
131
133
  v[:is_bt] && !v[:polymorphic] &&
132
134
  tbl != v[:inverse_table] && # Ignore self-referencing associations (stuff like "parent_id")
133
- !done.include?(v[:inverse_table])
135
+ !done.include?(v[:inverse_table]) &&
136
+ ::Brick.config.ignore_migration_fks.exclude?(snag_fk = "#{tbl}.#{v[:fk]}") &&
137
+ snag_fks << snag_fk
138
+ end
139
+ if snags&.present?
140
+ # puts snag_fks.inspect
141
+ stuck[tbl] = snags
134
142
  end
135
- stuck[tbl] = snags if snags&.present?
136
143
  end).present?
137
144
  fringe.each do |tbl|
138
145
  next unless (relation = ::Brick.relations.fetch(tbl, nil))&.fetch(:cols, nil)&.present?
139
146
 
140
- ar_base = Object.const_defined?(:ApplicationRecord) ? ApplicationRecord : Class.new(ActiveRecord::Base)
141
147
  pkey_cols = (rpk = relation[:pkey].values.flatten) & (arpk = [ar_base.primary_key].flatten.sort)
142
148
  # In case things aren't as standard
143
149
  if pkey_cols.empty?
@@ -246,7 +252,8 @@ module Brick
246
252
  suffix << ", index: { name: '#{shorter || idx_name}' }"
247
253
  indexes[shorter || idx_name] = nil
248
254
  end
249
- mig << " t.references :#{fk[:assoc_name]}#{suffix}, foreign_key: { to_table: #{to_table} }\n"
255
+ primary_key = ::Brick.relations[fk[:inverse_table]][:class_name]&.constantize&.primary_key
256
+ mig << " t.references :#{fk[:assoc_name]}#{suffix}, foreign_key: { to_table: #{to_table}#{", primary_key: :#{primary_key}" if primary_key != ar_base.primary_key} }\n"
250
257
  end
251
258
  else
252
259
  next if !id_option&.end_with?('id: false') && pkey_cols&.include?(col)
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'fancy_gets'
5
+
6
+ module Brick
7
+ class SeedsGenerator < ::Rails::Generators::Base
8
+ include FancyGets
9
+
10
+ desc 'Auto-generates a seeds file from existing data.'
11
+
12
+ def brick_seeds
13
+ # %%% If Apartment is active and there's no schema_to_analyse, ask which schema they want
14
+
15
+ ::Brick.mode = :on
16
+ ActiveRecord::Base.establish_connection
17
+
18
+ if (tables = ::Brick.relations.reject { |k, v| v.key?(:isView) && v[:isView] == true }.map(&:first).sort).empty?
19
+ puts "No tables found in database #{ActiveRecord::Base.connection.current_database}."
20
+ return
21
+ end
22
+
23
+ if File.exist?(seed_file_path = "#{::Rails.root}/db/seeds.rb")
24
+ puts "WARNING: seeds file #{seed_file_path} appears to already be present."
25
+ end
26
+
27
+ # Generate a list of tables that can be chosen
28
+ chosen = gets_list(list: tables, chosen: tables.dup)
29
+ schemas = chosen.each_with_object({}) do |v, s|
30
+ if (v_parts = v.split('.')).length > 1
31
+ s[v_parts.first] = nil unless [::Brick.default_schema, 'public'].include?(v_parts.first)
32
+ end
33
+ end
34
+ seeds = +"# Seeds file for #{ActiveRecord::Base.connection.current_database}:"
35
+ done = []
36
+ fks = {}
37
+ stuck = {}
38
+ indexes = {} # Track index names to make sure things are unique
39
+ ar_base = Object.const_defined?(:ApplicationRecord) ? ApplicationRecord : Class.new(ActiveRecord::Base)
40
+ # Start by making entries for fringe models (those with no foreign keys).
41
+ # Continue layer by layer, creating entries for models that reference ones already done, until
42
+ # no more entries can be created. (At that point hopefully all models are accounted for.)
43
+ while (fringe = chosen.reject do |tbl|
44
+ snag_fks = []
45
+ snags = ::Brick.relations.fetch(tbl, nil)&.fetch(:fks, nil)&.select do |_k, v|
46
+ v[:is_bt] && !v[:polymorphic] &&
47
+ tbl != v[:inverse_table] && # Ignore self-referencing associations (stuff like "parent_id")
48
+ !done.include?(v[:inverse_table]) &&
49
+ ::Brick.config.ignore_migration_fks.exclude?(snag_fk = "#{tbl}.#{v[:fk]}") &&
50
+ snag_fks << snag_fk
51
+ end
52
+ if snags&.present?
53
+ # puts snag_fks.inspect
54
+ stuck[tbl] = snags
55
+ end
56
+ end).present?
57
+ seeds << "\n"
58
+ fringe.each do |tbl|
59
+ next unless ::Brick.config.exclude_tables.exclude?(tbl) &&
60
+ (relation = ::Brick.relations.fetch(tbl, nil))&.fetch(:cols, nil)&.present? &&
61
+ (klass = Object.const_get(class_name = relation[:class_name])).table_exists?
62
+
63
+ pkey_cols = (rpk = relation[:pkey].values.flatten) & (arpk = [ar_base.primary_key].flatten.sort)
64
+ # In case things aren't as standard
65
+ if pkey_cols.empty?
66
+ pkey_cols = if rpk.empty? # && relation[:cols][arpk.first]&.first == key_type
67
+ arpk
68
+ elsif rpk.first
69
+ rpk
70
+ end
71
+ end
72
+ schema = if (tbl_parts = tbl.split('.')).length > 1
73
+ if tbl_parts.first == (::Brick.default_schema || 'public')
74
+ tbl_parts.shift
75
+ nil
76
+ else
77
+ tbl_parts.first
78
+ end
79
+ end
80
+
81
+ # %%% For the moment we're skipping polymorphics
82
+ fkeys = relation[:fks].values.select { |assoc| assoc[:is_bt] && !assoc[:polymorphic] }
83
+ # Refer to this table name as a symbol or dotted string as appropriate
84
+ # tbl_code = tbl_parts.length == 1 ? ":#{tbl_parts.first}" : "'#{tbl}'"
85
+ seeds << " # #{class_name}\n"
86
+
87
+ is_empty = true
88
+ klass.order(*pkey_cols).each do |obj|
89
+ is_empty = false
90
+ pk_val = obj.send(pkey_cols.first)
91
+ fk_vals = []
92
+ data = []
93
+ relation[:cols].each do |col, col_type|
94
+ next if !(fk = fkeys.find { |assoc| col == assoc[:fk] }) &&
95
+ pkey_cols.include?(col)
96
+
97
+ if (val = obj.send(col)) && (val.is_a?(Time) || val.is_a?(Date))
98
+ val = val.to_s
99
+ end
100
+ if fk
101
+ fk_vals << "#{fk[:assoc_name]}: #{fk[:inverse_table]}_#{val.inspect}" if val
102
+ else
103
+ data << "#{col}: #{val.inspect}"
104
+ end
105
+ end
106
+ seeds << "#{tbl}_#{pk_val} = #{class_name}.create(#{(fk_vals + data).join(', ')})\n"
107
+ end
108
+ File.open(seed_file_path, "w") { |f| f.write seeds }
109
+ end
110
+ done.concat(fringe)
111
+ chosen -= done
112
+ end
113
+ puts "\n*** Created seeds for #{done.length} models in db/seeds.rb ***"
114
+ end
115
+ end
116
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.154
4
+ version: 1.0.155
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-29 00:00:00.000000000 Z
11
+ date: 2023-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -257,6 +257,7 @@ files:
257
257
  - lib/generators/brick/install_generator.rb
258
258
  - lib/generators/brick/migrations_generator.rb
259
259
  - lib/generators/brick/models_generator.rb
260
+ - lib/generators/brick/seeds_generator.rb
260
261
  - lib/generators/brick/templates/add_object_changes_to_versions.rb.erb
261
262
  - lib/generators/brick/templates/create_versions.rb.erb
262
263
  homepage: https://github.com/lorint/brick