require 'flydata/table_ddl' require 'flydata-core/mysql/command_generator' require 'flydata-core/mysql/binlog_pos' module Flydata module SourceMysql class TableDdl def self.migrate_tables(tables, mysql_opts, sync_fm, position_file, context, &block) migrate_to_v2(tables, mysql_opts, sync_fm, position_file, context, &block) end private V2_TARGET_VERSION = Flydata::TableDdl::VERSION2 EVENT_TYPE = 'Query' ALTER_TABLE_CHARSET_SQL = <= V2_TARGET_VERSION if mysql_tabledefs.nil? FlydataCore::Mysql::CommandGenerator.each_mysql_tabledef(tables, mysql_opts) do |mysql_tabledef, error| raise error if error mysql_tabledefs ||= {} mysql_tabledefs[mysql_tabledef.table_name] = mysql_tabledef end end mysql_tabledef = mysql_tabledefs[table] if binlog_pos.nil? # get binlog position binlog_pos = FlydataCore::Mysql::BinlogPos.new(File.open(position_file){|f| f.read }) original_binlog_file = context.current_binlog_file context.current_binlog_file = binlog_pos.filename end # get charset charset = mysql_tabledef.default_charset_mysql # construct queries # column charset column_event = nil at_subquery = mysql_tabledef.column_def.select{|col, coldef| /CHARACTER SET/.match(coldef) }.collect{|col, coldef| CHANGE_COLUMN_SQL % [col, coldef]}.join(",") unless at_subquery.empty? column_query = ALTER_TABLE_SQL % [database, table, at_subquery] column_event = QueryEvent.new(EVENT_TYPE, database, table, binlog_pos.pos, event_size, column_query, Time.now.to_i) yield column_event end # table charset table_query = ALTER_TABLE_CHARSET_SQL % [database, table, charset] # create events and yield table_event = QueryEvent.new(EVENT_TYPE, database, table, binlog_pos.pos, event_size, table_query, Time.now.to_i) yield table_event $log.info "migrating table `#{table}` from version #{version} to version #{V2_TARGET_VERSION}. Table event #{table_event} Column event #{column_event}" # update generated_ddl sync_fm.save_generated_ddl([table], V2_TARGET_VERSION.to_s) end context.current_binlog_file = original_binlog_file if binlog_pos end end # mimics RubyBinlog::QueryEvent class QueryEvent def initialize(event_type, database_name, event_table_name, next_position, event_length, query, timestamp) @event_type = event_type @database_name = database_name @event_table_name = event_table_name @next_position = next_position @event_length = event_length @query = query @timestamp = timestamp end attr_reader :event_type, :database_name, :event_table_name, :next_position, :event_length, :query, :timestamp def to_s <