data_list_converter 0.3.10 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []