data_list_converter 0.3.10 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 85c9410c6b8c64a1af696f42485e098f43f432c2
4
- data.tar.gz: 930b7bb74e9d441e183451d4329e639c06aa3cdf
2
+ SHA256:
3
+ metadata.gz: f65479d343c6345e3dbaf9762d3dcd8e6e0fc353bfc8441cc1dd3e7d9385aaba
4
+ data.tar.gz: fc2be9587bfafe4a5da8558e10b49fd3a85b514e0c79057bb8abe61b5bb5f958
5
5
  SHA512:
6
- metadata.gz: b53cb6e80ac57b256b74100421b12d14c9e1f57bee172807bb0f6437efe27e2c2c8915705d52b0e1ff01855188a6e4a3ac274138f7623cbec648a187ba349631
7
- data.tar.gz: c87df4a93536be36f7aec7d88c3c93325b39fe03ab09414d4d1533024569e6d550f46cfff724df48bd39612bd6b52727473acbe20b1fdd273b92194b4f9286fc
6
+ metadata.gz: 9faf4b96e80b3bc6146ead5b2cbbdc6b707ccd472489fbbaab88723d57e1e4865037d11adeec061b9162cdacdc4ba9c8942a70acf1b617a153d2603fb3201196
7
+ data.tar.gz: '090045d9d7b897e899bbdaa53135854a98f66b1a3a4e698df7ba24ecfeb0c05c0ebf5a7527576af67bae4d997611625398b1d0efbe2a31e70f9d3fdb81b07c49'
data/README.md CHANGED
@@ -22,61 +22,73 @@ DataListConverter.convert(:xls_file, :multi_sheet_item_data, {filename: 'result.
22
22
  You can also add filter to this process:
23
23
 
24
24
  ```ruby
25
- filters = [
26
- # filter with default options
27
- :limit,
28
- # filter with options
29
- {limit: {size: 2}},
30
- # multiple filters
31
- [{limit: {size: 12}},
32
- {count: {size: 4}}],
33
- ]
34
- filters.map do |filter|
35
- data = [{name: "james"}] * 10
36
- DataListConverter.convert(:item_data, :table_data, data, table_iterator: {filter: filter})
37
- end
25
+ data = (1..20).map{|i| {name: "user-#{i}", age: i+20}}
26
+ # filter with default options (limit 10)
27
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: :limit})
28
+ # filter with options
29
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: {limit: {size: 2}}})
30
+ # multiple filters
31
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: [{limit: {size: 12}}, {count: {size: 4}}]})
38
32
  ```
39
33
 
40
- Please read [the source code](https://github.com/halida/data_list_converter/blob/master/lib/data_list_converter/) for more information,
41
- also you can check [test examples](https://github.com/halida/data_list_converter/blob/master/test/).
42
-
43
34
  ## Data Types
44
35
 
36
+ Default data types:
37
+
45
38
  - **item_data** like: `[{name: 'James', age: '22'}, ...]`, keys should be symbol.
46
39
  - **item_iterator** iterator for item_data, used like: iter.call{|item| out << item}
47
40
  - **table_data** like: `[["name", "age"], ["James", "22"], ["Bob", "33"], ...]`
48
41
  - **table_iterator** iterator for table_data
49
- - **csv_file** file in csv format
50
- - **xls_file** file in excel format, should install `spreadsheet` gem, and `require 'data_list_converter/types/xls_file'`
51
- - **xlsx_file** file in excel xml format, should install `rubyXL` gem, and `require 'data_list_converter/types/xlsx_file'`
52
42
  - **multi_sheet** Contains several data with sheets:
53
43
  - **multi_sheet_table_iterator**: like: `{sheet1: table_iterator1, sheet2: table_iterator2}`
54
44
  - **multi_sheet_table_data**: like: `{sheet1: [['name', 'age'], ...], sheet2: ...}`
55
45
  - **multi_sheet_item_iterator**: like: `{sheet1: item_iterator1, sheet2: item_iterator2}`
56
46
  - **multi_sheet_item_data**: like: `{sheet1: [{name: 'James', age: 32}], sheet2: ...}`
57
- - **records** ActiveRecord records, usage: `DataListConverter.convert(:records, :item_data, Users.where(condition), item_iterator: {columns: [:name, :age]})`
58
47
 
48
+ Plugin data types, should required first by `require 'data_list_converter/types/#{type}'`
49
+
50
+ - **csv_file** file in csv format
51
+ - **xls_file** file in excel format, should install `spreadsheet` gem first
52
+ - **xlsx_file** file in excel xml format, should install `rubyXL` gem first
53
+ - **records** ActiveRecord records
54
+
55
+ Please check [test examples](https://github.com/halida/data_list_converter/blob/master/test/types_test.rb) to see how to use those types.
59
56
 
60
57
  ## Filters
61
58
 
62
- **item_iterator/table_iterator limit**: limit item_iterator result counts, usage: `DataListConverter.convert(:item_data, :table_data, item_data, item_iterator: {filter: {limit: {size: 2}}})`
59
+ **item_iterator/table_iterator limit**: limit item_iterator result counts, usage: `DataListConverter.convert(:item_data, :table_data, item_data, item_iterator: {filter: {limit: {size: 2}}})`, default limit size is 10.
63
60
 
64
- **item_iterator count**: count item_iterator items, usage: `DataListConverter.convert(:xls_file, :item_data, {filename: 'result.xls'}, item_iterator: {filter: {count: {size: 10}}})`, it will print current item counts every `size`.
61
+ **item_iterator count**: count item_iterator items, usage: `DataListConverter.convert(:xls_file, :item_data, {filename: 'result.xls'}, item_iterator: {filter: {count: {size: 10}}})`, it will print current item counts every `size`, please [see here](https://github.com/halida/data_list_converter/blob/master/lib/data_list_converter/filters/count.rb) for more options.
65
62
 
66
- Please check more [test examples](https://github.com/halida/data_list_converter/blob/master/test/filters_test.rb)
63
+ Please see [test examples](https://github.com/halida/data_list_converter/blob/master/test/filters_test.rb) to learn how to use filter.
64
+
65
+ ## helpers
66
+
67
+ - **types**: Get current valid types.
68
+ - **routes**: Get current valid routes.
69
+ - **file_types**: Get current file types, which is the types has `_file` suffix.
70
+ - **get_file_format**: Get file type by filename, which compare file extension with `file_types`. `DataListConverter.get_file_format('xxx.xls') == :xls_file`
71
+ - **save_to_file**: Save data to file, it will use `get_file_format` to find proper file format. `DataListConverter.save_to_file(filename, data, data_format=:item_data)`
72
+ - **load_from_file**: Get data from file, it will use `get_file_format` to find proper file format. `DataListConverter.load_from_file(filename, data_format=:item_data)`
73
+ - **unify_item_data_keys**: Sometimes in the `item_data` list, each data keys don't exactly same, so use this function to fix it, example: `DataListConverter.unify_item_data_keys([{a: 12}, {b: 11}]) == [{a: 12, b: nil}, {a: nil, b: 11}]`.
74
+ - **flatten**: Flatten multi level item_data list into one level, example: `DataListConverter.flatten({a: {b: 12}, c: {d: {e: 11}}}) == {:"a:b"=>12, :"c:d:e"=>11}`, can change seperator: `DataListConverter.flatten(data, '_')`, set max level: `DataListConverter.flatten(data, '_', 2)`
67
75
 
68
76
  ## Extend
69
77
 
70
78
  You can add your own data types and filters, example:
71
79
 
72
80
  ```ruby
73
- DataListConverter.register_converter(:records, :item_iterator) do |records, options|
74
- columns = options[:columns]
81
+ DataListConverter.register_converter(:records, :item_iterator) do |input, options|
82
+ query = self.parameter(input, :query, :input)
83
+ columns = self.parameter(input, :columns, :input)
84
+ display = input[:display] || columns
85
+
75
86
  lambda { |&block|
76
- records.find_each do |record|
77
- item = columns.map do |column|
78
- [column.first.to_sym, record.send(column[1])]
79
- end.to_h
87
+ query.pluck(*columns).each do |data|
88
+ item = {}
89
+ data.each_with_index do |d, i|
90
+ item[display[i]] = d
91
+ end
80
92
  block.call(item)
81
93
  end
82
94
  }
@@ -94,14 +106,3 @@ DataListConverter.register_filter(:item_iterator, :limit) do |proc, options|
94
106
  }
95
107
  end
96
108
  ```
97
-
98
-
99
- ## Todo
100
-
101
- - check type exists
102
- - route not found, list all routes
103
- - register can bind method again
104
- - better API
105
- - better error message
106
- - load file/save file with auto format by extname
107
- - report error when cannot find type
@@ -1,3 +1,10 @@
1
+ ## 0.4
2
+
3
+ Add parameter check, type check, change record type API.
4
+
5
+ - 0.4.1 add max_level to flatten helper
6
+ - 0.4.2 fix value cannot save if value is symbol
7
+
1
8
  ## 0.3
2
9
 
3
10
  Refactor.
@@ -17,6 +17,10 @@ Gem::Specification.new do |s|
17
17
  s.add_development_dependency 'spreadsheet', '~> 1.0'
18
18
  s.add_development_dependency 'rubyXL', '~> 3.3'
19
19
  s.add_development_dependency 'pry', '~> 0.10.1'
20
+ s.add_development_dependency 'sqlite3', '~> 1.3'
21
+ s.add_development_dependency 'activerecord', '~> 4.2'
22
+ s.add_development_dependency 'xlsxtream'
23
+ s.add_development_dependency 'creek'
20
24
 
21
25
  s.files = `git ls-files`.split("\n")
22
26
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -21,6 +21,7 @@ class DataListConverter
21
21
  puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}\t#{msg}"
22
22
  end
23
23
 
24
+ # register_converter(:item_data, :item_iterator){ |data, options| ... }
24
25
  def register_converter(from_type, to_type, &block)
25
26
  @route_map = nil # clear cache
26
27
  CONVERTERS[[from_type, to_type]] = block
@@ -44,7 +45,7 @@ class DataListConverter
44
45
  def convert(from_type, to_type, from_value, options={})
45
46
  methods = []
46
47
  add_filter = lambda { |type|
47
- filters = (options[type] || {}).delete(:filter)
48
+ filters = (options[type] || {})[:filter]
48
49
  return unless filters
49
50
  methods += normalize_filters(type, filters)
50
51
  }
@@ -57,6 +58,7 @@ class DataListConverter
57
58
  from_type, to_type = route[i], route[i+1]
58
59
  method = CONVERTERS[[from_type, to_type]]
59
60
  raise "cannot find converter #{from_type} -> #{to_type}" unless method
61
+ self.log "#{from_type} -> #{to_type} options: #{options[to_type]}"
60
62
  methods.push([method, options[to_type] || {}])
61
63
  add_filter.call(to_type)
62
64
  end
@@ -91,7 +93,11 @@ class DataListConverter
91
93
  # If we want to convert between types, like: convert item_data into csv_file,
92
94
  # we need find all the intermidate data type, like: [:item_data, :item_iterator, :table_iterator, :csv_file]
93
95
  def find_route(from_type, to_type)
96
+ [from_type, to_type].each do |type|
97
+ raise Exception, "cannot find type: #{type}" unless self.types.include?(type)
98
+ end
94
99
  raise Exception, "from_type should not equal to to_type: #{from_type}" if from_type == to_type
100
+
95
101
  # map wide search
96
102
  checked = Set.new
97
103
  checking = Set.new([from_type])
@@ -124,7 +130,10 @@ class DataListConverter
124
130
  checking += Set.new(next_nodes) - checked
125
131
  end
126
132
  end
127
- raise Exception, "Route not found: #{from_type} -> #{to_type}"
133
+
134
+ log = ["Route not found: #{from_type} -> #{to_type}", "Current routes:"]
135
+ log += self.routes.map{|from, to| "#{from} -> #{to}"}
136
+ raise Exception, log.join("\n")
128
137
  end
129
138
 
130
139
  # convert adjacency list into quick lookup hash
@@ -5,6 +5,7 @@ class DataListConverter
5
5
  msg_format = options[:msg] || "on %{count}"
6
6
  total_format = options[:total] || "total: %{total}"
7
7
  out = options[:out] || STDOUT
8
+
8
9
  total = 1
9
10
  lambda { |&block|
10
11
  proc.call do |item|
@@ -1,14 +1,14 @@
1
1
  class DataListConverter
2
- def self.save_to_file(filename, data, data_format=:item_data)
2
+ def self.save_to_file(filename, data, data_format=:item_data, options={})
3
3
  file_format = self.get_file_format(filename)
4
- DataListConverter.convert(data_format, file_format, data,
5
- file_format => {filename: filename})
4
+ options[file_format] = {filename: filename}
5
+ DataListConverter.convert(data_format, file_format, data, options)
6
6
  end
7
7
 
8
- def self.load_from_file(filename, data_format=:item_data)
8
+ def self.load_from_file(filename, data_format=:item_data, options={})
9
9
  file_format = self.get_file_format(filename)
10
- DataListConverter.convert(file_format, data_format,
11
- {filename: filename})
10
+ options[:filename] = filename
11
+ DataListConverter.convert(file_format, data_format, options)
12
12
  end
13
13
 
14
14
  def self.get_file_format(filename)
@@ -23,6 +23,10 @@ class DataListConverter
23
23
  CONVERTERS.keys.flatten.uniq.sort
24
24
  end
25
25
 
26
+ def self.routes
27
+ CONVERTERS.keys
28
+ end
29
+
26
30
  def self.file_types
27
31
  matcher = /(.*)_file$/
28
32
  DataListConverter.types.select do |type|
@@ -51,22 +55,27 @@ class DataListConverter
51
55
  # {a: {b: 12}, c: {d: {e: 11}}}
52
56
  # =>
53
57
  # {:"a:b"=>12, :"c:d:e"=>11}
54
- def self.flatten(data, sep=':')
58
+ def self.flatten(data, sep=':', max_level=nil)
55
59
  out = {}
56
- recursive_flatten(out, data, nil, sep)
60
+ recursive_flatten(out, data, nil, sep, 1, max_level)
57
61
  out
58
62
  end
59
63
 
60
- def self.recursive_flatten(out, data, header, sep)
64
+ def self.recursive_flatten(out, data, header, sep, level, max_level)
61
65
  data.each do |k, v|
62
66
  k = header ? :"#{header}#{sep}#{k}" : k
63
- case v
64
- when Hash
65
- recursive_flatten(out, v, k, sep)
67
+ if v.kind_of?(Hash) and (!max_level or level <= max_level)
68
+ recursive_flatten(out, v, k, sep, level+1, max_level)
66
69
  else
67
70
  out[k] = v
68
71
  end
69
72
  end
70
73
  end
71
74
 
75
+ def self.parameter(data, key, type)
76
+ raise Exception, "`#{type}` should be hash, not `#{data.class}`: #{data}" unless data.kind_of?(Hash)
77
+ raise Exception, "Need `#{key}` for `#{type}`, current: #{data}" if not data.has_key?(key)
78
+ data.fetch(key)
79
+ end
80
+
72
81
  end
@@ -3,7 +3,8 @@ require 'csv'
3
3
  class DataListConverter
4
4
  self.register_converter(:csv_file, :table_iterator) do |input, options|
5
5
  lambda { |&block|
6
- CSV.open(input[:filename]) do |csv|
6
+ filename = self.parameter(input, :filename, :input)
7
+ CSV.open(filename) do |csv|
7
8
  csv.each do |row|
8
9
  block.call(row)
9
10
  end
@@ -12,7 +13,8 @@ class DataListConverter
12
13
  end
13
14
 
14
15
  self.register_converter(:table_iterator, :csv_file) do |proc, options|
15
- CSV.open(options[:filename], 'wb', force_quotes: true) do |csv|
16
+ filename = self.parameter(options, :filename, :csv_file)
17
+ CSV.open(filename, 'wb', force_quotes: true) do |csv|
16
18
  proc.call do |row|
17
19
  csv << row
18
20
  end
@@ -0,0 +1,58 @@
1
+ require 'xlsxtream'
2
+ require 'creek'
3
+
4
+ class DataListConverter
5
+
6
+ self.register_converter(:xlsx_file, :table_iterator) do |input, options|
7
+ lambda { |&block|
8
+ filename = self.parameter(input, :filename, :input)
9
+
10
+ creek = Creek::Book.new filename
11
+ sheet = creek.sheets[input[:sheet] || 0]
12
+ sheet.rows.each do |row|
13
+ block.call(row.values)
14
+ end
15
+ }
16
+ end
17
+
18
+ self.register_converter(:xlsx_file, :multi_sheet_table_iterator) do |input, options|
19
+ filename = self.parameter(input, :filename, :input)
20
+
21
+ creek = Creek::Book.new filename
22
+ creek.sheets.map do |sheet|
23
+ iterator = lambda { |&block|
24
+ sheet.rows.each do |row|
25
+ block.call(row.values)
26
+ end
27
+ }
28
+ [sheet.name.to_sym, iterator]
29
+ end.to_h
30
+ end
31
+
32
+ self.register_converter(:table_iterator, :xlsx_file) do |proc, options|
33
+ filename = self.parameter(options, :filename, :xlsx_file)
34
+ Xlsxtream::Workbook.open(filename) do |xlsx|
35
+ xlsx.write_worksheet (options[:sheet] || "Sheet1") do |sheet|
36
+ proc.call do |row|
37
+ sheet << row
38
+ end
39
+ end
40
+ end
41
+ filename
42
+ end
43
+
44
+ self.register_converter(:multi_sheet_table_iterator, :xlsx_file) do |data, options|
45
+ filename = self.parameter(options, :filename, :xlsx_file)
46
+ Xlsxtream::Workbook.open(filename) do |xlsx|
47
+ data.each do |name, table_iterator|
48
+ xlsx.write_worksheet(name.to_s) do |sheet|
49
+ table_iterator.call do |row|
50
+ sheet << row
51
+ end
52
+ end
53
+ end
54
+ end
55
+ filename
56
+ end
57
+
58
+ end
@@ -1,13 +1,15 @@
1
1
  class DataListConverter
2
2
 
3
3
  def self.marshal_file_to_data(input, options=nil)
4
- File.open(input[:filename]) do |f|
4
+ filename = self.parameter(input, :filename, :input)
5
+ File.open(filename) do |f|
5
6
  Marshal.load(f)
6
7
  end
7
8
  end
8
9
 
9
10
  def self.marshal_data_to_file(data, options)
10
- File.open(options[:filename], 'w+') do |f|
11
+ filename = self.parameter(options, :filename, :marshal)
12
+ File.open(filename, 'w+') do |f|
11
13
  Marshal.dump(data, f)
12
14
  end
13
15
  options[:filename]
@@ -19,8 +19,9 @@ class DataListConverter
19
19
  :"multi_sheet_#{from_type}",
20
20
  :"multi_sheet_#{to_type}",
21
21
  ) do |data, options|
22
+ self.log("multi_sheet #{from_type} -> #{to_type} with options: #{options}")
22
23
  data.map do |sheet, from_data|
23
- to_data = self.convert(from_type, to_type, from_data)
24
+ to_data = self.convert(from_type, to_type, from_data, options)
24
25
  [sheet, to_data]
25
26
  end.to_h
26
27
  end
@@ -1,13 +1,20 @@
1
1
  # ActiveRecords
2
2
  class DataListConverter
3
3
 
4
- self.register_converter(:records, :item_iterator) do |records, options|
5
- columns = options[:columns]
4
+ # columns = [:table_column1, :table_column2, ...]
5
+ # display = [:display_name1, :display_name2, ...]
6
+ # convert(:records, :item_data, query: query, columns: columns, display: display)
7
+ self.register_converter(:records, :item_iterator) do |input, options|
8
+ query = self.parameter(input, :query, :input)
9
+ columns = self.parameter(input, :columns, :input)
10
+ display = input[:display] || columns
11
+
6
12
  lambda { |&block|
7
- records.find_each do |record|
8
- item = columns.map do |column|
9
- [column[0].to_sym, record.send(column[1])]
10
- end.to_h
13
+ query.pluck(*columns).each do |data|
14
+ item = {}
15
+ data.each_with_index do |d, i|
16
+ item[display[i]] = d
17
+ end
11
18
  block.call(item)
12
19
  end
13
20
  }
@@ -5,7 +5,8 @@ class DataListConverter
5
5
 
6
6
  self.register_converter(:xls_file, :table_iterator) do |input, options|
7
7
  lambda { |&block|
8
- book = Spreadsheet.open(input[:filename])
8
+ filename = self.parameter(input, :filename, :input)
9
+ book = Spreadsheet.open(filename)
9
10
  sheet = book.worksheet input[:sheet] || 0
10
11
  sheet.each do |row|
11
12
  block.call(row.to_a)
@@ -18,11 +19,13 @@ class DataListConverter
18
19
  sheet = book.create_worksheet(name: (options[:sheet] || "Sheet1"))
19
20
  i = 0
20
21
  proc.call do |row|
22
+ row = row.map(&:to_s)
21
23
  sheet.row(i).push *row
22
24
  i += 1
23
25
  end
24
- book.write(options[:filename])
25
- options[:filename]
26
+ filename = self.parameter(options, :filename, :xls_file)
27
+ book.write(filename)
28
+ filename
26
29
  end
27
30
 
28
31
  self.register_converter(:multi_sheet_table_iterator, :xls_file) do |data, options|
@@ -31,17 +34,19 @@ class DataListConverter
31
34
  sheet = book.create_worksheet(name: name.to_s)
32
35
  i = 0
33
36
  table_iterator.call do |row|
37
+ row = row.map(&:to_s)
34
38
  sheet.row(i).concat(row)
35
39
  i += 1
36
40
  end
37
41
  end
38
- filename = options[:filename]
42
+ filename = self.parameter(options, :filename, :xls_file)
39
43
  book.write(filename)
40
44
  filename
41
45
  end
42
46
 
43
- self.register_converter(:xls_file, :multi_sheet_table_iterator) do |data, options|
44
- book = Spreadsheet.open(data[:filename])
47
+ self.register_converter(:xls_file, :multi_sheet_table_iterator) do |input, options|
48
+ filename = self.parameter(input, :filename, :input)
49
+ book = Spreadsheet.open(filename)
45
50
  book.worksheets.map do |sheet|
46
51
  iterator = lambda { |&block|
47
52
  sheet.each do |row|
@@ -5,7 +5,8 @@ class DataListConverter
5
5
 
6
6
  self.register_converter(:xlsx_file, :table_iterator) do |input, options|
7
7
  lambda { |&block|
8
- book = RubyXL::Parser.parse(input[:filename])
8
+ filename = self.parameter(input, :filename, :input)
9
+ book = RubyXL::Parser.parse(filename)
9
10
  sheet = book.worksheets[input[:sheet] || 0]
10
11
  sheet.each do |row|
11
12
  next unless row
@@ -22,11 +23,11 @@ class DataListConverter
22
23
  i = 0
23
24
  proc.call do |row|
24
25
  row.each_with_index do |v, j|
25
- sheet.add_cell(i, j, v)
26
+ sheet.add_cell(i, j, v.to_s)
26
27
  end
27
28
  i += 1
28
29
  end
29
- filename = options[:filename]
30
+ filename = self.parameter(options, :filename, :xlsx_file)
30
31
  book.write(filename)
31
32
  filename
32
33
  end
@@ -41,27 +42,28 @@ class DataListConverter
41
42
  row.each_with_index do |v, j|
42
43
  if v.kind_of?(Hash)
43
44
  # custom cell format
44
- cell = sheet.add_cell(i, j, v[:text])
45
+ cell = sheet.add_cell(i, j, v[:text].to_s)
45
46
  v.each do |k, v|
46
47
  next if k == :text
47
48
  cell.send(k, v)
48
49
  end
49
50
  cell.change_fill(v[:fill_color]) if v[:fill_color]
50
51
  else
51
- cell = sheet.add_cell(i, j, v)
52
+ cell = sheet.add_cell(i, j, v.to_s)
52
53
  end
53
54
 
54
55
  end
55
56
  i += 1
56
57
  end
57
58
  end
58
- filename = options[:filename]
59
+ filename = self.parameter(options, :filename, :xlsx_file)
59
60
  book.write(filename)
60
61
  filename
61
62
  end
62
63
 
63
- self.register_converter(:xlsx_file, :multi_sheet_table_iterator) do |data, options|
64
- book = RubyXL::Parser.parse(data[:filename])
64
+ self.register_converter(:xlsx_file, :multi_sheet_table_iterator) do |input, options|
65
+ filename = self.parameter(input, :filename, :input)
66
+ book = RubyXL::Parser.parse(filename)
65
67
  book.worksheets.map do |sheet|
66
68
  iterator = lambda { |&block|
67
69
  sheet.each do |row|
@@ -1,3 +1,3 @@
1
1
  class DataListConverter
2
- VERSION = "0.3.10".freeze
2
+ VERSION = "0.4.4".freeze
3
3
  end
@@ -40,6 +40,12 @@ describe DataListConverter do
40
40
  string.string.must_equal ".4\n.8\n.12\n"
41
41
  end
42
42
 
43
+ it 'test data format exists' do
44
+ -> {
45
+ DataListConverter.convert(:item_data, :ppp, {a: 12})
46
+ }.must_raise Exception
47
+ end
48
+
43
49
  end
44
50
 
45
51
  end
@@ -26,12 +26,30 @@ describe DataListConverter do
26
26
  string = StringIO.new
27
27
  filter = {count: {size: 4000,
28
28
  out: string,
29
- msg: "%{percent}%"}}
29
+ msg: "%{percent}%%"}}
30
30
  result = DataListConverter.convert(
31
31
  :item_iterator, :table_data, iter,
32
32
  item_iterator: {filter: filter})
33
33
  string.string.split("\n").must_equal ['total: 10000', '40.0%', '80.0%']
34
34
  end
35
35
  end
36
+
37
+ describe :remove_debug do
38
+ specify do
39
+ filter = {remove_debug: true}
40
+ item_data = [{name: "james", debug: "", a: 12}] * 2
41
+ result = DataListConverter.convert(
42
+ :item_data, :table_data, item_data,
43
+ table_iterator: {filter: filter})
44
+ result.must_equal [["name"], ["james"], ["james"]]
45
+
46
+ # check on multi_sheet
47
+ item_data = {a: [{name: "james", debug: "", a: 12}] * 2, b: [{name: 'cc', debug: "", b: 3}]*3}
48
+ result = DataListConverter.convert(
49
+ :multi_sheet_item_data, :multi_sheet_table_data, item_data,
50
+ multi_sheet_table_iterator: {table_iterator: {filter: {remove_debug: true}}})
51
+ result.must_equal(a: [["name"], ["james"], ["james"]], b: [["name"], ["cc"], ["cc"], ["cc"]])
52
+ end
53
+ end
36
54
 
37
55
  end
@@ -79,6 +79,12 @@ describe DataListConverter do
79
79
  # change sep
80
80
  data = {a: {b: 12}, c: {d: {e: 11}}}
81
81
  @c.flatten(data, '_').must_equal({:"a_b"=>12, :"c_d_e"=>11})
82
+
83
+ # set max level
84
+ data = {a: {b: 12}, c: {d: {e: {f: 11}}}}
85
+ @c.flatten(data, ':', 1).must_equal({:"a:b"=>12, :"c:d"=>{e: {f: 11}}})
86
+ data = {a: {b: 12}, c: {d: {e: {f: 11}}}}
87
+ @c.flatten(data, ':', 2).must_equal({:"a:b"=>12, :"c:d:e"=>{f: 11}})
82
88
  end
83
89
  end
84
90
  end
@@ -79,6 +79,27 @@ describe DataListConverter do
79
79
  end
80
80
  end
81
81
 
82
+ require 'data_list_converter/types/fast_xlsx_file'
83
+
84
+ describe :xlsx_file do
85
+ specify do
86
+ filename = 'test.xlsx'
87
+ begin
88
+ @c.convert(:item_data, :xlsx_file, ITEM_DATA, xlsx_file: {filename: filename})
89
+ @c.convert(:xlsx_file, :item_data, {filename: filename}).must_equal ITEM_DATA
90
+
91
+ @c.convert(:multi_sheet_table_data, :xlsx_file, MULTI_SHEET_TABLE_DATA,
92
+ xlsx_file: {filename: filename})
93
+ @c.convert(:xlsx_file, :multi_sheet_table_data,
94
+ {filename: filename},
95
+ ).must_equal(MULTI_SHEET_TABLE_DATA)
96
+ ensure
97
+ FileUtils.rm_f(filename)
98
+ end
99
+ end
100
+
101
+ end
102
+
82
103
  describe :marshal do
83
104
  specify do
84
105
  filename = 'test.marshal'
@@ -99,5 +120,36 @@ describe DataListConverter do
99
120
  end
100
121
  end
101
122
  end
123
+
124
+ describe :records do
125
+ specify do
126
+ require 'sqlite3'
127
+ require 'active_record'
128
+
129
+ ActiveRecord::Base.establish_connection(
130
+ adapter: 'sqlite3',
131
+ database: ':memory:'
132
+ )
133
+
134
+ ActiveRecord::Schema.define do
135
+ create_table :users, force: true do |t|
136
+ t.string :name
137
+ t.integer :age
138
+ end
139
+ end
140
+
141
+ class User < ActiveRecord::Base; end
142
+ (1..10).each{ |i| User.create(name: "user-#{i}", age: i+20) }
143
+
144
+ query = User.where("age > 25 and age < 27")
145
+ columns = [:name, :age]
146
+ @c.convert(:records, :item_data, query: query, columns: columns).
147
+ must_equal([{name: "user-6", age: 26}])
148
+
149
+ display = [:n, :a]
150
+ @c.convert(:records, :item_data, query: query, columns: columns, display: display).
151
+ must_equal([{n: "user-6", a: 26}])
152
+ end
153
+ end
102
154
 
103
155
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_list_converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.10
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - linjunhalida
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-02 00:00:00.000000000 Z
11
+ date: 2020-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -80,6 +80,62 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.10.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '4.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '4.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: xlsxtream
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: creek
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
83
139
  description: Data List Converter is a tool to convert data between different formats.
84
140
  email:
85
141
  - linjunhalida@gmail.com
@@ -102,6 +158,7 @@ files:
102
158
  - lib/data_list_converter/helper.rb
103
159
  - lib/data_list_converter/types/basic.rb
104
160
  - lib/data_list_converter/types/csv_file.rb
161
+ - lib/data_list_converter/types/fast_xlsx_file.rb
105
162
  - lib/data_list_converter/types/marshal.rb
106
163
  - lib/data_list_converter/types/multi_sheet.rb
107
164
  - lib/data_list_converter/types/records.rb
@@ -132,14 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
189
  - !ruby/object:Gem::Version
133
190
  version: '0'
134
191
  requirements: []
135
- rubyforge_project:
136
- rubygems_version: 2.4.8
192
+ rubygems_version: 3.0.8
137
193
  signing_key:
138
194
  specification_version: 4
139
195
  summary: convert data between different formats
140
- test_files:
141
- - test/base_test.rb
142
- - test/filters_test.rb
143
- - test/helper_test.rb
144
- - test/testdata.rb
145
- - test/types_test.rb
196
+ test_files: []