csv_class_maker 0.3.1 → 1.0.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 +4 -4
- data/lib/csv_class_maker/csv_class_maker.rb +7 -36
- data/lib/csv_class_maker/csv_find.rb +122 -60
- data/spec/csv_class_maker_spec.rb +18 -4
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95996b1056611f64e83ca3266b363c6c190f7647
|
4
|
+
data.tar.gz: 85b0848cd6cc24a07b80bd9013824e043afc3dc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e060ac87509f5ca88a09feab4ad1f7b2ce92d3e826f46b0a274fac6864c9de4a0ac75940c4821b74dd6d0350edbc930190f894254963dcd7ea028d94ead05f53
|
7
|
+
data.tar.gz: 6109f2f959a42c2f3b1efd43cf1e7e8d8379445b9ca99d8cb418a071e16d17382f10849d73393799e5493cfb7cf7f58ac8e994a820e674babb4dc260d4c820b5
|
@@ -13,45 +13,16 @@ module CsvClassMaker
|
|
13
13
|
return_headers: false
|
14
14
|
)
|
15
15
|
|
16
|
-
Object.const_set
|
16
|
+
Object.const_set(class_name, Class.new do
|
17
|
+
# remove building of the struct here. completely self contain method
|
18
|
+
# generation into the csv_find module so that you can pull extract headers
|
19
|
+
# method out.
|
17
20
|
|
18
|
-
# Class definition for dynamically generated classes.
|
19
21
|
require 'csv_class_maker/csv_find'
|
20
|
-
|
22
|
+
include CsvFind
|
21
23
|
|
22
|
-
|
23
|
-
if hash
|
24
|
-
hash.each { |k,v| send "#{k}=".to_sym, v }
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
@@file_options = options
|
29
|
-
@@file = CSV.new(File.open(file_name, 'r'), @@file_options)
|
30
|
-
@@first_line = 2
|
31
|
-
@@last_line = `wc -l #{file_name}`.split(' ').first.to_i
|
32
|
-
@@middle_line = (@@last_line/2)+1
|
33
|
-
@line_number = nil
|
34
|
-
|
35
|
-
attr_accessor :line_number
|
36
|
-
|
37
|
-
def self.file; return @@file; end
|
38
|
-
def self.first_line; return @@first_line; end
|
39
|
-
def self.middle_line; return @@middle_line; end
|
40
|
-
def self.last_line; return @@last_line; end
|
41
|
-
def self.file_options; return @@file_options; end
|
42
|
-
|
43
|
-
# End of class definition.
|
44
|
-
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def self.extract_headers(file_name, options)
|
51
|
-
csv_file = File.open(file_name,'r')
|
52
|
-
|
53
|
-
@csv_headers = CSV.new(csv_file, options).first.map do |headers, values|
|
54
|
-
headers
|
24
|
+
csv_file(file_name, options)
|
55
25
|
end
|
26
|
+
)
|
56
27
|
end
|
57
28
|
end
|
@@ -1,83 +1,145 @@
|
|
1
1
|
module CsvClassMaker::CsvFind
|
2
|
-
def
|
3
|
-
|
4
|
-
|
2
|
+
def self.included(base)
|
3
|
+
base.send :extend, ClassMethods
|
4
|
+
base.send :prepend, InstanceMethods
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
build_instance(row, row[:line_number])
|
10
|
-
end
|
7
|
+
module InstanceMethods
|
8
|
+
attr_accessor :line_number
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def initialize(hash = nil)
|
11
|
+
if hash
|
12
|
+
hash.each { |k,v| send("#{k}=".to_sym, v) }
|
13
|
+
end
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
def ==(other_instance)
|
17
|
+
instance_variables.map do |instance_variable|
|
18
|
+
self.instance_variable_get(instance_variable) ==
|
19
|
+
other_instance.instance_variable_get(instance_variable)
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
end
|
23
|
+
private
|
25
24
|
|
26
|
-
|
27
|
-
rewind
|
28
|
-
build_instance(file.first, first_line)
|
25
|
+
attr_reader :hash
|
29
26
|
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
module ClassMethods
|
29
|
+
def csv_file(file_name, options = {})
|
30
|
+
@@file_options = options
|
31
|
+
@@file = CSV.new(File.open(file_name, 'r'), @@file_options)
|
32
|
+
@@first_line = 2
|
33
|
+
@@last_line = `wc -l #{file_name}`.split(' ').first.to_i
|
34
|
+
@@middle_line = (@@last_line/2)+1
|
35
|
+
@line_number = nil
|
36
|
+
extract_headers(file_name, options)
|
37
|
+
define_accessors
|
38
|
+
end
|
39
|
+
|
40
|
+
def headers; return @@headers; end
|
41
|
+
def file; return @@file; end
|
42
|
+
def first_line; return @@first_line; end
|
43
|
+
def middle_line; return @@middle_line; end
|
44
|
+
def last_line; return @@last_line; end
|
45
|
+
def file_options; return @@file_options; end
|
46
|
+
|
47
|
+
def define_accessors
|
48
|
+
headers.each do |header|
|
49
|
+
self.send(:attr_accessor, header)
|
50
|
+
end
|
36
51
|
|
37
|
-
|
38
|
-
rewind
|
39
|
-
(first_line..last_line).each do |line_number|
|
40
|
-
yield find(line_number)
|
52
|
+
# self.send(:attr_accessor, :line_number)
|
41
53
|
end
|
42
|
-
end
|
43
54
|
|
44
|
-
|
55
|
+
def all
|
56
|
+
rewind
|
57
|
+
file.map { |row| build_instance(row, file.lineno) }
|
58
|
+
end
|
45
59
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
return new_instance
|
51
|
-
end
|
60
|
+
def find_by(key_val_pair)
|
61
|
+
row = search(key_val_pair).last
|
62
|
+
build_instance(row, row[:line_number])
|
63
|
+
end
|
52
64
|
|
53
|
-
|
54
|
-
|
55
|
-
|
65
|
+
def find_all_by(key_val_pair)
|
66
|
+
search(key_val_pair).map { |row| build_instance(row, row[:line_number]) }
|
67
|
+
end
|
56
68
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
69
|
+
def find(line_number)
|
70
|
+
row = if (first_line..last_line).include? line_number
|
71
|
+
front_find(line_number, file.path)
|
72
|
+
elsif (middle_line..last_line).include? line_number
|
73
|
+
back_find(line_number, file.path)
|
74
|
+
end
|
61
75
|
|
62
|
-
|
76
|
+
row.nil? ? row : build_instance(row, line_number)
|
77
|
+
end
|
63
78
|
|
64
|
-
|
65
|
-
|
79
|
+
def first
|
80
|
+
rewind
|
81
|
+
build_instance(file.first, first_line)
|
82
|
+
end
|
66
83
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
84
|
+
def last
|
85
|
+
command = `head -n 1 #{file.path} && tail -n 1 #{file.path}`
|
86
|
+
last_row = CSV.new(command, file_options).first
|
87
|
+
build_instance(last_row, last_line)
|
88
|
+
end
|
89
|
+
|
90
|
+
def each
|
91
|
+
rewind
|
92
|
+
(first_line..last_line).each do |line_number|
|
93
|
+
yield find(line_number)
|
71
94
|
end
|
72
|
-
end
|
73
|
-
end
|
95
|
+
end
|
74
96
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
97
|
+
private
|
98
|
+
|
99
|
+
def extract_headers(file_name, options)
|
100
|
+
csv_file = File.open(file_name,'r')
|
101
|
+
|
102
|
+
@@headers ||= CSV.new(csv_file, options).first.map do |headers, values|
|
103
|
+
headers
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def build_instance(row, line)
|
108
|
+
new_instance = self.new
|
109
|
+
row.each { |key, value| new_instance.send("#{key}=".to_sym, value) }
|
110
|
+
new_instance.line_number = line
|
111
|
+
return new_instance
|
112
|
+
end
|
113
|
+
|
114
|
+
def rewind
|
115
|
+
file.rewind
|
116
|
+
end
|
117
|
+
|
118
|
+
def search(key_val_pair)
|
119
|
+
rewind
|
120
|
+
@results = file
|
121
|
+
@pairs = key_val_pair
|
122
|
+
|
123
|
+
@pairs.each { |pair| @results = dig(pair, @results) }
|
124
|
+
|
125
|
+
@results
|
126
|
+
end
|
127
|
+
|
128
|
+
def dig(hash_pair, rows)
|
129
|
+
rows.map do |row|
|
130
|
+
if row[hash_pair.first] == hash_pair.last
|
131
|
+
$. != last_line ? row.push(line_number: $.) : row
|
132
|
+
end
|
133
|
+
end.reject(&:nil?)
|
134
|
+
end
|
135
|
+
|
136
|
+
def front_find(line_number, file_path)
|
137
|
+
command = `head -n 1 #{file_path} && head -n #{line_number} #{file_path} | tail -n 1`
|
138
|
+
CSV.new(command, file_options).first
|
139
|
+
end
|
140
|
+
def back_find(line_number, file_path)
|
141
|
+
command = `head -n 1 #{file_path} && tail -n #{last_line - line_number} #{file_path} | head -n 1`
|
142
|
+
CSV.new(command, file_options).first
|
143
|
+
end
|
82
144
|
end
|
83
145
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require './lib/csv_class_maker'
|
2
|
+
require 'byebug'
|
2
3
|
|
3
4
|
describe CsvClassMaker do
|
4
5
|
context 'class methods' do
|
@@ -18,48 +19,59 @@ end
|
|
18
19
|
|
19
20
|
describe Object do
|
20
21
|
before(:all){
|
21
|
-
@person1 = People.new(first: 'Mark', last: 'Platt', nickname: 'JCool')
|
22
|
-
@person2 = People.new(first: 'Longinus', last: 'Smith', nickname: 'Pebbles')
|
23
|
-
@person3 = People.new(first: 'Johnny', last: 'Radiation', nickname: 'Pebbles')
|
24
|
-
@person4 = People.new(first: 'Charlie', last: 'Mansfield', nickname: 'Sammykins')
|
22
|
+
@person1 = People.new(first: 'Mark', last: 'Platt', nickname: 'JCool', line_number: 2)
|
23
|
+
@person2 = People.new(first: 'Longinus', last: 'Smith', nickname: 'Pebbles', line_number: 3)
|
24
|
+
@person3 = People.new(first: 'Johnny', last: 'Radiation', nickname: 'Pebbles', line_number: 4)
|
25
|
+
@person4 = People.new(first: 'Charlie', last: 'Mansfield', nickname: 'Sammykins', line_number: 5)
|
25
26
|
}
|
26
27
|
|
27
28
|
context 'class methods' do
|
28
29
|
it "responds to .first" do
|
29
30
|
(People).should respond_to(:first)
|
30
31
|
end
|
32
|
+
|
31
33
|
it ".first returns correctly" do
|
32
34
|
expect(People.first).to eq @person1
|
33
35
|
end
|
36
|
+
|
34
37
|
it "responds to .last" do
|
35
38
|
(People).should respond_to(:last)
|
36
39
|
end
|
40
|
+
|
37
41
|
it ".last returns correctly" do
|
38
42
|
expect(People.last).to eq @person4
|
39
43
|
end
|
44
|
+
|
40
45
|
it "responds to .find" do
|
41
46
|
(People).should respond_to(:find)
|
42
47
|
end
|
48
|
+
|
43
49
|
it ".find returns correctly" do
|
44
50
|
expect(People.find(3)).to eq @person2
|
45
51
|
end
|
52
|
+
|
46
53
|
it "responds to .find_by" do
|
47
54
|
(People).should respond_to(:find_by)
|
48
55
|
end
|
56
|
+
|
49
57
|
it ".find_by returns correctly" do
|
50
58
|
expect(People.find_by(nickname: 'Pebbles')).to eq @person3
|
51
59
|
expect(People.find_by(nickname: 'Pebbles', last: 'Smith')).to eq @person2
|
52
60
|
end
|
61
|
+
|
53
62
|
it "responds to .find_all_by" do
|
54
63
|
(People).should respond_to(:find_all_by)
|
55
64
|
end
|
65
|
+
|
56
66
|
it ".find_all_by returns correctly" do
|
57
67
|
expect(People.find_all_by(nickname: 'Pebbles')).to eq [@person2, @person3]
|
58
68
|
expect(People.find_all_by(nickname: 'Pebbles', last: 'Radiation')).to eq [@person3]
|
59
69
|
end
|
70
|
+
|
60
71
|
it "responds to .each" do
|
61
72
|
(People).should respond_to(:each)
|
62
73
|
end
|
74
|
+
|
63
75
|
it ".each line yields" do
|
64
76
|
@output = []
|
65
77
|
People.each{ |person| @output << person.first }
|
@@ -70,9 +82,11 @@ describe Object do
|
|
70
82
|
it "responds to .first as defined in the csv" do
|
71
83
|
(People.new).should respond_to(:first)
|
72
84
|
end
|
85
|
+
|
73
86
|
it "responds to .last as defined in the csv" do
|
74
87
|
(People.new).should respond_to(:last)
|
75
88
|
end
|
89
|
+
|
76
90
|
it "responds to .nickname as defined in the csv" do
|
77
91
|
(People.new).should respond_to(:nickname)
|
78
92
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_class_maker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Platt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.14.1
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.14.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.5.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.5.1
|
27
41
|
description: '''csv_class_maker will create a class out of your csv''s headers, and
|
28
42
|
provide some methods for finding data in the CSV'''
|
29
43
|
email: mplatt@mrkplt.com
|
@@ -47,7 +61,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
61
|
requirements:
|
48
62
|
- - '>='
|
49
63
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
64
|
+
version: 2.0.0
|
51
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
66
|
requirements:
|
53
67
|
- - '>='
|