data_seeder 0.0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|