csv_class_maker 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/csv_class_maker.rb +1 -0
- data/lib/csv_class_maker/csv_class_maker.rb +46 -0
- data/lib/csv_class_maker/csv_find.rb +89 -0
- data/spec/csv_class_maker_spec.rb +67 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3decd1df13f382a8a4e45b80e04b1754edb935d0
|
4
|
+
data.tar.gz: 025dab04fab3222f4dd6440b7af9ab06fc940b0d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7f9d0a74aa622f4acb7013f106c161c7d420e7c2f5cab088fd277fe356ceb21a635c214079d3d07738990813e5f3a5f19c3e93f69b94a2dc51fbb8c8660989d
|
7
|
+
data.tar.gz: 1fb2d38a2412e57e915fed493172a345fd7a66c4999f2a1e9a9990243b67fed0bc37ededc43efa84ee77e2fdf642b8c6e379c554d9b9c18cd4b2a0d5624035dd
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'csv_class_maker/csv_class_maker'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Usage:
|
2
|
+
#
|
3
|
+
# require './csv_class_maker'
|
4
|
+
# CsvClassMaker::generate_class 'Batting', '/Users/mplatt/Desktop/Batting.csv'
|
5
|
+
|
6
|
+
module CsvClassMaker
|
7
|
+
require 'csv'
|
8
|
+
def self.generate_class(class_name, file_name)
|
9
|
+
Object.const_set class_name, Struct.new(*extract_headers(file_name)){
|
10
|
+
|
11
|
+
# Class definition for dynamically generated classes.
|
12
|
+
require './lib/csv_class_maker/csv_find'
|
13
|
+
extend CsvFind
|
14
|
+
|
15
|
+
def initialize(hash=nil)
|
16
|
+
if hash
|
17
|
+
hash.each { |k,v| send "#{k}=".to_sym, v }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@@file = CSV.new(File.open(file_name,'r'), headers: true, header_converters: :symbol, return_headers: false)
|
22
|
+
@@first_line = 2
|
23
|
+
@@last_line = `wc -l #{file_name}`.split(' ').first.to_i
|
24
|
+
@line_number = nil
|
25
|
+
|
26
|
+
attr_accessor :line_number
|
27
|
+
|
28
|
+
def self.file; return @@file; end
|
29
|
+
def self.first_line; return @@first_line; end
|
30
|
+
def self.last_line; return @@last_line; end
|
31
|
+
|
32
|
+
# End of class definition.
|
33
|
+
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def self.extract_headers(file_name)
|
40
|
+
@csv_headers = []
|
41
|
+
CSV.new(File.open(file_name,'r'), headers: true, header_converters: :symbol, return_headers: true).first.each do |headers, values|
|
42
|
+
@csv_headers << headers
|
43
|
+
end
|
44
|
+
@csv_headers
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module CsvClassMaker::CsvFind
|
2
|
+
|
3
|
+
def all
|
4
|
+
rewind
|
5
|
+
object_array = []
|
6
|
+
file.each {|row| object_array << build_instance(row, file.lineno) }
|
7
|
+
object_array
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_by(key_val_pair)
|
11
|
+
row = search(key_val_pair).last
|
12
|
+
build_instance(row, row[:line_number])
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_all_by(key_val_pair)
|
16
|
+
rows = search(key_val_pair)
|
17
|
+
output_objects = []
|
18
|
+
rows.each { |row|
|
19
|
+
output_objects << build_instance(row, row[:line_number])
|
20
|
+
}
|
21
|
+
output_objects
|
22
|
+
end
|
23
|
+
|
24
|
+
def find(line_number)
|
25
|
+
if (first_line..last_line).include? line_number
|
26
|
+
row = CSV.new(`head -n 1 #{file.path} && head -n #{line_number} #{file.path} | tail -n 1`, headers: true, header_converters: :symbol, return_headers: false).first
|
27
|
+
build_instance row, line_number
|
28
|
+
# elsif ((last_line/2)..last_line).include? line_number
|
29
|
+
# row = CSV.new(`head -n 1 #{file.path} && tail -n #{last_line+2 - line_number} #{file.path} | head -n 1`, headers: true, header_converters: :symbol, return_headers: false).first
|
30
|
+
# build_instance row, line_number
|
31
|
+
else
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def first
|
37
|
+
rewind
|
38
|
+
build_instance file.first, first_line
|
39
|
+
end
|
40
|
+
|
41
|
+
def last
|
42
|
+
last_row = CSV.new(`head -n 1 #{file.path} && tail -n 1 #{file.path}`, headers: true, header_converters: :symbol, return_headers: false).first
|
43
|
+
build_instance last_row, last_line
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def build_instance(row, line)
|
49
|
+
new_instance = self.new
|
50
|
+
row.each { |key, value| new_instance.send "#{key}=".to_sym, value }
|
51
|
+
new_instance.line_number = line
|
52
|
+
return new_instance
|
53
|
+
end
|
54
|
+
|
55
|
+
def rewind
|
56
|
+
file.rewind
|
57
|
+
end
|
58
|
+
|
59
|
+
def search(key_val_pair)
|
60
|
+
rewind
|
61
|
+
@results = file
|
62
|
+
@pairs = key_val_pair
|
63
|
+
|
64
|
+
@pairs.each { |pair|
|
65
|
+
@results = dig(pair, @results)
|
66
|
+
}
|
67
|
+
|
68
|
+
@results
|
69
|
+
end
|
70
|
+
|
71
|
+
def dig(hash_pair, rows)
|
72
|
+
@key = hash_pair.first
|
73
|
+
@value = hash_pair.last
|
74
|
+
@accumulator = []
|
75
|
+
|
76
|
+
rows.each { |row|
|
77
|
+
if row[@key] == @value
|
78
|
+
if $. != last_line
|
79
|
+
@accumulator << row.push(line_number: $.) if $. != last_line
|
80
|
+
else
|
81
|
+
@accumulator << row
|
82
|
+
end
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
@accumulator
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require './lib/csv_class_maker'
|
2
|
+
|
3
|
+
describe CsvClassMaker do
|
4
|
+
context 'class methods' do
|
5
|
+
describe 'generate_class' do
|
6
|
+
it 'makes a new class object from a file' do
|
7
|
+
CsvClassMaker::generate_class 'People', 'spec/support/demo.csv'
|
8
|
+
Object.constants.include? :People
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Object do
|
15
|
+
before(:all){
|
16
|
+
@person1 = People.new(first: 'Mark', last: 'Platt', nickname: 'JCool')
|
17
|
+
@person2 = People.new(first: 'Longinus', last: 'Smith', nickname: 'Pebbles')
|
18
|
+
@person3 = People.new(first: 'Johnny', last: 'Radiation', nickname: 'Pebbles')
|
19
|
+
@person4 = People.new(first: 'Charlie', last: 'Mansfield', nickname: 'Sammykins')
|
20
|
+
}
|
21
|
+
|
22
|
+
context 'class methods' do
|
23
|
+
it "responds to .first" do
|
24
|
+
(People).should respond_to(:first)
|
25
|
+
end
|
26
|
+
it ".first returns correctly" do
|
27
|
+
expect(People.first).to eq @person1
|
28
|
+
end
|
29
|
+
it "responds to .last" do
|
30
|
+
(People).should respond_to(:last)
|
31
|
+
end
|
32
|
+
it ".last returns correctly" do
|
33
|
+
expect(People.last).to eq @person4
|
34
|
+
end
|
35
|
+
it "responds to .find" do
|
36
|
+
(People).should respond_to(:find)
|
37
|
+
end
|
38
|
+
it ".find returns correctly" do
|
39
|
+
expect(People.find(3)).to eq @person2
|
40
|
+
end
|
41
|
+
it "responds to .find_by" do
|
42
|
+
(People).should respond_to(:find_by)
|
43
|
+
end
|
44
|
+
it ".find_by returns correctly" do
|
45
|
+
expect(People.find_by(nickname: 'Pebbles')).to eq @person3
|
46
|
+
expect(People.find_by(nickname: 'Pebbles', last: 'Smith')).to eq @person2
|
47
|
+
end
|
48
|
+
it "responds to .find_all_by" do
|
49
|
+
(People).should respond_to(:find_all_by)
|
50
|
+
end
|
51
|
+
it ".find_all_by returns correctly" do
|
52
|
+
expect(People.find_all_by(nickname: 'Pebbles')).to eq [@person2, @person3]
|
53
|
+
expect(People.find_all_by(nickname: 'Pebbles', last: 'Radiation')).to eq [@person3]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context 'instance methods' do
|
57
|
+
it "responds to .first as defined in the csv" do
|
58
|
+
(People.new).should respond_to(:first)
|
59
|
+
end
|
60
|
+
it "responds to .last as defined in the csv" do
|
61
|
+
(People.new).should respond_to(:last)
|
62
|
+
end
|
63
|
+
it "responds to .nickname as defined in the csv" do
|
64
|
+
(People.new).should respond_to(:nickname)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: csv_class_maker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Platt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: "'csv_class_maker will create a class out of your csv's headers, and
|
28
|
+
provide some methods for finding data in the CSV'"
|
29
|
+
email: mplatt@mrkplt.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/csv_class_maker.rb
|
35
|
+
- lib/csv_class_maker/csv_class_maker.rb
|
36
|
+
- lib/csv_class_maker/csv_find.rb
|
37
|
+
- spec/csv_class_maker_spec.rb
|
38
|
+
homepage: http://mrkplt.com
|
39
|
+
licenses:
|
40
|
+
- MIT
|
41
|
+
metadata: {}
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.9.3
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 2.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: "'Object oriented CSV reading'"
|
62
|
+
test_files:
|
63
|
+
- spec/csv_class_maker_spec.rb
|