rcsv_loader 0.0.1 → 0.2.0

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
2
  SHA1:
3
- metadata.gz: f581428c6e050728dbc4aa92a115ecd9c1441621
4
- data.tar.gz: cd70140fdf7f62279bb6b28e01dd36ab0c9411f3
3
+ metadata.gz: f16383a5089660aaa8623b243f05a9cdc72dc363
4
+ data.tar.gz: 592ee577893e3f81f4ba869bf1c227f1e7cba056
5
5
  SHA512:
6
- metadata.gz: 8e0da230d509d4dca60d489d23551c8fda507d672ef33f372cfba747fe2b2ea904f1e1c531d67e1db72461bbc89452293cb0346a033f6a4da8702b5de25fdcba
7
- data.tar.gz: 904038d9043c618727974778f5b93ea265abb6d8ac9f042ccec4a8867e60dabe5b0531a3403aa47ff8e1997292dfb2d8445e2cf5f768eb575aacca762c980de6
6
+ metadata.gz: ac77ebaaa41fe9c176b736953842de5c66a18752d000e3a312d5711b1d4094aa16d0432109b1de659bc24a064c3ae1cfd87736585da9281796885cb4c76385b4
7
+ data.tar.gz: af321f0a281ca5dd9d30a6443e1d349df33cf6f5e29f1f6678858be06ca37f6d4a34610eb07ab05451da89d179741f3b54cf56bab5929640497210a6026aab95
data/.travis.yml CHANGED
@@ -5,4 +5,6 @@ rvm:
5
5
  - 2.0.0
6
6
  - 2.1.0
7
7
  - 2.2.0
8
+ before_script:
9
+ - rake install
8
10
  script: bundle exec rspec spec
@@ -0,0 +1,11 @@
1
+ require 'csv'
2
+ require "rcsv_loader/version"
3
+ require 'rcsv_loader/core'
4
+
5
+ module RCsvLoader
6
+
7
+ class Base
8
+ include Core
9
+ end
10
+
11
+ end
@@ -0,0 +1,137 @@
1
+ require 'rcsv_loader/where'
2
+
3
+ module RCsvLoader
4
+ module Core
5
+ extend Forwardable
6
+
7
+ include Where
8
+
9
+ def self.included base
10
+ base.extend ClassMethods
11
+ end
12
+
13
+ module ClassMethods
14
+ #
15
+ # Laod a csv file
16
+ #
17
+ # options: The options for 'csv' which is Ruby's built-in library.
18
+ #
19
+ def load_csv file, options = {}
20
+
21
+ rows = CSV.readlines file, options
22
+
23
+ rows = yield rows if block_given?
24
+
25
+ self.new rows.map { |row| self::Row.new row }
26
+ end
27
+
28
+ attr_reader :headers
29
+
30
+ #
31
+ # Define accessor names for csv column.
32
+ #
33
+ def column column_name, alias_name = nil
34
+ alias_name = column_name.to_sym unless alias_name
35
+ @headers = all_headers
36
+ @headers.merge!(alias_name => column_name)
37
+ define_row(@headers)
38
+
39
+ @has_headers = true
40
+ end
41
+
42
+ #
43
+ # Define headers for no headers csv.
44
+ #
45
+ def insert_headers headers = []
46
+ @headers = Hash[headers.map.with_index { |e, i| [e, i] }]
47
+ define_row(@headers)
48
+
49
+ @has_headers = false
50
+ end
51
+
52
+ def headers?
53
+ !!@has_headers
54
+ end
55
+
56
+ private
57
+ #
58
+ # Get headers that include super class's one.
59
+ #
60
+ def all_headers current_class = nil
61
+ current_class ||= self
62
+ return {} if current_class == Object
63
+ current_header = current_class.headers || {}
64
+ return current_header.merge all_headers(current_class.superclass)
65
+ end
66
+
67
+ #
68
+ # Define a class which represent a row of csv.
69
+ #
70
+ def define_row headers
71
+ headers ||= {}
72
+
73
+ # get the superclass for Row
74
+ baseclass = if superclass.const_defined? :Row
75
+ superclass::Row
76
+ else
77
+ Object
78
+ end
79
+
80
+ # remove class definition
81
+ if const_defined? :Row and baseclass != self::Row
82
+ self.send :remove_const, :Row
83
+ end
84
+
85
+ # define Row class
86
+ const_set :Row, (Class.new(baseclass) do
87
+
88
+ attr_accessor *headers.keys
89
+
90
+ define_method :initialize do |line = {}|
91
+ headers.each do |k, v|
92
+ instance_variable_set "@#{k.to_s}", line[v]
93
+ end
94
+ end
95
+
96
+ define_method :to_csv do
97
+ CSV.generate_line headers.map { |k, v| self.send k }
98
+ end
99
+
100
+ end)
101
+ end
102
+ end
103
+
104
+ def_delegators :@rows, :+, :<<
105
+
106
+ def initialize rows = []
107
+ @rows = rows
108
+ end
109
+
110
+ def all
111
+ @rows
112
+ end
113
+
114
+ #
115
+ # Convert to csv string
116
+ #
117
+ # options: {
118
+ # headers: boolean
119
+ # }
120
+ #
121
+ def to_csv options = {}
122
+ csv = ""
123
+ csv += header_line if options[:headers].nil? or options[:headers]
124
+ csv += @rows.map(&:to_csv).join
125
+ end
126
+
127
+ private
128
+
129
+ #
130
+ # generate header line
131
+ #
132
+ def header_line
133
+ CSV.generate_line(self.class.headers.map { |k, v| self.class.headers? ? v.to_s : k.to_s })
134
+ end
135
+
136
+ end
137
+ end
@@ -1,3 +1,3 @@
1
1
  module RCsvLoader
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,50 @@
1
+ module RCsvLoader
2
+ module Where
3
+
4
+ #
5
+ # params = {
6
+ # :#{accessor_name} => expected_value,
7
+ # ...
8
+ # }
9
+ #
10
+ # compare with '=='
11
+ #
12
+ # options = {
13
+ # :regexp => true
14
+ # }
15
+ #
16
+ # return empty array if the condition is invalid or couldn't find any rows.
17
+ #
18
+ def where conditions = {}, options = {}
19
+ rows = @rows || []
20
+ return rows if conditions.empty?
21
+
22
+ # filter the conditions.
23
+ c = conditions.select do |k, v|
24
+ self.class.headers.keys.any? { |key| key.to_s == k.to_s }
25
+ end
26
+
27
+ return [] if c.empty?
28
+
29
+ if options[:regexp]
30
+ where_with_regexp c
31
+ else
32
+ rows.select { |row| c.all? { |attr, con| (row.send attr) == con } }
33
+ end
34
+
35
+ end
36
+
37
+ private
38
+
39
+ #
40
+ # evaluate expression with #match
41
+ #
42
+ def where_with_regexp conditions = {}
43
+ rows = @rows || []
44
+ return rows if conditions.empty?
45
+ rows.select { |row| conditions.all? { |attr, con| (row.send attr).match con } }
46
+ end
47
+
48
+ end
49
+ end
50
+
data/lib/rcsv_loader.rb CHANGED
@@ -2,139 +2,5 @@ require "rcsv_loader/version"
2
2
  require 'csv'
3
3
 
4
4
  module RCsvLoader
