Class: ActiveRecord::ConnectionAdapters::MysqlAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/connection_adapters/mysql_adapter.rb

Overview

The purpose of this extension to MysqlAdapter is to exploit the referential constraints offered in MySQL >=5.0, and to make the table and column metadata stored in MySQL available to ActiveRecord objects

Currently, CHECK constraints are not supported in MySQL 5.x. Although the syntax for creating CHECK constraints is supported, they are ignored by MySQL

Instance Method Summary collapse

Instance Method Details

#columns(table_name, name = nil) ⇒ Object

The “EXTRA” column is discarded in the standard Rails implementation of MysqlAdapter.columns. ActiveRecord can use this column to generate validations



67
68
69
70
71
72
# File 'lib/connection_adapters/mysql_adapter.rb', line 67

def columns(table_name, name = nil)#:nodoc:
  sql = "SHOW FIELDS FROM #{table_name}"
  columns = []
  execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES", field[5])}
  columns
end

#constraints(table_name, name = nil) ⇒ Object

Retrieve each DB constraint from the information_schema database that is either a constraint on table_name or references table_name (eg. FK into table_name)



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/connection_adapters/mysql_adapter.rb', line 76

def constraints(table_name, name = nil)#:nodoc:
  constraints = []
  sql = %Q{
    select KCU.constraint_name, KCU.table_schema, KCU.table_name, KCU.column_name, TC.constraint_type, 
      KCU.referenced_table_name, KCU.referenced_column_name 
    from ((select constraint_name, constraint_type, table_name 
      from information_schema.table_constraints 
        where table_schema='#{schema}' and table_name='#{table_name}') as TC 
    right join (select * 
      from information_schema.key_column_usage 
      where table_schema='#{schema}' 
      and (table_name='#{table_name}' or referenced_table_name='#{table_name}')) as KCU 
    on (TC.constraint_name=KCU.constraint_name AND TC.table_name=KCU.table_name))}
  results = execute(sql, name)
  
  constraint_name_hash = {}
  results.each do |row| 
    comparable_constraint_name = row[0].upcase + row[2].upcase
    referenced_column_name = row[6]
    column_name = row[3]
    existing_constraint = constraint_name_hash[comparable_constraint_name]
    if !existing_constraint
      new_constraint = MysqlConstraint.new(row[0], row[1], row[2], row[3], row[4], row[5], row[6])
      constraints << new_constraint
      constraint_name_hash[comparable_constraint_name] = new_constraint
    else
      existing_constraint.column_names << column_name unless existing_constraint.column_names.include?(column_name)
      if referenced_column_name
        existing_constraint.referenced_column_names << referenced_column_name unless existing_constraint.referenced_column_names.include?(referenced_column_name)
      end
    end
  end
  constraints
end

#schemaObject

FIXME filter SQL queries on information_schema by schema name in case a table

with the same name exists in > 1 schema (i.e. test vs. dev schema)


61
62
63
# File 'lib/connection_adapters/mysql_adapter.rb', line 61

def schema
  @connection_options[3]
end