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.)
Class Method Summary collapse
-
.included(base) ⇒ Object
:enddoc:.
Instance Method Summary collapse
- #default_expr_valid?(expr) ⇒ Boolean
-
#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) ⇒ Object
- #remove_foreign_key(table_name, foreign_key_name, options = {}) ⇒ Object
- #rename_table_with_schema_plus(oldname, newname) ⇒ Object
- #reverse_foreign_keys(table_name, name = nil) ⇒ Object
- #sql_for_function(function) ⇒ 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
#default_expr_valid?(expr) ⇒ Boolean
150 151 152 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 150 def default_expr_valid?(expr) false # only the TIMESTAMP column accepts SQL column defaults and rails uses DATETIME end |
#drop_table(name, options = {}) ⇒ Object
implement cascade by removing foreign keys
57 58 59 60 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 57 def drop_table(name, ={}) reverse_foreign_keys(name).each{ |foreign_key| remove_foreign_key(foreign_key.table_name, foreign_key.name) } if [:cascade] super 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
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 44 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
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 66 def foreign_keys(table_name, name = nil) results = execute("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 |row| row[1].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) ⇒ Object
30 31 32 33 34 35 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 30 def remove_column_with_schema_plus(table_name, column_name) 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 remove_column_without_schema_plus(table_name, column_name) end |
#remove_foreign_key(table_name, foreign_key_name, options = {}) ⇒ Object
62 63 64 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 62 def remove_foreign_key(table_name, foreign_key_name, = {}) execute "ALTER TABLE #{quote_table_name(table_name)} DROP FOREIGN KEY #{foreign_key_name}" end |
#rename_table_with_schema_plus(oldname, newname) ⇒ Object
37 38 39 40 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 37 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
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 98 def reverse_foreign_keys(table_name, name = nil) results = execute(<<-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[3]) == 0 if current_foreign_key != row[0] referenced_table_name = row[1] referenced_table_name = namespace_prefix + referenced_table_name if table_namespace_prefix(referenced_table_name).blank? references_table_name = row[3] references_table_name = namespace_prefix + references_table_name if table_namespace_prefix(references_table_name).blank? foreign_keys << ForeignKeyDefinition.new(row[0], referenced_table_name, [], references_table_name, []) current_foreign_key = row[0] end foreign_keys.last.column_names << row[2] foreign_keys.last.references_column_names << row[4] end foreign_keys end |
#sql_for_function(function) ⇒ Object
154 155 156 157 158 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 154 def sql_for_function(function) case function when :now then 'CURRENT_TIMESTAMP' end 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
137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 137 def view_definition(view_name, name = nil) result = execute("SELECT view_definition, check_option FROM information_schema.views WHERE table_schema = SCHEMA() AND table_name = #{quote(view_name)}", name) return nil unless (result.respond_to?(:num_rows) ? result.num_rows : result.to_a.size) > 0 # mysql vs mysql2 row = result.respond_to?(:fetch_row) ? result.fetch_row : result.first sql = row[0] sql.gsub!(%r{#{quote_table_name(current_database)}[.]}, '') case row[1] when "CASCADED" then sql += " WITH CASCADED CHECK OPTION" when "LOCAL" then sql += " WITH LOCAL CHECK OPTION" end sql end |
#views(name = nil) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb', line 129 def views(name = nil) views = [] execute("SELECT table_name FROM information_schema.views WHERE table_schema = SCHEMA()", name).each do |row| views << row[0] end views end |