brick 1.0.143 → 1.0.144

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: 5f3f2c35ad5ad81b538cb12c4d5166ed24bbf5e60bbc02583ed3d6f60cb38783
4
- data.tar.gz: 2e598860e1be1b371160146ad05b8c43dfaa108c6125a1c567774fc928945a5f
3
+ metadata.gz: 6b84f681ffcc3cfbc37531e21ee68c07a27df07d0b0b63aed94d7e13fedc8ec1
4
+ data.tar.gz: b1f96b376d7c27b9a01e8025f8628efdfedff77875b089323e66bdff557a4141
5
5
  SHA512:
6
- metadata.gz: d4a99c758d21966a05f82b10d6b33865c17d85dcacb1a0c2af5d6cada712f062f30ebeab0124e7a8d31d132fe83cc265474246b2d45efa98a0b0a0c86f377cb9
7
- data.tar.gz: 004b04e031315c1b7b96b516a55c13a7587fe109179b6ae1bd7dbe11ca305c37adfdb61b2f6c2acf26fb35cb9fbbba898c18552bc2ad050bec48fa5dec072c3d
6
+ metadata.gz: d6b2dfbd93defb98b61bd20c405657d8b3df5c9f1c4887dc37fe75a09fdcc61abc9ba15a1e9a16006487017f270d62ca1843fefeea574eb8df07fc55f136693b
7
+ data.tar.gz: 4f1d192f9420b9f8cfac9fa7d6f7f6c057d5bb0f852b8066937f79410b20005b4080b6bdec16f2e470e8fa1a9e5331fd26b64d675e1e397942ec65a371f8d977
@@ -316,8 +316,10 @@ module ActiveRecord
316
316
  def self.brick_import_template
317
317
  template = constants.include?(:IMPORT_TEMPLATE) ? self::IMPORT_TEMPLATE : suggest_template(0, false, true)
318
318
  # Add the primary key to the template as being unique (unless it's already there)
319
- template[:uniques] = [pk = primary_key.to_sym]
320
- template[:all].unshift(pk) unless template[:all].include?(pk)
319
+ if primary_key
320
+ template[:uniques] = [pk = primary_key.to_sym]
321
+ template[:all].unshift(pk) unless template[:all].include?(pk)
322
+ end
321
323
  template
322
324
  end
323
325
 
@@ -512,9 +514,6 @@ module ActiveRecord
512
514
  # model early in case the user wants to do an ORDER BY based on any of that.
513
515
  model._brick_calculate_bts_hms(translations, join_array) if is_add_bts || is_add_hms
514
516
 
515
- is_postgres = ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
516
- is_mysql = ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
517
- is_mssql = ActiveRecord::Base.connection.adapter_name == 'SQLServer'
518
517
  is_distinct = nil
519
518
  wheres = {}
520
519
  params.each do |k, v|
@@ -836,47 +835,27 @@ module ActiveRecord
836
835
  next
837
836
  end
838
837
 
839
- tbl_alias = if is_mysql
840
- "`b_r_#{hm.name}`"
841
- elsif is_postgres
842
- "\"b_r_#{hm.name}\""
843
- else
844
- "b_r_#{hm.name}"
845
- end
846
- pri_tbl_name = is_mysql ? "`#{pri_tbl.table_name}`" : "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
847
- pri_tbl_name = if is_mysql
848
- "`#{pri_tbl.table_name}`"
849
- elsif is_postgres || is_mssql
850
- "\"#{pri_tbl.table_name.gsub('.', '"."')}\""
851
- else
852
- pri_tbl.table_name
853
- end
838
+ tbl_alias = "b_r_#{hm.name}"
854
839
  on_clause = []
855
840
  hm_selects = if fk_col.is_a?(Array) # Composite key?
856
- fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl_name}.#{pri_key[idx]}" }
841
+ fk_col.each_with_index { |fk_col_part, idx| on_clause << "#{tbl_alias}.#{fk_col_part} = #{pri_tbl.table_name}.#{pri_key[idx]}" }
857
842
  fk_col.dup
