brick 1.0.61 → 1.0.62

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: 67de1c0cde3f28379388dfe0c2aa488197c5cfaad1a108408b506ba66ab64b38
4
- data.tar.gz: 7d3e40960043e5e09e483dee791dd5f7c1d0f54f692a39ec2ef85b1b5cba1073
3
+ metadata.gz: ae6fe72ae3ec1d2ba6318f1bb6cb4964b29a1479e3b76e2cb560537cc6a6ff6c
4
+ data.tar.gz: 608fbd2c50c31dd4eff33a4d7c8a19786c53518e9fc1ff38059bf47ca254b6ba
5
5
  SHA512:
6
- metadata.gz: 90ae5f021e562d3188c4bde03e9b71a744417c5223f5736cff97cce90646b8b06860b245dcb718414fdce00df2c772bcbe1ad0d102310d7f3ff030641591387d
7
- data.tar.gz: 704f2dde1c0043a141d96ff272346ac583e7f784df494bb4ce39f4bf5e2cd06ffadfa37783a1bfb0671c5a5fd120819c9f286e5c9bd0608764aa10338840d881
6
+ metadata.gz: 0b0c3fcc243cde60b35f2cf07277a53c413b1b805d9a31cf00f4d89676b7eaf0d79ba1ea22bc33190ff8df55eab96e62b0c986f1894dc11e55b8358dbae7cc57
7
+ data.tar.gz: 32d9c0e8bba6f2a477ed85347680113ab92d1ed52ce044d97bacf734d33fa7c9e7f62bc87ab01b2a027e1f41c62afe802f3601e14f7bdc9d8026b03050337c23
@@ -1132,6 +1132,7 @@ class Object
1132
1132
  @_brick_bt_descrip = model._br_bt_descrip
1133
1133
  @_brick_hm_counts = model._br_hm_counts
1134
1134
  @_brick_join_array = join_array
1135
+ @_brick_erd = params['_brick_erd']&.to_i
1135
1136
  end
1136
1137
 
1137
1138
  _, order_by_txt = model._brick_calculate_ordering(default_ordering(table_name, pk))
@@ -1542,8 +1543,10 @@ module ActiveRecord::ConnectionHandling
1542
1543
  ON kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
1543
1544
  AND kcu.TABLE_NAME = tc.TABLE_NAME
1544
1545
  AND kcu.CONSTRAINT_NAME = tc.constraint_name
1545
- WHERE t.table_schema #{
1546
- is_postgres ? "NOT IN ('information_schema', 'pg_catalog')" : "= '#{ActiveRecord::Base.connection.current_database.tr("'", "''")}'"}#{"
1546
+ WHERE t.table_schema #{is_postgres ?
1547
+ "NOT IN ('information_schema', 'pg_catalog')"
1548
+ :
1549
+ "= '#{ActiveRecord::Base.connection.current_database.tr("'", "''")}'"}#{"
1547
1550
  AND t.table_schema = COALESCE(current_setting('SEARCH_PATH'), 'public')" if is_postgres && schema }
1548
1551
  -- AND t.table_type IN ('VIEW') -- 'BASE TABLE', 'FOREIGN TABLE'
1549
1552
  AND t.table_name NOT IN ('pg_stat_statements', ?, ?)
@@ -47,7 +47,10 @@ module Brick
47
47
  end
48
48
 
49
49
  # After we're initialized and before running the rest of stuff, put our configuration in place
50
- ActiveSupport.on_load(:after_initialize) do
50
+ ActiveSupport.on_load(:after_initialize) do |app|
51
+ assets_path = File.expand_path("#{__dir__}/../../../../vendor/assets")
52
+ (app.config.assets.precompile ||= []) << "#{assets_path}/images/brick_erd.png"
53
+ (app.config.assets.paths ||= []) << assets_path
51
54
  # ====================================
52
55
  # Dynamically create generic templates
53
56
  # ====================================
@@ -179,6 +182,30 @@ module Brick
179
182
  h1, h3 {
180
183
  margin-bottom: 0;
181
184
  }
