strata 0.0.1
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.
- data/Gemfile +6 -0
- data/Gemfile.lock +31 -0
- data/README +1 -0
- data/Rakefile +7 -0
- data/lib/strata.rb +9 -0
- data/lib/strata/record_writer.rb +199 -0
- data/lib/strata/version.rb +3 -0
- data/spec/lib/record_writer_spec.rb +44 -0
- data/spec/spec_helper.rb +8 -0
- data/strata.gemspec +23 -0
- metadata +80 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
strata (0.0.1)
|
5
|
+
activesupport
|
6
|
+
i18n
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.2)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
diff-lcs (1.1.3)
|
15
|
+
i18n (0.6.0)
|
16
|
+
multi_json (1.1.0)
|
17
|
+
rspec (2.8.0)
|
18
|
+
rspec-core (~> 2.8.0)
|
19
|
+
rspec-expectations (~> 2.8.0)
|
20
|
+
rspec-mocks (~> 2.8.0)
|
21
|
+
rspec-core (2.8.0)
|
22
|
+
rspec-expectations (2.8.0)
|
23
|
+
diff-lcs (~> 1.1.2)
|
24
|
+
rspec-mocks (2.8.0)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
rspec
|
31
|
+
strata!
|
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
A gem for defining string-based records.
|
data/Rakefile
ADDED
data/lib/strata.rb
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
module Strata
|
2
|
+
module RecordWriter
|
3
|
+
|
4
|
+
def layout_rules
|
5
|
+
@layout_rules ||= self.class.class_layout_rules
|
6
|
+
end
|
7
|
+
|
8
|
+
def exposed_rules
|
9
|
+
layout_rules.select {|key, rule| !(rule["expose"] == false && rule.has_key?("expose")) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def filler_rules
|
13
|
+
@filler_rules ||= self.class.filler_layout_rules
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_layout_variables(options = {})
|
17
|
+
self.class.define_attribute_accessors
|
18
|
+
|
19
|
+
options.each do |k,v|
|
20
|
+
raise "#{k}: Argument is not a string" unless v.is_a? String
|
21
|
+
self.class.send :attr_accessor, k
|
22
|
+
self.send "#{k}=", v.upcase
|
23
|
+
end
|
24
|
+
|
25
|
+
layout_rules.each do |k,v|
|
26
|
+
self.class.send(:attr_accessor, k) unless (v["expose"] && v["expose"] == false)
|
27
|
+
# self.send "#{k}=", v['fixed_val'] if v.has_key? ""
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_filler(string)
|
32
|
+
filler_rules.each do |key, value|
|
33
|
+
string[(value["offset"] - 1), value["length"]] = value["fixed_val"]
|
34
|
+
end
|
35
|
+
|
36
|
+
return string
|
37
|
+
end
|
38
|
+
|
39
|
+
def record_length
|
40
|
+
self.class.class_variable_get(:@@record_length) || 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def record_delimiter
|
44
|
+
self.class.class_variable_get(:@@record_delimiter) || ""
|
45
|
+
end
|
46
|
+
|
47
|
+
def allowed_characters
|
48
|
+
if self.class.class_variable_defined?(:@@record_allowed_characters)
|
49
|
+
self.class.class_variable_get(:@@record_allowed_characters)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
@string = " " * record_length + record_delimiter
|
55
|
+
@string = set_filler(@string)
|
56
|
+
|
57
|
+
@string = "#{@string}"
|
58
|
+
|
59
|
+
self.exposed_rules.each do |field_name,rule|
|
60
|
+
value = self.send(field_name) || ""
|
61
|
+
|
62
|
+
value = value.rjust(rule['length'], "0") if rule['data_type'] == 'N'
|
63
|
+
value = value.ljust(rule['length'], " ") if rule['data_type'] == 'A'
|
64
|
+
|
65
|
+
offset = rule['offset'] - 1
|
66
|
+
length = rule['length']
|
67
|
+
|
68
|
+
@string[(offset), length] = value
|
69
|
+
end
|
70
|
+
|
71
|
+
@string
|
72
|
+
end
|
73
|
+
|
74
|
+
def valid_characters(string)
|
75
|
+
return true unless allowed_characters
|
76
|
+
string.each_char.all? {|c| allowed_characters.include?(c)}
|
77
|
+
end
|
78
|
+
|
79
|
+
def validate_field(field_name, field_value)
|
80
|
+
if field_name != :user_ref
|
81
|
+
raise "#{field_name}: Invalid character used in #{field_value}" unless valid_characters(field_value)
|
82
|
+
end
|
83
|
+
|
84
|
+
raise "#{field_name}: Argument is not a string" unless field_value.is_a? String
|
85
|
+
end
|
86
|
+
|
87
|
+
def validate!(options)
|
88
|
+
options.each do |k,v|
|
89
|
+
rule = layout_rules[k.to_s]
|
90
|
+
|
91
|
+
validate_field(k, v)
|
92
|
+
raise "#{k}: Input too long" if v.length > rule['length']
|
93
|
+
raise "#{k}: Invalid data" if rule['regex'] && ((v =~ /#{rule['regex']}/) != 0)
|
94
|
+
raise "#{k}: Invalid data - expected #{rule['fixed_val']}, got #{v}" if rule['fixed_val'] && (v != rule['fixed_val'])
|
95
|
+
raise "#{k}: Numeric value required" if (rule['data_type'] == 'N') && !(Float(v) rescue false)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
module ClassMethods
|
100
|
+
|
101
|
+
def set_record_length(length)
|
102
|
+
class_variable_set(:@@record_length, length)
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_delimiter(delimiter)
|
106
|
+
class_variable_set(:@@record_delimiter, delimiter)
|
107
|
+
end
|
108
|
+
|
109
|
+
def set_allowed_characters(chars)
|
110
|
+
class_variable_set(:@@record_allowed_characters, chars)
|
111
|
+
end
|
112
|
+
|
113
|
+
# TODO: remove this method or require config path to be specified OR.. make it redundant by refactoring behind an add_rule method
|
114
|
+
def class_layout_rules
|
115
|
+
file_name = "#{Absa::H2h::CONFIG_DIR}/#{self.name.split("::")[-2].underscore}.yml"
|
116
|
+
record_type = self.name.split("::")[-1].underscore
|
117
|
+
|
118
|
+
YAML.load(File.open(file_name))[record_type]
|
119
|
+
end
|
120
|
+
|
121
|
+
def exposed_class_layout_rules
|
122
|
+
self.class_layout_rules.select {|key, rule| !(rule["expose"] == false && rule.has_key?("expose")) }
|
123
|
+
end
|
124
|
+
|
125
|
+
def filler_layout_rules
|
126
|
+
class_layout_rules.select {|key, rule| rule.has_key?("expose") && rule["expose"] == false && rule.has_key?("fixed_val")}
|
127
|
+
end
|
128
|
+
|
129
|
+
def define_attribute_accessors
|
130
|
+
self.class_layout_rules.each do |k,v|
|
131
|
+
(class << self; self; end).send :attr_accessor, k
|
132
|
+
self.send :attr_accessor, k
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def template_options
|
137
|
+
hash = {}
|
138
|
+
|
139
|
+
self.exposed_class_layout_rules.each do |field, rule|
|
140
|
+
value = rule.has_key?('fixed_val') ? rule['fixed_val'] : nil
|
141
|
+
|
142
|
+
if value
|
143
|
+
value = value.rjust(rule['length'], "0") if rule['data_type'] == 'N'
|
144
|
+
value = value.ljust(rule['length'], " ") if rule['data_type'] == 'A'
|
145
|
+
end
|
146
|
+
|
147
|
+
hash[field.to_sym] = value
|
148
|
+
end
|
149
|
+
|
150
|
+
hash
|
151
|
+
end
|
152
|
+
|
153
|
+
def retrieve_field_value(string, field, rule)
|
154
|
+
offset = rule['offset'] - 1
|
155
|
+
length = rule['length']
|
156
|
+
field_type = rule['data_type']
|
157
|
+
|
158
|
+
value = string[offset, length]
|
159
|
+
|
160
|
+
unless rule['fixed_val'] || rule['no_strip']
|
161
|
+
value = value.rstrip if field_type == 'A'
|
162
|
+
value = value.to_i.to_s if field_type == 'N'
|
163
|
+
end
|
164
|
+
|
165
|
+
value
|
166
|
+
end
|
167
|
+
|
168
|
+
def matches_definition?(string)
|
169
|
+
self.class_layout_rules.each do |field, rule|
|
170
|
+
regex = rule['regex']
|
171
|
+
fixed_val = rule['fixed_val']
|
172
|
+
value = self.retrieve_field_value(string, field, rule)
|
173
|
+
|
174
|
+
return false if fixed_val and value != fixed_val
|
175
|
+
return false if regex and not value =~ /#{regex}/
|
176
|
+
end
|
177
|
+
|
178
|
+
true
|
179
|
+
end
|
180
|
+
|
181
|
+
def string_to_hash(string)
|
182
|
+
hash = {}
|
183
|
+
|
184
|
+
self.exposed_class_layout_rules.each do |field, rule|
|
185
|
+
hash[field.to_sym] = self.retrieve_field_value(string, field, rule)
|
186
|
+
end
|
187
|
+
|
188
|
+
hash
|
189
|
+
end
|
190
|
+
|
191
|
+
def from_s(string)
|
192
|
+
options = self.string_to_hash(string)
|
193
|
+
record = self.new(options)
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Strata::RecordWriter do
|
4
|
+
|
5
|
+
it "should allow the record length to be specified" do
|
6
|
+
|
7
|
+
class String
|
8
|
+
include Strata::RecordWriter
|
9
|
+
extend Strata::RecordWriter::ClassMethods
|
10
|
+
|
11
|
+
set_record_length 200
|
12
|
+
end
|
13
|
+
|
14
|
+
string = "test1234"
|
15
|
+
string.record_length.should == 200
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not validate characters if no character set was specified" do
|
19
|
+
class String
|
20
|
+
include Strata::RecordWriter
|
21
|
+
extend Strata::RecordWriter::ClassMethods
|
22
|
+
|
23
|
+
set_record_length 200
|
24
|
+
|
25
|
+
string = "test1234"
|
26
|
+
string.valid_characters("ADAWVDAWVGr#&^ @").should == true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should validate that a record contains only valid characters" do
|
31
|
+
class String
|
32
|
+
include Strata::RecordWriter
|
33
|
+
extend Strata::RecordWriter::ClassMethods
|
34
|
+
|
35
|
+
set_record_length 200
|
36
|
+
set_allowed_characters ('A'..'Z').to_a
|
37
|
+
|
38
|
+
string = "test1234"
|
39
|
+
string.valid_characters("ADAWVDAWVGR").should == true
|
40
|
+
string.valid_characters("ADAWVDAWVGr").should == false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/strata.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "strata/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "strata"
|
7
|
+
s.version = Strata::VERSION
|
8
|
+
s.authors = ["Douglas Anderson", "Jeffrey van Aswegen"]
|
9
|
+
s.email = ["i.am.douglas.anderson@gmail.com, jeffmess@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A gem for manipulating string-based records.}
|
12
|
+
s.description = %q{A gem for manipulating string-based records.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "strata"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "activesupport"
|
22
|
+
s.add_dependency "i18n"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: strata
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Douglas Anderson
|
9
|
+
- Jeffrey van Aswegen
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-04-04 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
requirement: &70149324763260 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70149324763260
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: i18n
|
28
|
+
requirement: &70149324762840 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *70149324762840
|
37
|
+
description: A gem for manipulating string-based records.
|
38
|
+
email:
|
39
|
+
- i.am.douglas.anderson@gmail.com, jeffmess@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- Gemfile
|
45
|
+
- Gemfile.lock
|
46
|
+
- README
|
47
|
+
- Rakefile
|
48
|
+
- lib/strata.rb
|
49
|
+
- lib/strata/record_writer.rb
|
50
|
+
- lib/strata/version.rb
|
51
|
+
- spec/lib/record_writer_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
- strata.gemspec
|
54
|
+
homepage: ''
|
55
|
+
licenses: []
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project: strata
|
74
|
+
rubygems_version: 1.8.6
|
75
|
+
signing_key:
|
76
|
+
specification_version: 3
|
77
|
+
summary: A gem for manipulating string-based records.
|
78
|
+
test_files:
|
79
|
+
- spec/lib/record_writer_spec.rb
|
80
|
+
- spec/spec_helper.rb
|