5
-
6
- attr_reader :headers
7
-
8
- #
9
- # Define accessor names for csv column.
10
- #
11
- def column column_name, alias_name = nil
12
- alias_name = column_name.to_sym unless alias_name
13
- @headers = all_headers
14
- @headers.merge!(alias_name => column_name)
15
- define_row(@headers)
16
- end
17
-
18
- #
19
- # Define headers for no headers csv.
20
- #
21
- def insert_headers headers = []
22
- @headers = Hash[headers.map.with_index { |e, i| [e, i] }]
23
- define_row(@headers)
24
- end
25
-
26
- class Base
27
- extend RCsvLoader
28
- extend Forwardable
29
-
30
- #
31
- # Laod a csv file
32
- #
33
- # options: The options for 'csv' which is Ruby's built-in library.
34
- #
35
- def self.load_csv file, options = {}
36
-
37
- rows = CSV.readlines file, options
38
-
39
- rows = yield rows if block_given?
40
-
41
- self.new rows.map { |row| self::Row.new row }
42
- end
43
-
44
- def_delegators :@rows, :+, :<<
45
-
46
- def initialize rows = []
47
- @rows = rows
48
- end
49
-
50
- def all
51
- @rows
52
- end
53
-
54
- #
55
- # params = {
56
- # :#{accessor_name} => expected_value,
57
- # ...
58
- # }
59
- #
60
- # compare with '=='
61
- #
62
- # return empty array if the condition is invalid or couldn't find any rows.
63
- #
64
- def where params = {}
65
- return @rows if params.empty?
66
-
67
- # filter the conditions.
68
- params.select! do |k, v|
69
- self.class.headers.keys.any? { |key| key.to_s == k.to_s }
70
- end
71
-
72
- return [] if params.empty?
73
-
74
- @rows.select do |row|
75
- params.all? { |attr, con| (row.send attr) == con }
76
- end
77
-
78
- end
79
-
80
- #
81
- # Convert to csv string
82
- #
83
- # options: {
84
- # headers: boolean
85
- # }
86
- #
87
- def to_csv options = {}
88
- csv = ""
89
- csv += CSV.generate_line(self.class.headers.map { |k, v| v } ) if options[:headers]
90
- csv += @rows.map(&:to_csv).join
91
- end
92
- end
93
-
94
- private
95
- #
96
- # Get headers that include super class's one.
97
- #
98
- def all_headers current_class = nil
99
- current_class ||= self
100
- return {} if current_class == Base
101
- current_header = current_class.headers || {}
102
- return current_header.merge all_headers(current_class.superclass)
103
- end
104
-
105
- #
106
- # Define a class which represent a row of csv.
107
- #
108
- def define_row headers
109
- headers ||= {}
110
-
111
- # get the superclass for Row
112
- baseclass = if superclass.const_defined? :Row
113
- superclass::Row
114
- else
115
- Object
116
- end
117
-
118
- # remove class definition
119
- if const_defined? :Row and baseclass != self::Row
120
- self.send :remove_const, :Row
121
- end
122
-
123
- # define Row class
124
- const_set :Row, (Class.new(baseclass) do
125
-
126
- attr_accessor *headers.keys
127
-
128
- define_method :initialize do |line = {}|
129
- headers.each do |k, v|
130
- instance_variable_set "@#{k.to_s}", line[v]
131
- end
132
- end
133
-
134
- define_method :to_csv do
135
- CSV.generate_line headers.map { |k, v| self.send k }
136
- end
137
-
138
- end)
139
- end
5
+ autoload :Base, 'rcsv_loader/base'
140
6
  end
