brick 1.0.63 → 1.0.66

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: c28a4db728e9312def40be9a9a790f1f22f464c6d6ade2b6e12f255730cd4111
4
- data.tar.gz: c2e75de42686c9ad0707fd6eca3d0b0a12207e051d77622d70276845d9af0949
3
+ metadata.gz: c7e8235e9e499424e41a8329f9056b4ab801fd7502889dfdafc527522f061ad3
4
+ data.tar.gz: 898b3f172cb9eb6594b382087394857d7ff471a833069bfe7e060f404bfd2d4c
5
5
  SHA512:
6
- metadata.gz: a897f30028aac1b6e14edc967a82c268aa58236cd424ecf977409a0c893d42b9e291c11ac2b2a411f00dc35c23b80a4ed6adecde394587c96d11b9f51c173fd8
7
- data.tar.gz: 538d694b6a0717045c6e23ec536a000a552bc0ece9009f74511e33013e0dde97f8cefadbc61a45d4b7ea884dd0c1dd985f5defc58175ec51318d345a7e561c2d
6
+ metadata.gz: 0d0b88ac19a60e25ee48074e5ee67037c41d77b80a54ea22ad1813d22d4e3d233d253ed92a39e317f3faa86aac290ee51e0bed7ab178c583ca1d06b075bfaac1
7
+ data.tar.gz: a0d8f7683236868789c9262a08a8c615786afdd6ad93b1f330807d5acad5962ea2e2ea645a236e37926b42bfd09db00ec9d00fae15de90da8fe589bfbe493b65
@@ -257,7 +257,7 @@ module ActiveRecord
257
257
  # For our purposes a :has_one is similar enough to a :belongs_to that we can just join forces
258
258
  _br_bt_descrip[k] = { hm.klass => hm.klass.brick_parse_dsl(join_array, k, translations) }
259
259
  else # Standard :has_many
260
- _br_hm_counts[k] = hm
260
+ _br_hm_counts[k] = hm unless hm.options[:through] && !_br_associatives.fetch(hm.name, nil)
261
261
  end
262
262
  end
263
263
  end
@@ -398,7 +398,7 @@ module ActiveRecord
398
398
  if selects&.empty? # Default to all columns
399
399
  tbl_no_schema = table.name.split('.').last
400
400
  columns.each do |col|
401
- col_alias = ' AS _class' if (col_name = col.name) == 'class'
401
+ col_alias = " AS _#{col.name}" if (col_name = col.name) == 'class'
402
402
  selects << if is_mysql
403
403
  "`#{tbl_no_schema}`.`#{col_name}`#{col_alias}"
404
404
  else
@@ -479,24 +479,25 @@ module ActiveRecord
479
479
  end
480
480
  next unless count_column # %%% Would be able to remove this when multiple foreign keys to same destination becomes bulletproof
481
481
 
482
- tbl_alias = "_br_#{hm.name}"
482
+ tbl_alias = is_mysql ? "`_br_#{hm.name}`" : "\"_br_#{hm.name}\""
483
483
  pri_tbl = hm.active_record
484
+ pri_tbl_name = is_mysql ? "`#{pri_tbl.table_name}`" : "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
484
485
  on_clause = []
485
486
  if fk_col.is_a?(Array) # Composite key?
486
- fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl.table_name}.#{pri_tbl.primary_key[idx]}" }
487
+ fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl_name}.#{pri_tbl.primary_key[idx]}" }
487
488
  selects = fk_col.dup
488
489
  else
489
490
  selects = [fk_col]
490
- on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl.table_name}.#{pri_tbl.primary_key}"
491
+ on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl_name}.#{pri_tbl.primary_key}"
491
492
  end
492
493
  if poly_type
493
494
  selects << poly_type
494
495
  on_clause << "#{tbl_alias}.#{poly_type} = '#{name}'"
495
496
  end
497
+ hm_table_name = is_mysql ? "`#{associative&.table_name || hm.klass.table_name}`" : "\"#{(associative&.table_name || hm.klass.table_name).gsub('.', '"."')}\""
496
498
  join_clause = "LEFT OUTER
