kevintyll-ssn_validator 1.0.0 → 1.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/History.txt +7 -1
- data/Manifest.txt +2 -0
- data/lib/ssn_validator/models/death_master_file_loader.rb +25 -25
- data/lib/ssn_validator.rb +1 -1
- data/lib/tasks/ssn_validator.rake +1 -1
- data/test/files/test_dmf_funky_data_load.txt +6 -0
- data/test/files/valid_csv_from_funky_data_file.txt +6 -0
- data/test/mocks/test/death_master_file_loader.rb +5 -0
- data/test/test_death_master_file_loader.rb +28 -0
- metadata +3 -1
data/History.txt
CHANGED
@@ -14,5 +14,11 @@
|
|
14
14
|
* 1 major enhancement:
|
15
15
|
* Added the death master file to determine if the ssn belongs to the deceased.
|
16
16
|
|
17
|
-
* 1
|
17
|
+
* 1 bug fix:
|
18
18
|
* Fixed bug where an error was thrown if the ssn area has not been assigned yet.
|
19
|
+
|
20
|
+
== 1.0.1 2009-04-23
|
21
|
+
|
22
|
+
* 2 bug fixes:
|
23
|
+
* Fixed dmf mysql load error when single quote is in a data file record.
|
24
|
+
* Fixed ssn_validator:update_data rake task that broke on the last build.
|
data/Manifest.txt
CHANGED
@@ -19,7 +19,7 @@ class DeathMasterFileLoader
|
|
19
19
|
raise(ArgumentError, "as_of not specified") unless @file_as_of
|
20
20
|
max_as_of = DeathMasterFile.maximum(:as_of)
|
21
21
|
raise(ArgumentError, "A more recent file has already been processed. DB as_of date #{max_as_of}") if max_as_of && (max_as_of >= @file_as_of.to_date)
|
22
|
-
|
22
|
+
|
23
23
|
if File.exists?(@file_path_or_url)
|
24
24
|
@download_file = File.open(@file_path_or_url)
|
25
25
|
elsif URI.parse(@file_path_or_url).kind_of?(URI::HTTP)
|
@@ -45,19 +45,19 @@ class DeathMasterFileLoader
|
|
45
45
|
|
46
46
|
def get_file_from_web
|
47
47
|
uri = URI.parse(@file_path_or_url)
|
48
|
-
|
48
|
+
|
49
49
|
request = Net::HTTP::Get.new(uri.request_uri)
|
50
50
|
request.basic_auth(SsnValidator::Ntis.user_name,SsnValidator::Ntis.password)
|
51
51
|
|
52
52
|
http = Net::HTTP.new(uri.host, uri.port)
|
53
53
|
http.use_ssl = (uri.port == 443)
|
54
54
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
55
|
-
|
55
|
+
|
56
56
|
response = http.request(request)
|
57
|
-
|
57
|
+
|
58
58
|
raise(ArgumentError, "Invalid URL: #{@file_path_or_url}") if response.kind_of?(Net::HTTPNotFound)
|
59
59
|
raise(ArgumentError, "Authorization Required: Invalid username or password. Set the variables SsnValidator::Ntis.user_name and SsnValidator::Ntis.password in your environment.rb file.") if response.kind_of?(Net::HTTPUnauthorized)
|
60
|
-
|
60
|
+
|
61
61
|
return response.body
|
62
62
|
end
|
63
63
|
|
@@ -81,7 +81,7 @@ class DeathMasterFileLoader
|
|
81
81
|
# Processes 28 million rows in 23 minutes. Input file 2.6GB output: 2.9GB.
|
82
82
|
# Used to convert a packed fixed-length file into csv for mysql import.
|
83
83
|
def convert_file_to_csv
|
84
|
-
|
84
|
+
|
85
85
|
csv_file = Tempfile.new("dmf") # create temp file for converted csv formmat.
|
86
86
|
|
87
87
|
|
@@ -98,37 +98,37 @@ class DeathMasterFileLoader
|
|
98
98
|
@delete_ssns << attributes_hash[:social_security_number]
|
99
99
|
else
|
100
100
|
# empty field for id to be generated by mysql.
|
101
|
-
newline = "
|
101
|
+
newline = "``," +
|
102
102
|
# social_security_number
|
103
|
-
"
|
103
|
+
"`#{attributes_hash[:social_security_number]}`," +
|
104
104
|
# last_name
|
105
|
-
"
|
105
|
+
"`#{attributes_hash[:last_name]}`," +
|
106
106
|
# name_suffix
|
107
|
-
"
|
107
|
+
"`#{attributes_hash[:name_suffix]}`," +
|
108
108
|
# first_name
|
109
|
-
"
|
109
|
+
"`#{attributes_hash[:first_name]}`," +
|
110
110
|
# middle_name
|
111
|
-
"
|
111
|
+
"`#{attributes_hash[:middle_name]}`," +
|
112
112
|
# verify_proof_code
|
113
|
-
"
|
113
|
+
"`#{attributes_hash[:verify_proof_code]}`," +
|
114
114
|
# date_of_death - need YYYY-MM-DD.
|
115
|
-
"
|
115
|
+
"`#{attributes_hash[:date_of_death]}`," +
|
116
116
|
# date_of_birth - need YYYY-MM-DD.
|
117
|
-
"
|
117
|
+
"`#{attributes_hash[:date_of_birth]}`," +
|
118
118
|
# state_of_residence - must be code between 01 and 65 or else nil.
|
119
|
-
"
|
119
|
+
"`#{attributes_hash[:state_of_residence]}`," +
|
120
120
|
# last_known_zip_residence
|
121
|
-
"
|
121
|
+
"`#{attributes_hash[:last_known_zip_residence]}`," +
|
122
122
|
# last_known_zip_payment
|
123
|
-
"
|
123
|
+
"`#{attributes_hash[:last_known_zip_payment]}`," +
|
124
124
|
# created_at
|
125
|
-
"
|
125
|
+
"`#{timenow}`," +
|
126
126
|
# updated_at
|
127
|
-
"
|
127
|
+
"`#{timenow}`," +
|
128
128
|
# as_of
|
129
|
-
"
|
129
|
+
"`#{attributes_hash[:as_of]}`" +"\n"
|
130
130
|
|
131
|
-
csv_file.
|
131
|
+
csv_file.syswrite newline
|
132
132
|
puts "#{i} records processed." if (i % 25000 == 0) && (i > 0)
|
133
133
|
end
|
134
134
|
end
|
@@ -201,9 +201,9 @@ class DeathMasterFileLoader
|
|
201
201
|
|
202
202
|
#This will insert new records, and replace records with existing ssns.
|
203
203
|
#This only works because there is a unique index on social_security_number.
|
204
|
-
mysql_command =
|
205
|
-
LOAD DATA LOCAL INFILE '#{csv_file.path}' REPLACE INTO TABLE death_master_files FIELDS TERMINATED BY ',' ENCLOSED BY "
|
206
|
-
TEXT
|
204
|
+
mysql_command = <<-TEXT
|
205
|
+
LOAD DATA LOCAL INFILE '#{csv_file.path}' REPLACE INTO TABLE death_master_files FIELDS TERMINATED BY ',' ENCLOSED BY "`" LINES TERMINATED BY '\n';
|
206
|
+
TEXT
|
207
207
|
|
208
208
|
DeathMasterFile.connection.execute(mysql_command)
|
209
209
|
puts "Mysql import complete."
|
data/lib/ssn_validator.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
namespace :ssn_validator do
|
3
3
|
desc "Loads the current file from http://www.socialsecurity.gov/employer/ssns/highgroup.txt if it hasn't already been loaded."
|
4
4
|
task :update_data => :environment do
|
5
|
-
|
5
|
+
SsnHighGroupCodeLoader.load_current_high_group_codes_file
|
6
6
|
end
|
7
7
|
|
8
8
|
namespace :death_master_file do
|
@@ -0,0 +1,6 @@
|
|
1
|
+
A772781978BAD DEATH DAY ANTHONY GABRIEL P031020090130200910
|
2
|
+
A772783025BAD DEATH MONTH JUAN P000220091101191010
|
3
|
+
A772786197BAD BIRTH YEAR ISAIAH P0202200901100009FO
|
4
|
+
A772786123QUOTED MIDDLE NAME ISAIAH ' P0202200901102009FO
|
5
|
+
A342786123QUOTED'NAME ISAIAH P0202200901102009FO
|
6
|
+
A344566123QUOTED NAME' ISAIAH P0202200901102009FO
|
@@ -0,0 +1,6 @@
|
|
1
|
+
``,`772781978`,`BAD DEATH DAY`,``,`ANTHONY`,`GABRIEL`,`P`,`2009-03-10`,`2009-01-30`,`10`,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
2
|
+
``,`772783025`,`BAD DEATH MONTH`,``,`JUAN`,``,`P`,``,`1910-11-01`,`10`,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
3
|
+
``,`772786197`,`BAD BIRTH YEAR`,``,`ISAIAH`,``,`P`,`2009-02-02`,`0009-01-10`,``,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
4
|
+
``,`772786123`,`QUOTED MIDDLE NAME`,``,`ISAIAH`,`'`,`P`,`2009-02-02`,`2009-01-10`,``,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
5
|
+
``,`342786123`,`QUOTED'NAME`,``,`ISAIAH`,``,`P`,`2009-02-02`,`2009-01-10`,``,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
6
|
+
``,`344566123`,`QUOTED NAME'`,``,`ISAIAH`,``,`P`,`2009-02-02`,`2009-01-10`,``,``,``,`2009-04-23 13:59:45`,`2009-04-23 13:59:45`,`2009-11-30`
|
@@ -2,6 +2,11 @@ require 'ssn_validator/models/death_master_file_loader'
|
|
2
2
|
|
3
3
|
class DeathMasterFileLoader
|
4
4
|
|
5
|
+
#Gives access to the private convert_file_to_csv method
|
6
|
+
def create_csv_file
|
7
|
+
convert_file_to_csv
|
8
|
+
end
|
9
|
+
|
5
10
|
def get_file_from_web
|
6
11
|
case @file_path_or_url
|
7
12
|
when /MA\d\d\d\d\d\d/ #these are the valid urls I want to mock a response to.
|
@@ -78,8 +78,36 @@ class TestDeathMasterFileLoader < Test::Unit::TestCase
|
|
78
78
|
assert DeathMasterFile.find_by_as_of((initial_run += 1.month).to_s(:db))
|
79
79
|
assert DeathMasterFile.find_by_as_of((initial_run += 1.month).to_s(:db))
|
80
80
|
assert DeathMasterFile.find_by_as_of((initial_run += 1.month).to_s(:db))
|
81
|
+
end
|
81
82
|
|
83
|
+
def test_should_load_file_with_funky_data
|
84
|
+
DeathMasterFileLoader.new(File.dirname(__FILE__) + '/files/test_dmf_funky_data_load.txt','2009-04-01').load_file
|
85
|
+
assert DeathMasterFile.count == 6
|
86
|
+
DeathMasterFile.find(:all).each do |dmf|
|
87
|
+
# this is more of an issue with the bulk mysql load, but since, I'm using
|
88
|
+
#sqlight3 for it's in memory db, I can't test the mysql load.
|
89
|
+
assert_not_nil dmf.as_of
|
90
|
+
end
|
91
|
+
end
|
82
92
|
|
93
|
+
def test_should_create_csv_file_for_mysql_import
|
94
|
+
#since, I'm using sqlight3 for it's in memory db, I can't test the mysql load
|
95
|
+
#but I can test the csv file creation.
|
96
|
+
loader = DeathMasterFileLoader.new(File.dirname(__FILE__) + '/files/test_dmf_funky_data_load.txt','2009-11-30')
|
97
|
+
csv = loader.create_csv_file #this method was created in the mock only to call the private convert_file_to_csv method
|
98
|
+
correctly_formatted_csv = File.open(File.dirname(__FILE__) + '/files/valid_csv_from_funky_data_file.txt')
|
99
|
+
#csv is open and at the end of the file, so we need to reopen it so we can read the lines.
|
100
|
+
generated_file = File.open(csv.path).readlines
|
101
|
+
#compare the values of each csv line, with the correctly formated "control file"
|
102
|
+
correctly_formatted_csv.each_with_index do |line,i|
|
103
|
+
csv_line = generated_file[i]
|
104
|
+
correctly_formatted_record_array = line.split(',')
|
105
|
+
csv_record_array = csv_line.split(',')
|
106
|
+
comparable_value_indices = (0..11).to_a << 14 #skip indices 12 and 13, they are the created_at and updated_at fields, they will never match.
|
107
|
+
comparable_value_indices.each do |i|
|
108
|
+
assert_equal correctly_formatted_record_array[i], csv_record_array[i]
|
109
|
+
end
|
110
|
+
end
|
83
111
|
end
|
84
112
|
|
85
113
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kevintyll-ssn_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Tyll
|
@@ -83,3 +83,5 @@ test_files:
|
|
83
83
|
- test/mocks/test/death_master_file_loader.rb
|
84
84
|
- test/files/test_dmf_initial_load.txt
|
85
85
|
- test/files/test_dmf_update_load.txt
|
86
|
+
- test/files/test_dmf_funky_data_load.txt
|
87
|
+
- test/files/valid_csv_from_funky_data_file.txt
|