brick 1.0.56 → 1.0.57
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 +4 -4
- data/lib/brick/version_number.rb +1 -1
- data/lib/generators/brick/migrations_generator.rb +59 -35
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 930370b67a72b31db99cc8d50afa80d4c3be0d07e727155eb20ac5a7628bb1bb
|
|
4
|
+
data.tar.gz: f2d7964c79172a438800b3c69c63e62b26a4984357ca5d6c7ff9e2ef72e5308f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03e7ba018c426517060aa6312d14a9f1e0877d82b376782ea46b4b1506433bbe3e9e4d2c3d88aaf3d5fb356c68a129fd975b1718d7b2ac826b241efab3f2cee6
|
|
7
|
+
data.tar.gz: 645c6b750dd870180e312ffddff1d199bb84e92cdde0309f253ec8c927f3ba5304b84ae95b066c260d0523048c607b28148d1b577a479ec661b94de05248813a
|
data/lib/brick/version_number.rb
CHANGED
|
@@ -5,12 +5,14 @@ require 'rails/generators/active_record'
|
|
|
5
5
|
require 'fancy_gets'
|
|
6
6
|
|
|
7
7
|
module Brick
|
|
8
|
-
# Auto-generates
|
|
8
|
+
# Auto-generates migration files
|
|
9
9
|
class MigrationsGenerator < ::Rails::Generators::Base
|
|
10
10
|
include FancyGets
|
|
11
11
|
# include ::Rails::Generators::Migration
|
|
12
12
|
|
|
13
|
-
# SQL types
|
|
13
|
+
# Many SQL types are the same as their migration data type name:
|
|
14
|
+
# text, integer, bigint, date, boolean, decimal, float
|
|
15
|
+
# These however are not:
|
|
14
16
|
SQL_TYPES = { 'character varying' => 'string',
|
|
15
17
|
'character' => 'string', # %%% Need to put in "limit: 1"
|
|
16
18
|
'xml' => 'text',
|
|
@@ -23,15 +25,7 @@ module Brick
|
|
|
23
25
|
'smallint' => 'integer' } # %%% Need to put in "limit: 2"
|
|
24
26
|
# (Still need to find what "inet" and "json" data types map to.)
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
# class_option(
|
|
28
|
-
# :with_changes,
|
|
29
|
-
# type: :boolean,
|
|
30
|
-
# default: false,
|
|
31
|
-
# desc: 'Add IMPORT_TEMPLATE to model'
|
|
32
|
-
# )
|
|
33
|
-
|
|
34
|
-
desc 'Auto-generates migrations for an existing database.'
|
|
28
|
+
desc 'Auto-generates migration files for an existing database.'
|
|
35
29
|
|
|
36
30
|
def brick_migrations
|
|
37
31
|
# If Apartment is active, see if a default schema to analyse is indicated
|
|
@@ -47,11 +41,14 @@ module Brick
|
|
|
47
41
|
key_type = (ActiveRecord.version < ::Gem::Version.new('5.1') ? 'integer' : 'bigint')
|
|
48
42
|
is_4x_rails = ActiveRecord.version < ::Gem::Version.new('5.0')
|
|
49
43
|
ar_version = "[#{ActiveRecord.version.segments[0..1].join('.')}]" unless is_4x_rails
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
is_insert_versions = true
|
|
45
|
+
is_delete_versions = false
|
|
46
|
+
versions_to_delete_or_append = nil
|
|
47
|
+
if Dir.exist?(mig_path = ActiveRecord::Migrator.migrations_paths.first || "#{::Rails.root}/db/migrate")
|
|
52
48
|
if Dir["#{mig_path}/**/*.rb"].present?
|
|
53
49
|
puts "WARNING: migrations folder #{mig_path} appears to already have ruby files present."
|
|
54
50
|
mig_path2 = "#{::Rails.root}/tmp/brick_migrations"
|
|
51
|
+
is_insert_versions = false unless mig_path == mig_path2
|
|
55
52
|
if Dir.exist?(mig_path2)
|
|
56
53
|
if Dir["#{mig_path2}/**/*.rb"].present?
|
|
57
54
|
puts "As well, temporary folder #{mig_path2} also has ruby files present."
|
|
@@ -59,10 +56,15 @@ module Brick
|
|
|
59
56
|
mig_path2 = gets_list(list: ['Cancel operation!', "Append migration files into #{mig_path} anyway", mig_path, mig_path2])
|
|
60
57
|
return if mig_path2.start_with?('Cancel')
|
|
61
58
|
|
|
59
|
+
existing_mig_files = Dir["#{mig_path2}/**/*.rb"]
|
|
60
|
+
if (is_insert_versions = mig_path == mig_path2)
|
|
61
|
+
versions_to_delete_or_append = existing_mig_files.map { |ver| ver.split('/').last.split('_').first }
|
|
62
|
+
end
|
|
62
63
|
if mig_path2.start_with?('Append migration files into ')
|
|
63
64
|
mig_path2 = mig_path
|
|
64
65
|
else
|
|
65
|
-
|
|
66
|
+
is_delete_versions = true
|
|
67
|
+
existing_mig_files.each { |rb| File.delete(rb) }
|
|
66
68
|
end
|
|
67
69
|
else
|
|
68
70
|
puts "Using temporary folder #{mig_path2} for created migration files.\n\n"
|
|
@@ -88,7 +90,9 @@ module Brick
|
|
|
88
90
|
fks = {}
|
|
89
91
|
stuck = {}
|
|
90
92
|
indexes = {} # Track index names to make sure things are unique
|
|
91
|
-
|
|
93
|
+
built_schemas = {} # Track all built schemas so we can place an appropriate drop_schema command only in the first
|
|
94
|
+
# migration in which that schema is referenced, thereby allowing rollbacks to function properly.
|
|
95
|
+
versions_to_create = [] # Resulting versions to be used when updating the schema_migrations table
|
|
92
96
|
# Start by making migrations for fringe tables (those with no foreign keys).
|
|
93
97
|
# Continue layer by layer, creating migrations for tables that reference ones already done, until
|
|
94
98
|
# no more migrations can be created. (At that point hopefully all tables are accounted for.)
|
|
@@ -113,7 +117,7 @@ module Brick
|
|
|
113
117
|
end
|
|
114
118
|
end
|
|
115
119
|
schema = if (tbl_parts = tbl.split('.')).length > 1
|
|
116
|
-
if tbl_parts.first == 'public'
|
|
120
|
+
if tbl_parts.first == (::Brick.default_schema || 'public')
|
|
117
121
|
tbl_parts.shift
|
|
118
122
|
nil
|
|
119
123
|
else
|
|
@@ -123,10 +127,13 @@ module Brick
|
|
|
123
127
|
# %%% For the moment we're skipping polymorphics
|
|
124
128
|
fkey_cols = relation[:fks].values.select { |assoc| assoc[:is_bt] && !assoc[:polymorphic] }
|
|
125
129
|
mig = +"class Create#{(full_table_name = tbl_parts.join('_')).camelize} < ActiveRecord::Migration#{ar_version}\n"
|
|
130
|
+
# If the primary key is also used as a foreign key, will need to do id: false and then build out
|
|
131
|
+
# a column definition which includes :primary_key -- %%% also using a data type of bigserial or serial
|
|
132
|
+
# if this one has come in as bigint or integer.
|
|
133
|
+
pk_is_also_fk = fkey_cols.any? { |assoc| pkey_cols&.first == assoc[:fk] } ? pkey_cols&.first : nil
|
|
126
134
|
# Support missing primary key (by adding: ,id: false)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
unless pkey_cols&.present?
|
|
135
|
+
id_option = if pk_is_also_fk || (pkey_col_first = relation[:cols][pkey_cols&.first]&.first) != key_type
|
|
136
|
+
if pk_is_also_fk || !pkey_cols&.present?
|
|
130
137
|
', id: false'
|
|
131
138
|
else
|
|
132
139
|
case pkey_col_first
|
|
@@ -157,21 +164,12 @@ module Brick
|
|
|
157
164
|
# Refer to this table name as a symbol or dotted string as appropriate
|
|
158
165
|
tbl_code = tbl_parts.length == 1 ? ":#{tbl_parts.first}" : "'#{tbl}'"
|
|
159
166
|
mig << " def change\n return unless reverting? || !table_exists?(#{tbl_code})\n\n"
|
|
160
|
-
mig << " create_schema :#{schema} unless schema_exists?(:#{schema})\n" if schema
|
|
167
|
+
mig << " create_schema :#{schema} unless reverting? || schema_exists?(:#{schema})\n" if schema
|
|
161
168
|
mig << " create_table #{tbl_code}#{id_option} do |t|\n"
|
|
162
169
|
possible_ts = [] # Track possible generic timestamps
|
|
163
170
|
add_fks = [] # Track foreign keys to add after table creation
|
|
164
171
|
relation[:cols].each do |col, col_type|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
# See if there are generic timestamps
|
|
168
|
-
if (sql_type = SQL_TYPES[col_type.first]) == 'timestamp' &&
|
|
169
|
-
['created_at','updated_at'].include?(col)
|
|
170
|
-
possible_ts << [col, !col_type[3]]
|
|
171
|
-
next
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
sql_type ||= col_type.first
|
|
172
|
+
sql_type = SQL_TYPES[col_type.first] || col_type.first
|
|
175
173
|
suffix = col_type[3] ? +', null: false' : +''
|
|
176
174
|
if !is_4x_rails && klass && (comment = klass.columns_hash.fetch(col, nil)&.comment)&.present?
|
|
177
175
|
suffix << ", comment: #{comment.inspect}"
|
|
@@ -201,7 +199,14 @@ module Brick
|
|
|
201
199
|
mig << " t.references :#{fk[:assoc_name]}#{suffix}, foreign_key: { to_table: #{to_table} }\n"
|
|
202
200
|
end
|
|
203
201
|
else
|
|
204
|
-
|
|
202
|
+
next if !id_option&.end_with?('id: false') && pkey_cols.include?(col)
|
|
203
|
+
|
|
204
|
+
# See if there are generic timestamps
|
|
205
|
+
if sql_type == 'timestamp' && ['created_at','updated_at'].include?(col)
|
|
206
|
+
possible_ts << [col, !col_type[3]]
|
|
207
|
+
else
|
|
208
|
+
mig << emit_column(sql_type, col, suffix)
|
|
209
|
+
end
|
|
205
210
|
end
|
|
206
211
|
end
|
|
207
212
|
if possible_ts.length == 2 && # Both created_at and updated_at
|
|
@@ -212,6 +217,7 @@ module Brick
|
|
|
212
217
|
possible_ts.each { |ts| emit_column('timestamp', ts.first, nil) }
|
|
213
218
|
end
|
|
214
219
|
mig << " end\n"
|
|
220
|
+
mig << " execute('ALTER TABLE #{tbl} ADD PRIMARY KEY (#{pk_is_also_fk});')\n" if pk_is_also_fk
|
|
215
221
|
add_fks.each do |add_fk|
|
|
216
222
|
is_commented = false
|
|
217
223
|
# add_fk[2] holds the inverse relation
|
|
@@ -224,9 +230,13 @@ module Brick
|
|
|
224
230
|
# to_table column
|
|
225
231
|
mig << " #{'# ' if is_commented}add_foreign_key #{tbl_code}, #{add_fk[0]}, column: :#{add_fk[1]}, primary_key: :#{pk}\n"
|
|
226
232
|
end
|
|
233
|
+
unless built_schemas.key?(schema)
|
|
234
|
+
mig << " drop_schema :#{schema} if reverting? && schema_exists?(:#{schema})\n"
|
|
235
|
+
built_schemas[schema] = nil
|
|
236
|
+
end
|
|
227
237
|
mig << " end\nend\n"
|
|
228
238
|
current_mig_time += 1.minute
|
|
229
|
-
|
|
239
|
+
versions_to_create << (version = current_mig_time.strftime('%Y%m%d%H%M00')).split('_').first
|
|
230
240
|
File.open("#{mig_path}/#{version}_create_#{full_table_name}.rb", "w") { |f| f.write mig }
|
|
231
241
|
end
|
|
232
242
|
done.concat(fringe)
|
|
@@ -250,9 +260,23 @@ module Brick
|
|
|
250
260
|
}:"
|
|
251
261
|
pp stuck_sorted[0..4]
|
|
252
262
|
else # Successful, and now we can update the schema_migrations table accordingly
|
|
253
|
-
ActiveRecord::
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
unless ActiveRecord::Migration.table_exists?(ActiveRecord::Base.schema_migrations_table_name)
|
|
264
|
+
ActiveRecord::SchemaMigration.create_table
|
|
265
|
+
end
|
|
266
|
+
# Remove to_delete - to_create
|
|
267
|
+
if ((versions_to_delete_or_append ||= []) - versions_to_create).present? && is_delete_versions
|
|
268
|
+
ActiveRecord::Base.execute_sql("DELETE FROM #{
|
|
269
|
+
ActiveRecord::Base.schema_migrations_table_name} WHERE version IN (#{
|
|
270
|
+
(versions_to_delete_or_append - versions_to_create).map { |vtd| "'#{vtd}'" }.join(', ')}
|
|
271
|
+
)")
|
|
272
|
+
end
|
|
273
|
+
# Add to_create - to_delete
|
|
274
|
+
if is_insert_versions && ((versions_to_create ||= []) - versions_to_delete_or_append).present?
|
|
275
|
+
ActiveRecord::Base.execute_sql("INSERT INTO #{
|
|
276
|
+
ActiveRecord::Base.schema_migrations_table_name} (version) VALUES #{
|
|
277
|
+
(versions_to_create - versions_to_delete_or_append).map { |vtc| "('#{vtc}')" }.join(', ')
|
|
278
|
+
}")
|
|
279
|
+
end
|
|
256
280
|
end
|
|
257
281
|
end
|
|
258
282
|
|
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.57
|
|
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-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|