#!/usr/bin/env ruby require 'rubygems' require 'optparse' require 'io/console' require 'csv' require 'open3' require_relative '../lib/muzzy' Version = Muzzy::VERSION ## check environments kakasi_path = File.absolute_path(File.expand_path('..', __FILE__) + "/../vendor/bin/kakasi") unless File.exists?(kakasi_path) $stderr.puts "cannot find kakasi. please check kakasi installation is successed." $stderr.puts "expect path: #{kakasi_path}" $stderr.puts "If you have not execute `muzzy_setup` yet, please run `muzzy_setup` first." exit 1 end mysql_cmd = `which mysql`.to_s.chomp if mysql_cmd == '' $stderr.puts "cannot find mysql client" exit 1 end mysqlimport_cmd = `which mysqlimport`.to_s.chomp if mysqlimport_cmd == '' $stderr.puts "cannot find mysqlimport command" exit 1 end options = { file: '', verbose: false, mysql_config: { user: 'root', host: 'localhost', use_password: false, database: 'muzzy', }, mysqlimport_config: { delete: false }, } def check_file(file) if File.directory?(file) $stderr.puts "muzzy: #{file}: is directory" exit Errno::ENOENT::Errno end unless File.exists?(file) $stderr.puts "muzzy: #{file}: No such file or directory" exit Errno::ENOENT::Errno end end ## parse arguments ARGV.options do |opt| opt.banner = "Usage: muzzy [filepath] [options]" begin opt.on('-u', "--user [USER]", String, 'mysql user') {|user| options[:mysql_config][:user] = user } opt.on('-h [HOST]', 'mysql host') {|v| options[:mysql_config][:host] = v } opt.on('-p', 'using mysql password') {|v| options[:mysql_config][:use_password] = v } opt.on('-V', '--verbose', 'verbose option') { options[:verbose] = true } opt.on('-r', 'remove data and insert it') { options[:mysqlimport_config][:delete] = true } if ARGV[0].to_s.length > 0 && ARGV[0].to_s[0] != '-' options[:file] = ARGV[0] elsif ARGV.last.to_s.length > 0 && ARGV.last.to_s[0] != '-' options[:file] = ARGV.last else opt.on('-f', '--file [FILEPATH]', 'path to target file') {|v| options[:file] = v } end check_file(options[:file]) opt.on('-v', '--version') { $stdout.puts opt.ver exit } opt.parse! if options[:file].nil? || options[:file] == '' $stdout.puts opt.help exit 1 end rescue => e $stderr.puts("[ERROR] #{e.message}") exit 1 end end if options[:mysql_config][:database] !~ /\A(\w)+\z/ $stderr.puts "illegal database name" exit 1 end filetype_detector = Muzzy::FiletypeDetector.new(options[:file]) if filetype_detector.unknown? $stderr.puts "illegal file" exit 1 end first_row = filetype_detector.first_row second_row = filetype_detector.second_row fields_terminated_by = filetype_detector.tsv? ? "\t" : ',' # detect first_row is header or data row first_row_is_header = Muzzy::HeaderDetector.detect([first_row, second_row]) if first_row_is_header == nil # cannot judge header is header or not puts "first row is" puts first_row.join(',') puts "first row is HEADER? [y/n]" loop do y_or_n = $stdin.gets.to_s.chomp if y_or_n.match(/\A[Yy]\z/) first_row_is_header = true break end if y_or_n.match(/\A[Nn]\z/) first_row_is_header = false break end puts "plase enter y or n" end end if first_row_is_header first_row = first_row.map do |str| std_out = Open3.capture2('echo', str)[0] Open3.capture2(kakasi_path, '-Ja', '-Ha', '-Ka', '-Ea', '-i', 'utf8', '-o', 'utf8', stdin_data: std_out)[0] end.map(&:chomp).map do |x| # kakasi returns ko^do if 'コード' given so trimming x.gsub(/[\^]/, '') end end # TODO ヘッダが空白含んでたりするやつとかをなんとかする col_data_types = [] Cell = Struct.new(:type, :name) if first_row_is_header if first_row col_data_types = first_row.map.with_index do |str, i| if str.to_s.match(/\A[\d,]+\z/) # number Cell.new('integer', first_row[i]) else Cell.new('text', first_row[i]) end end else col_data_types = first_row.map.with_index do |str, i| colname = first_row[i].gsub(/[,-]/, '') if str.to_s.match(/_id/i) && str.to_s.match(/\A[\w]+\z/i) # number Cell.new('integer', colname) else Cell.new('text', colname) end end end else # TODO not create table option # first row is data(not header) col_data_types = first_row.map.with_index do |str, i| if str.to_s.match(/\A[\d,]+\z/) # number Cell.new('integer', "col#{i}") else Cell.new('text', "col#{i}") end end end config = { filepath: options[:file], cmd_path: mysql_cmd, mysqlimport_path: mysqlimport_cmd, user: options[:mysql_config][:user], host: options[:mysql_config][:host], # password: options[:mysql_config][:password], use_password: options[:mysql_config][:use_password], database_name: options[:mysql_config][:database], } db_adapter = Muzzy::DatabaseAdapter::MysqlAdapter.new( config, verbose: options[:verbose] ) unless db_adapter.confirm_database unless db_adapter.create_database # database create failed exit 1 end end filename = File.basename(options[:file]) table_name = filename.match(/\A(\w+)(\.\w+)?\z/)[1] # confirm table unless db_adapter.confirm_table(table_name) # cannot confirm table so create table unless db_adapter.create_table(table_name, col_data_types) # error, cannot create table exit 1 end end # import db_adapter.import(table_name, { first_row_is_header: first_row_is_header, fields_terminated_by: fields_terminated_by, delete: options[:mysqlimport_config][:delete] }) exit 0