brick 1.0.53 → 1.0.54
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09f9f2f9f7e21a96d29cdad815c069e52280ea068051f27a542541bcefd33e87'
|
4
|
+
data.tar.gz: 54e032633f930a43d1bc929d05d241367d9ebbdb8010f588b922d1111077524e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56cad221c2b20ac62839c1b7904c8acb9bc392b0779946bbe325c48c8ee5cf00b33413e070674343809ee851804e5f9bbec2d6469a148688c4aecbbcaee3e09d
|
7
|
+
data.tar.gz: 9757effb2a1d058ae4ccd259b59e0218e002928d90dadfd6ff3d0acd05fb12e27cfcfef30afa3964637e0e4f1e4246b410deba45fb01e452e20056df94820377
|
data/lib/brick/extensions.rb
CHANGED
@@ -1289,7 +1289,10 @@ module ActiveRecord::ConnectionHandling
|
|
1289
1289
|
alias _brick_establish_connection establish_connection
|
1290
1290
|
def establish_connection(*args)
|
1291
1291
|
conn = _brick_establish_connection(*args)
|
1292
|
-
|
1292
|
+
begin
|
1293
|
+
_brick_reflect_tables
|
1294
|
+
rescue ActiveRecord::NoDatabaseError
|
1295
|
+
end
|
1293
1296
|
conn
|
1294
1297
|
end
|
1295
1298
|
|
data/lib/brick/version_number.rb
CHANGED
@@ -7,13 +7,13 @@ module Brick
|
|
7
7
|
class InstallGenerator < ::Rails::Generators::Base
|
8
8
|
# include ::Rails::Generators::Migration
|
9
9
|
|
10
|
-
source_root File.expand_path('templates', __dir__)
|
11
|
-
class_option(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
)
|
10
|
+
# source_root File.expand_path('templates', __dir__)
|
11
|
+
# class_option(
|
12
|
+
# :with_changes,
|
13
|
+
# type: :boolean,
|
14
|
+
# default: false,
|
15
|
+
# desc: 'Store changeset (diff) with each version'
|
16
|
+
# )
|
17
17
|
|
18
18
|
desc 'Generates an initializer file for configuring Brick'
|
19
19
|
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators'
|
4
|
+
require 'rails/generators/active_record'
|
5
|
+
require 'fancy_gets'
|
6
|
+
|
7
|
+
module Brick
|
8
|
+
# Auto-generates migrations
|
9
|
+
class MigrationsGenerator < ::Rails::Generators::Base
|
10
|
+
include FancyGets
|
11
|
+
# include ::Rails::Generators::Migration
|
12
|
+
|
13
|
+
# SQL types that are the same as their migration data type name: text, integer, bigint, smallint, date, boolean, decimal, float
|
14
|
+
SQL_TYPES = { 'character varying' =>'string',
|
15
|
+
'timestamp without time zone' =>'timestamp',
|
16
|
+
'timestamp with time zone' =>'timestamp',
|
17
|
+
'double precision' =>'float' } # might work with 'double'
|
18
|
+
# (Still need to find what "inet" and "json" data types map to.)
|
19
|
+
|
20
|
+
# # source_root File.expand_path('templates', __dir__)
|
21
|
+
# class_option(
|
22
|
+
# :with_changes,
|
23
|
+
# type: :boolean,
|
24
|
+
# default: false,
|
25
|
+
# desc: 'Add IMPORT_TEMPLATE to model'
|
26
|
+
# )
|
27
|
+
|
28
|
+
desc 'Auto-generates migrations for an existing database.'
|
29
|
+
|
30
|
+
def brick_migrations
|
31
|
+
# If Apartment is active, see if a default schema to analyse is indicated
|
32
|
+
|
33
|
+
# # Load all models
|
34
|
+
# Rails.configuration.eager_load_namespaces.select { |ns| ns < Rails::Application }.each(&:eager_load!)
|
35
|
+
|
36
|
+
if (tables = ::Brick.relations.reject { |k, v| v.key?(:isView) && v[:isView] == true }.map(&:first).sort).empty?
|
37
|
+
puts "No tables found in database #{ActiveRecord::Base.connection.current_database}."
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
ar_version = unless ActiveRecord.version < ::Gem::Version.new('5.0')
|
42
|
+
arv = ActiveRecord.version.segments[0..1]
|
43
|
+
arv.pop if arv&.last == 0
|
44
|
+
"[#{arv.join('.')}]"
|
45
|
+
end
|
46
|
+
default_mig_path = (mig_path = ActiveRecord::Migrator.migrations_paths.first || "#{File.expand_path(__dir__)}/db/migrate")
|
47
|
+
if Dir.exist?(mig_path)
|
48
|
+
if Dir["#{mig_path}/**/*.rb"].present?
|
49
|
+
puts "WARNING: migrations folder #{mig_path} appears to already have ruby files present."
|
50
|
+
mig_path2 = "#{File.expand_path(__dir__)}/tmp/brick_migrations"
|
51
|
+
if Dir.exist?(mig_path2)
|
52
|
+
if Dir["#{mig_path2}/**/*.rb"].present?
|
53
|
+
puts "As well, temporary folder #{mig_path2} also has ruby files present."
|
54
|
+
puts "Choose a destination -- all existing .rb files will be removed:"
|
55
|
+
mig_path2 = gets_list(list: ['Cancel operation!', "Add all migration files to #{mig_path} anyway", mig_path, mig_path2])
|
56
|
+
return if mig_path2.start_with?('Cancel')
|
57
|
+
|
58
|
+
if mig_path2.start_with?('Add all migration files to ')
|
59
|
+
mig_path2 = mig_path
|
60
|
+
else
|
61
|
+
Dir["#{mig_path2}/**/*.rb"].each { |rb| File.delete(rb) }
|
62
|
+
end
|
63
|
+
else
|
64
|
+
puts "Using temporary folder #{mig_path2} for created migration files.\n\n"
|
65
|
+
end
|
66
|
+
else
|
67
|
+
puts "Creating the temporary folder #{mig_path2} for created migration files.\n\n"
|
68
|
+
Dir.mkdir(mig_path2)
|
69
|
+
end
|
70
|
+
mig_path = mig_path2
|
71
|
+
else
|
72
|
+
puts "Using standard migration folder #{mig_path} for created migration files.\n\n"
|
73
|
+
end
|
74
|
+
else
|
75
|
+
puts "Creating standard ActiveRecord migration folder #{mig_path} to hold new migration files.\n\n"
|
76
|
+
Dir.mkdir(mig_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Generate a list of tables that can be chosen
|
80
|
+
chosen = gets_list(list: tables, chosen: tables.dup)
|
81
|
+
# Work from now back the same number of minutes as expected migrations to create
|
82
|
+
current_mig_time = Time.now - chosen.length.minutes
|
83
|
+
done = []
|
84
|
+
fks = {}
|
85
|
+
stuck = {}
|
86
|
+
# Start by making migrations for fringe tables (those with no foreign keys).
|
87
|
+
# Continue layer by layer, creating migrations for tables that reference ones already done, until
|
88
|
+
# no more migrations can be created. (At that point hopefully all tables are accounted for.)
|
89
|
+
while (fringe = chosen.reject do |tbl|
|
90
|
+
snags = ::Brick.relations[tbl][:fks].select do |_k, v|
|
91
|
+
v[:is_bt] && !v[:polymorphic] &&
|
92
|
+
tbl != v[:inverse_table] && # Ignore self-referencing associations (stuff like "parent_id")
|
93
|
+
!done.include?(v[:inverse_table])
|
94
|
+
end
|
95
|
+
stuck[tbl] = snags if snags.present?
|
96
|
+
end).present?
|
97
|
+
fringe.each do |tbl|
|
98
|
+
tbl = tbl[7..-1] if tbl.start_with?('public.') # %%% Provide better multitenancy support later
|
99
|
+
pkey_cols = ::Brick.relations[chosen.first][:pkey].values.flatten
|
100
|
+
# %%% For the moment we're skipping polymorphics
|
101
|
+
fkey_cols = ::Brick.relations[tbl][:fks].values.select { |assoc| assoc[:is_bt] && !assoc[:polymorphic] }
|
102
|
+
mig = +"class Create#{table_name = tbl.camelize} < ActiveRecord::Migration#{ar_version}\n"
|
103
|
+
# %%% Support missing foreign key (by adding: ,id: false)
|
104
|
+
# also bigint / uuid / other non-standard data type for primary key
|
105
|
+
mig << " def change\n create_table :#{tbl} do |t|\n"
|
106
|
+
possible_ts = [] # Track possible generic timestamps
|
107
|
+
(relation = ::Brick.relations[tbl])[:cols].each do |col, col_type|
|
108
|
+
next if pkey_cols.include?(col)
|
109
|
+
|
110
|
+
# See if there are generic timestamps
|
111
|
+
if (sql_type = SQL_TYPES[col_type.first]) == 'timestamp' && ['created_at','updated_at'].include?(col)
|
112
|
+
possible_ts << col
|
113
|
+
next
|
114
|
+
end
|
115
|
+
|
116
|
+
sql_type ||= col_type.first
|
117
|
+
# Determine if this column is used as part of a foreign key
|
118
|
+
if fk = fkey_cols.find { |assoc| col == assoc[:fk] }
|
119
|
+
mig << " t.references :#{fk[:assoc_name]}#{", type: #{sql_type}" unless sql_type == 'integer'}\n"
|
120
|
+
else
|
121
|
+
mig << emit_column(sql_type, col)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
if possible_ts.length == 2 # Both created_at and updated_at
|
125
|
+
mig << "\n t.timestamps\n"
|
126
|
+
else # Just one or the other
|
127
|
+
possible_ts.each { |ts| emit_column('timestamp', ts) }
|
128
|
+
end
|
129
|
+
mig << " end\n end\nend\n"
|
130
|
+
current_mig_time += 1.minute
|
131
|
+
File.open("#{mig_path}/#{current_mig_time.strftime('%Y%m%d%H%M00')}_create_#{tbl}.rb", "w") { |f| f.write mig }
|
132
|
+
end
|
133
|
+
done.concat(fringe)
|
134
|
+
chosen -= done
|
135
|
+
end
|
136
|
+
stuck_counts = Hash.new { |h, k| h[k] = 0 }
|
137
|
+
chosen.each do |leftover|
|
138
|
+
puts "Can't do #{leftover} because:\n #{stuck[leftover].map do |snag|
|
139
|
+
stuck_counts[snag.last[:inverse_table]] += 1
|
140
|
+
snag.last[:assoc_name]
|
141
|
+
end.join(', ')}"
|
142
|
+
end
|
143
|
+
pretty_mig_path = mig_path[cur_path.length] if mig_path.start_with?(cur_path = File.expand_path(__dir__))
|
144
|
+
puts "*** Created #{done.length} migration files under #{pretty_mig_path || mig_path} ***"
|
145
|
+
if (stuck_sorted = stuck_counts.to_a.sort { |a, b| b.last <=> a.last }).length.positive?
|
146
|
+
puts "-----------------------------------------"
|
147
|
+
puts "Unable to create migrations for #{stuck_sorted.length} tables#{
|
148
|
+
". Here's the top 5 blockers" if stuck_sorted.length > 5
|
149
|
+
}:"
|
150
|
+
pp stuck_sorted[0..4]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def emit_column(type, name)
|
157
|
+
" t.#{type.start_with?('numeric') ? 'decimal' : type} :#{name}\n"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -59,7 +59,6 @@ module Brick
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
models.each do |m| # Find longest name in the list for future use to show lists on the right side of the screen
|
62
|
-
# Strangely this can't be inlined since it assigns to "len"
|
63
62
|
if longest_length < (len = m.name.length)
|
64
63
|
longest_length = len
|
65
64
|
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.
|
4
|
+
version: 1.0.54
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lorin Thwaits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -238,6 +238,7 @@ files:
|
|
238
238
|
- lib/brick/version_number.rb
|
239
239
|
- lib/generators/brick/USAGE
|
240
240
|
- lib/generators/brick/install_generator.rb
|
241
|
+
- lib/generators/brick/migrations_generator.rb
|
241
242
|
- lib/generators/brick/model_generator.rb
|
242
243
|
- lib/generators/brick/templates/add_object_changes_to_versions.rb.erb
|
243
244
|
- lib/generators/brick/templates/create_versions.rb.erb
|