Skip to content

Instantly share code, notes, and snippets.

@Naggi-Goishi
Last active December 5, 2017 14:15
Show Gist options
  • Save Naggi-Goishi/fb04e83ee7fb45a50f4c57f880072eda to your computer and use it in GitHub Desktop.
Save Naggi-Goishi/fb04e83ee7fb45a50f4c57f880072eda to your computer and use it in GitHub Desktop.
Convert mysql to rails migration file
require 'date'
class Converter
def initialize(file_name)
@file_name = file_name
@tables = {}
@current_table = {}
end
def to_ruby(rails_v)
@tables.each do |t_name, table|
file_name = "#{DateTime.now().strftime('%Y%m%d%H%M')}_create_#{t_name}.rb"
File.open("db/migrate/#{file_name}", 'wb') do |f|
if rails_v < 5.0
f << "class Create#{t_name.capitalize} < ActiveRecord::Migration\n"
else
f << "class Create#{t_name.capitalize} < ActiveRecord::Migration[#{rails_v}]\n"
end
f << " def change\n"
f << " create_table :#{t_name} do |t|\n"
table[:columns].each do |name, column|
str_options = column[:options].inject('') { |options, (k, v)| options + ", #{k}: #{v}" } if column[:options].length > 0
next if name == 'id'
f << " t.#{column[:type]} :#{column[:name]}#{str_options}\n"
end
f << " end\n"
f << " end\n"
f << "end\n"
end
end
end
def read
in_table = false
File.open(@file_name, 'r') do |f|
f.each_line do |line|
line = line.strip
if in_table
if /\);/.match? line
@tables[@current_table[:name]] = @current_table
in_table = false
next
end
column = /^`(.*)`/.match(line)[1] if /^`(.*)`/.match? line
type = sql_to_rails(/INT|varchar|bool/.match(line)[0]) if /INT|varchar/.match? line
options = options_to_hash(line)
@current_table[:columns][column] = { name: column, type: type, options: options } if (column && type)
end
create_table_regex = /^CREATE TABLE `(.*)` \(/
alter_table_regex = /^ALTER TABLE `.*` ADD CONSTRAINT `.*` FOREIGN KEY \(`.*`\) REFERENCES `.*`\(`.*`\)/
table_name_regex = /^ALTER TABLE `(.*)` ADD CONSTRAINT `.*` FOREIGN KEY \(`.*`\) REFERENCES `.*`\(`.*`\)/
column_regex = /^ALTER TABLE `.*` ADD CONSTRAINT `.*` FOREIGN KEY \(`(.*)`\) REFERENCES `.*`\(`.*`\)/
if create_table_regex.match? line
table_name = create_table_regex.match(line)[1]
@current_table = { name: table_name, columns: {} }
in_table = true
elsif alter_table_regex.match? line
table_name = table_name_regex.match(line)[1]
column = column_regex.match(line)[1]
@tables[table_name][:columns][column][:name] = column
@tables[table_name][:columns][column][:type] = 'references'
end
end
self
end
end
private
def sql_to_rails(type_in_sql)
case type_in_sql
when 'INT'
'integer'
when 'varchar'
'string'
when 'bool'
'boolean'
end
end
def options_to_hash(line)
options = {}
options['null'] = false if /NOT NULL/.match? line
options['uniqueness'] = true if /UNIQUE/.match? line
options['default'] = /DEFAULT (.*)/.match(line)[1] if /DEFAULT (.*)/.match? line
options
end
end
converter = Converter.new('./mysqls/Kakaxi_mysql_create.sql').read
converter.to_ruby(5.1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment