data_list_converter 0.3.9 → 0.4.3
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 +5 -5
 - data/README.md +41 -39
 - data/changelog.md +8 -0
 - data/data_list_converter.gemspec +2 -0
 - data/lib/data_list_converter/base.rb +11 -2
 - data/lib/data_list_converter/filters/count.rb +1 -0
 - data/lib/data_list_converter/helper.rb +38 -6
 - data/lib/data_list_converter/types/csv_file.rb +4 -2
 - data/lib/data_list_converter/types/marshal.rb +4 -2
 - data/lib/data_list_converter/types/multi_sheet.rb +2 -1
 - data/lib/data_list_converter/types/records.rb +13 -6
 - data/lib/data_list_converter/types/xls_file.rb +11 -6
 - data/lib/data_list_converter/types/xlsx_file.rb +10 -8
 - data/lib/data_list_converter/version.rb +1 -1
 - data/test/base_test.rb +6 -0
 - data/test/filters_test.rb +19 -1
 - data/test/helper_test.rb +17 -0
 - data/test/types_test.rb +31 -0
 - metadata +32 -10
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: ed694a5c72e52682133a22004d381f3968c3d28db54cbeba194eda7c793e70a9
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 656daa9eb323ffa7b7bddb8e40df86606889f091f56c47069f39e37c9f434741
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ad413ccb9e7f0552a39965c69f7924df825eda9933d9acfb83e20455ea03cdd25f34dd8275187190ca868b34fa490c4025c1024820ebf8627345b7e1d6a8d969
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: be36997b5d5b37af61e8c5281038ecb8187650ee3d8c506ea852fec5bba8c324a8434e53fe2e2ba729a86deb667376d331aed6194c9cd05286fd636cdbc48219
         
     | 
    
        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 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       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  
     | 
| 
      
 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 | 
     | 
| 
       74 
     | 
    
         
            -
               
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
       77 
     | 
    
         
            -
                  item =  
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
      
 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,13 +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 
     | 
    
         
            -
            - register can bind method again
         
     | 
| 
       103 
     | 
    
         
            -
            - better API
         
     | 
| 
       104 
     | 
    
         
            -
            - better error message
         
     | 
| 
       105 
     | 
    
         
            -
            - load file/save file with auto format by extname
         
     | 
| 
       106 
     | 
    
         
            -
            - report error when cannot find type
         
     | 
    
        data/changelog.md
    CHANGED
    
    | 
         @@ -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.
         
     | 
| 
         @@ -8,6 +15,7 @@ Refactor. 
     | 
|
| 
       8 
15 
     | 
    
         
             
            - 0.3.7 add marshal_file type, and load_from_file, save_to_file helper
         
     | 
| 
       9 
16 
     | 
    
         
             
            - 0.3.8 add raw type
         
     | 
| 
       10 
17 
     | 
    
         
             
            - 0.3.9 add unify_item_data_keys helper
         
     | 
| 
      
 18 
     | 
    
         
            +
            - 0.3.10 add flatten
         
     | 
| 
       11 
19 
     | 
    
         | 
| 
       12 
20 
     | 
    
         
             
            ## 0.2
         
     | 
| 
       13 
21 
     | 
    
         | 
    
        data/data_list_converter.gemspec
    CHANGED
    
    | 
         @@ -17,6 +17,8 @@ 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'
         
     | 
| 
       20 
22 
     | 
    
         | 
| 
       21 
23 
     | 
    
         
             
              s.files         = `git ls-files`.split("\n")
         
     | 
| 
       22 
24 
     | 
    
         
             
              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] || {}) 
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
      
 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
         
     | 
| 
         @@ -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 
     | 
    
         
            -
                 
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 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|
         
     | 
| 
         @@ -46,4 +50,32 @@ class DataListConverter 
     | 
|
| 
       46 
50 
     | 
    
         
             
                  end
         
     | 
| 
       47 
51 
     | 
    
         
             
                end
         
     | 
| 
       48 
52 
     | 
    
         
             
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              # flatten multi level item data into one level, example:
         
     | 
| 
      
 55 
     | 
    
         
            +
              #   {a: {b: 12}, c: {d: {e: 11}}}
         
     | 
| 
      
 56 
     | 
    
         
            +
              #   =>
         
     | 
| 
      
 57 
     | 
    
         
            +
              #   {:"a:b"=>12, :"c:d:e"=>11}
         
     | 
| 
      
 58 
     | 
    
         
            +
              def self.flatten(data, sep=':', max_level=nil)
         
     | 
| 
      
 59 
     | 
    
         
            +
                out = {}
         
     | 
| 
      
 60 
     | 
    
         
            +
                recursive_flatten(out, data, nil, sep, 1, max_level)
         
     | 
| 
      
 61 
     | 
    
         
            +
                out
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              def self.recursive_flatten(out, data, header, sep, level, max_level)
         
     | 
| 
      
 65 
     | 
    
         
            +
                data.each do |k, v|
         
     | 
| 
      
 66 
     | 
    
         
            +
                  k = header ? :"#{header}#{sep}#{k}" : k
         
     | 
