brick 1.0.232 → 1.0.234

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: ec8b0390d538c25946d68d51b1394875a02203694bc2d28928df1fd63987f40f
4
- data.tar.gz: de49f7332e2a08a21a22e92cbac5c9668079551de6ba36ff45fd02dcac9102db
3
+ metadata.gz: de2c4e94eca5667096154e57b49fc68273d85d5aa4f3830d68781f742204aa4c
4
+ data.tar.gz: 181c532f44cea33088556c7a1c54525898209335fde70d4328faeb09cf55bd54
5
5
  SHA512:
6
- metadata.gz: 7e77492d4d72836a829f9e073eaa14cb1f2c676aefbd053b0466e43b0d0f79141ec661bb38a377391d96711338f9bab5535ee52d51fc90964013ea042219cddc
7
- data.tar.gz: '099332256ecadb0948c329dc8a3b06c1b460da5de41e8f183fc5dd937651edd57895b2d3c57399455af5732bab7172e6e88435560cd2d6b1d2e6f42eafefe71d'
6
+ metadata.gz: dafe49d283394fc7d411241662a3910266fb98e82679c3ac6aa575b88f6f640908dced9e62ccf077544c2a9732a43b6bc0691a20f83f44d4caa8d9621884dd63
7
+ data.tar.gz: 37db140de791a556266a43bd3ee4040d412e0436ffac0e6bf5fb5a11108f3030226c59710b801237176c935963418ea2cd9f1de2e4a6c3beb76dc3138640500e
@@ -2521,6 +2521,7 @@ class Object
2521
2521
  end
2522
2522
  ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
2523
2523
  instance_variable_set("@#{plural_table_name}".to_sym, ar_select)
2524
+ @_lookup_context.instance_variable_set(:@_brick_is_postgres, true) if is_postgres
2524
2525
  table_name_no_schema = singular_table_name.pluralize
2525
2526
  if namespace && (idx = lookup_context.prefixes.index(table_name_no_schema))
2526
2527
  lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
@@ -2665,6 +2666,7 @@ class Object
2665
2666
  @_lookup_context.instance_variable_set(:@_brick_model, real_model)
2666
2667
  if created_obj.errors.empty?
2667
2668
  instance_variable_set("@#{singular_table_name}".to_sym, created_obj)
2669
+ @_lookup_context.instance_variable_set(:@_brick_is_postgres, true) if is_postgres
2668
2670
  index
2669
2671
  render :index
2670
2672
  else # Surface errors to the user in a flash message
@@ -745,8 +745,10 @@ window.addEventListener(\"popstate\", linkSchemas);
745
745
  hm_entry << if hm_assoc.macro == :has_one
746
746
  'nil'
747
747
  else # :has_many or :has_and_belongs_to_many
748
+ b_r_name = "b_r_#{assoc_name}_ct"
748
749
  # Postgres column names are limited to 63 characters
749
- "'" + "b_r_#{assoc_name}_ct"[0..62] + "'"
750
+ b_r_name = b_r_name[0..62] if @_brick_is_postgres
751
+ "'#{b_r_name}'"
750
752
  end
751
753
  hm_entry << ", #{path_keys(hm_assoc, hm_fk_name, pk).inspect}]"
752
754
  hms_columns << hm_entry
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 232
8
+ TINY = 234
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
@@ -64,11 +64,11 @@ Please provide your Airtable PAT:"
64
64
  else
65
65
  # puts col['type']
66
66
  dt = case col['type']
67
- when 'singleLineText', 'url', 'singleSelect'
67
+ when 'singleLineText', 'url', 'email', 'singleSelect'
68
68
  'string'
69
69
  when 'multilineText'
70
70
  'text'
71
- when 'number'
71
+ when 'number', 'currency'
72
72
  'decimal'
73
73
  when 'checkbox'
74
74
  'boolean'
@@ -140,7 +140,7 @@ Please provide your Airtable PAT:"
140
140
  end
141
141
 
142
142
  def sane_name(col_name)
143
- sane_table_name(col_name.gsub('&', 'and').tr('()?', ''))
143
+ sane_table_name(col_name.gsub('&', 'and').tr('()?', '').tr('/', '_'))
144
144
  end
145
145
 
146
146
  def sane_table_name(tbl_name)
@@ -183,7 +183,9 @@ module Brick
183
183
  # to_table column
184
184
  mig << "#{add_fk[0]}, column: :#{add_fk[1]}, primary_key: :#{pk}\n"
185
185
  end
186
- if after_fks.length > 500
186
+ # If there are LOTS of foreign keys then give extra database maintenance info and initially
187
+ # disable the final FK migration by using a ".rbx" file extension.
188
+ fks_extension = if after_fks.length > 500
187
189
  minutes = (after_fks.length + 1000) / 1500
188
190
  mig << " if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'\n"
189
191
  mig << " puts 'NOTE: It could take around #{minutes} #{'minute'.pluralize(minutes)} on a FAST machine for Postgres to do all the final processing for these foreign keys. Please be patient!'\n"
@@ -194,14 +196,19 @@ module Brick
194
196
  execute('VACUUM FULL')
195
197
  execute('BEGIN TRANSACTION')
196
198
  end\n"
199
+ 'rbx'
200
+ else
201
+ 'rb'
197
202
  end
198
203
  mig << +" end\n"
199
204
  current_mig_time[0] += 1.minute
200
- versions_to_create << migration_file_write(mig_path, 'create_brick_fks.rbx', current_mig_time, ar_version, mig)
201
- puts "Have written out a final migration called 'create_brick_fks.rbx' which creates #{after_fks.length} foreign keys.
202
- This file extension (.rbx) will cause it not to run yet when you do a 'rails db:migrate'.
205
+ versions_to_create << migration_file_write(mig_path, "create_brick_fks.#{fks_extension}", current_mig_time, ar_version, mig)
206
+ puts "Have written out a final migration called 'create_brick_fks.#{fks_extension}' which creates #{after_fks.length} foreign keys."
207
+ if fks_extension == 'rbx'
208
+ puts " This file extension (.rbx) will cause it not to run yet when you do a 'rails db:migrate'.
203
209
  The idea here is to do all data loading first, and then rename that migration file back
204
210
  into having a .rb extension, and run a final db:migrate to put the foreign keys in place."
211
+ end
205
212
 
206
213
  when 'Create' # Show additional_references entries that can be added into brick.rb
207
214
  puts 'Place this block into your brick.rb file:'
@@ -162,14 +162,14 @@ module Brick
162
162
  s[col_name] = obj['fields'][field.first]
163
163
  else # Consider N:M fks
164
164
  hm_fk = relation[:fks].find { |_k, fk1| !fk1[:is_bt] && fk1[:assoc_name] == ::Brick::AirtableApiCaller.sane_name(field.first) }&.last
165
- if (t_table = hm_fk&.fetch(:inverse_table, nil))
166
- associative_fks = relations[hm_fk&.fetch(:inverse_table, nil)][:fks]
165
+ if (assoc_table = hm_fk&.fetch(:inverse_table, nil))
166
+ associative_fks = relations[assoc_table][:fks]
167
167
  # near_side_fk = associative_fks.find { |_k, fk1| fk1[:is_bt] && fk1[:assoc_name] == ::Brick::AirtableApiCaller.sane_name(field.first) }&.last
168
168
  far_side_fk = associative_fks.find { |_k, fk1| fk1[:is_bt] && fk1[:assoc_name] != ::Brick::AirtableApiCaller.sane_name(field.first) }&.last
169
169
  field.last.each do |nm_rec|
170
170
  # Can trade out: hm_fk[:fk] for: near_side_fk[:inverse_table]
171
- airtable_assoc_recids[t_table] << "#{hm_fk[:fk]}: #{hm_fk[:fk].singularize}_#{nm_rec[3..-1]}, " \
172
- "#{far_side_fk[:assoc_name]}: #{far_side_fk[:inverse_table].singularize}_#{obj['id'][3..-1]}"
171
+ airtable_assoc_recids[assoc_table] << "#{hm_fk[:fk]}: #{hm_fk[:fk].singularize}_#{nm_rec[3..-1]}, " \
172
+ "#{far_side_fk[:assoc_name]}: #{far_side_fk[:inverse_table].singularize}_#{obj['id'][3..-1]}"
173
173
  end
174
174
  end
175
175
  end
@@ -183,7 +183,7 @@ module Brick
183
183
  end
184
184
  is_empty = false
185
185
  # For Airtable, take off the "rec___" prefix
186
- pk_val = is_airtable ? airtable_id[3..-1] : brick_escape(obj.attributes_before_type_cast[pkey_cols.first])
186
+ pk_val = is_airtable ? airtable_id[3..-1] : brick_escape(orig_pk_val = obj.attributes_before_type_cast[pkey_cols.first])
187
187
  var_name = "#{tbl.singularize.gsub('.', '__')}_#{pk_val}"
188
188
  fk_vals = []
189
189
  data = []
@@ -192,8 +192,8 @@ module Brick
192
192
  # Skip primary key columns, unless they are part of a foreign key.
193
193
  # (But always add all columns if it's Airtable!)
194
194
  next if !(fk = fkeys.find { |assoc| col == assoc[:fk] }) &&
195
- pkey_cols.include?(col) &&
196
- !is_airtable
195
+ !is_airtable &&
196
+ pkey_cols.include?(col) && orig_pk_val.is_a?(Integer)
197
197
 
198
198
  # Used to be: obj.send(col)
199
199
  # (and with that it was possible to raise ActiveRecord::Encryption::Errors::Configuration...)
@@ -202,16 +202,13 @@ module Brick
202
202
  val = val.to_s
203
203
  end
204
204
  if fk
205
- inv_tbl = fk[:inverse_table].gsub('.', '__')
206
205
  fk_val = if is_airtable
207
- inv_tbl = inv_tbl.singularize
208
- # Used to be: fk[:airtable_col]
209
- # Take off the "rec___" prefix
210
- obj.attributes_before_type_cast[fk[:assoc_name]]&.first&.[](3..-1)
206
+ # The (3..-1) is to take off the "rec___" prefix
207
+ obj.attributes_before_type_cast[fk[:assoc_name]]&.first&.[](3..-1) if is_airtable
211
208
  else
212
209
  brick_escape(val)
213
210
  end
214
- fk_vals << "#{fk[:assoc_name]}: #{inv_tbl}_#{fk_val}" if fk_val
211
+ fk_vals << "#{fk[:assoc_name]}: #{fk[:inverse_table].singularize.gsub('.', '__')}_#{fk_val}" if fk_val
215
212
  else
216
213
  val = case val.class.name
217
214
  when 'ActiveStorage::Filename'
@@ -262,7 +259,9 @@ end\n"
262
259
  end
263
260
  updates.each { |update| seeds << update } # Anything that needs patching up after-the-fact
264
261
  end
265
- seeds << " # (Skipping #{klass_name} as it has no rows)\n" unless has_rows
262
+ unless has_rows || klass_name.nil?
263
+ seeds << " # (Skipping #{klass_name} as it has no rows)\n"
264
+ end
266
265
  end
267
266
  done.concat(fringe)
268
267
  chosen -= done
@@ -276,7 +275,7 @@ end\n"
276
275
  File.open(seed_file_path, "w") { |f| f.write seeds }
277
276
  stuck_counts = Hash.new { |h, k| h[k] = 0 }
278
277
  chosen.each do |leftover|
279
- puts "Can't do #{leftover.klass_name} because:\n #{stuck[leftover.table_name].map do |snag|
278
+ puts "Can't do #{leftover.klass.name} because:\n #{stuck[leftover.table_name].map do |snag|
280
279
  stuck_counts[snag.last[:inverse_table]] += 1
281
280
  snag.last[:assoc_name]
282
281
  end.join(', ')}"
@@ -299,8 +298,8 @@ end\n"
299
298
  when String
300
299
  ret = +''
301
300
  val.each_char do |ch|
302
- if ch < '0' || (ch > '9' && ch < 'A') || ch > 'Z'
303
- ret << (ch == '_' ? ch : "x#{'K'.unpack('H*')[0]}")
301
+ if ch < '0' || (ch > '9' && ch < 'A') || (ch > 'Z' && ch < 'a') || ch == 'x' || ch > 'z'
302
+ ret << (ch == '_' ? ch : "x#{ch.unpack('H*')[0]}")
304
303
  else
305
304
  ret << ch
306
305
  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.232
4
+ version: 1.0.234
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-15 00:00:00.000000000 Z
11
+ date: 2025-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord