data_seeder 0.0.5 → 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/README.md +71 -98
- data/app/models/data_seeder/seed_file.rb +54 -14
- data/lib/data_seeder.rb +30 -10
- data/lib/data_seeder/config.rb +39 -17
- data/lib/data_seeder/loader.rb +80 -85
- data/lib/data_seeder/loader/csv.rb +2 -1
- data/lib/data_seeder/loader/txt.rb +1 -6
- data/lib/data_seeder/loader/yaml.rb +1 -1
- data/lib/data_seeder/version.rb +1 -1
- data/test/dummy/app/models/app_error_data_seeder.rb +10 -8
- data/test/dummy/app/models/country.rb +0 -12
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/seed.test/{bar.err → bar_err/bar.err} +0 -0
- data/test/dummy/db/seed.test/countries_csv/countries.cfg +9 -0
- data/test/dummy/db/seed.test/countries_csv/countries.csv +249 -0
- data/test/dummy/db/seed.test/countries_txt/countries.cfg +6 -0
- data/test/dummy/db/seed.test/{countries.txt → countries_txt/countries.txt} +0 -0
- data/test/dummy/db/seed.test/{foo.err → foo_err/foo.err} +0 -0
- data/test/dummy/db/seed.test/{states.csv → states_csv/states.csv} +0 -0
- data/test/dummy/db/seed.test/states_json/states.cfg +1 -0
- data/test/dummy/db/seed.test/{states.json → states_json/states.json} +0 -1
- data/test/dummy/db/seed.test/states_txt/states.cfg +6 -0
- data/test/dummy/db/seed.test/{states.txt → states_txt/states.txt} +0 -1
- data/test/dummy/db/seed.test/states_yml/states.cfg +1 -0
- data/test/dummy/db/seed.test/{states.yml → states_yml/states.yml} +0 -1
- data/test/dummy/db/seed.test/{zulu.err → zulu_err/zulu.err} +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +126 -0
- data/test/dummy/log/test.log +90945 -0
- data/test/models/data_seeder_test.rb +50 -30
- metadata +33 -20
- data/lib/data_seeder/logger.rb +0 -15
data/lib/data_seeder/loader.rb
CHANGED
@@ -2,68 +2,42 @@ require 'English'
|
|
2
2
|
|
3
3
|
module DataSeeder
|
4
4
|
module Loader
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
end
|
18
|
-
|
19
|
-
def config
|
20
|
-
DataSeeder.config
|
5
|
+
attr_reader :seeder_config, :config, :key_attribute, :klass, :path, :path_minus_ext
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@seeder_config = DataSeeder.config
|
9
|
+
@config = config
|
10
|
+
@key_attribute = config[:key_attribute] || :id
|
11
|
+
@klass = config[:klass]
|
12
|
+
@path = config[:path]
|
13
|
+
@path_minus_ext = config[:path_minus_ext]
|
14
|
+
# Default purge to true if unspecified
|
15
|
+
@config[:purge] = true unless config.has_key?(:purge)
|
16
|
+
@old_ids = Set.new
|
21
17
|
end
|
22
18
|
|
23
19
|
def logger
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def klass!
|
28
|
-
@path_minus_ext.classify.constantize
|
29
|
-
rescue NameError => e
|
30
|
-
raise "#{@path} doesn't match a corresponding model"
|
31
|
-
end
|
32
|
-
|
33
|
-
def klass
|
34
|
-
# This should always translate to a class except for custom loaders
|
35
|
-
@path_minus_ext.classify.constantize rescue nil
|
20
|
+
@seeder_config.logger
|
36
21
|
end
|
37
22
|
|
38
|
-
def process(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@file_config = {}
|
43
|
-
cfg_file = "#{@path_minus_ext}.cfg"
|
44
|
-
@file_config = eval(File.read(cfg_file)) if File.exist?(cfg_file)
|
45
|
-
File.open(@path, 'r') do |fin|
|
46
|
-
load_file_config(fin) if @file_config.empty?
|
47
|
-
@file_config = ActiveSupport::HashWithIndifferentAccess.new(@file_config)
|
48
|
-
setup
|
49
|
-
load(fin)
|
50
|
-
teardown
|
51
|
-
end
|
52
|
-
call_file_method(:teardown)
|
23
|
+
def process(io)
|
24
|
+
setup
|
25
|
+
load(io)
|
26
|
+
teardown
|
53
27
|
end
|
54
28
|
|
55
29
|
def setup
|
56
|
-
@
|
57
|
-
@old_keys = self.klass!.all.pluck(@key_attribute).map(&:to_s) if @purge
|
58
|
-
logger.info { "Loading #{@path}" }
|
59
|
-
call_file_method(:setup)
|
30
|
+
@old_ids = klass.all.pluck(:id).to_set if config[:purge]
|
60
31
|
end
|
61
32
|
|
62
33
|
def teardown
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
|
34
|
+
destroy_models(klass, @old_ids)
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy_models(klass, ids)
|
38
|
+
ids.each do |id|
|
39
|
+
if model = klass.find_by(id: id)
|
40
|
+
destroy_model(model)
|
67
41
|
end
|
68
42
|
end
|
69
43
|
end
|
@@ -72,68 +46,89 @@ module DataSeeder
|
|
72
46
|
# The changes argument will be the model.changes on an update.
|
73
47
|
def model_info(model, changes=nil)
|
74
48
|
if changes
|
75
|
-
attr =
|
76
|
-
|
49
|
+
if attr = config[:update_display_method]
|
50
|
+
"#{model.send(attr)}: #{changes.inspect}"
|
51
|
+
elsif @key_attribute.kind_of?(Enumerable)
|
52
|
+
label = @key_attribute.map {|k| "#{k}=#{model.send(k)}"}.join(' ')
|
53
|
+
"#{label}: #{changes.inspect}"
|
54
|
+
else
|
55
|
+
"#{model.send(@key_attribute)}: #{changes.inspect}"
|
56
|
+
end
|
77
57
|
else
|
78
58
|
model.inspect
|
79
59
|
end
|
80
60
|
end
|
81
61
|
|
82
|
-
def
|
83
|
-
config_line = fin.readline
|
84
|
-
if match = config_line.match(/^\s*#\s*config:(.*)/)
|
85
|
-
@file_config = eval(match[1])
|
86
|
-
else
|
87
|
-
fin.seek(0)
|
88
|
-
if self.klass && self.klass.respond_to?(:data_seeder_config)
|
89
|
-
@file_config = self.klass.data_seeder_config
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def load(fin)
|
62
|
+
def load(io)
|
95
63
|
throw 'Must override load'
|
96
64
|
end
|
97
65
|
|
66
|
+
# This doesn't work in some versions of JRuby (version 9.0.3.0?)
|
98
67
|
def line_number
|
99
68
|
$INPUT_LINE_NUMBER
|
100
69
|
end
|
101
70
|
|
102
71
|
def save(attr)
|
103
|
-
|
104
|
-
|
72
|
+
attr = call_method(:postprocess, attr) || attr
|
73
|
+
if config[:use_line_number_as_id]
|
74
|
+
find_hash = { @key_attribute => self.line_number }
|
75
|
+
elsif @key_attribute.kind_of?(Enumerable)
|
76
|
+
find_hash = {}
|
77
|
+
@key_attribute.each do |k|
|
78
|
+
find_hash[k] = attr[k.to_s] || attr[k.to_sym]
|
79
|
+
end
|
105
80
|
else
|
106
81
|
key = attr[@key_attribute.to_s] || attr[@key_attribute.to_sym]
|
107
82
|
raise "No #{@key_attribute} in #{attr.inspect}" unless key
|
83
|
+
find_hash = { @key_attribute => key }
|
108
84
|
end
|
109
|
-
|
110
|
-
method.call(attr)
|
111
|
-
elsif self.klass!.respond_to?(:data_seeder_postprocess)
|
112
|
-
self.klass!.send(:data_seeder_postprocess, attr)
|
113
|
-
end
|
114
|
-
@old_keys.delete(key.to_s)
|
115
|
-
model = self.klass!.find_or_initialize_by(@key_attribute => key)
|
85
|
+
model = self.klass.find_or_initialize_by(find_hash)
|
116
86
|
model.attributes = attr
|
117
87
|
save_model(model)
|
118
88
|
end
|
119
89
|
|
120
90
|
def save_model(model)
|
121
91
|
if model.new_record?
|
122
|
-
|
92
|
+
log_save(model)
|
123
93
|
else
|
124
|
-
|
125
|
-
return
|
126
|
-
|
94
|
+
@old_ids.delete(model.id)
|
95
|
+
return unless model.changed?
|
96
|
+
log_update(model)
|
127
97
|
end
|
128
98
|
model.save!
|
129
99
|
end
|
130
100
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
101
|
+
# Allow override for potential soft-delete
|
102
|
+
def destroy_model(model)
|
103
|
+
log_destroy(model)
|
104
|
+
model.destroy
|
105
|
+
end
|
106
|
+
|
107
|
+
def log_save(model)
|
108
|
+
logger.debug { "Saving #{model_info(model)}" }
|
109
|
+
end
|
110
|
+
|
111
|
+
def log_update(model)
|
112
|
+
logger.debug { "Updating #{model_info(model, model.changes)}" }
|
113
|
+
end
|
114
|
+
|
115
|
+
def log_destroy(model)
|
116
|
+
logger.debug { "Destroying #{model_info(model)}" }
|
117
|
+
end
|
118
|
+
|
119
|
+
def log_indent(&block)
|
120
|
+
@seeder_config.log_indent(&block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def call_method(name, *args)
|
124
|
+
if self.respond_to?(name)
|
125
|
+
return send(name, *args)
|
126
|
+
elsif val = config[name]
|
127
|
+
if val.kind_of?(Proc)
|
128
|
+
return val.call(*args)
|
129
|
+
else
|
130
|
+
return val
|
131
|
+
end
|
137
132
|
end
|
138
133
|
return nil
|
139
134
|
end
|
@@ -4,16 +4,11 @@ module DataSeeder
|
|
4
4
|
include Loader
|
5
5
|
|
6
6
|
def load(io)
|
7
|
-
if method =
|
7
|
+
if method = config[:line]
|
8
8
|
io.each_line do |line|
|
9
9
|
next if line.blank? || line.match(/^\s*#/)
|
10
10
|
save(method.call(line))
|
11
11
|
end
|
12
|
-
elsif self.klass.respond_to?(:data_seeder_line)
|
13
|
-
io.each_line do |line|
|
14
|
-
next if line.blank? || line.match(/^\s*#/)
|
15
|
-
save(self.klass.send(:data_seeder_line, line))
|
16
|
-
end
|
17
12
|
else
|
18
13
|
raise "No line method defined for #{self.klass.name}"
|
19
14
|
end
|
data/lib/data_seeder/version.rb
CHANGED
@@ -7,10 +7,10 @@ class AppErrorDataSeeder
|
|
7
7
|
@app = App.find_or_initialize_by(name: self.path_minus_ext)
|
8
8
|
@existing_errors = {}
|
9
9
|
if @app.new_record?
|
10
|
-
logger.
|
10
|
+
logger.debug { "Loading errors for new App: #{@app.name}" }
|
11
11
|
@app.save!
|
12
12
|
else
|
13
|
-
logger.
|
13
|
+
logger.debug { "Loading errors for existing App: #{@app.name}" }
|
14
14
|
@app.app_errors.each do |app_error|
|
15
15
|
@existing_errors[app_error.code] = app_error
|
16
16
|
end
|
@@ -19,10 +19,12 @@ class AppErrorDataSeeder
|
|
19
19
|
|
20
20
|
def teardown
|
21
21
|
unless @existing_errors.empty?
|
22
|
-
logger.
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
logger.debug { "The following are begin removed:" }
|
23
|
+
log_indent do
|
24
|
+
@existing_errors.each do |code, app_error|
|
25
|
+
logger.debug { "#{code}: #{app_error.message}" }
|
26
|
+
app_error.destroy
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
@@ -40,11 +42,11 @@ class AppErrorDataSeeder
|
|
40
42
|
@existing_errors.delete(code)
|
41
43
|
app_error.message = message
|
42
44
|
unless app_error.changes.empty?
|
43
|
-
logger.
|
45
|
+
logger.debug { "Changing #{code}: #{app_error.changes}" }
|
44
46
|
app_error.save!
|
45
47
|
end
|
46
48
|
else
|
47
|
-
logger.
|
49
|
+
logger.debug { "Creating #{code}: #{message}" }
|
48
50
|
@app.app_errors.create!(code: code, message: message)
|
49
51
|
end
|
50
52
|
end
|
Binary file
|
File without changes
|
@@ -0,0 +1,249 @@
|
|
1
|
+
country_code,country
|
2
|
+
AD,"Andorra"
|
3
|
+
AE,"United Arab Emirates"
|
4
|
+
AF,"Afghanistan"
|
5
|
+
AG,"Antigua and Barbuda"
|
6
|
+
AI,"Anguilla"
|
7
|
+
AL,"Albania"
|
8
|
+
AM,"Armenia"
|
9
|
+
AO,"Angola"
|
10
|
+
AQ,"Antarctica"
|
11
|
+
AR,"Argentina"
|
12
|
+
AS,"American Samoa"
|
13
|
+
AT,"Austria"
|
14
|
+
AU,"Australia"
|
15
|
+
AW,"Aruba"
|
16
|
+
AX,"Åland Islands"
|
17
|
+
AZ,"Azerbaijan"
|
18
|
+
BA,"Bosnia and Herzegovina"
|
19
|
+
BB,"Barbados"
|
20
|
+
BD,"Bangladesh"
|
21
|
+
BE,"Belgium"
|
22
|
+
BF,"Burkina Faso"
|
23
|
+
BG,"Bulgaria"
|
24
|
+
BH,"Bahrain"
|
25
|
+
BI,"Burundi"
|
26
|
+
BJ,"Benin"
|
27
|
+
BL,"Saint Barthélemy"
|
28
|
+
BM,"Bermuda"
|
29
|
+
BN,"Brunei Darussalam"
|
30
|
+
BO,"Bolivia, Plurinational State of"
|
31
|
+
BQ,"Bonaire, Sint Eustatius and Saba"
|
32
|
+
BR,"Brazil"
|
33
|
+
BS,"Bahamas"
|
34
|
+
BT,"Bhutan"
|
35
|
+
BV,"Bouvet Island"
|
36
|
+
BW,"Botswana"
|
37
|
+
BY,"Belarus"
|
38
|
+
BZ,"Belize"
|
39
|
+
CA,"Canada"
|
40
|
+
CC,"Cocos (Keeling) Islands"
|
41
|
+
CD,"Congo, the Democratic Republic of the"
|
42
|
+
CF,"Central African Republic"
|
43
|
+
CG,"Congo"
|
44
|
+
CH,"Switzerland"
|
45
|
+
CI,"Côte d'Ivoire"
|
46
|
+
CK,"Cook Islands"
|
47
|
+
CL,"Chile"
|
48
|
+
CM,"Cameroon"
|
49
|
+
CN,"China"
|
50
|
+
CO,"Colombia"
|
51
|
+
CR,"Costa Rica"
|
52
|
+
CU,"Cuba"
|
53
|
+
CV,"Cape Verde"
|
54
|
+
CW,"Curaçao"
|
55
|
+
CX,"Christmas Island"
|
56
|
+
CY,"Cyprus"
|
57
|
+
CZ,"Czech Republic"
|
58
|
+
DE,"Germany"
|
59
|
+
DJ,"Djibouti"
|
60
|
+
DK,"Denmark"
|
61
|
+
DM,"Dominica"
|
62
|
+
DO,"Dominican Republic"
|
63
|
+
DZ,"Algeria"
|
64
|
+
EC,"Ecuador"
|
65
|
+
EE,"Estonia"
|
66
|
+
EG,"Egypt"
|
67
|
+
EH,"Western Sahara"
|
68
|
+
ER,"Eritrea"
|
69
|
+
ES,"Spain"
|
70
|
+
ET,"Ethiopia"
|
71
|
+
FI,"Finland"
|
72
|
+
FJ,"Fiji"
|
73
|
+
FK,"Falkland Islands (Malvinas)"
|
74
|
+
FM,"Micronesia, Federated States of"
|
75
|
+
FO,"Faroe Islands"
|
76
|
+
FR,"France"
|
77
|
+
GA,"Gabon"
|
78
|
+
GB,"United Kingdom"
|
79
|
+
GD,"Grenada"
|
80
|
+
GE,"Georgia"
|
81
|
+
GF,"French Guiana"
|
82
|
+
GG,"Guernsey"
|
83
|
+
GH,"Ghana"
|
84
|
+
GI,"Gibraltar"
|
85
|
+
GL,"Greenland"
|
86
|
+
GM,"Gambia"
|
87
|
+
GN,"Guinea"
|
88
|
+
GP,"Guadeloupe"
|
89
|
+
GQ,"Equatorial Guinea"
|
90
|
+
GR,"Greece"
|
91
|
+
GS,"South Georgia and the South Sandwich Islands"
|
92
|
+
GT,"Guatemala"
|
93
|
+
GU,"Guam"
|
94
|
+
GW,"Guinea-Bissau"
|
95
|
+
GY,"Guyana"
|
96
|
+
HK,"Hong Kong"
|
97
|
+
HM,"Heard Island and McDonald Islands"
|
98
|
+
HN,"Honduras"
|
99
|
+
HR,"Croatia"
|
100
|
+
HT,"Haiti"
|
101
|
+
HU,"Hungary"
|
102
|
+
ID,"Indonesia"
|
103
|
+
IE,"Ireland"
|
104
|
+
IL,"Israel"
|
105
|
+
IM,"Isle of Man"
|
106
|
+
IN,"India"
|
107
|
+
IO,"British Indian Ocean Territory"
|
108
|
+
IQ,"Iraq"
|
109
|
+
IR,"Iran, Islamic Republic of"
|
110
|
+
IS,"Iceland"
|
111
|
+
IT,"Italy"
|
112
|
+
JE,"Jersey"
|
113
|
+
JM,"Jamaica"
|
114
|
+
JO,"Jordan"
|
115
|
+
JP,"Japan"
|
116
|
+
KE,"Kenya"
|
117
|
+
KG,"Kyrgyzstan"
|
118
|
+
KH,"Cambodia"
|
119
|
+
KI,"Kiribati"
|
120
|
+
KM,"Comoros"
|
121
|
+
KN,"Saint Kitts and Nevis"
|
122
|
+
KP,"Korea, Democratic People's Republic of"
|
123
|
+
KR,"Korea, Republic of"
|
124
|
+
KW,"Kuwait"
|
125
|
+
KY,"Cayman Islands"
|
126
|
+
KZ,"Kazakhstan"
|
127
|
+
LA,"Lao People's Democratic Republic"
|
128
|
+
LB,"Lebanon"
|
129
|
+
LC,"Saint Lucia"
|
130
|
+
LI,"Liechtenstein"
|
131
|
+
LK,"Sri Lanka"
|
132
|
+
LR,"Liberia"
|
133
|
+
LS,"Lesotho"
|
134
|
+
LT,"Lithuania"
|
135
|
+
LU,"Luxembourg"
|
136
|
+
LV,"Latvia"
|
137
|
+
LY,"Libya"
|
138
|
+
MA,"Morocco"
|
139
|
+
MC,"Monaco"
|
140
|
+
MD,"Moldova, Republic of"
|
141
|
+
ME,"Montenegro"
|
142
|
+
MF,"Saint Martin (French part)"
|
143
|
+
MG,"Madagascar"
|
144
|
+
MH,"Marshall Islands"
|
145
|
+
MK,"Macedonia, the former Yugoslav Republic of"
|
146
|
+
ML,"Mali"
|
147
|
+
MM,"Myanmar"
|
148
|
+
MN,"Mongolia"
|
149
|
+
MO,"Macao"
|
150
|
+
MP,"Northern Mariana Islands"
|
151
|
+
MQ,"Martinique"
|
152
|
+
MR,"Mauritania"
|
153
|
+
MS,"Montserrat"
|
154
|
+
MT,"Malta"
|
155
|
+
MU,"Mauritius"
|
156
|
+
MV,"Maldives"
|
157
|
+
MW,"Malawi"
|
158
|
+
MX,"Mexico"
|
159
|
+
MY,"Malaysia"
|
160
|
+
MZ,"Mozambique"
|
161
|
+
NA,"Namibia"
|
162
|
+
NC,"New Caledonia"
|
163
|
+
NE,"Niger"
|
164
|
+
NF,"Norfolk Island"
|
165
|
+
NG,"Nigeria"
|
166
|
+
NI,"Nicaragua"
|
167
|
+
NL,"Netherlands"
|
168
|
+
NO,"Norway"
|
169
|
+
NP,"Nepal"
|
170
|
+
NR,"Nauru"
|
171
|
+
NU,"Niue"
|
172
|
+
NZ,"New Zealand"
|
173
|
+
OM,"Oman"
|
174
|
+
PA,"Panama"
|
175
|
+
PE,"Peru"
|
176
|
+
PF,"French Polynesia"
|
177
|
+
PG,"Papua New Guinea"
|
178
|
+
PH,"Philippines"
|
179
|
+
PK,"Pakistan"
|
180
|
+
PL,"Poland"
|
181
|
+
PM,"Saint Pierre and Miquelon"
|
182
|
+
PN,"Pitcairn"
|
183
|
+
PR,"Puerto Rico"
|
184
|
+
PS,"Palestine, State of"
|
185
|
+
PT,"Portugal"
|
186
|
+
PW,"Palau"
|
187
|
+
PY,"Paraguay"
|
188
|
+
QA,"Qatar"
|
189
|
+
RE,"Réunion"
|
190
|
+
RO,"Romania"
|
191
|
+
RS,"Serbia"
|
192
|
+
RU,"Russian Federation"
|
193
|
+
RW,"Rwanda"
|
194
|
+
SA,"Saudi Arabia"
|
195
|
+
SB,"Solomon Islands"
|
196
|
+
SC,"Seychelles"
|
197
|
+
SD,"Sudan"
|
198
|
+
SE,"Sweden"
|
199
|
+
SG,"Singapore"
|
200
|
+
SH,"Saint Helena, Ascension and Tristan da Cunha"
|
201
|
+
SI,"Slovenia"
|
202
|
+
SJ,"Svalbard and Jan Mayen"
|
203
|
+
SK,"Slovakia"
|
204
|
+
SL,"Sierra Leone"
|
205
|
+
SM,"San Marino"
|
206
|
+
SN,"Senegal"
|
207
|
+
SO,"Somalia"
|
208
|
+
SR,"Suriname"
|
209
|
+
SS,"South Sudan"
|
210
|
+
ST,"Sao Tome and Principe"
|
211
|
+
SV,"El Salvador"
|
212
|
+
SX,"Sint Maarten (Dutch part)"
|
213
|
+
SY,"Syrian Arab Republic"
|
214
|
+
SZ,"Swaziland"
|
215
|
+
TC,"Turks and Caicos Islands"
|
216
|
+
TD,"Chad"
|
217
|
+
TF,"French Southern Territories"
|
218
|
+
TG,"Togo"
|
219
|
+
TH,"Thailand"
|
220
|
+
TJ,"Tajikistan"
|
221
|
+
TK,"Tokelau"
|
222
|
+
TL,"Timor-Leste"
|
223
|
+
TM,"Turkmenistan"
|
224
|
+
TN,"Tunisia"
|
225
|
+
TO,"Tonga"
|
226
|
+
TR,"Turkey"
|
227
|
+
TT,"Trinidad and Tobago"
|
228
|
+
TV,"Tuvalu"
|
229
|
+
TW,"Taiwan, Province of China"
|
230
|
+
TZ,"Tanzania, United Republic of"
|
231
|
+
UA,"Ukraine"
|
232
|
+
UG,"Uganda"
|
233
|
+
UM,"United States Minor Outlying Islands"
|
234
|
+
US,"United States"
|
235
|
+
UY,"Uruguay"
|
236
|
+
UZ,"Uzbekistan"
|
237
|
+
VA,"Holy See (Vatican City State)"
|
238
|
+
VC,"Saint Vincent and the Grenadines"
|
239
|
+
VE,"Venezuela, Bolivarian Republic of"
|
240
|
+
VG,"Virgin Islands, British"
|
241
|
+
VI,"Virgin Islands, U.S."
|
242
|
+
VN,"Viet Nam"
|
243
|
+
VU,"Vanuatu"
|
244
|
+
WF,"Wallis and Futuna"
|
245
|
+
WS,"Samoa"
|
246
|
+
YE,"Yemen"
|
247
|
+
YT,"Mayotte"
|
248
|
+
ZA,"South Africa"
|
249
|
+
ZM,"Zambia"
|