strata 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in strata.gemspec
4
+ gemspec
5
+
6
+ gem 'rspec'
@@ -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.
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ require "strata/version"
2
+ require "active_support/core_ext/string"
3
+ require "yaml"
4
+
5
+ module Strata
6
+ CONFIG_DIR = File.expand_path(File.dirname(__FILE__)) + "/config"
7
+ end
8
+
9
+ require 'strata/record_writer'
@@ -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,3 @@
1
+ module Strata
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'strata'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -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