brick 1.0.53 → 1.0.54
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:
|
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
|