brick 1.0.98 → 1.0.99
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 +44 -14
- data/lib/brick/frameworks/rails/engine.rb +18 -2
- data/lib/brick/frameworks/rails/form_tags.rb +47 -2
- data/lib/brick/version_number.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: 431e2aee4c3c199095d8475eeedcc46bd95e86a47c51623e3cea7fbbde59edcd
|
4
|
+
data.tar.gz: 32144a9a9ab6ec60ef297f27ae73e35cc891e5f9462b9beae4e7a0534ab77135
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f471bc993d97e92deae3c03e6cac9db0e350e72bd070afe5bcde1d0ca18d650b546db0d018a101009e429e9870a7e2c5e566f980c9e5b1319bc18873271c5550
|
7
|
+
data.tar.gz: 95f128f0f2a29cf0d1af1b5001eae27885b7e11ce23194e4a4da0141a0bfc059edd1917036f4addf1ee2aa4b69f763962e821ca31f9473048a6934dbecd8518e
|
data/lib/brick/extensions.rb
CHANGED
@@ -398,15 +398,27 @@ module ActiveRecord
|
|
398
398
|
# Links from ActiveRecord association pathing names over to real table correlation names
|
399
399
|
# that get chosen when the AREL AST tree is walked.
|
400
400
|
def brick_links
|
401
|
-
@brick_links ||= {}
|
401
|
+
@brick_links ||= { '' => table_name }
|
402
402
|
end
|
403
403
|
|
404
404
|
def brick_select(params, selects = [], order_by = nil, translations = {}, join_array = ::Brick::JoinArray.new)
|
405
405
|
is_add_bts = is_add_hms = true
|
406
406
|
|
407
|
-
|
408
|
-
|
409
|
-
|
407
|
+
if selects.empty?
|
408
|
+
# Build out cust_cols, bt_descrip and hm_counts now so that they are available on the
|
409
|
+
# model early in case the user wants to do an ORDER BY based on any of that.
|
410
|
+
model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
|
411
|
+
else
|
412
|
+
is_api = true
|
413
|
+
# If there are any provided selects, treat them as API columns and build them as cust_cols since they
|
414
|
+
# can be built using DSL.
|
415
|
+
# false = not polymorphic, and true = yes -- please emit_dsl
|
416
|
+
selects.each do |api_col|
|
417
|
+
pieces, my_dsl = brick_parse_dsl(join_array, [], translations, false, "[#{api_col}]", true)
|
418
|
+
_br_cust_cols[api_col.tr('.', '_')] = [pieces, my_dsl]
|
419
|
+
end
|
420
|
+
selects.clear # Now these have become custom columns
|
421
|
+
end
|
410
422
|
|
411
423
|
is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
412
424
|
is_mysql = ActiveRecord::Base.connection.adapter_name == 'Mysql2'
|
@@ -414,7 +426,7 @@ module ActiveRecord
|
|
414
426
|
is_distinct = nil
|
415
427
|
wheres = {}
|
416
428
|
params.each do |k, v|
|
417
|
-
next if ['_brick_schema', '_brick_order', 'controller', 'action'].include?(k)
|
429
|
+
next if ['_brick_schema', '_brick_order', '_brick_api', 'controller', 'action'].include?(k)
|
418
430
|
|
419
431
|
if (where_col = (ks = k.split('.')).last)[-1] == '!'
|
420
432
|
where_col = where_col[0..-2]
|
@@ -436,11 +448,14 @@ module ActiveRecord
|
|
436
448
|
|
437
449
|
# %%% Skip the metadata columns
|
438
450
|
if selects.empty? # Default to all columns
|
451
|
+
id_parts = (id_col = klass.primary_key).is_a?(Array) ? id_col : [id_col]
|
439
452
|
tbl_no_schema = table.name.split('.').last
|
440
453
|
# %%% Have once gotten this error with MSSQL referring to http://localhost:3000/warehouse/cold_room_temperatures__archive
|
441
454
|
# ActiveRecord::StatementInvalid (TinyTds::Error: DBPROCESS is dead or not enabled)
|
442
455
|
# Relevant info here: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/402
|
443
456
|
columns.each do |col|
|
457
|
+
next if is_api && id_parts.exclude?(col.name) # Only keep the ID columns if this is an API request
|
458
|
+
|
444
459
|
col_alias = " AS #{col.name}_" if (col_name = col.name) == 'class'
|
445
460
|
selects << if is_mysql
|
446
461
|
"`#{tbl_no_schema}`.`#{col_name}`#{col_alias}"
|
@@ -490,22 +505,28 @@ module ActiveRecord
|
|
490
505
|
# binding.pry
|
491
506
|
next
|
492
507
|
end
|
493
|
-
|
494
508
|
key_klass = nil
|
495
509
|
key_tbl_name = nil
|
496
510
|
dest_pk = nil
|
497
511
|
key_alias = nil
|
498
512
|
cc.first.each do |cc_part|
|
499
|
-
dest_klass = cc_part[0..-2].inject(klass)
|
513
|
+
dest_klass = cc_part[0..-2].inject(klass) do |kl, cc_part_term|
|
514
|
+
# %%% Clear column info properly so we can do multiple subsequent requests
|
515
|
+
# binding.pry unless kl.reflect_on_association(cc_part_term)
|
516
|
+
kl.reflect_on_association(cc_part_term)&.klass || klass
|
517
|
+
end
|
500
518
|
tbl_name = rel_dupe.brick_links[cc_part[0..-2].map(&:to_s).join('.')]
|
501
519
|
# Deal with the conflict if there are two parts in the custom column named the same,
|
502
520
|
# "category.name" and "product.name" for instance will end up with aliases of "name"
|
503
521
|
# and "product__name".
|
504
|
-
cc_part_idx = cc_part.length - 1
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
522
|
+
if (cc_part_idx = cc_part.length - 1).zero?
|
523
|
+
col_alias = "br_cc_#{k}__#{table_name.tr('.', '_')}"
|
524
|
+
else
|
525
|
+
while cc_part_idx > 0 &&
|
526
|
+
(col_alias = "br_cc_#{k}__#{cc_part[cc_part_idx..-1].map(&:to_s).join('__').tr('.', '_')}") &&
|
527
|
+
used_col_aliases.key?(col_alias)
|
528
|
+
cc_part_idx -= 1
|
529
|
+
end
|
509
530
|
end
|
510
531
|
used_col_aliases[col_alias] = nil
|
511
532
|
# Set up custom column links by preparing key_klass and key_alias
|
@@ -1372,7 +1393,7 @@ class Object
|
|
1372
1393
|
when Symbol
|
1373
1394
|
order_tbl[order_default] || order_default
|
1374
1395
|
else
|
1375
|
-
pk.map(
|
1396
|
+
pk.map { |part| "#{table_name}.#{part}"}.join(', ') # If it's not a custom ORDER BY, just use the key
|
1376
1397
|
end
|
1377
1398
|
end
|
1378
1399
|
|
@@ -1568,7 +1589,15 @@ class Object
|
|
1568
1589
|
order_by, _ = model._brick_calculate_ordering(ordering, true) # Don't do the txt part
|
1569
1590
|
|
1570
1591
|
ar_relation = ActiveRecord.version < Gem::Version.new('4') ? model.preload : model.all
|
1571
|
-
|
1592
|
+
|
1593
|
+
if (cc = params['_brick_api']&.split(','))
|
1594
|
+
is_api = true
|
1595
|
+
selects = cc
|
1596
|
+
counts = [] # No need for any extra HM count columns
|
1597
|
+
model._br_cust_cols.clear
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
@_brick_params = ar_relation.brick_select(params, (selects ||= []), order_by,
|
1572
1601
|
translations = {},
|
1573
1602
|
join_array = ::Brick::JoinArray.new)
|
1574
1603
|
# %%% Add custom HM count columns
|
@@ -1582,6 +1611,7 @@ class Object
|
|
1582
1611
|
"b_r_#{v.first}.c_t_ AS \"b_r_#{v.first}_ct\""
|
1583
1612
|
end
|
1584
1613
|
end
|
1614
|
+
|
1585
1615
|
ar_select = ar_relation.respond_to?(:_select!) ? ar_relation.dup._select!(*selects, *counts) : ar_relation.select(selects + counts)
|
1586
1616
|
instance_variable_set("@#{table_name.pluralize}".to_sym, ar_select)
|
1587
1617
|
if namespace && (idx = lookup_context.prefixes.index(table_name))
|
@@ -424,6 +424,14 @@ h1, h3 {
|
|
424
424
|
cursor: pointer;
|
425
425
|
}
|
426
426
|
|
427
|
+
#apiToggle {
|
428
|
+
border: 2px solid purple;
|
429
|
+
}
|
430
|
+
|
431
|
+
#apiToggle, .apiColName {
|
432
|
+
cursor: pointer;
|
433
|
+
}
|
434
|
+
|
427
435
|
#dropper {
|
428
436
|
background-color: #eee;
|
429
437
|
}
|
@@ -1004,6 +1012,9 @@ erDiagram
|
|
1004
1012
|
<p style=\"color: green\"><%= notice %></p>#{"
|
1005
1013
|
#{schema_options}" if schema_options}
|
1006
1014
|
<select id=\"tbl\">#{table_options}</select>
|
1015
|
+
|
1016
|
+
<%= pick_api(#{model_name}).html_safe %>
|
1017
|
+
|
1007
1018
|
<table id=\"resourceName\"><tr>
|
1008
1019
|
<td><h1>#{model_name}</h1></td>
|
1009
1020
|
<td id=\"imgErd\" title=\"Show ERD\"></td>
|
@@ -1077,8 +1088,13 @@ erDiagram
|
|
1077
1088
|
end
|
1078
1089
|
|
1079
1090
|
# Write out the mega-grid
|
1080
|
-
|
1081
|
-
|
1091
|
+
if params['_brick_api'] # API response?
|
1092
|
+
brick_grid(@#{table_name}, @_brick_bt_descrip, @_brick_sequence, [], @_brick_excl,
|
1093
|
+
cols, poly_cols, {}, [], {})
|
1094
|
+
else
|
1095
|
+
brick_grid(@#{table_name}, @_brick_bt_descrip, @_brick_sequence, @_brick_incl, @_brick_excl,
|
1096
|
+
cols, poly_cols, bts, #{hms_keys.inspect}, {#{hms_columns.join(', ')}})
|
1097
|
+
end %>
|
1082
1098
|
|
1083
1099
|
#{"<hr><%= link_to \"New #{obj_name}\", new_#{path_obj_name}_path %>" unless @_brick_model.is_view?}
|
1084
1100
|
#{script}
|
@@ -11,7 +11,7 @@ module Brick::Rails::FormTags
|
|
11
11
|
out << "<th x-order=\"#{pk.join(',')}\"></th>"
|
12
12
|
end
|
13
13
|
|
14
|
-
col_keys
|
14
|
+
col_keys ||= relation.columns.each_with_object([]) do |col, s|
|
15
15
|
col_name = col.name
|
16
16
|
next if inclusions&.exclude?(col_name) ||
|
17
17
|
(pk.include?(col_name) && [:integer, :uuid].include?(col.type) && !bts.key?(col_name)) ||
|
@@ -122,7 +122,7 @@ module Brick::Rails::FormTags
|
|
122
122
|
if (link_id = obj.send(cust_col.last[1]) if cust_col.last)
|
123
123
|
out << link_to(cust_txt, send("#{cust_col.last.first._brick_index(:singular)}_path", link_id))
|
124
124
|
else
|
125
|
-
out << cust_txt
|
125
|
+
out << (cust_txt || '')
|
126
126
|
end
|
127
127
|
else # Bad column name!
|
128
128
|
out << '?'
|
@@ -137,6 +137,51 @@ module Brick::Rails::FormTags
|
|
137
137
|
out.html_safe
|
138
138
|
end # brick_grid
|
139
139
|
|
140
|
+
# Recursively render UL and LI to choose columns to include
|
141
|
+
def pick_api(model, is_last = nil, visited = [])
|
142
|
+
out = +''
|
143
|
+
if visited.empty?
|
144
|
+
out << '<span id="apiToggle">API buffet</span><div id="apiBuffet" style="display: none;">'
|
145
|
+
out << '<textarea id="apiCode" cols="100"></textarea>'
|
146
|
+
out << '<input type="button" id="apiRender" value="Render">'
|
147
|
+
end
|
148
|
+
out << "\n#{indent = ' ' * visited.length}<ul>"
|
149
|
+
model.column_names.each { |col_name| out << "\n#{indent} <li class=\"apiColName\" x-nm=\"#{visited.map { |v| "#{v.last}." }.join}#{col_name}\">#{col_name}</li>" }
|
150
|
+
unless is_last || visited.length == 2
|
151
|
+
model.reflect_on_all_associations.each_with_object({}) do |v, s|
|
152
|
+
next if v.macro == :has_many || v.polymorphic?
|
153
|
+
|
154
|
+
out << "\n#{indent} <li><b>#{v.name}</b>#{pick_api(v.klass, visited.map(&:first).include?(v.klass),
|
155
|
+
visited.dup << [v.klass, v.name]
|
156
|
+
)}"
|
157
|
+
out << "\n#{indent} </li>"
|
158
|
+
s[v.name] = nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
out << "\n#{indent}</ul>"
|
162
|
+
if visited.empty?
|
163
|
+
out << '</div><script>[... document.getElementsByClassName("apiColName")].forEach(function (li) {li.addEventListener("click", apiColClick);});'
|
164
|
+
out << "
|
165
|
+
var colList = [];
|
166
|
+
var apiBuffet = document.getElementById(\"apiBuffet\");
|
167
|
+
var apiCode = document.getElementById(\"apiCode\");
|
168
|
+
function apiColClick(evt) {
|
169
|
+
apiCode.innerHTML += this.getAttribute(\"x-nm\") + \",\\n\";
|
170
|
+
}
|
171
|
+
document.getElementById(\"apiToggle\").addEventListener(\"click\", function () {
|
172
|
+
apiBuffet.style.display = (apiBuffet.style.display === \"block\" ? \"none\" : \"block\");
|
173
|
+
});
|
174
|
+
// Cheap and cheerful way to render a list of columns just for the demo
|
175
|
+
document.getElementById(\"apiRender\").addEventListener(\"click\", function () {
|
176
|
+
var changecolList = apiCode.innerHTML.substring(0, apiCode.innerHTML.length - 2);
|
177
|
+
location.href = changeout(location.href, \"_brick_api\", changecolList);
|
178
|
+
});
|
179
|
+
</script>
|
180
|
+
"
|
181
|
+
end
|
182
|
+
out
|
183
|
+
end
|
184
|
+
|
140
185
|
def link_to_brick(*args, **kwargs)
|
141
186
|
return unless ::Brick.config.mode == :on
|
142
187
|
|
data/lib/brick/version_number.rb
CHANGED
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.99
|
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-12-
|
11
|
+
date: 2022-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|