brick 1.0.60 → 1.0.63
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/extensions.rb +8 -3
- data/lib/brick/frameworks/rails/engine.rb +159 -16
- data/lib/brick/version_number.rb +1 -1
- data/lib/generators/brick/migrations_generator.rb +1 -1
- 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: c28a4db728e9312def40be9a9a790f1f22f464c6d6ade2b6e12f255730cd4111
|
4
|
+
data.tar.gz: c2e75de42686c9ad0707fd6eca3d0b0a12207e051d77622d70276845d9af0949
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a897f30028aac1b6e14edc967a82c268aa58236cd424ecf977409a0c893d42b9e291c11ac2b2a411f00dc35c23b80a4ed6adecde394587c96d11b9f51c173fd8
|
7
|
+
data.tar.gz: 538d694b6a0717045c6e23ec536a000a552bc0ece9009f74511e33013e0dde97f8cefadbc61a45d4b7ea884dd0c1dd985f5defc58175ec51318d345a7e561c2d
|
data/lib/brick/extensions.rb
CHANGED
@@ -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))
|
@@ -1460,7 +1461,9 @@ module ActiveRecord::ConnectionHandling
|
|
1460
1461
|
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu2
|
1461
1462
|
ON kcu2.CONSTRAINT_CATALOG = rc.UNIQUE_CONSTRAINT_CATALOG
|
1462
1463
|
AND kcu2.CONSTRAINT_SCHEMA = rc.UNIQUE_CONSTRAINT_SCHEMA
|
1463
|
-
AND kcu2.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
|
1464
|
+
AND kcu2.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME#{"
|
1465
|
+
AND kcu2.TABLE_NAME = kcu1.REFERENCED_TABLE_NAME
|
1466
|
+
AND kcu2.COLUMN_NAME = kcu1.REFERENCED_COLUMN_NAME" unless is_postgres }
|
1464
1467
|
AND kcu2.ORDINAL_POSITION = kcu1.ORDINAL_POSITION#{"
|
1465
1468
|
WHERE kcu1.CONSTRAINT_SCHEMA = COALESCE(current_setting('SEARCH_PATH'), 'public')" if is_postgres && schema }"
|
1466
1469
|
# AND kcu2.TABLE_NAME = ?;", Apartment::Tenant.current, table_name
|
@@ -1540,8 +1543,10 @@ module ActiveRecord::ConnectionHandling
|
|
1540
1543
|
ON kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
|
1541
1544
|
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
1542
1545
|
AND kcu.CONSTRAINT_NAME = tc.constraint_name
|
1543
|
-
WHERE t.table_schema
|
1544
|
-
|
1546
|
+
WHERE t.table_schema #{is_postgres ?
|
1547
|
+
"NOT IN ('information_schema', 'pg_catalog')"
|
1548
|
+
:
|
1549
|
+
"= '#{ActiveRecord::Base.connection.current_database.tr("'", "''")}'"}#{"
|
1545
1550
|
AND t.table_schema = COALESCE(current_setting('SEARCH_PATH'), 'public')" if is_postgres && schema }
|
1546
1551
|
-- AND t.table_type IN ('VIEW') -- 'BASE TABLE', 'FOREIGN TABLE'
|
1547
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
|
-
|
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
|
-
<
|
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
|
-
|
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
|
700
|
-
|
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
|
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 =
|
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) {
|
data/lib/brick/version_number.rb
CHANGED
@@ -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',
|
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.
|
4
|
+
version: 1.0.63
|
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-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|