Class: RailsLens::Schema::Adapters::Mysql
- Inherits:
-
Base
- Object
- Base
- RailsLens::Schema::Adapters::Mysql
show all
- Defined in:
- lib/rails_lens/schema/adapters/mysql.rb
Instance Attribute Summary
Attributes inherited from Base
#connection, #table_name
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Base
#generate_view_annotation, #initialize, #unqualified_table_name
Class Method Details
.fetch_functions(connection) ⇒ Object
Fetch all user-defined functions
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 383
def self.fetch_functions(connection)
result = connection.exec_query(<<~SQL.squish, 'MySQL Functions')
SELECT
ROUTINE_NAME AS name,
ROUTINE_SCHEMA AS `schema`,
DATA_TYPE AS return_type,
ROUTINE_COMMENT AS description
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = DATABASE()
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY ROUTINE_NAME
SQL
result.rows.map do |row|
{
name: row[0],
schema: row[1],
language: 'SQL',
return_type: row[2],
description: row[3]
}
end
rescue ActiveRecord::StatementInvalid, Mysql2::Error => e
RailsLens.logger.debug { "Failed to fetch functions: #{e.message}" }
[]
end
|
Instance Method Details
#adapter_name ⇒ Object
7
8
9
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 7
def adapter_name
'MySQL'
end
|
Extract function/procedure call from trigger action statement
368
369
370
371
372
373
374
375
376
377
378
379
380
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 368
def (action_statement)
return nil unless action_statement
match = action_statement.match(/CALL\s+(?:`?(\w+)`?\.)?`?(\w+)`?/i)
if match
schema_part = match[1]
proc_name = match[2]
schema_part ? "#{schema_part}.#{proc_name}" : proc_name
else
'inline'
end
end
|
#fetch_triggers ⇒ Object
Fetch triggers for the table
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 337
def fetch_triggers
quoted_table = connection.quote(unqualified_table_name)
result = connection.exec_query(<<~SQL.squish, 'MySQL Table Triggers')
SELECT
TRIGGER_NAME AS name,
ACTION_TIMING AS timing,
EVENT_MANIPULATION AS event,
'ROW' AS for_each,
ACTION_STATEMENT AS action_statement
FROM information_schema.TRIGGERS
WHERE TRIGGER_SCHEMA = DATABASE()
AND EVENT_OBJECT_TABLE = #{quoted_table}
ORDER BY TRIGGER_NAME
SQL
result.rows.map do |row|
{
name: row[0],
timing: row[1],
event: row[2],
for_each: row[3],
function: (row[4]),
definition: row[4]
}
end
rescue ActiveRecord::StatementInvalid, Mysql2::Error => e
RailsLens.logger.debug { "Failed to fetch triggers for #{table_name}: #{e.message}" }
[]
end
|
Fetch all view metadata in a single consolidated query
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 267
def fetch_view_metadata
result = connection.exec_query(<<~SQL.squish, 'MySQL View Metadata')
SELECT
v.is_updatable,
COALESCE(
(
SELECT GROUP_CONCAT(DISTINCT vtu.table_name ORDER BY vtu.table_name)
FROM information_schema.view_table_usage vtu
WHERE vtu.view_schema = DATABASE()
AND vtu.view_name = '#{connection.quote_string(table_name)}'
),
''
) as dependencies
FROM information_schema.views v
WHERE v.table_schema = DATABASE()
AND v.table_name = '#{connection.quote_string(table_name)}'
LIMIT 1
SQL
return nil if result.rows.empty?
row = result.rows.first
{
type: 'regular', updatable: row[0] == 'YES',
dependencies: row[1].to_s.split(',').reject(&:empty?)
}
rescue ActiveRecord::StatementInvalid, Mysql2::Error => e
RailsLens.logger.debug { "Failed to fetch view metadata for #{table_name}: #{e.message}" }
nil
end
|
#generate_annotation(model_class) ⇒ Object
11
12
13
14
15
16
17
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 11
def generate_annotation(model_class)
if model_class && ModelDetector.view_exists?(model_class)
generate_view_annotation(model_class)
else
generate_table_annotation(model_class)
end
end
|
#generate_table_annotation(_model_class) ⇒ Object
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 19
def generate_table_annotation(_model_class)
lines = []
lines << "table = \"#{table_name}\""
lines << "database_dialect = \"#{database_dialect}\""
if (engine = table_storage_engine)
lines << "storage_engine = \"#{engine}\""
end
if (charset = table_charset)
lines << "character_set = \"#{charset}\""
end
if (collation = table_collation)
lines << "collation = \"#{collation}\""
end
lines << ''
add_columns_toml(lines)
add_indexes_toml(lines) if show_indexes?
add_foreign_keys_toml(lines) if show_foreign_keys?
add_triggers_toml(lines) if show_triggers?
add_partitions_toml(lines) if has_partitions?
lines.join("\n")
end
|
#view_definition ⇒ Object
315
316
317
318
319
320
321
322
323
324
325
326
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 315
def view_definition
result = connection.exec_query(<<~SQL.squish, 'MySQL View Definition')
SELECT view_definition FROM information_schema.views
WHERE table_schema = DATABASE()
AND table_name = '#{connection.quote_string(table_name)}'
LIMIT 1
SQL
result.rows.first&.first&.strip
rescue ActiveRecord::StatementInvalid, Mysql2::Error
nil
end
|
#view_dependencies ⇒ Object
310
311
312
313
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 310
def view_dependencies
@view_metadata ||= fetch_view_metadata
@view_metadata&.dig(:dependencies) || []
end
|
#view_last_refreshed ⇒ Object
332
333
334
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 332
def view_last_refreshed
nil end
|
#view_refresh_strategy ⇒ Object
328
329
330
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 328
def view_refresh_strategy
nil end
|
#view_type ⇒ Object
Legacy methods - kept for backward compatibility but now use consolidated query
300
301
302
303
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 300
def view_type
@view_metadata ||= fetch_view_metadata
@view_metadata&.dig(:type)
end
|
#view_updatable? ⇒ Boolean
305
306
307
308
|
# File 'lib/rails_lens/schema/adapters/mysql.rb', line 305
def view_updatable?
@view_metadata ||= fetch_view_metadata
@view_metadata&.dig(:updatable) || false
end
|