config-importer.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. config_path, ini_path, code_path, text_path, is_generate_field_info = *ARGV
  2. is_generate_field_info = (is_generate_field_info == 'true')
  3. require 'csv'
  4. def convert_case(source)
  5. return source.split('_').collect(&:capitalize).join
  6. end
  7. # 各类型定义
  8. TypeInfo = Struct.new(:data_type, :data_type_extra, :ref_info, :default_value)
  9. FieldInfo = Struct.new(:column_id, :identifier, :comment, :type_info)
  10. Table = Struct.new(:csv, :fields, :name2id, :id_field)
  11. Ini = Struct.new(:io, :tables)
  12. inis = {}
  13. # 读取配置表子目录,以形成配置数据目录
  14. Dir["#{config_path}/*"].each do |path|
  15. ini_name = File::basename(path)
  16. ini = (inis[ini_name] ||= Ini.new(File.open("#{ini_path}/#{ini_name}.ini", 'wb'), {}))
  17. next unless File::directory?(path)
  18. # 每个配置表子目录将成为一个 ini 文件
  19. # 内含全部子 .csv 表格的导入数据
  20. Dir["#{path}/*.csv"].each do |file|
  21. table_name = File::basename(file, '.csv')
  22. table = (ini.tables[convert_case(table_name)] = Table.new(csv = CSV.open(file), [], {}, nil))
  23. identifiers = csv.readline
  24. comments = csv.readline
  25. type_infos = csv.readline
  26. field_id = nil
  27. field_id_name = nil
  28. # 处理表头列
  29. identifiers.each_with_index do |identifier, index|
  30. next if identifier.nil? || identifier.empty?
  31. type_info = TypeInfo.new(nil, nil, nil, nil)
  32. type_infos[index].gsub(/\s+/, '').scan(/[(:|,|@|=)][a-zA-Z_]+/).each do |info|
  33. type_info.data_type = info[1..info.size] if info.start_with?(':')
  34. type_info.data_type_extra = info[1..info.size] if info.start_with?(',')
  35. type_info.ref_info = info[1..info.size] if info.start_with?('@')
  36. type_info.default_value = info[1..info.size] if info.start_with?('=')
  37. end
  38. field = FieldInfo.new(index, identifier, comments[index], type_info)
  39. # 处理特殊类型的字段
  40. case type_info.data_type
  41. when 'id'
  42. field_id = field
  43. next
  44. when 'id_name'
  45. field_id_name = field
  46. next
  47. end
  48. # 参与导入的条目
  49. table.fields << field
  50. end
  51. # 验证 Id 列
  52. next if field_id.nil?
  53. table.id_field = field_id
  54. # 处理条目形成引用表
  55. while !csv.eof?
  56. line = csv.readline
  57. table.name2id[line[field_id_name.column_id]] = line[field_id.column_id].upcase
  58. end
  59. # 回滚 csv 状态至表头读取后
  60. csv.rewind
  61. 3.times { csv.readline }
  62. end
  63. end
  64. # 导入实际数据条目
  65. inis.each_pair do |ini_name, ini_data|
  66. register_table = {}
  67. buffer = StringIO.new
  68. ini_data.tables.each_pair do |table_name, table|
  69. register = (register_table[table_name] = [])
  70. while !table.csv.eof?
  71. line = table.csv.readline
  72. id = line[table.id_field.column_id].upcase
  73. buffer.puts "[#{id}]"
  74. table.fields.each do |field|
  75. value = line[field.column_id]
  76. next if value.nil? || value.empty?
  77. buffer.puts "#{field.identifier}=#{value}"
  78. end
  79. buffer.puts
  80. register << id
  81. end
  82. end
  83. File.open("#{ini_path}/#{ini_name}.ini", 'wb') do |ini|
  84. ini.puts '[REGISTER]'
  85. register_table.each_pair do |table_name, register|
  86. ini.puts "#{table_name}=#{register.join(',')}"
  87. end
  88. ini.puts
  89. ini.puts buffer.string
  90. end
  91. end