インデックスの文字数制限もSchemaDumpできるようにする
MySQLのあるテーブルにINDEXをつけていたのだけれど、フィールドの型がTEXTだったので、「最初の500文字まで」という制限をかけていた。(MySQLではINDEXをつけられる文字数に制限がある)ところがこの文字数制限、RailsのSchemaDumperではダンプできない。
で、Schema中にはSQLを直接書いていたのだけれど、それだとテストができないのだ。
rakeでテストを走らせると、「開発用DBからRuby形式でテーブル形式をダンプ→それをテスト用データベースに適用」する。のだけれど、上述の制限がうまく動いていない。SQL形式でダンプするやり方があるだろうと探したのだけれど、見つける前にRuby形式に適当に手を入れた方が早そうだと思った。ので、作った。
# インデックスの制限もDumpできるようにする module ActiveRecord module ConnectionAdapters class MysqlAdapter < AbstractAdapter def indexes(table_name, name = nil)#:nodoc: indexes = [] current_index = nil execute("SHOW KEYS FROM #{table_name}", name).each do |row| if current_index != row[2] next if row[2] == "PRIMARY" # skip the primary key current_index = row[2] indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", []) end cname = [row[4]] cname << "(#{row[7]})" if row[7] cname = cname[0] if cname.size == 1 indexes.last.columns << cname end indexes end end end module ConnectionAdapters # :nodoc: module SchemaStatements def add_index(table_name, column_name, options = {}) column_names = Array(column_name) index_name = index_name(table_name, :column => column_names.first) if Hash === options # legacy support, since this param was a string index_type = options[:unique] ? "UNIQUE" : "" index_name = options[:name] || index_name else index_type = options end quoted_column_names = column_names.map { |e| if e.is_a? Array n = e.shift quote_column_name(n) + e.join(" ") else quote_column_name(e) end }.join(", ") execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names})" end end end end
- これを lib/schema_dumper_putch.rb として保存
- Rakefile に
require 'rake' require 'rake/testtask' require 'rake/rdoctask' require 'lib/schema_dumper_patch.rb' # これを追加 require 'tasks/rails'
すると、何とか上手くテストが起動できるようになった。よかった。
形式があまりにその場しのぎなので、応用性はないかもしれないけど。