| 
      
 67 
     | 
    
         
            +
                  if v.kind_of?(Hash) and (!max_level or level <= max_level)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    recursive_flatten(out, v, k, sep, level+1, max_level)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  else
         
     | 
| 
      
 70 
     | 
    
         
            +
                    out[k] = v
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 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 
     | 
    
         
            +
             
     | 
| 
       49 
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 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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
         
     | 
| 
         @@ -1,13 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class DataListConverter
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
              def self.marshal_file_to_data(input, options=nil)
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
       8 
     | 
    
         
            -
                    item =  
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
       25 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
| 
      
 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 | 
     | 
| 
       44 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
| 
      
 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 
     | 
| 
      
 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 | 
     | 
| 
       64 
     | 
    
         
            -
                 
     | 
| 
      
 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|
         
     | 
    
        data/test/base_test.rb
    CHANGED
    
    
    
        data/test/filters_test.rb
    CHANGED
    
    | 
         @@ -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
         
     | 
    
        data/test/helper_test.rb
    CHANGED
    
    | 
         @@ -70,4 +70,21 @@ describe DataListConverter do 
     | 
|
| 
       70 
70 
     | 
    
         
             
                end
         
     | 
| 
       71 
71 
     | 
    
         
             
              end
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              describe :flatten do
         
     | 
| 
      
 75 
     | 
    
         
            +
                specify do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  data = {a: {b: 12}, c: {d: {e: 11}}}
         
     | 
| 
      
 77 
     | 
    
         
            +
                  @c.flatten(data).must_equal({:"a:b"=>12, :"c:d:e"=>11})
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  # change sep
         
     | 
| 
      
 80 
     | 
    
         
            +
                  data = {a: {b: 12}, c: {d: {e: 11}}}
         
     | 
| 
      
 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}})
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
       73 
90 
     | 
    
         
             
            end
         
     | 
    
        data/test/types_test.rb
    CHANGED
    
    | 
         @@ -99,5 +99,36 @@ describe DataListConverter do 
     | 
|
| 
       99 
99 
     | 
    
         
             
                  end
         
     | 
| 
       100 
100 
     | 
    
         
             
                end
         
     | 
| 
       101 
101 
     | 
    
         
             
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
              describe :records do
         
     | 
| 
      
 104 
     | 
    
         
            +
                specify do
         
     | 
| 
      
 105 
     | 
    
         
            +
                  require 'sqlite3'
         
     | 
| 
      
 106 
     | 
    
         
            +
                  require 'active_record'
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  ActiveRecord::Base.establish_connection(
         
     | 
| 
      
 109 
     | 
    
         
            +
                    adapter: 'sqlite3',
         
     | 
| 
      
 110 
     | 
    
         
            +
                    database: ':memory:'
         
     | 
| 
      
 111 
     | 
    
         
            +
                  )
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  ActiveRecord::Schema.define do
         
     | 
| 
      
 114 
     | 
    
         
            +
                    create_table :users, force: true do |t|
         
     | 
| 
      
 115 
     | 
    
         
            +
                      t.string :name
         
     | 
| 
      
 116 
     | 
    
         
            +
                      t.integer :age
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                  class User < ActiveRecord::Base; end
         
     | 
| 
      
 121 
     | 
    
         
            +
                  (1..10).each{ |i| User.create(name: "user-#{i}", age: i+20) }
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  query = User.where("age > 25 and age < 27")
         
     | 
| 
      
 124 
     | 
    
         
            +
                  columns = [:name, :age]
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @c.convert(:records, :item_data, query: query, columns: columns).
         
     | 
| 
      
 126 
     | 
    
         
            +
                    must_equal([{name: "user-6", age: 26}])
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  display = [:n, :a]
         
     | 
| 
      
 129 
     | 
    
         
            +
                  @c.convert(:records, :item_data, query: query, columns: columns, display: display).
         
     | 
| 
      
 130 
     | 
    
         
            +
                    must_equal([{n: "user-6", a: 26}])
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
       102 
133 
     | 
    
         | 
| 
       103 
134 
     | 
    
         
             
            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 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.4.3
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - linjunhalida
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-08-04 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: rake
         
     | 
| 
         @@ -80,6 +80,34 @@ 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'
         
     | 
| 
       83 
111 
     | 
    
         
             
            description: Data List Converter is a tool to convert data between different formats.
         
     | 
| 
       84 
112 
     | 
    
         
             
            email:
         
     | 
| 
       85 
113 
     | 
    
         
             
            - linjunhalida@gmail.com
         
     | 
| 
         @@ -132,14 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       132 
160 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       133 
161 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       134 
162 
     | 
    
         
             
            requirements: []
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
            rubygems_version: 2.4.8
         
     | 
| 
      
 163 
     | 
    
         
            +
            rubygems_version: 3.0.6
         
     | 
| 
       137 
164 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       138 
165 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       139 
166 
     | 
    
         
             
            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
         
     | 
| 
      
 167 
     | 
    
         
            +
            test_files: []
         
     |