data/spec/core_spec.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'pathname'
3
+
4
+ require 'models/sample_csv'
5
+ require 'models/sample_csv_no_headers'
6
+
7
+ describe RCsvLoader do
8
+
9
+ describe RCsvLoader::Core do
10
+
11
+ shared_examples 'to_csv' do |expected|
12
+ subject { data.to_csv }
13
+ it { is_expected.to eq expected }
14
+ end
15
+
16
+ shared_examples 'to_csv without headers' do |expected|
17
+ subject { data.to_csv headers: false }
18
+ it { is_expected.to eq expected }
19
+ end
20
+
21
+ context "sample"do
22
+ let(:path) { File.join Pathname(__FILE__).dirname, "fixtures/sample.csv" }
23
+ let(:data) { SampleCsv.load_csv path, headers: true }
24
+
25
+ expected_with_headers = [
26
+ 'id,file name,extension,url',
27
+ '1,file_01.zip,zip,https://example.com/file_01.zip',
28
+ '2,file_02.zip,zip,https://example.com/file_02.zip',
29
+ ''
30
+ ].join($/)
31
+ it_behaves_like 'to_csv', expected_with_headers
32
+
33
+ expected_without_headers = [
34
+ '1,file_01.zip,zip,https://example.com/file_01.zip',
35
+ '2,file_02.zip,zip,https://example.com/file_02.zip',
36
+ ''
37
+ ].join($/)
38
+ it_behaves_like 'to_csv without headers', expected_without_headers
39
+ end
40
+
41
+ context "sample_without_headers" do
42
+ let(:path) { File.join Pathname(__FILE__).dirname, "fixtures/no_headers_sample.csv" }
43
+ let(:data) { SampleCsvNoHeaders.load_csv path, headers: false }
44
+
45
+ expected_with_headers = [
46
+ 'id,file_name,extension,url',
47
+ '1,file_01.zip,zip,https://example.com/file_01.zip',
48
+ '2,file_02.zip,zip,https://example.com/file_02.zip',
49
+ ''
50
+ ].join($/)
51
+ it_behaves_like 'to_csv', expected_with_headers
52
+
53
+ expected_without_headers = [
54
+ '1,file_01.zip,zip,https://example.com/file_01.zip',
55
+ '2,file_02.zip,zip,https://example.com/file_02.zip',
56
+ ''
57
+ ].join($/)
58
+ it_behaves_like 'to_csv without headers', expected_without_headers
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -84,6 +84,19 @@ describe RCsvLoader do
84
84
  }
85
85
  it_behaves_like "where", expected
86
86
  end
87
+
88
+ context ':regexp => true, :file_name => ".*?\.zip"' do
89
+ let(:results) { sample.where( { :file_name => ".*?\.zip" }, :regexp => true) }
90
+ expected = {
91
+ :data_count => 2,
92
+ :first_row => {
93
+ :file_name => "file_01.zip",
94
+ :extension => "zip",
95
+ :url => "https://example.com/file_01.zip"
96
+ }
97
+ }
98
+ it_behaves_like "where", expected
99
+ end
87
100
  end
88
101
  end
89
102
 
@@ -130,6 +143,20 @@ describe RCsvLoader do
130
143
  }
131
144
  it_behaves_like "where", expected
132
145
  end
146
+
147
+ context ':regexp => true, :file_name => ".*?\.zip"' do
148
+ let(:results) { sample.where( { :file_name => ".*?\.zip" }, :regexp => true) }
149
+ expected = {
150
+ :data_count => 2,
151
+ :first_row => {
152
+ :file_name => "file_01.zip",
153
+ :extension => "zip",
154
+ :url => "https://example.com/file_01.zip"
155
+ }
156
+ }
157
+ it_behaves_like "where", expected
158
+ end
159
+
133
160
  end
134
161
 
135
162
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcsv_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - osadake212
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-10 00:00:00.000000000 Z
11
+ date: 2015-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,8 +67,12 @@ files:
67
67
  - README.md
68
68
  - Rakefile
69
69
  - lib/rcsv_loader.rb
70
+ - lib/rcsv_loader/base.rb
71
+ - lib/rcsv_loader/core.rb
70
72
  - lib/rcsv_loader/version.rb
73
+ - lib/rcsv_loader/where.rb
71
74
  - rcsv_loader.gemspec
75
+ - spec/core_spec.rb
72
76
  - spec/fixtures/no_headers_sample.csv
73
77
  - spec/fixtures/sample.csv
74
78
  - spec/models/sample_csv.rb
@@ -100,6 +104,7 @@ signing_key:
100
104
  specification_version: 4
101
105
  summary: A simple csv loader.
102
106
  test_files:
107
+ - spec/core_spec.rb
103
108
  - spec/fixtures/no_headers_sample.csv
104
109
  - spec/fixtures/sample.csv
105
110
  - spec/models/sample_csv.rb