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 +4 -4
- data/lib/brick/extensions.rb +102 -60
- data/lib/brick/frameworks/rails/engine.rb +2 -3
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +18 -16
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6bf3e38aef34261d9398b25f804504e7152721673b0534253c4284c9018013
|
4
|
+
data.tar.gz: 766af0df2edc3dc8c8c73a5d1ecd99c8d738ed7cd00fc21c79c38ac3db991819
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40f2eacaf7fada3056f5bfc701b01441ad02e34e76e87dc8e53b36a546c87216e8a319c3f0763b8fecff49344224d5660ff5b875937a3e30e2e7c80c662f684c
|
7
|
+
data.tar.gz: 7901020af2ec1759c27c16a0c3a3ffbcddcd09691c652c14c02781823964e36409533afc562fb0d9beb508cc3329b601d6fe8c266c101f6db6d93aad5e055a3e
|
data/lib/brick/extensions.rb
CHANGED
@@ -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 =
|
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 = "#{
|
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'}
|
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
|
-
|
295
|
-
puts ActiveRecord::Base.connection.execute("SELECT current_setting('SEARCH_PATH')").to_a.inspect
|
296
|
-
|
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
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
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
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
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
|
-
|
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
|
data/lib/brick/version_number.rb
CHANGED
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
|
-
|
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
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
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.
|
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-
|
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
|