185
+ #resourceName {
186
+ }
187
+ #imgErd {
188
+ background-image:url(assets/brick_erd.png);
189
+ background-size: 100% 100%;
190
+ width: 2.2em;
191
+ height: 2.2em;
192
+ cursor: pointer;
193
+ }
194
+ #mermaidErd {
195
+ position: relative;
196
+ display: none;
197
+ }
198
+ #mermaidErd .exclude {
199
+ position: absolute;
200
+ color: red;
201
+ top: 0;
202
+ right: 0;
203
+ cursor: pointer;
204
+ }
205
+ .relatedModel {
206
+ cursor: pointer;
207
+ }
208
+
182
209
  #dropper {
183
210
  background-color: #eee;
184
211
  }
@@ -196,6 +223,8 @@ table {
196
223
  border-collapse: collapse;
197
224
  font-size: 0.9em;
198
225
  font-family: sans-serif;
226
+ }
227
+ table.shadow {
199
228
  min-width: 400px;
200
229
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
201
230
  }
@@ -213,6 +242,7 @@ tr th {
213
242
  display: none;
214
243
  top: 0;
215
244
  right: 0;
245
+ cursor: pointer;
216
246
  }
217
247
  #headerTop tr th:hover {
218
248
  background-color: #18B090;
@@ -245,7 +275,7 @@ tr th, tr td {
245
275
  color: #80B8D2;
246
276
  }
247
277
 
248
- table tbody tr {
278
+ table.shadow tbody tr {
249
279
  border-bottom: thin solid #dddddd;
250
280
  }
251
281
 
@@ -253,7 +283,7 @@ table tbody tr:nth-of-type(even) {
253
283
  background-color: #f3f3f3;
254
284
  }
255
285
 
256
- table tbody tr:last-of-type {
286
+ table.shadow tbody tr:last-of-type {
257
287
  border-bottom: 2px solid #009879;
258
288
  }
259
289
 
@@ -327,6 +357,28 @@ def hide_bcrypt(val, max_len = 200)
327
357
  end
328
358
  val
329
359
  end
360
+ end
361
+ def display_value(col_type, val)
362
+ case col_type
363
+ when 'geometry'
364
+ if Object.const_defined?('RGeo')
365
+ @is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2' if @is_mysql.nil?
366
+ if @is_mysql
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..]
370
+ end
371
+ RGeo::WKRep::WKBParser.new.parse(val)
372
+ else
373
+ '(Add RGeo gem to parse geometry detail)'
374
+ end
375
+ else
376
+ if col_type
377
+ hide_bcrypt(val)
378
+ else
379
+ '?'
380
+ end
381
+ end
330
382
  end %>"
331
383
 
332
384
  if ['index', 'show', 'update'].include?(args.first)
@@ -416,10 +468,11 @@ function changeout(href, param, value, trimAfter) {
416
468
  hrefParts[0] = pathParts.join(\"/\");
417
469
  }
418
470
  var params = hrefParts.length > 1 ? hrefParts[1].split(\"&\") : [];
419
- params = params.reduce(function (s, v) { var parts = v.split(\"=\"); s[parts[0]] = parts[1]; return s; }, {});
471
+ params = params.reduce(function (s, v) { var parts = v.split(\"=\"); if (parts[1] !== null) s[parts[0]] = parts[1]; return s; }, {});
420
472
  if (value === undefined) return params[param];
421
473
  params[param] = value;
422
- return hrefParts[0] + \"?\" + Object.keys(params).reduce(function (s, v) { s.push(v + \"=\" + params[v]); return s; }, []).join(\"&\");
474
+ var finalParams = Object.keys(params).reduce(function (s, v) { if (params[v] !== null) s.push(v + \"=\" + params[v]); return s; }, []).join(\"&\");
475
+ return hrefParts[0] + (finalParams.length > 0 ? \"?\" + finalParams : \"\");
423
476
  }
424
477
 
425
478
  // Snag first TR for sticky header
@@ -583,7 +636,10 @@ if (headerTop) {
583
636
  <p style=\"color: green\"><%= notice %></p>#{"
584
637
  <select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
585
638
  <select id=\"tbl\">#{table_options}</select>
586
- <h1>#{model_plural = model_name.pluralize}</h1>#{template_link}<%
639
+ <table id=\"resourceName\"><tr>
640
+ <td><h1>#{model_plural = model_name.pluralize}</h1></td>
641
+ <td id=\"imgErd\" title=\"Show ERD\"></td>
642
+ </tr></table>#{template_link}<%
587
643
  if (description = (relation = Brick.relations[#{model_name}.table_name])&.fetch(:description, nil)) %><%=
588
644
  description %><br><%
589
645
  end
@@ -614,10 +670,41 @@ if (headerTop) {
614
670
  });
615
671
  });
616
672
  </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
+ <% end %>
696
+ <% callbacks.keys.each do |cb|
697
+ %> <%= cb %> {
698
+ int id
699
+ }
700
+ <% end
701
+ # callback < %= cb_k % > erdClick
702
+ %>
703
+ </div>
617
704
  <% end
618
705
 
619
- %><table id=\"headerTop\">
620
- <table id=\"#{table_name}\">
706
+ %><table id=\"headerTop\"></table>
707
+ <table id=\"#{table_name}\" class=\"shadow\">
621
708
  <thead><tr>#{"<th x-order=\"#{pk.join(',')}\"></th>" if pk.present?}<%=
622
709
  # Consider getting the name from the association -- hm.first.name -- if a more \"friendly\" alias should be used for a screwy table name
623
710
  cols = {#{hms_keys = []
@@ -683,7 +770,7 @@ if (headerTop) {
683
770
  <% end
684
771
  elsif (hms_col = hms_cols[col_name])
685
772
  if hms_col.length == 1 %>
686
- <%= hms_col.first %>
773
+ <%= hms_col.first %>
687
774
  <% else
688
775
  klass = (col = cols[col_name])[1]
689
776
  txt = if col[2] == 'HO'
@@ -696,8 +783,8 @@ if (headerTop) {
696
783
  end %>
697
784
  <%= link_to txt, send(\"#\{klass.name.underscore.tr('/', '_').pluralize}_path\".to_sym, hms_col[2]) unless hms_col[1]&.zero? %>
698
785
  <% end
699
- elsif cols.key?(col_name)
700
- %><%= hide_bcrypt(val) %><%
786
+ elsif (col = cols[col_name])
787
+ %><%= display_value(col&.type || col&.sql_type, val) %><%
701
788
  else # Bad column name!
702
789
  %>?<%
703
790
  end
@@ -720,7 +807,7 @@ if (headerTop) {
720
807
  <select id=\"schema\">#{schema_options}</select>" if ::Brick.config.schema_behavior[:multitenant] && ::Brick.db_schemas.length > 1}
721
808
  <select id=\"tbl\">#{table_options}</select>
722
809
  <h1>Status</h1>
723
- <table id=\"status\"><thead><tr>
810
+ <table id=\"status\" class=\"shadow\"><thead><tr>
724
811
  <th>Resource</th>
725
812
  <th>Table</th>
726
813
  <th>Migration</th>
@@ -754,7 +841,7 @@ if (headerTop) {
754
841
  %></td>
755
842
  <tr>
756
843
  <% end %>
757
- </tbody><table>
844
+ </tbody></table>
758
845
  #{script}"
759
846
 
760
847
  when 'orphans'
@@ -796,7 +883,7 @@ end
796
883
  # path_options << { '_brick_schema': } if
797
884
  # url = send(:#{model_name.underscore}_path, obj.#{pk})
798
885
  form_for(obj.becomes(#{model_name})) do |f| %>
799
- <table>
886
+ <table class=\"shadow\">
800
887
  <% has_fields = false
801
888
  @#{obj_name}.attributes.each do |k, val|
802
889
  col = #{model_name}.columns_hash[k] %>
@@ -853,7 +940,7 @@ end
853
940
  <% else
854
941
  html_options = {}
855
942
  html_options[:class] = 'dimmed' unless val
856
- case (col_type = #{model_name}.column_for_attribute(k).type)
943
+ case (col_type = col.type || col.sql_type)
857
944
  when :string, :text %>
858
945
  <% if is_bcrypt?(val) # || .readonly? %>
859
946
  <%= hide_bcrypt(val, 1000) %>
@@ -883,6 +970,8 @@ end
883
970
  # If it's not yet enabled then: create extension ltree;
884
971
  val %>
885
972
  <% when :binary, :primary_key %>
973
+ <% else %>
974
+ <%= display_value(col_type, val) %>
886
975
  <% end %>
887
976
  <% end %>
888
977
  </td>
@@ -903,7 +992,7 @@ end
903
992
  if (pk = hm.first.klass.primary_key)
904
993
  hm_singular_name = (hm_name = hm.first.name.to_s).singularize.underscore
905
994
  obj_pk = (pk.is_a?(Array) ? pk : [pk]).each_with_object([]) { |pk_part, s| s << "#{hm_singular_name}.#{pk_part}" }.join(', ')
906
- s << "<table id=\"#{hm_name}\">
995
+ s << "<table id=\"#{hm_name}\" class=\"shadow\">
907
996
  <tr><th>#{hm[3]}</th></tr>
908
997
  <% collection = @#{obj_name}.#{hm_name}
909
998
  collection = collection.is_a?(ActiveRecord::Associations::CollectionProxy) ? collection.order(#{pk.inspect}) : [collection].compact
@@ -938,7 +1027,61 @@ flatpickr(\".datetimepicker\", {enableTime: true});
938
1027
  flatpickr(\".timepicker\", {enableTime: true, noCalendar: true});
939
1028
  </script>
940
1029
  <% end %>
1030
+
1031
+ <% if true # @_brick_erd
1032
+ %>
941
1033
  <script>
1034
+ var imgErd = document.getElementById(\"imgErd\");
1035
+ var mermaidErd = document.getElementById(\"mermaidErd\");
1036
+ var mermaidCode;
1037
+ var cbs = {<%= callbacks.map { |k, v| \"#\{k}: \\\"#\{v.underscore.pluralize}\\\"\" }.join(', ').html_safe %>};
1038
+ imgErd.addEventListener(\"click\", showErd);
1039
+ function showErd() {
1040
+ imgErd.style.display = \"none\";
1041
+ mermaidErd.style.display = \"inline-block\";
1042
+ if (mermaidCode) return; // Cut it short if we've already rendered the diagram
1043
+
1044
+ mermaidCode = document.createElement(\"SCRIPT\");
1045
+ mermaidCode.setAttribute(\"src\", \"https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js\");
1046
+ mermaidCode.addEventListener(\"load\", function () {
1047
+ mermaid.initialize({
1048
+ startOnLoad: true,
1049
+ securityLevel: \"loose\",
1050
+ mermaid: {callback: function(objId) {
1051
+ var svg = document.getElementById(objId);
1052
+ var cb;
1053
+ for(cb in cbs) {
1054
+ var gErd = svg.getElementById(cb);
1055
+ gErd.setAttribute(\"class\", \"relatedModel\");
1056
+ gErd.addEventListener(\"click\",
1057
+ function (evt) {
1058
+ location.href = changeout(changeout(location.href, null, cbs[this.id]), \"_brick_erd\", \"1\");
1059
+ }
1060
+ );
1061
+ }
1062
+ }}
1063
+ });
1064
+ mermaid.contentLoaded();
1065
+ // Add <span> at the end
1066
+ var span = document.createElement(\"SPAN\");
1067
+ span.className = \"exclude\";
1068
+ span.innerHTML = \"X\";
1069
+ span.addEventListener(\"click\", function (e) {
1070
+ e.stopPropagation();
1071
+ imgErd.style.display = \"table-cell\";
1072
+ mermaidErd.style.display = \"none\";
1073
+ window.history.pushState({}, '', changeout(location.href, '_brick_erd', null));
1074
+ });
1075
+ mermaidErd.appendChild(span);
1076
+ });
1077
+ document.body.appendChild(mermaidCode);
1078
+ }
1079
+ <%= \" showErd();\n\" if (@_brick_erd || 0) > 0
1080
+ %></script>
1081
+
1082
+ <% end
1083
+
1084
+ %><script>
942
1085
  <% # Make column headers sort when clicked
943
1086
  # %%% Create a smart javascript routine which can do this client-side %>
944
1087
  [... document.getElementsByTagName(\"TH\")].forEach(function (th) {
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 61
8
+ TINY = 62
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
@@ -21,7 +21,7 @@ module Brick
21
21
  'timestamp with time zone' => 'timestamp',
22
22
  'time without time zone' => 'time',
23
23
  'time with time zone' => 'time',
24
- 'double precision' => 'float', # might work with 'double'
24
+ 'double precision' => 'float',
25
25
  'smallint' => 'integer' } # %%% Need to put in "limit: 2"
26
26
  # (Still need to find what "inet" and "json" data types map to.)
27
27
 
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.61
4
+ version: 1.0.62
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-23 00:00:00.000000000 Z
11
+ date: 2022-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord