brick 1.0.3 → 1.0.4

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: 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