Module: SchemaPlus::ActiveRecord::ConnectionAdapters::MysqlAdapter
- Defined in:
- lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb
Overview
SchemaPlus includes a MySQL implementation of the AbstractAdapter extensions. (This works with both the mysql</t> and <tt>mysql2
gems.)
Defined Under Namespace
Modules: AddColumnOptions
Class Method Summary collapse
-
.included(base) ⇒ Object
:enddoc:.
Instance Method Summary collapse
-
#drop_table(name, options = {}) ⇒ Object
implement cascade by removing foreign keys.
-
#exec_stmt_with_schema_plus(sql, name, binds, &block) ⇒ Object
used only for mysql not mysql2.
- #foreign_keys(table_name, name = nil) ⇒ Object
- #remove_column_with_schema_plus(table_name, column_name, type = nil, options = {}) ⇒ Object
- #remove_foreign_key(table_name, *args) ⇒ Object
- #remove_foreign_key_sql(table_name, *args) ⇒ Object
- #remove_index_sql(table_name, options) ⇒ Object
- #rename_table_with_schema_plus(oldname, newname) ⇒ Object
- #reverse_foreign_keys(table_name, name = nil) ⇒ Object
- #tables_with_schema_plus(name = nil, *args) ⇒ Object
- #view_definition(view_name, name = nil) ⇒ Object
- #views(name = nil) ⇒ Object
Class Method Details
.included(base) ⇒ Object
:enddoc:
11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 11 def self.included(base) base.class_eval do alias_method_chain :tables, :schema_plus alias_method_chain :remove_column, :schema_plus alias_method_chain :rename_table, :schema_plus alias_method_chain :exec_stmt, :schema_plus rescue nil # only defined for mysql not mysql2 end if ::ActiveRecord::VERSION::MAJOR.to_i >= 4 base.class_eval do include ::ActiveRecord::ConnectionAdapters::SchemaStatements::AddIndex end end end |
Instance Method Details
#drop_table(name, options = {}) ⇒ Object
implement cascade by removing foreign keys
61 62 63 64 65 66 67 68 69 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 61 def drop_table(name, ={}) reverse_foreign_keys(name).each{ |foreign_key| remove_foreign_key(foreign_key.table_name, foreign_key.name) } if [:cascade] sql = "DROP" sql += " TEMPORARY" if [:temporary] sql += " TABLE" sql += " IF EXISTS" if [:if_exists] sql += " #{quote_table_name(name)}" execute sql end |
#exec_stmt_with_schema_plus(sql, name, binds, &block) ⇒ Object
used only for mysql not mysql2. the quoting methods on ActiveRecord::DB_DEFAULT are sufficient for mysql2
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 48 def exec_stmt_with_schema_plus(sql, name, binds, &block) if binds.any?{ |col, val| val.equal? ::ActiveRecord::DB_DEFAULT} binds.each_with_index do |(col, val), i| if val.equal? ::ActiveRecord::DB_DEFAULT sql = sql.sub(/(([^?]*?){#{i}}[^?]*)\?/, "\\1DEFAULT") end end binds = binds.reject{|col, val| val.equal? ::ActiveRecord::DB_DEFAULT} end exec_stmt_without_schema_plus(sql, name, binds, &block) end |
#foreign_keys(table_name, name = nil) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 89 def foreign_keys(table_name, name = nil) results = select_all("SHOW CREATE TABLE #{quote_table_name(table_name)}", name) table_name = table_name.to_s namespace_prefix = table_namespace_prefix(table_name) foreign_keys = [] results.each do |result| create_table_sql = result["Create Table"] create_table_sql.lines.each do |line| if line =~ /^ CONSTRAINT [`"](.+?)[`"] FOREIGN KEY \([`"](.+?)[`"]\) REFERENCES [`"](.+?)[`"] \((.+?)\)( ON DELETE (.+?))?( ON UPDATE (.+?))?,?$/ name = $1 column_names = $2 references_table_name = $3 references_table_name = namespace_prefix + references_table_name if table_namespace_prefix(references_table_name).blank? references_column_names = $4 on_update = $8 on_delete = $6 on_update = on_update ? on_update.downcase.gsub(' ', '_').to_sym : :restrict on_delete = on_delete ? on_delete.downcase.gsub(' ', '_').to_sym : :restrict foreign_keys << ForeignKeyDefinition.new(name, namespace_prefix + table_name, column_names.gsub('`', '').split(', '), references_table_name, references_column_names.gsub('`', '').split(', '), on_update, on_delete) end end end foreign_keys end |
#remove_column_with_schema_plus(table_name, column_name, type = nil, options = {}) ⇒ Object
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 30 def remove_column_with_schema_plus(table_name, column_name, type=nil, ={}) foreign_keys(table_name).select { |foreign_key| foreign_key.column_names.include?(column_name.to_s) }.each do |foreign_key| remove_foreign_key(table_name, foreign_key.name) end if ::ActiveRecord::VERSION::MAJOR.to_i >= 4 remove_column_without_schema_plus(table_name, column_name, type, ) else remove_column_without_schema_plus(table_name, column_name) end end |
#remove_foreign_key(table_name, *args) ⇒ Object
83 84 85 86 87 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 83 def remove_foreign_key(table_name, *args) case sql = remove_foreign_key_sql(table_name, *args) when String then execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}" end end |
#remove_foreign_key_sql(table_name, *args) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 76 def remove_foreign_key_sql(table_name, *args) case ret = super when String then ret.sub(/DROP CONSTRAINT/, 'DROP FOREIGN KEY') else ret end end |
#remove_index_sql(table_name, options) ⇒ Object
71 72 73 74 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 71 def remove_index_sql(table_name, ) return [] if .delete(:if_exists) and not index_exists?(table_name, ) super end |
#rename_table_with_schema_plus(oldname, newname) ⇒ Object
41 42 43 44 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 41 def rename_table_with_schema_plus(oldname, newname) rename_table_without_schema_plus(oldname, newname) rename_indexes_and_foreign_keys(oldname, newname) end |
#reverse_foreign_keys(table_name, name = nil) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 122 def reverse_foreign_keys(table_name, name = nil) results = select_all(<<-SQL, name) SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name FROM information_schema.key_column_usage WHERE table_schema = #{table_schema_sql(table_name)} AND referenced_table_schema = table_schema ORDER BY constraint_name, ordinal_position; SQL current_foreign_key = nil foreign_keys = [] namespace_prefix = table_namespace_prefix(table_name) results.each do |row| next unless table_name_without_namespace(table_name).casecmp(row["referenced_table_name"]) == 0 if current_foreign_key != row["constraint_name"] referenced_table_name = row["table_name"] referenced_table_name = namespace_prefix + referenced_table_name if table_namespace_prefix(referenced_table_name).blank? references_table_name = row["referenced_table_name"] references_table_name = namespace_prefix + references_table_name if table_namespace_prefix(references_table_name).blank? foreign_keys << ForeignKeyDefinition.new(row["constraint_name"], referenced_table_name, [], references_table_name, []) current_foreign_key = row["constraint_name"] end foreign_keys.last.column_names << row["column_name"] foreign_keys.last.references_column_names << row["referenced_column_name"] end foreign_keys end |
#tables_with_schema_plus(name = nil, *args) ⇒ Object
26 27 28 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 26 def tables_with_schema_plus(name=nil, *args) tables_without_schema_plus(name, *args) - views(name) end |
#view_definition(view_name, name = nil) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 161 def view_definition(view_name, name = nil) results = select_all("SELECT view_definition, check_option FROM information_schema.views WHERE table_schema = SCHEMA() AND table_name = #{quote(view_name)}", name) return nil unless results.any? row = results.first sql = row["view_definition"] sql.gsub!(%r{#{quote_table_name(current_database)}[.]}, '') case row["check_option"] when "CASCADED" then sql += " WITH CASCADED CHECK OPTION" when "LOCAL" then sql += " WITH LOCAL CHECK OPTION" end sql end |
#views(name = nil) ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 153 def views(name = nil) views = [] select_all("SELECT table_name FROM information_schema.views WHERE table_schema = SCHEMA()", name).each do |row| views << row["table_name"] end views end |