858
843
  else
859
- on_clause << "#{tbl_alias}.#{fk_col} = #{pri_tbl_name}.#{pri_key}"
844
+ on_clause << "#{_br_quoted_name("#{tbl_alias}.#{fk_col}")} = #{_br_quoted_name("#{pri_tbl.table_name}.#{pri_key}")}"
860
845
  [fk_col]
861
846
  end
862
847
  if poly_type
863
848
  hm_selects << poly_type
864
- on_clause << "#{tbl_alias}.#{poly_type} = '#{name}'"
849
+ on_clause << "#{_br_quoted_name("#{tbl_alias}.#{poly_type}")} = '#{name}'"
865
850
  end
866
851
  unless from_clause
867
852
  tbl_nm = hm.macro == :has_and_belongs_to_many ? hm.join_table : hm.table_name
868
- hm_table_name = if is_mysql
869
- "`#{tbl_nm}`"
870
- elsif is_postgres || is_mssql
871
- "\"#{(tbl_nm).gsub('.', '"."')}\""
872
- else
873
- tbl_nm
874
- end
853
+ hm_table_name = _br_quoted_name(tbl_nm)
875
854
  end
876
855
  group_bys = ::Brick.is_oracle || is_mssql ? hm_selects : (1..hm_selects.length).to_a
877
856
  join_clause = "LEFT OUTER
878
- JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{count_column
879
- }) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{tbl_alias}"
857
+ JOIN (SELECT #{hm_selects.map { |s| _br_quoted_name("#{'br_t0.' if from_clause}#{s}") }.join(', ')}, COUNT(#{'DISTINCT ' if hm.options[:through]}#{_br_quoted_name(count_column)
858
+ }) AS c_t_ FROM #{from_clause || hm_table_name} GROUP BY #{group_bys.join(', ')}) #{_br_quoted_name(tbl_alias)}"
880
859
  self.joins_values |= ["#{join_clause} ON #{on_clause.join(' AND ')}"] # Same as: joins!(...)
881
860
  end unless cust_col_override
882
861
  while (n = nix.pop)
@@ -924,6 +903,7 @@ JOIN (SELECT #{hm_selects.map { |s| "#{'br_t0.' if from_clause}#{s}" }.join(', '
924
903
  s << v
925
904
  end
926
905
  else # String stuff (which defines a custom ORDER BY) just comes straight through
906
+ v = v.split('.').map { |x| "\"#{x}\"" }.join('.')
927
907
  s << v
928
908
  # Avoid "PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list" in Postgres
929
909
  selects << v if is_distinct
@@ -1015,6 +995,26 @@ Might want to add this in your brick.rb:
1015
995
  def shift_or_first(ary)
1016
996
  ary.length > 1 ? ary.shift : ary.first
1017
997
  end
998
+
999
+ def _br_quoted_name(name)
1000
+ if is_mysql
1001
+ "`#{name}`"
1002
+ elsif is_postgres || is_mssql
1003
+ "\"#{(name).gsub('.', '"."')}\""
1004
+ else
1005
+ name
1006
+ end
1007
+ end
1008
+
1009
+ def is_postgres
1010
+ @is_postgres ||= ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
1011
+ end
1012
+ def is_mysql
1013
+ @is_mysql ||= ['Mysql2', 'Trilogy'].include?(ActiveRecord::Base.connection.adapter_name)
1014
+ end
1015
+ def is_mssql
1016
+ @is_mssql ||= ActiveRecord::Base.connection.adapter_name == 'SQLServer'
1017
+ end
1018
1018
  end
1019
1019
 
1020
1020
  module Inheritance
@@ -2452,7 +2452,7 @@ end.class_exec do
2452
2452
  end
2453
2453
  relation_name = schema_name ? "#{schema_name}.#{r['relation_name']}" : r['relation_name']
2454
2454
  # Both uppers and lowers as well as underscores?
2455
- apply_double_underscore_patch if relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2455
+ ::Brick.apply_double_underscore_patch if relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2456
2456
  relation = relations[relation_name]
2457
2457
  relation[:isView] = true if r['table_type'] == 'VIEW'
2458
2458
  relation[:description] = r['table_description'] if r['table_description']
@@ -2501,7 +2501,7 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2501
2501
  relation_name.downcase!
2502
2502
  # Both uppers and lowers as well as underscores?
2503
2503
  elsif relation_name =~ /[A-Z]/ && relation_name =~ /[a-z]/ && relation_name.index('_')
2504
- apply_double_underscore_patch
2504
+ ::Brick.apply_double_underscore_patch
2505
2505
  end
2506
2506
  # Expect the default schema for SQL Server to be 'dbo'.
2507
2507
  if (::Brick.is_oracle && r[0] != schema) || (is_mssql && r[0] != 'dbo')
@@ -2528,6 +2528,15 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2528
2528
  end
2529
2529
  end
2530
2530
 
2531
+ # PostGIS adds three views which would confuse Rails if models were to be built for them.
2532
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
2533
+ if relations.key?('geography_columns') && relations.key?('geometry_columns') && relations.key?('spatial_ref_sys')
2534
+ (::Brick.config.exclude_tables ||= []) << 'geography_columns'
2535
+ ::Brick.config.exclude_tables << 'geometry_columns'
2536
+ ::Brick.config.exclude_tables << 'spatial_ref_sys'
2537
+ end
2538
+ end
2539
+
2531
2540
  # # Add unique OIDs
2532
2541
  # if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
2533
2542
  # ActiveRecord::Base.execute_sql(
@@ -2706,43 +2715,6 @@ ORDER BY 1, 2, c.internal_column_id, acc.position"
2706
2715
  ar_imtn = ActiveRecord.version >= ::Gem::Version.new('5.0') ? ActiveRecord::Base.internal_metadata_table_name : 'ar_internal_metadata'
2707
2716
  [ar_smtn, ar_imtn]
2708
2717
  end
2709
-
2710
- def apply_double_underscore_patch
2711
- unless @double_underscore_applied
2712
- # Same as normal #camelize and #underscore, just that double-underscores turn into a single underscore
2713
- ActiveSupport::Inflector.class_eval do
2714
- def camelize(term, uppercase_first_letter = true)
2715
- strings = term.to_s.split('__').map do |string|
2716
- # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
2717
- if !uppercase_first_letter || uppercase_first_letter == :lower
2718
- string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
2719
- else
2720
- string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
2721
- end
2722
- string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
2723
- word = $2
2724
- substituted = inflections.acronyms[word] || word.capitalize! || word
2725
- $1 ? "::#{substituted}" : substituted
2726
- end
2727
- string
2728
- end
2729
- strings.join('_')
2730
- end
2731
-
2732
- def underscore(camel_cased_word)
2733
- return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
2734
- camel_cased_word.to_s.gsub("::", "/").split('_').map do |word|
2735
- word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
2736
- word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << "_" }
2737
- word.tr!("-", "_")
2738
- word.downcase!
2739
- word
2740
- end.join('__')
2741
- end
2742
- end
2743
- @double_underscore_applied = true
2744
- end
2745
- end
2746
2718
  end
2747
2719
 
2748
2720
  # ==========================================
@@ -2769,7 +2741,7 @@ module Brick
2769
2741
 
2770
2742
  class << self
2771
2743
  def _add_bt_and_hm(fk, relations, polymorphic_class = nil, is_optional = false)
2772
- bt_assoc_name = ::Brick.namify(fk[2], :downcase)
2744
+ bt_assoc_name = ::Brick.namify(fk[2].dup, :downcase)
2773
2745
  unless polymorphic_class
2774
2746
  bt_assoc_name = if bt_assoc_name.underscore.end_with?('_id')
2775
2747
  bt_assoc_name[-3] == '_' ? bt_assoc_name[0..-4] : bt_assoc_name[0..-3]
@@ -1258,57 +1258,73 @@ erDiagram
1258
1258
  // Have a click on the sheets link to bring up the sign-in window. (Must happen from some kind of user click.)
1259
1259
  sheetsLink.addEventListener(\"click\", async function (evt) {
1260
1260
  evt.preventDefault();
1261
- await gapi.load(\"client\", function () {
1262
- gapi.client.init({ // Load the discovery doc to initialize the API
1263
- clientId: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
1264
- scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
1265
- discoveryDocs: [\"https://sheets.googleapis.com/$discovery/rest?version=v4\"]
1266
- }).then(function () {
1267
- gapi.auth2.getAuthInstance().isSignedIn.listen(updateSignInStatus);
1268
- updateSignInStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
1269
- });
1261
+ var client = google.accounts.oauth2.initTokenClient({
1262
+ client_id: \"487319557829-fgj4u660igrpptdji7ev0r5hb6kh05dh.apps.googleusercontent.com\",
1263
+ scope: \"https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file\",
1264
+ callback: updateSignInStatus
1270
1265
  });
1266
+ client.requestAccessToken();
1271
1267
  });
1272
1268
  }
1273
1269
 
1274
- async function updateSignInStatus(isSignedIn) {
1275
- if (isSignedIn) {
1276
- await gapi.client.sheets.spreadsheets.create({
1277
- properties: {
1278
- title: #{table_name.inspect},
1279
- },
1280
- sheets: [
1281
- // sheet1, sheet2, sheet3
1282
- ]
1283
- }).then(function (response) {
1284
- sheetUrl = response.result.spreadsheetUrl;
1285
- spreadsheetId = response.result.spreadsheetId;
1286
- sheetsLink.setAttribute(\"href\", sheetUrl); // response.result.spreadsheetUrl
1287
- console.log(\"x1\", sheetUrl);
1288
-
1289
- // Get JSON data
1290
- fetch(changeout(<%= #{@_brick_model._brick_index}_path(format: :js).inspect.html_safe %>, \"_brick_schema\", brickSchema)).then(function (response) {
1291
- response.json().then(function (data) {
1292
- gapi.client.sheets.spreadsheets.values.append({
1293
- spreadsheetId: spreadsheetId,
1294
- range: \"Sheet1\",
1295
- valueInputOption: \"RAW\",
1296
- insertDataOption: \"INSERT_ROWS\"
1297
- }, {
1298
- range: \"Sheet1\",
1299
- majorDimension: \"ROWS\",
1300
- values: data,
1301
- }).then(function (response2) {
1302
- // console.log(\"beefcake\", response2);
1303
- });
1270
+ async function updateSignInStatus(token) {
1271
+ await new Promise(function (resolve) {
1272
+ gapi.load(\"client\", function () {
1273
+ resolve(); // gapi client code now loaded
1274
+ });
1275
+ }).then(async function (x) {
1276
+ gapi.client.setToken(token);
1277
+ var discoveryDoc = await (await fetch(\"https://sheets.googleapis.com/$discovery/rest?version=v4\")).json();
1278
+ await gapi.client.load(discoveryDoc, function () {
1279
+ resolve(); // Spreadsheets code now loaded
1280
+ });
1281
+ });
1282
+
1283
+ await gapi.client.sheets.spreadsheets.create({
1284
+ properties: {
1285
+ title: #{table_name.inspect},
1286
+ },
1287
+ sheets: [
1288
+ // sheet1, sheet2, sheet3
1289
+ ]
1290
+ }).then(function (response) {
1291
+ sheetUrl = response.result.spreadsheetUrl;
1292
+ spreadsheetId = response.result.spreadsheetId;
1293
+ // sheetsLink.setAttribute(\"href\", sheetUrl);
1294
+
1295
+ // Get JSON data
1296
+ var jsPath = <%= #{@_brick_model._brick_index}_path(format: :js).inspect.html_safe %>;
1297
+ if (brickSchema) jsPath = changeout(jsPath, \"_brick_schema\", brickSchema);
1298
+ fetch(jsPath).then(function (response) {
1299
+ response.json().then(function (resp) {
1300
+ // Expect the first row to have field names
1301
+ var colHeaders = Object.keys(resp.data[0]);;
1302
+ var ary = [colHeaders];
1303
+ // Add all the rows
1304
+ var row;
1305
+ resp.data.forEach(function (row) {
1306
+ ary.push(Object.keys(colHeaders).reduce(function(x, y) {
1307
+ x.push(row[colHeaders[y]]); return x
1308
+ }, []));
1309
+ });
1310
+ // Send to spreadsheet
1311
+ gapi.client.sheets.spreadsheets.values.append({
1312
+ spreadsheetId: spreadsheetId,
1313
+ range: 'Sheet1',
1314
+ valueInputOption: 'RAW',
1315
+ insertDataOption: 'INSERT_ROWS',
1316
+ values: ary
1317
+ }).then(function (response2) {
1318
+ // console.log('Spreadsheet created', response2);
1304
1319
  });
1305
1320
  });
1306
1321
  });
1307
1322
  window.open(sheetUrl, '_blank');
1308
- }
1323
+ });
1309
1324
  }
1310
1325
  </script>
1311
- <script async defer src=\"https://apis.google.com/js/api.js\" onload=\"gapiLoaded()\"></script>
1326
+ <script src=\"https://apis.google.com/js/api.js\"></script>
1327
+ <script async defer src=\"https://accounts.google.com/gsi/client\" onload=\"gapiLoaded()\"></script>
1312
1328
  "
1313
1329
  end # DutyFree data export and import
1314
1330
  # %%% Instead of our current "for Janet Leverling (Employee)" kind of link we previously had this code that did a "where x = 123" thing:
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 143
8
+ TINY = 144
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
data/lib/brick.rb CHANGED
@@ -695,6 +695,44 @@ In config/initializers/brick.rb appropriate entries would look something like:
695
695
  end
696
696
  [klass, sti_type, found]
697
697
  end
698
+
699
+ def apply_double_underscore_patch
700
+ unless @double_underscore_applied
701
+ # Same as normal #camelize and #underscore, just that double-underscores turn into a single underscore
702
+ ActiveSupport::Inflector.class_eval do
703
+ def camelize(term, uppercase_first_letter = true)
704
+ strings = term.to_s.split('__').map do |string|
705
+ # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
706
+ if !uppercase_first_letter || uppercase_first_letter == :lower
707
+ string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
708
+ else
709
+ string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
710
+ end
711
+ string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
712
+ word = $2
713
+ substituted = inflections.acronyms[word] || word.capitalize! || word
714
+ $1 ? "::#{substituted}" : substituted
715
+ end
716
+ string
717
+ end
718
+ strings.join('_')
719
+ end
720
+
721
+ def underscore(camel_cased_word)
722
+ return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
723
+ regex = inflections.respond_to?(:acronyms_underscore_regex) ? inflections.acronyms_underscore_regex : inflections.acronym_regex
724
+ camel_cased_word.to_s.gsub('::', '/').split('_').map do |word|
725
+ word.gsub!(regex) { "#{$1 && '_' }#{$2.downcase}" }
726
+ word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << '_' }
727
+ word.tr!('-', '_')
728
+ word.downcase!
729
+ word
730
+ end.join('__')
731
+ end
732
+ end
733
+ @double_underscore_applied = true
734
+ end
735
+ end
698
736
  end
699
737
 
700
738
  module RouteSet
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.143
4
+ version: 1.0.144
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-19 00:00:00.000000000 Z
11
+ date: 2023-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord