brick 1.0.3 → 1.0.4

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: ff255b32c913dbb0e02d3f197d035faf43dc44afc4041cda3f57e92fc9df893a
4
- data.tar.gz: 763b5579402a7668abf3d266665879643b8d44ed04686a35f2df145b1ddfee72
3
+ metadata.gz: fe6bf3e38aef34261d9398b25f804504e7152721673b0534253c4284c9018013
4
+ data.tar.gz: 766af0df2edc3dc8c8c73a5d1ecd99c8d738ed7cd00fc21c79c38ac3db991819
5
5
  SHA512:
6
- metadata.gz: f513e360dcba221bbd5061eb2ef3ef349a7c18ec6babae32273e877ba5b8cd0071f337f11c63460157afaa55cb0e8eea7dc99d80f64231270fc76218ef84397e
7
- data.tar.gz: eb684612e551f8c884b618985884ad88b5ed827680fb4056f91f6c575fb479d18b92e6d4fa6de222ec24a7991f419723447313780fdbe5b7a0a903561dcb3dd7
6
+ metadata.gz: 40f2eacaf7fada3056f5bfc701b01441ad02e34e76e87dc8e53b36a546c87216e8a319c3f0763b8fecff49344224d5660ff5b875937a3e30e2e7c80c662f684c
7
+ data.tar.gz: 7901020af2ec1759c27c16a0c3a3ffbcddcd09691c652c14c02781823964e36409533afc562fb0d9beb508cc3329b601d6fe8c266c101f6db6d93aad5e055a3e
@@ -26,7 +26,11 @@
26
26
 
27
27
  # colour coded origins
28
28
 
29
- # Drag TmfModel#name onto the rows and have it automatically add five columns -- where type=zone / where type = sectionn / etc
29
+ # Drag something like TmfModel#name onto the rows and have it automatically add five columns -- where type=zone / where type = section / etc
30
+
31
+ # Support for Postgres / MySQL enums (add enum to model, use model enums to make a drop-down in the UI)
32
+
33
+ # Currently quadrupling up routes
30
34
 
31
35
  # ==========================================================
32
36
  # Dynamically create model or controller classes when needed
@@ -77,16 +81,6 @@ module ActiveRecord
77
81
  end
78
82
  end
79
83
 
80
- # Rails::Application.class_exec do
81
- # alias _brick_initialize! initialize!
82
- # # Run Before initialize make sure our settings
83
- # def initialize!
84
- # # initialization code goes here
85
- # puts "BEFORE1"
86
- # _brick_initialize!
87
- # end
88
- # end
89
-
90
84
  # Object.class_exec do
91
85
  class Object
92
86
  class << self
@@ -180,15 +174,6 @@ class Object
180
174
  code << " # Could not identify any column(s) to use as a primary key\n" unless is_view
181
175
  end
182
176
 
183
- # if relation[:cols].key?('last_update')
184
- # define_method :updated_at do
185
- # last_update
186
- # end
187
- # define_method :'updated_at=' do |val|
188
- # last_update=(val)
189
- # end
190
- # end
191
-
192
177
  fks = relation[:fks] || {}
193
178
  fks.each do |_constraint_name, assoc|
194
179
  assoc_name = assoc[:assoc_name]
@@ -204,7 +189,7 @@ class Object
204
189
  # need_class_name = ActiveSupport::Inflector.singularize(assoc_name) == ActiveSupport::Inflector.singularize(table_name.underscore)
205
190
  # Are there multiple foreign keys out to the same table?
206
191
  assoc_name, need_class_name = _brick_get_hm_assoc_name(relation, assoc)
207
- need_fk = "#{singular_table_name}_id" != assoc[:fk]
192
+ need_fk = "#{ActiveSupport::Inflector.singularize(assoc[:inverse][:inverse_table])}_id" != assoc[:fk]
208
193
  # fks[table_name].find { |other_assoc| other_assoc.object_id != assoc.object_id && other_assoc[:assoc_name] == assoc[assoc_name] }
209
194
  :has_many
210
195
  end
@@ -243,7 +228,7 @@ class Object
243
228
  Object.const_set(class_name.to_sym, new_controller_class)
244
229
 
245
230
  code << " def index\n"
246
- code << " @#{table_name} = #{model.name}#{model.primary_key ? ".order(#{model.primary_key.inspect}" : '.all'})\n"
231
+ code << " @#{table_name} = #{model.name}#{model.primary_key ? ".order(#{model.primary_key.inspect})" : '.all'}\n"
247
232
  code << " @#{table_name}.brick_where(params)\n"
248
233
  code << " end\n"
249
234
  self.define_method :index do
@@ -291,13 +276,31 @@ module ActiveRecord::ConnectionHandling
291
276
  x = _brick_establish_connection(*args)
292
277
 
293
278
  if (relations = ::Brick.relations).empty?
294
- schema = 'public'
295
- puts ActiveRecord::Base.connection.execute("SELECT current_setting('SEARCH_PATH')").to_a.inspect
296
- sql = ActiveRecord::Base.send(:sanitize_sql_array, [
279
+ # Only for Postgres? (Doesn't work in sqlite3)
280
+ # puts ActiveRecord::Base.connection.execute("SELECT current_setting('SEARCH_PATH')").to_a.inspect
281
+
282
+ case ActiveRecord::Base.connection.adapter_name
283
+ when 'PostgreSQL'
284
+ schema = 'public'
285
+ when 'Mysql2'
286
+ schema = ActiveRecord::Base.connection.current_database
287
+ when 'SQLite'
288
+ sql = "SELECT m.name AS relation_name, UPPER(m.type) AS table_type,
289
+ p.name AS column_name, p.type AS data_type,
290
+ CASE p.pk WHEN 1 THEN 'PRIMARY KEY' END AS const
291
+ FROM sqlite_master AS m
292
+ INNER JOIN pragma_table_info(m.name) AS p
293
+ WHERE m.name NOT IN ('ar_internal_metadata', 'schema_migrations')
294
+ ORDER BY m.name, p.cid"
295
+ else
296
+ puts "Unfamiliar with connection adapter #{ActiveRecord::Base.connection.adapter_name}"
297
+ end
298
+
299
+ sql ||= ActiveRecord::Base.send(:sanitize_sql_array, [
297
300
  "SELECT t.table_name AS relation_name, t.table_type,
298
301
  c.column_name, c.data_type,
299
302
  COALESCE(c.character_maximum_length, c.numeric_precision) AS max_length,
300
- tc.constraint_type AS const, kcu.constraint_name AS key
303
+ tc.constraint_type AS const, kcu.constraint_name AS \"key\"
301
304
  FROM INFORMATION_SCHEMA.tables AS t
302
305
  LEFT OUTER JOIN INFORMATION_SCHEMA.columns AS c ON t.table_schema = c.table_schema
303
306
  AND t.table_name = c.table_name
@@ -309,48 +312,87 @@ module ActiveRecord::ConnectionHandling
309
312
  AND kcu.ordinal_position = c.ordinal_position
310
313
  LEFT OUTER JOIN INFORMATION_SCHEMA.table_constraints AS tc
311
314
  ON kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
315
+ AND kcu.TABLE_NAME = tc.TABLE_NAME
312
316
  AND kcu.CONSTRAINT_NAME = tc.constraint_name
313
317
  WHERE t.table_schema = ? -- COALESCE(current_setting('SEARCH_PATH'), 'public')
314
318
  -- AND t.table_type IN ('VIEW') -- 'BASE TABLE', 'FOREIGN TABLE'
315
319
  AND t.table_name NOT IN ('pg_stat_statements', 'ar_internal_metadata', 'schema_migrations')
316
320
  ORDER BY 1, t.table_type DESC, c.ordinal_position", schema
317
321
  ])
318
- ActiveRecord::Base.connection.execute(sql).each do |r|
319
- # next if internal_views.include?(r['relation_name']) # Skip internal views such as v_all_assessments
320
-
321
- relation = relations[r['relation_name']]
322
- relation[:isView] = true if r['table_type'] == 'VIEW'
323
- col_name = r['column_name']
324
- cols = relation[:cols] # relation.fetch(:cols) { relation[:cols] = [] }
325
- key = case r['const']
326
- when 'PRIMARY KEY'
327
- relation[:pkey][r['key']] ||= []
328
- when 'UNIQUE'
329
- relation[:ukeys][r['key']] ||= []
330
- # key = (relation[:ukeys] = Hash.new { |h, k| h[k] = [] }) if key.is_a?(Array)
331
- # key[r['key']]
332
- end
333
- key << col_name if key
334
- cols[col_name] = [r['data_type'], r['max_length'], r['measures']&.include?(col_name)]
335
- # puts "KEY! #{r['relation_name']}.#{col_name} #{r['key']} #{r['const']}" if r['key']
322
+
323
+ measures = []
324
+ case ActiveRecord::Base.connection.adapter_name
325
+ when 'PostgreSQL', 'SQLite' # These bring back a hash for each row because the query uses column aliases
326
+ ActiveRecord::Base.connection.execute(sql).each do |r|
327
+ # next if internal_views.include?(r['relation_name']) # Skip internal views such as v_all_assessments
328
+ relation = relations[(relation_name = r['relation_name'])]
329
+ relation[:isView] = true if r['table_type'] == 'VIEW'
330
+ col_name = r['column_name']
331
+ key = case r['const']
332
+ when 'PRIMARY KEY'
333
+ relation[:pkey][r['key'] || relation_name] ||= []
334
+ when 'UNIQUE'
335
+ relation[:ukeys][r['key'] || "#{relation_name}.#{col_name}"] ||= []
336
+ # key = (relation[:ukeys] = Hash.new { |h, k| h[k] = [] }) if key.is_a?(Array)
337
+ # key[r['key']]
338
+ end
339
+ key << col_name if key
340
+ cols = relation[:cols] # relation.fetch(:cols) { relation[:cols] = [] }
341
+ cols[col_name] = [r['data_type'], r['max_length'], measures&.include?(col_name)]
342
+ # puts "KEY! #{r['relation_name']}.#{col_name} #{r['key']} #{r['const']}" if r['key']
343
+ end
344
+ else # MySQL2 acts a little differently, bringing back an array for each row
345
+ ActiveRecord::Base.connection.execute(sql).each do |r|
346
+ # next if internal_views.include?(r['relation_name']) # Skip internal views such as v_all_assessments
347
+ relation = relations[(relation_name = r[0])] # here relation represents a table or view from the database
348
+ relation[:isView] = true if r[1] == 'VIEW' # table_type
349
+ col_name = r[2]
350
+ key = case r[5] # constraint type
351
+ when 'PRIMARY KEY'
352
+ # key
353
+ relation[:pkey][r[6] || relation_name] ||= []
354
+ when 'UNIQUE'
355
+ relation[:ukeys][r[6] || "#{relation_name}.#{col_name}"] ||= []
356
+ # key = (relation[:ukeys] = Hash.new { |h, k| h[k] = [] }) if key.is_a?(Array)
357
+ # key[r['key']]
358
+ end
359
+ key << col_name if key
360
+ cols = relation[:cols] # relation.fetch(:cols) { relation[:cols] = [] }
361
+ # 'data_type', 'max_length'
362
+ cols[col_name] = [r[3], r[4], measures&.include?(col_name)]
363
+ # puts "KEY! #{r['relation_name']}.#{col_name} #{r['key']} #{r['const']}" if r['key']
364
+ end
336
365
  end
337
366
 
338
- sql = ActiveRecord::Base.send(:sanitize_sql_array, [
339
- "SELECT kcu1.TABLE_NAME, kcu1.COLUMN_NAME, kcu2.TABLE_NAME, kcu1.CONSTRAINT_NAME
340
- FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS rc
341
- INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu1
342
- ON kcu1.CONSTRAINT_CATALOG = rc.CONSTRAINT_CATALOG
343
- AND kcu1.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
344
- AND kcu1.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
345
- INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu2
346
- ON kcu2.CONSTRAINT_CATALOG = rc.UNIQUE_CONSTRAINT_CATALOG
347
- AND kcu2.CONSTRAINT_SCHEMA = rc.UNIQUE_CONSTRAINT_SCHEMA
348
- AND kcu2.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
349
- AND kcu2.ORDINAL_POSITION = kcu1.ORDINAL_POSITION
350
- WHERE kcu1.CONSTRAINT_SCHEMA = ? -- COALESCE(current_setting('SEARCH_PATH'), 'public')", schema
351
- # AND kcu2.TABLE_NAME = ?;", Apartment::Tenant.current, table_name
352
- ])
353
- ActiveRecord::Base.connection.execute(sql).values.each { |fk| ::Brick._add_bt_and_hm(fk, relations) }
367
+ case ActiveRecord::Base.connection.adapter_name
368
+ when 'PostgreSQL', 'Mysql2'
369
+ sql = ActiveRecord::Base.send(:sanitize_sql_array, [
370
+ "SELECT kcu1.TABLE_NAME, kcu1.COLUMN_NAME, kcu2.TABLE_NAME, kcu1.CONSTRAINT_NAME
371
+ FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS rc
372
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu1
373
+ ON kcu1.CONSTRAINT_CATALOG = rc.CONSTRAINT_CATALOG
374
+ AND kcu1.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
375
+ AND kcu1.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
376
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu2
377
+ ON kcu2.CONSTRAINT_CATALOG = rc.UNIQUE_CONSTRAINT_CATALOG
378
+ AND kcu2.CONSTRAINT_SCHEMA = rc.UNIQUE_CONSTRAINT_SCHEMA
379
+ AND kcu2.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
380
+ AND kcu2.ORDINAL_POSITION = kcu1.ORDINAL_POSITION
381
+ WHERE kcu1.CONSTRAINT_SCHEMA = ? -- COALESCE(current_setting('SEARCH_PATH'), 'public')", schema
382
+ # AND kcu2.TABLE_NAME = ?;", Apartment::Tenant.current, table_name
383
+ ])
384
+ when 'SQLite'
385
+ sql = "SELECT m.name, fkl.\"from\", fkl.\"table\", m.name || '_' || fkl.\"from\" AS constraint_name
386
+ FROM sqlite_master m
387
+ INNER JOIN pragma_foreign_key_list(m.name) fkl ON m.type = 'table'
388
+ ORDER BY m.name, fkl.seq"
389
+ else
390
+ end
391
+ if sql
392
+ result = ActiveRecord::Base.connection.execute(sql)
393
+ result = result.values unless result.is_a?(Array)
394
+ result.each { |fk| ::Brick._add_bt_and_hm(fk, relations) }
395
+ end
354
396
  end
355
397
 
356
398
  puts "Classes that can be built from tables:"
@@ -119,7 +119,7 @@ module Brick
119
119
  is_need_id_col = true %>
120
120
  </th><th>
121
121
  <% end %>
122
- BT <%= bt[1].name %>
122
+ BT <%= \"#\{bt.first\}-\" unless bt[1].name.underscore == bt.first.to_s %><%= bt[1].name %>
123
123
  <% else
124
124
  is_first = false %>
125
125
  <%= col %>
@@ -159,9 +159,8 @@ module Brick
159
159
  <% end %>
160
160
  </table>
161
161
 
162
- <%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>
162
+ #{"<hr><%= link_to \"New #{obj_name}\", new_#{obj_name}_path %>" unless @_brick_model.is_view?}
163
163
  "
164
- # "<%= @#{@_brick_model.name.underscore.pluralize}.inspect %>"
165
164
  when 'show'
166
165
  "<%= @#{@_brick_model.name.underscore}.inspect %>"
167
166
  end
@@ -5,7 +5,7 @@ module Brick
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 3
8
+ TINY = 4
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
@@ -76,7 +76,10 @@ end
76
76
  # is first established), and then automatically creates models, controllers, views,
77
77
  # and routes based on those available relations.
78
78
  require 'brick/config'
79
- require 'brick/frameworks/rails'
79
+ if Gem::Specification.all_names.any? { |g| g.start_with?('rails-') }
80
+ require 'rails'
81
+ require 'brick/frameworks/rails'
82
+ end
80
83
  module Brick
81
84
  class << self
82
85
  # All tables and views (what Postgres calls "relations" including column and foreign key info)
@@ -197,10 +200,7 @@ module Brick
197
200
  end
198
201
  end
199
202
 
200
- require 'brick/extensions'
201
203
  require 'brick/version_number'
202
- # require 'brick/serializers/json'
203
- # require 'brick/serializers/yaml'
204
204
 
205
205
  require 'active_record'
206
206
  # Major compatibility fixes for ActiveRecord < 4.2
@@ -426,18 +426,18 @@ ActiveSupport.on_load(:active_record) do
426
426
  end
427
427
  end
428
428
 
429
- include ::Brick::Extensions
430
-
431
- unless ::Brick::Extensions::IS_AMOEBA
432
- # Add amoeba-compatible support
433
- module ActiveRecord
434
- class Base
435
- def self.amoeba(*args)
436
- puts "Amoeba called from #{name} with #{args.inspect}"
437
- end
438
- end
439
- end
440
- end
429
+ # include ::Brick::Extensions
430
+
431
+ # unless ::Brick::Extensions::IS_AMOEBA
432
+ # # Add amoeba-compatible support
433
+ # module ActiveRecord
434
+ # class Base
435
+ # def self.amoeba(*args)
436
+ # puts "Amoeba called from #{name} with #{args.inspect}"
437
+ # end
438
+ # end
439
+ # end
440
+ # end
441
441
  end
442
442
 
443
443
  # Do this earlier because stuff here gets mixed into JoinDependency::JoinAssociation and AssociationScope
@@ -526,3 +526,5 @@ if ActiveRecord.version < ::Gem::Version.new('5.2')
526
526
  end # module ActiveRecord
527
527
  # rubocop:enable Style/CommentedKeyword
528
528
  end
529
+
530
+ require 'brick/extensions'
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.3
4
+ version: 1.0.4
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-03-14 00:00:00.000000000 Z
11
+ date: 2022-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -156,6 +156,20 @@ dependencies:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
158
  version: 1.42.0
159
+ - !ruby/object:Gem::Dependency
160
+ name: mysql2
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.5'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '0.5'
159
173
  - !ruby/object:Gem::Dependency
160
174
  name: pg
161
175
  requirement: !ruby/object:Gem::Requirement