497
499
  JOIN (SELECT #{selects.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
498
- }) AS _ct_ FROM #{associative&.table_name || hm.klass.table_name
499
- } GROUP BY #{(1..selects.length).to_a.join(', ')}) AS #{tbl_alias}"
500
+ }) AS _ct_ FROM #{hm_table_name} GROUP BY #{(1..selects.length).to_a.join(', ')}) AS #{tbl_alias}"
500
501
  joins!("#{join_clause} ON #{on_clause.join(' AND ')}")
501
502
  end
502
503
  where!(wheres) unless wheres.empty?
@@ -1016,6 +1017,7 @@ class Object
1016
1017
  table_name = ActiveSupport::Inflector.underscore(plural_class_name)
1017
1018
  singular_table_name = ActiveSupport::Inflector.singularize(table_name)
1018
1019
  pk = model&._brick_primary_key(relations.fetch(table_name, nil))
1020
+ is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
1019
1021
 
1020
1022
  namespace_name = "#{namespace.name}::" if namespace
1021
1023
  code = +"class #{namespace_name}#{class_name} < ApplicationController\n"
@@ -1119,7 +1121,9 @@ class Object
1119
1121
  @_brick_params = (ar_relation = model.all).brick_select(params, (selects = []), order_by, translations, join_array)
1120
1122
  # %%% Add custom HM count columns
1121
1123
  # %%% What happens when the PK is composite?
1122
- counts = model._br_hm_counts.each_with_object([]) { |v, s| s << "_br_#{v.first}._ct_ AS _br_#{v.first}_ct" }
1124
+ counts = model._br_hm_counts.each_with_object([]) do |v, s|
1125
+ s << (is_mysql ? "`_br_#{v.first}`._ct_ AS \"_br_#{v.first}_ct\"" : "\"_br_#{v.first}\"._ct_ AS \"_br_#{v.first}_ct\"")
1126
+ end
1123
1127
  instance_variable_set("@#{table_name}".to_sym, ar_relation.dup._select!(*selects, *counts))
1124
1128
  if namespace && (idx = lookup_context.prefixes.index(table_name))
1125
1129
  lookup_context.prefixes[idx] = "#{namespace.name.underscore}/#{lookup_context.prefixes[idx]}"
@@ -1525,7 +1529,9 @@ module ActiveRecord::ConnectionHandling
1525
1529
 
1526
1530
  def retrieve_schema_and_tables(sql = nil, is_postgres = nil, schema = nil)
1527
1531
  sql ||= "SELECT t.table_schema AS \"schema\", t.table_name AS relation_name, t.table_type,#{"
1528
- pg_catalog.obj_description((t.table_schema || '.' || t.table_name)::regclass, 'pg_class') AS table_description," if is_postgres}
1532
+ pg_catalog.obj_description(
1533
+ ('\"' || t.table_schema || '\".\"' || t.table_name || '\"')::regclass, 'pg_class'
1534
+ ) AS table_description," if is_postgres}
1529
1535
  c.column_name, c.data_type,
1530
1536
  COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
1531
1537
  tc.constraint_type AS const, kcu.constraint_name AS \"key\",
@@ -1595,6 +1601,8 @@ module Brick
1595
1601
  "#{bt_assoc_name}_bt"
1596
1602
  end
1597
1603
  end
1604
+ bt_assoc_name = "_#{bt_assoc_name}" if bt_assoc_name == 'attribute'
1605
+
1598
1606
  # %%% Temporary schema patch
1599
1607
  for_tbl = fk[1]
1600
1608
  apartment = Object.const_defined?('Apartment') && Apartment
@@ -118,7 +118,9 @@ module Brick
118
118
  hm_stuff = [(hm_assoc = hm.last),
119
119
  "H#{hm_assoc.macro == :has_one ? 'O' : 'M'}#{'T' if hm_assoc.options[:through]}",
120
120
  (assoc_name = hm.first)]
121
- hm_fk_name = if hm_assoc.options[:through]
121
+ hm_fk_name = if (through = hm_assoc.options[:through])
122
+ next unless @_brick_model.instance_methods.include?(through)
123
+
122
124
  associative = @_brick_model._br_associatives[hm.first]
123
125
  tbl_nm = if hm_assoc.options[:source]
124
126
  associative.klass.reflect_on_association(hm_assoc.options[:source]).inverse_of&.name
@@ -182,10 +184,8 @@ module Brick
182
184
  h1, h3 {
183
185
  margin-bottom: 0;
184
186
  }
185
- #resourceName {
186
- }
187
187
  #imgErd {
188
- background-image:url(assets/brick_erd.png);
188
+ background-image:url(/assets/brick_erd.png);
189
189
  background-size: 100% 100%;
190
190
  width: 2.2em;
191
191
  height: 2.2em;
@@ -365,8 +365,8 @@ def display_value(col_type, val)
365
365
  @is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2' if @is_mysql.nil?
366
366
  if @is_mysql
367
367
  # MySQL's \"Internal Geometry Format\" is like WKB, but with an initial 4 bytes that indicates the SRID.
368
- srid = val[..3].unpack('I')
369
- val = val[4..]
368
+ srid = val[0..3].unpack('I')
369
+ val = val[4..-1]
370
370
  end
371
371
  RGeo::WKRep::WKBParser.new.parse(val)
372
372
  else
@@ -453,25 +453,27 @@ window.addEventListener(\"pageshow\", function() {
453
453
 
454
454
  function changeout(href, param, value, trimAfter) {
455
455
  var hrefParts = href.split(\"?\");
456
- if (param === undefined || param === null) {
456
+ var params = hrefParts.length > 1 ? hrefParts[1].split(\"&\") : [];
457
+ if (param === undefined || param === null || param === -1) {
457
458
  hrefParts = hrefParts[0].split(\"://\");
458
459
  var pathParts = hrefParts[hrefParts.length - 1].split(\"/\");
459
460
  if (value === undefined)
460
461
  // A couple possibilities if it's namespaced, starting with two parts in the path -- and then try just one
461
462
  return [pathParts.slice(1, 3).join('/'), pathParts.slice(1, 2)[0]];
462
- else
463
- return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value;
463
+ else {
464
+ var queryString = param ? \"?\" + params.join(\"&\") : \"\";
465
+ return hrefParts[0] + \"://\" + pathParts[0] + \"/\" + value + queryString;
466
+ }
464
467
  }
465
468
  if (trimAfter) {
466
469
  var pathParts = hrefParts[0].split(\"/\");
467
470
  while (pathParts.lastIndexOf(trimAfter) !== pathParts.length - 1) pathParts.pop();
468
471
  hrefParts[0] = pathParts.join(\"/\");
469
472
  }
470
- var params = hrefParts.length > 1 ? hrefParts[1].split(\"&\") : [];
471
- params = params.reduce(function (s, v) { var parts = v.split(\"=\"); if (parts[1] !== null) s[parts[0]] = parts[1]; return s; }, {});
473
+ params = params.reduce(function (s, v) { var parts = v.split(\"=\"); if (parts[1]) s[parts[0]] = parts[1]; return s; }, {});
472
474
  if (value === undefined) return params[param];
473
475
  params[param] = value;
474
- var finalParams = Object.keys(params).reduce(function (s, v) { if (params[v] !== null) s.push(v + \"=\" + params[v]); return s; }, []).join(\"&\");
476
+ var finalParams = Object.keys(params).reduce(function (s, v) { if (params[v]) s.push(v + \"=\" + params[v]); return s; }, []).join(\"&\");
475
477
  return hrefParts[0] + (finalParams.length > 0 ? \"?\" + finalParams : \"\");
476
478
  }
477
479
 
@@ -534,6 +536,65 @@ if (headerTop) {
534
536
  }, true);
535
537
  }
536
538
  </script>"
539
+
540
+ erd_markup = "<div id=\"mermaidErd\" class=\"mermaid\">
541
+ erDiagram
542
+ <% model_short_name = #{@_brick_model.name.split('::').last.inspect}
543
+ callbacks = {}
544
+ @_brick_bt_descrip&.each do |bt|
545
+ bt_class = bt[1].first.first
546
+ callbacks[bt_name = bt_class.name.split('::').last] = bt_class
547
+ is_has_one = #{@_brick_model.name}.reflect_on_association(bt.first).inverse_of&.macro == :has_one ||
548
+ ::Brick.config.has_ones&.fetch('#{@_brick_model.name}', nil)&.key?(bt.first.to_s)
549
+ %> <%= \"#\{model_short_name} #\{is_has_one ? '||' : '}o'}--|| #\{bt_name} : \\\"#\{
550
+ bt.first unless bt.first.to_s == bt[1].first.first.name.underscore.singularize.tr('/', '_')
551
+ }\\\"\".html_safe %>
552
+ <% end
553
+ last_through = nil
554
+ @_brick_hm_counts&.each do |hm|
555
+ # Skip showing self-referencing HM links since they would have already been drawn while evaluating the BT side
556
+ next if (hm_class = hm.last&.klass) == #{@_brick_model.name}
557
+
558
+ callbacks[hm_name = hm_class.name.split('::').last] = hm_class
559
+ if (through = hm.last.options[:through]&.to_s) # has_many :through (HMT)
560
+ callbacks[through.singularize.camelize] = (through_assoc = hm.last.source_reflection).active_record
561
+ if last_through == through # Same HM, so no need to build it again, and for clarity just put in a blank line
562
+ %><%= \"\n\"
563
+ %><% else
564
+ %> <%= \"#\{model_short_name} ||--o{ #\{through_assoc.active_record.name}\".html_safe %> : \"\"
565
+ <% last_through = through
566
+ end
567
+ %> <%= \"#\{through_assoc.active_record.name} }o--|| #\{hm_name}\".html_safe %> : \"\"
568
+ <%= \"#\{model_short_name} }o..o{ #\{hm_name} : \\\"#\{hm.first}\\\"\".html_safe %><%
569
+ else # has_many
570
+ %> <%= \"#\{model_short_name} ||--o{ #\{hm_name} : \\\"#\{
571
+ hm_name unless hm.first.to_s == hm_class.name.underscore.pluralize.tr('/', '_')
572
+ }\\\"\".html_safe %><%
573
+ end %>
574
+ <% end
575
+ callbacks.merge({model_short_name => #{@_brick_model.name}}).each do |cb_k, cb_class|
576
+ cb_relation = ::Brick.relations[cb_class.table_name]
577
+ pkeys = cb_relation[:pkey]&.first&.last
578
+ fkeys = cb_relation[:fks]&.values&.each_with_object([]) { |fk, s| s << fk[:fk] if fk.fetch(:is_bt, nil) }
579
+ %> <%= cb_k %> {<%
580
+ pkeys&.each do |pk| %>
581
+ <%= \"int #\{pk} \\\"PK#\{' fk' if fkeys&.include?(pk)}\\\"\".html_safe %><%
582
+ end %><%
583
+ fkeys&.each do |fk|
584
+ if fk.is_a?(Array)
585
+ fk.each do |fk_part| %>
586
+ <%= \"int #\{fk_part} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk_part) %><%
587
+ end
588
+ else %>
589
+ <%= \"int #\{fk} \\\"&nbsp;&nbsp;&nbsp;&nbsp;fk\\\"\".html_safe unless pkeys&.include?(fk) %><%
590
+ end
591
+ end %>
592
+ }
593
+ <% end
594
+ # callback < %= cb_k % > erdClick
595
+ %>
596
+ </div>
597
+ "
537
598
  inline = case args.first
538
599
  when 'index'
539
600
  obj_pk = if pk&.is_a?(Array) # Composite primary key?
@@ -670,40 +731,9 @@ if (headerTop) {
670
731
  });
671
732
  });
672
733
  </script>
673
- <% end
674
- if true # @_brick_erd
675
- %><div id=\"mermaidErd\" class=\"mermaid\">
676
- erDiagram
677
- <% model_short_name = #{@_brick_model.name.split('::').last.inspect}
678
- callbacks = {}
679
- @_brick_bt_descrip.each do |bt|
680
- bt_full_name = bt[1].first.first.name
681
- callbacks[bt_name = bt_full_name.split('::').last] = bt_full_name
682
- # binding.pry
683
- %> <%= \"#\{model_short_name} #\{'||'}--#\{
684
- 'o{'} #\{bt_name} : \\\"#\{
685
- bt.first unless bt.first.to_s == bt[1].first.first.name.underscore.singularize.tr('/', '_')
686
- }\\\"\".html_safe %>
687
- <% end %>
688
- <% @_brick_hm_counts.each do |hm|
689
- hm_full_name = hm.last.klass.name
690
- callbacks[hm_name = hm_full_name.split('::').last] = hm_full_name
691
- %> <%= \"#\{model_short_name} #\{'}o'}--#\{
692
- '||'} #\{hm_name} : \\\"#\{
693
- hm.first unless hm.first.to_s == hm_full_name.underscore.pluralize.tr('/', '_')
694
- }\\\"\".html_safe %>
695
734
  <% end %>
696
- <% callbacks.keys.each do |cb|
697
- %> <%= cb %> {
698
- int id
699
- }
700
- <% end
701
- # callback < %= cb_k % > erdClick
702
- %>
703
- </div>
704
- <% end
705
-
706
- %><table id=\"headerTop\"></table>
735
+ #{erd_markup}
736
+ <table id=\"headerTop\"></table>
707
737
  <table id=\"#{table_name}\" class=\"shadow\">
708
738
  <thead><tr>#{"<th x-order=\"#{pk.join(',')}\"></th>" if pk.present?}<%=
709
739
  # Consider getting the name from the association -- hm.first.name -- if a more \"friendly\" alias should be used for a screwy table name
@@ -877,6 +907,7 @@ if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(
877
907
  description %><br><%
878
908
  end
879
909
  %><%= link_to '(See all #{obj_name.pluralize})', #{path_obj_name.pluralize}_path %>
910
+ #{erd_markup}
880
911
  <% if obj %>
881
912
  <br><br>
882
913
  <%= # path_options = [obj.#{pk}]
@@ -1034,7 +1065,7 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1034
1065
  var imgErd = document.getElementById(\"imgErd\");
1035
1066
  var mermaidErd = document.getElementById(\"mermaidErd\");
1036
1067
  var mermaidCode;
1037
- var cbs = {<%= callbacks.map { |k, v| \"#\{k}: \\\"#\{v.underscore.pluralize}\\\"\" }.join(', ').html_safe %>};
1068
+ var cbs = {<%= callbacks.map { |k, v| \"#\{k}: \\\"#\{v.name.underscore.pluralize}\\\"\" }.join(', ').html_safe %>};
1038
1069
  imgErd.addEventListener(\"click\", showErd);
1039
1070
  function showErd() {
1040
1071
  imgErd.style.display = \"none\";
@@ -1049,13 +1080,14 @@ flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
1049
1080
  securityLevel: \"loose\",
1050
1081
  mermaid: {callback: function(objId) {
1051
1082
  var svg = document.getElementById(objId);
1083
+ svg.removeAttribute(\"width\");
1052
1084
  var cb;
1053
1085
  for(cb in cbs) {
1054
1086
  var gErd = svg.getElementById(cb);
1055
1087
  gErd.setAttribute(\"class\", \"relatedModel\");
1056
1088
  gErd.addEventListener(\"click\",
1057
1089
  function (evt) {
1058
- location.href = changeout(changeout(location.href, null, cbs[this.id]), \"_brick_erd\", \"1\");
1090
+ location.href = changeout(changeout(location.href, -1, cbs[this.id]), \"_brick_erd\", \"1\");
1059
1091
  }
1060
1092
  );
1061
1093
  }
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 63
8
+ TINY = 66
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
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.63
4
+ version: 1.0.66
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-24 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord