Skip to content

Instantly share code, notes, and snippets.

@yuya-takeyama
Last active August 29, 2015 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuya-takeyama/9129312 to your computer and use it in GitHub Desktop.
Save yuya-takeyama/9129312 to your computer and use it in GitHub Desktop.
mysqldump のダンプファイルをテーブル単位に分割するヤツのプロトタイプ

mysqldump のダンプファイルをテーブル単位に分割するヤツのプロトタイプ

使い方

$ ruby mysqldump_splitter.rb dumpfile [-t tables]

table.*.sql というファイルのテーブルが出力される。

-t を指定すると、そのテーブルだけが出力されるようになる。 (, 区切りで複数可能)

現状の問題

以下の行がスキップされる。 (コメントだから実害無いけど)

--
-- Dumping data for table `some_table`
--

今後やりたいこと

  • コマンドラインオプションの追加
    • ファイルの出力先
    • 出力ファイル名のフォーマット
  • 標準入力からの読み込み
  • Go への移植
#!/usr/bin/env ruby
# coding: utf-8
$KCODE = "u" if RUBY_VERSION < '1.9'
class MysqldumpSplitter
STATE_INITIAL = 0
STATE_MAYBE_BEGINNING_OF_TABLE_STRUCTURE = 1
STATE_ENTERING_TABLE_STRUCTURE = 2
STATE_IN_TABLE_STRUCTURE = 3
def initialize(file, target_tables)
@file = file
@target_tables = target_tables
@state = STATE_INITIAL
@prev_state = nil
@table = nil
@table_num = 1
end
def exec
open(@file).each do |line|
case @state
when STATE_INITIAL
change_state STATE_MAYBE_BEGINNING_OF_TABLE_STRUCTURE if line == "--\n"
when STATE_MAYBE_BEGINNING_OF_TABLE_STRUCTURE
matched = line.match(/^-- Table structure for table `([^`]+)`$/)
if matched
change_state STATE_ENTERING_TABLE_STRUCTURE
change_table matched[1]
write_table_file @prev_line
write_table_file line
else
write_table_file @prev_line
write_table_file line
revert_state
end
when STATE_ENTERING_TABLE_STRUCTURE
write_table_file line
change_state STATE_IN_TABLE_STRUCTURE
when STATE_IN_TABLE_STRUCTURE
if line == "--\n"
change_state STATE_MAYBE_BEGINNING_OF_TABLE_STRUCTURE
else
write_table_file line
end
end
@prev_line = line
end
end
private
def change_state(next_state)
@prev_state = @state
@state = next_state
end
def revert_state
@state = @prev_state
end
def change_table(table)
@table = table
@table_file = nil
end
def write_table_file(line)
if @target_tables.size == 0 or @target_tables.include? @table
file = @table_file || open_new_table_file
file.puts line
end
end
def open_new_table_file
file = open('table.' + ("%04d" % @table_num) + "." + @table + ".sql", 'a')
@table_num += 1
@table_file = file
file
end
end
require 'optparse'
tables = []
opt = OptionParser.new
opt.on('-t tables', 'comma-separated tables names to extract') {|_tables| tables = _tables.split(',') }
opt.parse! ARGV
splitter = MysqldumpSplitter.new(ARGV[0], tables)
splitter.exec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment