worlddb 1.6.4 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Manifest.txt +2 -0
- data/lib/worlddb/models/city.rb +154 -0
- data/lib/worlddb/models/country.rb +155 -0
- data/lib/worlddb/models/region.rb +113 -1
- data/lib/worlddb/reader.rb +49 -315
- data/lib/worlddb/utils.rb +36 -0
- data/lib/worlddb/version.rb +1 -1
- data/lib/worlddb.rb +1 -1
- data/test/helper.rb +56 -0
- data/test/test_values.rb +114 -0
- metadata +17 -13
data/.gemtest
ADDED
File without changes
|
data/Manifest.txt
CHANGED
data/lib/worlddb/models/city.rb
CHANGED
@@ -3,6 +3,14 @@
|
|
3
3
|
module WorldDb::Models
|
4
4
|
|
5
5
|
class City < ActiveRecord::Base
|
6
|
+
|
7
|
+
extend WorldDb::TagHelper # will add self.find_tags, self.find_tags_in_hash!, etc.
|
8
|
+
|
9
|
+
# NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
|
10
|
+
# self.create_or_update_from_values
|
11
|
+
extend TextUtils::ValueHelper # e.g. is_year?, is_region?, is_address?, is_taglist? etc.
|
12
|
+
|
13
|
+
|
6
14
|
self.table_name = 'cities'
|
7
15
|
|
8
16
|
belongs_to :country, :class_name => 'Country', :foreign_key => 'country_id'
|
@@ -109,6 +117,152 @@ class City < ActiveRecord::Base
|
|
109
117
|
end # each city
|
110
118
|
end
|
111
119
|
|
120
|
+
|
121
|
+
def self.create_or_update_from_titles( titles, more_attributes = {} ) # ary of titles e.g. ['Wien', 'Graz'] etc.
|
122
|
+
|
123
|
+
# fix: add/configure logger for ActiveRecord!!!
|
124
|
+
logger = LogKernel::Logger.root
|
125
|
+
|
126
|
+
titles.each do |title|
|
127
|
+
|
128
|
+
new_attributes = {}
|
129
|
+
key = TextUtils.title_to_key( title ) # auto generate key from title
|
130
|
+
|
131
|
+
# check if it exists
|
132
|
+
# todo/fix: add country_id for lookup?
|
133
|
+
city = City.find_by_key( key )
|
134
|
+
if city.present?
|
135
|
+
logger.debug "update city #{city.id}-#{city.key}:"
|
136
|
+
else
|
137
|
+
logger.debug "create city:"
|
138
|
+
city = City.new
|
139
|
+
new_attributes[ :key ] = key
|
140
|
+
end
|
141
|
+
|
142
|
+
new_attributes[ :title ] = title
|
143
|
+
|
144
|
+
## merge in passed in attribes (e.g. country_id etc.)
|
145
|
+
new_attributes.merge!( more_attributes )
|
146
|
+
|
147
|
+
logger.debug new_attributes.to_json
|
148
|
+
|
149
|
+
city.update_attributes!( new_attributes )
|
150
|
+
|
151
|
+
### todo/fix: add captial ref to country/region
|
152
|
+
end # each city
|
153
|
+
end # method create_or_update_from_titles
|
154
|
+
|
155
|
+
|
156
|
+
def self.create_or_update_from_values( new_attributes, values, opts={} )
|
157
|
+
|
158
|
+
## opts e.g. :skip_tags true|false
|
159
|
+
|
160
|
+
## fix: add/configure logger for ActiveRecord!!!
|
161
|
+
logger = LogKernel::Logger.root
|
162
|
+
|
163
|
+
value_numbers = []
|
164
|
+
value_tag_keys = []
|
165
|
+
|
166
|
+
### check for "default" tags - that is, if present new_attributes[:tags] remove from hash
|
167
|
+
value_tag_keys += find_tags_in_hash!( new_attributes )
|
168
|
+
|
169
|
+
new_attributes[ :c ] = true # assume city type by default (use metro,district to change in fixture)
|
170
|
+
|
171
|
+
## check for optional values
|
172
|
+
values.each_with_index do |value,index|
|
173
|
+
if value =~ /^region:/ ## region:
|
174
|
+
value_region_key = value[7..-1] ## cut off region: prefix
|
175
|
+
## NB: requires country_id to make unique!
|
176
|
+
value_region = Region.find_by_key_and_country_id!( value_region_key, new_attributes[:country_id] )
|
177
|
+
new_attributes[ :region_id ] = value_region.id
|
178
|
+
elsif value =~ /^metro$/ ## metro(politan area)
|
179
|
+
new_attributes[ :c ] = false # turn off default c|city flag; make it m|metro only
|
180
|
+
new_attributes[ :m ] = true
|
181
|
+
elsif value =~ /^country:/ ## country:
|
182
|
+
value_country_key = value[8..-1] ## cut off country: prefix
|
183
|
+
value_country = Country.find_by_key!( value_country_key )
|
184
|
+
new_attributes[ :country_id ] = value_country.id
|
185
|
+
elsif value =~ /^metro:/ ## metro:
|
186
|
+
value_city_key = value[6..-1] ## cut off metro: prefix
|
187
|
+
value_city = City.find_by_key!( value_city_key )
|
188
|
+
new_attributes[ :city_id ] = value_city.id
|
189
|
+
elsif value =~ /^city:/ ## city:
|
190
|
+
value_city_key = value[5..-1] ## cut off city: prefix
|
191
|
+
value_city = City.find_by_key!( value_city_key )
|
192
|
+
new_attributes[ :city_id ] = value_city.id
|
193
|
+
new_attributes[ :c ] = false # turn off default c|city flag; make it d|district only
|
194
|
+
new_attributes[ :d ] = true
|
195
|
+
elsif value =~ /^m:/ ## m:
|
196
|
+
value_popm_str = value[2..-1] ## cut off m: prefix
|
197
|
+
value_popm = value_popm_str.gsub(/[ _]/, '').to_i
|
198
|
+
new_attributes[ :popm ] = value_popm
|
199
|
+
new_attributes[ :m ] = true # auto-mark city as m|metro too
|
200
|
+
elsif is_region?( value ) ## assume region code e.g. TX for city
|
201
|
+
value_region = Region.find_by_key_and_country_id!( value.downcase, new_attributes[:country_id] )
|
202
|
+
new_attributes[ :region_id ] = value_region.id
|
203
|
+
elsif value =~ /^[A-Z]{2,3}$/ ## assume two or three-letter code
|
204
|
+
new_attributes[ :code ] = value
|
205
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9]|[0-9]{1,2})(?:\s*(?:km2|km²)\s*)$/
|
206
|
+
## allow numbers like 453 km²
|
207
|
+
value_numbers << value.gsub( 'km2', '').gsub( 'km²', '' ).gsub(/[ _]/, '').to_i
|
208
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9])|([0-9]{1,2})$/ ## numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
|
209
|
+
value_numbers << value.gsub(/[ _]/, '').to_i
|
210
|
+
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
211
|
+
logger.debug " found tags: >>#{value}<<"
|
212
|
+
value_tag_keys += find_tags( value )
|
213
|
+
else
|
214
|
+
# issue warning: unknown type for value
|
215
|
+
logger.warn "unknown type for value >#{value}<"
|
216
|
+
end
|
217
|
+
end # each value
|
218
|
+
|
219
|
+
if value_numbers.size > 0
|
220
|
+
new_attributes[ :pop ] = value_numbers[0] # assume first number is pop for cities
|
221
|
+
new_attributes[ :area ] = value_numbers[1]
|
222
|
+
end # if value_numbers.size > 0
|
223
|
+
|
224
|
+
rec = City.find_by_key( new_attributes[ :key ] )
|
225
|
+
|
226
|
+
if rec.present?
|
227
|
+
logger.debug "update City #{rec.id}-#{rec.key}:"
|
228
|
+
else
|
229
|
+
logger.debug "create City:"
|
230
|
+
rec = City.new
|
231
|
+
end
|
232
|
+
|
233
|
+
logger.debug new_attributes.to_json
|
234
|
+
|
235
|
+
rec.update_attributes!( new_attributes )
|
236
|
+
|
237
|
+
##################
|
238
|
+
## add taggings
|
239
|
+
|
240
|
+
## todo/fix: reuse - move add taggings into method etc.
|
241
|
+
|
242
|
+
if value_tag_keys.size > 0
|
243
|
+
|
244
|
+
if opts[:skip_tags].present?
|
245
|
+
logger.debug " skipping add taggings (flag skip_tag)"
|
246
|
+
else
|
247
|
+
value_tag_keys.uniq! # remove duplicates
|
248
|
+
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
249
|
+
|
250
|
+
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
251
|
+
|
252
|
+
value_tag_keys.each do |key|
|
253
|
+
tag = Tag.find_by_key( key )
|
254
|
+
if tag.nil? # create tag if it doesn't exit
|
255
|
+
logger.debug " creating tag >#{key}<"
|
256
|
+
tag = Tag.create!( key: key )
|
257
|
+
end
|
258
|
+
rec.tags << tag
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
rec
|
264
|
+
end # method create_or_update_from_values
|
265
|
+
|
112
266
|
end # class Cities
|
113
267
|
|
114
268
|
end # module WorldDb::Models
|
@@ -3,6 +3,14 @@
|
|
3
3
|
module WorldDb::Models
|
4
4
|
|
5
5
|
class Country < ActiveRecord::Base
|
6
|
+
|
7
|
+
extend WorldDb::TagHelper # will add self.find_tags, self.find_tags_in_hash!, etc.
|
8
|
+
|
9
|
+
# NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
|
10
|
+
# self.create_or_update_from_values
|
11
|
+
extend TextUtils::ValueHelper # e.g. is_year?, is_region?, is_address?, is_taglist? etc.
|
12
|
+
|
13
|
+
|
6
14
|
self.table_name = 'countries'
|
7
15
|
|
8
16
|
belongs_to :continent, :class_name => 'Continent', :foreign_key => 'continent_id'
|
@@ -95,6 +103,153 @@ class Country < ActiveRecord::Base
|
|
95
103
|
end # each country
|
96
104
|
end
|
97
105
|
|
106
|
+
|
107
|
+
def self.create_or_update_from_values( new_attributes, values, opts={} )
|
108
|
+
|
109
|
+
## opts e.g. :skip_tags true|false
|
110
|
+
|
111
|
+
## fix: add/configure logger for ActiveRecord!!!
|
112
|
+
logger = LogKernel::Logger.root
|
113
|
+
|
114
|
+
value_numbers = []
|
115
|
+
value_tag_keys = []
|
116
|
+
value_cities = []
|
117
|
+
|
118
|
+
### check for "default" tags - that is, if present new_attributes[:tags] remove from hash
|
119
|
+
value_tag_keys += find_tags_in_hash!( new_attributes )
|
120
|
+
|
121
|
+
|
122
|
+
new_attributes[ :c ] = true # assume country type by default (use supra,depend to change)
|
123
|
+
|
124
|
+
## check for optional values
|
125
|
+
values.each_with_index do |value,index|
|
126
|
+
if value =~ /^supra$/ ## supra(national)
|
127
|
+
new_attributes[ :c ] = false # turn off default c|country flag; make it s|supra only
|
128
|
+
new_attributes[ :s ] = true
|
129
|
+
## auto-add tag supra
|
130
|
+
value_tag_keys << 'supra'
|
131
|
+
elsif value =~ /^supra:/ ## supra:
|
132
|
+
value_country_key = value[6..-1] ## cut off supra: prefix
|
133
|
+
value_country = Country.find_by_key!( value_country_key )
|
134
|
+
new_attributes[ :country_id ] = value_country.id
|
135
|
+
elsif value =~ /^country:/ ## country:
|
136
|
+
value_country_key = value[8..-1] ## cut off country: prefix
|
137
|
+
value_country = Country.find_by_key!( value_country_key )
|
138
|
+
new_attributes[ :country_id ] = value_country.id
|
139
|
+
new_attributes[ :c ] = false # turn off default c|country flag; make it d|depend only
|
140
|
+
new_attributes[ :d ] = true
|
141
|
+
## auto-add tag supra
|
142
|
+
value_tag_keys << 'territory' # rename tag to dependency? why? why not?
|
143
|
+
elsif value =~ /^[A-Z]{2,3}$/ ## assume two or three-letter code
|
144
|
+
new_attributes[ :code ] = value
|
145
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9]|[0-9]{1,2})(?:\s*(?:km2|km²)\s*)$/
|
146
|
+
## allow numbers like 453 km²
|
147
|
+
value_numbers << value.gsub( 'km2', '').gsub( 'km²', '' ).gsub(/[ _]/, '').to_i
|
148
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9])|([0-9]{1,2})$/ ## numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
|
149
|
+
value_numbers << value.gsub(/[ _]/, '').to_i
|
150
|
+
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
151
|
+
logger.debug " found tags: >>#{value}<<"
|
152
|
+
value_tag_keys += find_tags( value )
|
153
|
+
else
|
154
|
+
|
155
|
+
### assume it is the capital city - mark it for auto add
|
156
|
+
value_cities << value
|
157
|
+
next
|
158
|
+
|
159
|
+
# issue warning: unknown type for value
|
160
|
+
# logger.warn "unknown type for value >#{value}<"
|
161
|
+
end
|
162
|
+
end # each value
|
163
|
+
|
164
|
+
if value_numbers.size > 0
|
165
|
+
new_attributes[ :area ] = value_numbers[0]
|
166
|
+
new_attributes[ :pop ] = value_numbers[1]
|
167
|
+
end
|
168
|
+
|
169
|
+
=begin
|
170
|
+
# auto-add tags
|
171
|
+
area = value_numbers[0]
|
172
|
+
pop = value_numbers[1]
|
173
|
+
|
174
|
+
# categorize into brackets
|
175
|
+
if area >= 1_000_000
|
176
|
+
value_tag_keys << 'area_1_000_000_n_up'
|
177
|
+
elsif area >= 100_000
|
178
|
+
value_tag_keys << 'area_100_000_to_1_000_000'
|
179
|
+
elsif area >= 1000
|
180
|
+
value_tag_keys << 'area_1_000_to_100_000'
|
181
|
+
else
|
182
|
+
value_tag_keys << 'area_1_000_n_less' # microstate
|
183
|
+
end
|
184
|
+
|
185
|
+
# include all
|
186
|
+
value_tag_keys << 'area_100_000_n_up' if area >= 100_000
|
187
|
+
value_tag_keys << 'area_1_000_n_up' if area >= 1_000
|
188
|
+
|
189
|
+
|
190
|
+
# categorize into brackets
|
191
|
+
if pop >= 100_000_000
|
192
|
+
value_tag_keys << 'pop_100m_n_up'
|
193
|
+
elsif pop >= 10_000_000
|
194
|
+
value_tag_keys << 'pop_10m_to_100m'
|
195
|
+
elsif pop >= 1_000_000
|
196
|
+
value_tag_keys << 'pop_1m_to_10m'
|
197
|
+
else
|
198
|
+
value_tag_keys << 'pop_1m_n_less'
|
199
|
+
end
|
200
|
+
|
201
|
+
# include all
|
202
|
+
value_tag_keys << 'pop_10m_n_up' if pop >= 10_000_000
|
203
|
+
value_tag_keys << 'pop_1m_n_up' if pop >= 1_000_000
|
204
|
+
=end
|
205
|
+
|
206
|
+
rec = Country.find_by_key( new_attributes[ :key ] )
|
207
|
+
|
208
|
+
if rec.present?
|
209
|
+
logger.debug "update Country #{rec.id}-#{rec.key}:"
|
210
|
+
else
|
211
|
+
logger.debug "create Country:"
|
212
|
+
rec = Country.new
|
213
|
+
end
|
214
|
+
|
215
|
+
logger.debug new_attributes.to_json
|
216
|
+
|
217
|
+
rec.update_attributes!( new_attributes )
|
218
|
+
|
219
|
+
#################
|
220
|
+
## auto add capital cities
|
221
|
+
|
222
|
+
City.create_or_update_from_titles( value_cities, country_id: rec.id )
|
223
|
+
|
224
|
+
##################
|
225
|
+
## add taggings
|
226
|
+
|
227
|
+
if value_tag_keys.size > 0
|
228
|
+
|
229
|
+
if opts[:skip_tags].present?
|
230
|
+
logger.debug " skipping add taggings (flag skip_tag)"
|
231
|
+
else
|
232
|
+
value_tag_keys.uniq! # remove duplicates
|
233
|
+
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
234
|
+
|
235
|
+
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
236
|
+
|
237
|
+
value_tag_keys.each do |key|
|
238
|
+
tag = Tag.find_by_key( key )
|
239
|
+
if tag.nil? # create tag if it doesn't exit
|
240
|
+
logger.debug " creating tag >#{key}<"
|
241
|
+
tag = Tag.create!( key: key )
|
242
|
+
end
|
243
|
+
rec.tags << tag
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
rec
|
249
|
+
|
250
|
+
end # method create_or_update_from_values
|
251
|
+
|
252
|
+
|
98
253
|
end # class Country
|
99
254
|
|
100
255
|
|
@@ -1,7 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
module WorldDb::Models
|
2
4
|
|
3
5
|
class Region < ActiveRecord::Base
|
4
6
|
|
7
|
+
extend WorldDb::TagHelper # will add self.find_tags, self.find_tags_in_hash!, etc.
|
8
|
+
|
9
|
+
# NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
|
10
|
+
# self.create_or_update_from_values
|
11
|
+
extend TextUtils::ValueHelper # e.g. is_year?, is_region?, is_address?, is_taglist? etc.
|
12
|
+
|
13
|
+
|
5
14
|
belongs_to :country, :class_name => 'Country', :foreign_key => 'country_id'
|
6
15
|
|
7
16
|
has_many :cities, :class_name => 'City', :foreign_key => 'region_id'
|
@@ -9,7 +18,7 @@ class Region < ActiveRecord::Base
|
|
9
18
|
has_many :taggings, :as => :taggable
|
10
19
|
has_many :tags, :through => :taggings
|
11
20
|
|
12
|
-
validates :key, :format => { :with => /^[a-z]
|
21
|
+
validates :key, :format => { :with => /^[a-z]+$/, :message => 'expected one or more lowercase letters a-z' }
|
13
22
|
validates :code, :format => { :with => /^[A-Z_]{2,3}$/, :message => 'expected two or three uppercase letters A-Z (and _)' }, :allow_nil => true
|
14
23
|
|
15
24
|
|
@@ -48,6 +57,109 @@ class Region < ActiveRecord::Base
|
|
48
57
|
end # each region
|
49
58
|
end
|
50
59
|
|
60
|
+
|
61
|
+
def self.create_or_update_from_values( new_attributes, values, opts={} )
|
62
|
+
|
63
|
+
## opts e.g. :skip_tags true|false
|
64
|
+
|
65
|
+
## fix: add/configure logger for ActiveRecord!!!
|
66
|
+
logger = LogKernel::Logger.root
|
67
|
+
|
68
|
+
value_numbers = []
|
69
|
+
value_tag_keys = []
|
70
|
+
value_cities = []
|
71
|
+
|
72
|
+
### check for "default" tags - that is, if present new_attributes[:tags] remove from hash
|
73
|
+
value_tag_keys += find_tags_in_hash!( new_attributes )
|
74
|
+
|
75
|
+
## check for optional values
|
76
|
+
values.each_with_index do |value,index|
|
77
|
+
if value =~ /^country:/ ## country:
|
78
|
+
value_country_key = value[8..-1] ## cut off country: prefix
|
79
|
+
value_country = Country.find_by_key!( value_country_key )
|
80
|
+
new_attributes[ :country_id ] = value_country.id
|
81
|
+
elsif value =~ /^[A-Z]{2,3}$/ ## assume two or three-letter code
|
82
|
+
new_attributes[ :code ] = value
|
83
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9]|[0-9]{1,2})(?:\s*(?:km2|km²)\s*)$/
|
84
|
+
## allow numbers like 453 km²
|
85
|
+
value_numbers << value.gsub( 'km2', '').gsub( 'km²', '' ).gsub(/[ _]/, '').to_i
|
86
|
+
elsif value =~ /^([0-9][0-9 _]+[0-9])|([0-9]{1,2})$/ ## numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
|
87
|
+
value_numbers << value.gsub(/[ _]/, '').to_i
|
88
|
+
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
89
|
+
logger.debug " found tags: >>#{value}<<"
|
90
|
+
value_tag_keys += find_tags( value )
|
91
|
+
else
|
92
|
+
|
93
|
+
### assume it is the capital city - mark it for auto add
|
94
|
+
value_cities << value
|
95
|
+
next
|
96
|
+
|
97
|
+
# issue warning: unknown type for value
|
98
|
+
# logger.warn "unknown type for value >#{value}<"
|
99
|
+
end
|
100
|
+
end # each value
|
101
|
+
|
102
|
+
if value_numbers.size > 0
|
103
|
+
new_attributes[ :area ] = value_numbers[0]
|
104
|
+
new_attributes[ :pop ] = value_numbers[1]
|
105
|
+
end # if value_numbers.size > 0
|
106
|
+
|
107
|
+
## todo: assert that country_id is present/valid, that is, NOT null
|
108
|
+
rec = Region.find_by_key_and_country_id( new_attributes[ :key ], new_attributes[ :country_id] )
|
109
|
+
|
110
|
+
if rec.present?
|
111
|
+
logger.debug "update Region #{rec.id}-#{rec.key}:"
|
112
|
+
else
|
113
|
+
logger.debug "create Region:"
|
114
|
+
rec = Region.new
|
115
|
+
end
|
116
|
+
|
117
|
+
logger.debug new_attributes.to_json
|
118
|
+
|
119
|
+
rec.update_attributes!( new_attributes )
|
120
|
+
|
121
|
+
#################
|
122
|
+
# auto add capital cities
|
123
|
+
|
124
|
+
City.create_or_update_from_titles( value_cities,
|
125
|
+
region_id: rec.id,
|
126
|
+
country_id: rec.country_id )
|
127
|
+
|
128
|
+
### todo/fix: add captial ref to country/region
|
129
|
+
|
130
|
+
|
131
|
+
##################
|
132
|
+
# add taggings
|
133
|
+
|
134
|
+
## todo/fix: reuse - move add taggings into method etc.
|
135
|
+
|
136
|
+
if value_tag_keys.size > 0
|
137
|
+
|
138
|
+
if opts[:skip_tags].present?
|
139
|
+
logger.debug " skipping add taggings (flag skip_tag)"
|
140
|
+
else
|
141
|
+
value_tag_keys.uniq! # remove duplicates
|
142
|
+
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
143
|
+
|
144
|
+
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
145
|
+
|
146
|
+
value_tag_keys.each do |key|
|
147
|
+
tag = Tag.find_by_key( key )
|
148
|
+
if tag.nil? # create tag if it doesn't exit
|
149
|
+
logger.debug " creating tag >#{key}<"
|
150
|
+
tag = Tag.create!( key: key )
|
151
|
+
end
|
152
|
+
rec.tags << tag
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
rec
|
158
|
+
|
159
|
+
end # method create_or_update_from_values
|
160
|
+
|
161
|
+
|
162
|
+
|
51
163
|
end # class Region
|
52
164
|
|
53
165
|
end # module WorldDb::Models
|
data/lib/worlddb/reader.rb
CHANGED
@@ -2,6 +2,40 @@
|
|
2
2
|
|
3
3
|
module WorldDb
|
4
4
|
|
5
|
+
|
6
|
+
### fix: move to textutils
|
7
|
+
## PlusReaderWrapper find a better name than Plus?
|
8
|
+
#
|
9
|
+
# todo: also add a ValuesReaderPlus and use it
|
10
|
+
|
11
|
+
class HashReaderPlus
|
12
|
+
include LogUtils::Logging
|
13
|
+
|
14
|
+
def initialize( name, include_path )
|
15
|
+
@name = name
|
16
|
+
@include_path = include_path
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :name
|
20
|
+
attr_reader :include_path
|
21
|
+
|
22
|
+
def each
|
23
|
+
path = "#{include_path}/#{name}.yml"
|
24
|
+
reader = HashReader.new( path )
|
25
|
+
|
26
|
+
logger.info "parsing data '#{name}' (#{path})..."
|
27
|
+
|
28
|
+
reader.each do |key, value|
|
29
|
+
yield( key, value )
|
30
|
+
end
|
31
|
+
Prop.create_from_fixture!( name, path )
|
32
|
+
end
|
33
|
+
|
34
|
+
end # class HashReaderPlus
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
5
39
|
class Reader
|
6
40
|
|
7
41
|
include LogUtils::Logging
|
@@ -114,22 +148,16 @@ class Reader
|
|
114
148
|
|
115
149
|
|
116
150
|
def load_regions_xxx( country_key, xxx, name )
|
117
|
-
path = "#{include_path}/#{name}.yml"
|
118
|
-
|
119
|
-
logger.info "parsing data '#{name}' (#{path})..."
|
120
|
-
|
121
151
|
country = Country.find_by_key!( country_key )
|
122
152
|
logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
|
123
153
|
|
124
|
-
reader =
|
154
|
+
reader = HashReaderPlus.new( name, include_path )
|
125
155
|
|
126
156
|
reader.each do |key, value|
|
127
157
|
region = Region.find_by_country_id_and_key!( country.id, key )
|
128
158
|
region.send( "#{xxx}=", value )
|
129
159
|
region.save!
|
130
160
|
end
|
131
|
-
|
132
|
-
Prop.create_from_fixture!( name, path )
|
133
161
|
end
|
134
162
|
|
135
163
|
|
@@ -141,27 +169,8 @@ class Reader
|
|
141
169
|
end
|
142
170
|
|
143
171
|
|
144
|
-
|
145
|
-
def with_path_for( name )
|
146
|
-
## todo: find a better name?
|
147
|
-
# e.g. find_path_for or open_fixture_for ??
|
148
|
-
|
149
|
-
path = "#{include_path}/#{name}.yml"
|
150
|
-
|
151
|
-
logger.info "parsing data '#{name}' (#{path})..."
|
152
|
-
|
153
|
-
yield( path )
|
154
|
-
|
155
|
-
Prop.create_from_fixture!( name, path )
|
156
|
-
end
|
157
|
-
|
158
|
-
|
159
172
|
def load_continent_refs( name )
|
160
|
-
|
161
|
-
|
162
|
-
logger.info "parsing data '#{name}' (#{path})..."
|
163
|
-
|
164
|
-
reader = HashReader.new( path )
|
173
|
+
reader = HashReaderPlus.new( name, include_path )
|
165
174
|
|
166
175
|
reader.each do |key, value|
|
167
176
|
country = Country.find_by_key!( key )
|
@@ -169,10 +178,9 @@ class Reader
|
|
169
178
|
country.continent_id = continent.id
|
170
179
|
country.save!
|
171
180
|
end
|
172
|
-
|
173
|
-
Prop.create_from_fixture!( name, path )
|
174
181
|
end
|
175
182
|
|
183
|
+
|
176
184
|
def load_continent_defs( name, more_values={} )
|
177
185
|
path = "#{include_path}/#{name}.txt"
|
178
186
|
|
@@ -208,11 +216,9 @@ class Reader
|
|
208
216
|
|
209
217
|
def load_langs( name )
|
210
218
|
|
211
|
-
|
212
|
-
|
213
|
-
reader = HashReader.new( path )
|
219
|
+
reader = HashReaderPlus.new( name, include_path )
|
214
220
|
|
215
|
-
|
221
|
+
reader.each do |key, value|
|
216
222
|
|
217
223
|
logger.debug "adding lang >>#{key}<< >>#{value}<<..."
|
218
224
|
|
@@ -236,17 +242,14 @@ class Reader
|
|
236
242
|
logger.debug lang_attribs.to_json
|
237
243
|
|
238
244
|
lang.update_attributes!( lang_attribs )
|
239
|
-
|
240
|
-
end # with_path_for
|
245
|
+
end # each key,value
|
241
246
|
|
242
247
|
end # method load_langs
|
243
248
|
|
244
249
|
|
245
250
|
def load_tags( name, more_values={} )
|
246
251
|
|
247
|
-
|
248
|
-
|
249
|
-
reader = HashReader.new( path )
|
252
|
+
reader = HashReaderPlus.new( name, include_path )
|
250
253
|
|
251
254
|
grade = 1
|
252
255
|
|
@@ -291,19 +294,13 @@ class Reader
|
|
291
294
|
|
292
295
|
tag.update_attributes!( tag_attribs )
|
293
296
|
end
|
294
|
-
|
295
|
-
|
296
|
-
end # with_path_for
|
297
|
-
|
297
|
+
end # each key,value
|
298
|
+
|
298
299
|
end # method load_tags
|
299
300
|
|
300
301
|
|
301
302
|
def load_usages( name )
|
302
|
-
|
303
|
-
|
304
|
-
logger.info "parsing data '#{name}' (#{path})..."
|
305
|
-
|
306
|
-
reader = HashReader.new( path )
|
303
|
+
reader = HashReaderPlus.new( name, include_path )
|
307
304
|
|
308
305
|
reader.each do |key, value|
|
309
306
|
logger.debug " adding langs >>#{value}<<to country >>#{key}<<"
|
@@ -322,28 +319,19 @@ class Reader
|
|
322
319
|
Usage.create!( country_id: country.id, lang_id: lang.id, official: true, minor: false )
|
323
320
|
end
|
324
321
|
end
|
325
|
-
|
326
|
-
Prop.create_from_fixture!( name, path )
|
327
322
|
end
|
328
323
|
|
329
324
|
|
330
325
|
def load_xxx( xxx, name )
|
331
|
-
|
332
|
-
|
333
|
-
logger.info "parsing data '#{name}' (#{path})..."
|
334
|
-
|
335
|
-
reader = HashReader.new( path )
|
326
|
+
reader = HashReaderPlus.new( name, include_path )
|
336
327
|
|
337
328
|
reader.each do |key, value|
|
338
329
|
country = Country.find_by_key!( key )
|
339
330
|
country.send( "#{xxx}=", value )
|
340
331
|
country.save!
|
341
332
|
end
|
342
|
-
|
343
|
-
Prop.create_from_fixture!( name, path )
|
344
333
|
end
|
345
334
|
|
346
|
-
|
347
335
|
private
|
348
336
|
def load_fixtures_for( clazz, name, more_values={} ) # load from file system
|
349
337
|
path = "#{include_path}/#{name}.txt"
|
@@ -352,267 +340,13 @@ private
|
|
352
340
|
|
353
341
|
reader = ValuesReader.new( path, more_values )
|
354
342
|
|
355
|
-
|
343
|
+
reader.each_line do |new_attributes, values|
|
344
|
+
opts = { skip_tags: skip_tags? }
|
345
|
+
clazz.create_or_update_from_values( new_attributes, values, opts )
|
346
|
+
end
|
356
347
|
|
357
348
|
Prop.create_from_fixture!( name, path )
|
358
349
|
end
|
359
|
-
|
360
|
-
|
361
|
-
def load_fixtures_worker_for( clazz, reader )
|
362
|
-
|
363
|
-
## NB: assumes active activerecord db connection
|
364
|
-
##
|
365
|
-
|
366
|
-
reader.each_line do |attribs, values|
|
367
|
-
|
368
|
-
value_numbers = []
|
369
|
-
value_tag_keys = []
|
370
|
-
value_cities = []
|
371
|
-
|
372
|
-
### check for "default" tags - that is, if present attribs[:tags] remove from hash
|
373
|
-
|
374
|
-
if attribs[:tags].present?
|
375
|
-
more_tag_keys = attribs[:tags].split('|')
|
376
|
-
attribs.delete(:tags)
|
377
|
-
|
378
|
-
## unify; replace _w/ space; remove leading n trailing whitespace
|
379
|
-
more_tag_keys = more_tag_keys.map do |key|
|
380
|
-
key = key.gsub( '_', ' ' )
|
381
|
-
key = key.strip
|
382
|
-
key
|
383
|
-
end
|
384
|
-
|
385
|
-
value_tag_keys += more_tag_keys
|
386
|
-
end
|
387
|
-
|
388
|
-
|
389
|
-
if clazz == City
|
390
|
-
attribs[ :c ] = true # assume city type by default (use metro,district to change in fixture)
|
391
|
-
elsif clazz == Country
|
392
|
-
attribs[ :c ] = true # assume country type by default (use supra,depend to change)
|
393
|
-
end
|
394
|
-
|
395
|
-
## check for optional values
|
396
|
-
values.each_with_index do |value,index|
|
397
|
-
if value =~ /^region:/ ## region:
|
398
|
-
value_region_key = value[7..-1] ## cut off region: prefix
|
399
|
-
## NB: requires country_id to make unique!
|
400
|
-
value_region = Region.find_by_key_and_country_id!( value_region_key, attribs[:country_id] )
|
401
|
-
attribs[ :region_id ] = value_region.id
|
402
|
-
elsif value =~ /^metro$/ ## metro(politan area)
|
403
|
-
attribs[ :c ] = false # turn off default c|city flag; make it m|metro only
|
404
|
-
attribs[ :m ] = true
|
405
|
-
elsif value =~ /^supra$/ ## supra(national)
|
406
|
-
attribs[ :c ] = false # turn off default c|country flag; make it s|supra only
|
407
|
-
attribs[ :s ] = true
|
408
|
-
## auto-add tag supra
|
409
|
-
value_tag_keys << 'supra'
|
410
|
-
elsif value =~ /^supra:/ ## supra:
|
411
|
-
value_country_key = value[6..-1] ## cut off supra: prefix
|
412
|
-
value_country = Country.find_by_key!( value_country_key )
|
413
|
-
attribs[ :country_id ] = value_country.id
|
414
|
-
elsif value =~ /^country:/ ## country:
|
415
|
-
value_country_key = value[8..-1] ## cut off country: prefix
|
416
|
-
value_country = Country.find_by_key!( value_country_key )
|
417
|
-
attribs[ :country_id ] = value_country.id
|
418
|
-
attribs[ :c ] = false # turn off default c|country flag; make it d|depend only
|
419
|
-
attribs[ :d ] = true
|
420
|
-
## auto-add tag supra
|
421
|
-
value_tag_keys << 'territory' # rename tag to dependency? why? why not?
|
422
|
-
elsif value =~ /^metro:/ ## metro:
|
423
|
-
value_city_key = value[6..-1] ## cut off metro: prefix
|
424
|
-
value_city = City.find_by_key!( value_city_key )
|
425
|
-
attribs[ :city_id ] = value_city.id
|
426
|
-
elsif value =~ /^city:/ ## city:
|
427
|
-
value_city_key = value[5..-1] ## cut off city: prefix
|
428
|
-
value_city = City.find_by_key!( value_city_key )
|
429
|
-
attribs[ :city_id ] = value_city.id
|
430
|
-
attribs[ :c ] = false # turn off default c|city flag; make it d|district only
|
431
|
-
attribs[ :d ] = true
|
432
|
-
elsif value =~ /^m:/ ## m:
|
433
|
-
value_popm_str = value[2..-1] ## cut off m: prefix
|
434
|
-
value_popm = value_popm_str.gsub(/[ _]/, '').to_i
|
435
|
-
attribs[ :popm ] = value_popm
|
436
|
-
attribs[ :m ] = true # auto-mark city as m|metro too
|
437
|
-
elsif is_region?( value ) && clazz == City ## assume region code e.g. TX for city
|
438
|
-
value_region = Region.find_by_key_and_country_id!( value.downcase, attribs[:country_id] )
|
439
|
-
attribs[ :region_id ] = value_region.id
|
440
|
-
elsif value =~ /^[A-Z]{2,3}$/ ## assume two or three-letter code
|
441
|
-
attribs[ :code ] = value
|
442
|
-
elsif value =~ /^([0-9][0-9 _]+[0-9]|[0-9]{1,2})(?:\s*(?:km2|km²)\s*)$/
|
443
|
-
## allow numbers like 453 km²
|
444
|
-
value_numbers << value.gsub( 'km2', '').gsub( 'km²', '' ).gsub(/[ _]/, '').to_i
|
445
|
-
elsif value =~ /^([0-9][0-9 _]+[0-9])|([0-9]{1,2})$/ ## numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
|
446
|
-
value_numbers << value.gsub(/[ _]/, '').to_i
|
447
|
-
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
448
|
-
|
449
|
-
logger.debug " found tags: >>#{value}<<"
|
450
|
-
|
451
|
-
tag_keys = value.split('|')
|
452
|
-
|
453
|
-
## unify; replace _w/ space; remove leading n trailing whitespace
|
454
|
-
tag_keys = tag_keys.map do |key|
|
455
|
-
key = key.gsub( '_', ' ' )
|
456
|
-
key = key.strip
|
457
|
-
key
|
458
|
-
end
|
459
|
-
|
460
|
-
value_tag_keys += tag_keys
|
461
|
-
else
|
462
|
-
|
463
|
-
if clazz == Country || clazz == Region
|
464
|
-
### assume it is the capital city - mark it for auto add
|
465
|
-
value_cities << value
|
466
|
-
next
|
467
|
-
end
|
468
|
-
|
469
|
-
# issue warning: unknown type for value
|
470
|
-
logger.warn "unknown type for value >#{value}<"
|
471
|
-
end
|
472
|
-
end # each value
|
473
|
-
|
474
|
-
|
475
|
-
if value_numbers.size > 0
|
476
|
-
if clazz == City
|
477
|
-
attribs[ :pop ] = value_numbers[0] # assume first number is pop for cities
|
478
|
-
attribs[ :area ] = value_numbers[1]
|
479
|
-
else # countries,regions
|
480
|
-
attribs[ :area ] = value_numbers[0]
|
481
|
-
attribs[ :pop ] = value_numbers[1]
|
482
|
-
|
483
|
-
|
484
|
-
=begin
|
485
|
-
if clazz == Country
|
486
|
-
# auto-add tags
|
487
|
-
area = value_numbers[0]
|
488
|
-
pop = value_numbers[1]
|
489
|
-
|
490
|
-
# categorize into brackets
|
491
|
-
if area >= 1_000_000
|
492
|
-
value_tag_keys << 'area_1_000_000_n_up'
|
493
|
-
elsif area >= 100_000
|
494
|
-
value_tag_keys << 'area_100_000_to_1_000_000'
|
495
|
-
elsif area >= 1000
|
496
|
-
value_tag_keys << 'area_1_000_to_100_000'
|
497
|
-
else
|
498
|
-
value_tag_keys << 'area_1_000_n_less' # microstate
|
499
|
-
end
|
500
|
-
|
501
|
-
# include all
|
502
|
-
value_tag_keys << 'area_100_000_n_up' if area >= 100_000
|
503
|
-
value_tag_keys << 'area_1_000_n_up' if area >= 1_000
|
504
|
-
|
505
|
-
|
506
|
-
# categorize into brackets
|
507
|
-
if pop >= 100_000_000
|
508
|
-
value_tag_keys << 'pop_100m_n_up'
|
509
|
-
elsif pop >= 10_000_000
|
510
|
-
value_tag_keys << 'pop_10m_to_100m'
|
511
|
-
elsif pop >= 1_000_000
|
512
|
-
value_tag_keys << 'pop_1m_to_10m'
|
513
|
-
else
|
514
|
-
value_tag_keys << 'pop_1m_n_less'
|
515
|
-
end
|
516
|
-
|
517
|
-
# include all
|
518
|
-
value_tag_keys << 'pop_10m_n_up' if pop >= 10_000_000
|
519
|
-
value_tag_keys << 'pop_1m_n_up' if pop >= 1_000_000
|
520
|
-
end
|
521
|
-
=end
|
522
|
-
|
523
|
-
|
524
|
-
end
|
525
|
-
end # if value_numbers.size > 0
|
526
|
-
|
527
|
-
rec = nil
|
528
|
-
|
529
|
-
if clazz == Region ## requires country_id
|
530
|
-
## todo: assert that country_id is present/valid, that is, NOT null
|
531
|
-
rec = clazz.find_by_key_and_country_id( attribs[ :key ], attribs[ :country_id] )
|
532
|
-
else
|
533
|
-
rec = clazz.find_by_key( attribs[ :key ] )
|
534
|
-
end
|
535
|
-
|
536
|
-
if rec.present?
|
537
|
-
## nb: [17..-1] cut off WorldDB::Models:: in name
|
538
|
-
logger.debug "update #{clazz.name[17..-1].downcase} #{rec.id}-#{rec.key}:"
|
539
|
-
else
|
540
|
-
logger.debug "create #{clazz.name[17..-1].downcase}:"
|
541
|
-
rec = clazz.new
|
542
|
-
end
|
543
|
-
|
544
|
-
logger.debug attribs.to_json
|
545
|
-
|
546
|
-
rec.update_attributes!( attribs )
|
547
|
-
|
548
|
-
#################
|
549
|
-
## auto add capital cities
|
550
|
-
|
551
|
-
value_cities.each do |city_title|
|
552
|
-
|
553
|
-
city_attribs = {}
|
554
|
-
city_key = TextUtils.title_to_key( city_title )
|
555
|
-
|
556
|
-
## check if it exists
|
557
|
-
## todo/fix: add country_id for lookup?
|
558
|
-
city = City.find_by_key( city_key )
|
559
|
-
if city.present?
|
560
|
-
logger.debug "update city #{city.id}-#{city.key}:"
|
561
|
-
else
|
562
|
-
logger.debug "create city:"
|
563
|
-
city = City.new
|
564
|
-
city_attribs[ :key ] = city_key
|
565
|
-
end
|
566
|
-
|
567
|
-
city_attribs[ :title ] = city_title
|
568
|
-
|
569
|
-
if clazz == Country
|
570
|
-
city_attribs[ :country_id ] = rec.id
|
571
|
-
elsif clazz == Region
|
572
|
-
city_attribs[ :region_id ] = rec.id
|
573
|
-
city_attribs[ :country_id ] = rec.country_id
|
574
|
-
else
|
575
|
-
## issue warning: unknown type for city!!!
|
576
|
-
end
|
577
|
-
|
578
|
-
logger.debug city_attribs.to_json
|
579
|
-
|
580
|
-
city.update_attributes!( city_attribs )
|
581
|
-
|
582
|
-
### todo/fix: add captial ref to country/region
|
583
|
-
|
584
|
-
end # each city
|
585
|
-
|
586
|
-
|
587
|
-
##################
|
588
|
-
## add taggings
|
589
|
-
|
590
|
-
if value_tag_keys.size > 0
|
591
|
-
|
592
|
-
if skip_tags?
|
593
|
-
logger.debug " skipping add taggings (flag skip_tag)"
|
594
|
-
else
|
595
|
-
value_tag_keys.uniq! # remove duplicates
|
596
|
-
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
597
|
-
|
598
|
-
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
599
|
-
|
600
|
-
value_tag_keys.each do |key|
|
601
|
-
tag = Tag.find_by_key( key )
|
602
|
-
if tag.nil? # create tag if it doesn't exit
|
603
|
-
logger.debug " creating tag >#{key}<"
|
604
|
-
tag = Tag.create!( key: key )
|
605
|
-
end
|
606
|
-
rec.tags << tag
|
607
|
-
end
|
608
|
-
end
|
609
|
-
end
|
610
|
-
|
611
|
-
|
612
|
-
end # each_line
|
613
|
-
|
614
|
-
end # method load_fixture_worker_for
|
615
|
-
|
616
350
|
|
617
351
|
end # class Reader
|
618
352
|
end # module WorldDb
|
data/lib/worlddb/utils.rb
CHANGED
@@ -16,3 +16,39 @@ class Time
|
|
16
16
|
end
|
17
17
|
|
18
18
|
end # class Time
|
19
|
+
|
20
|
+
|
21
|
+
##### fix/todo: move to helper folder - use one file per module/helper
|
22
|
+
|
23
|
+
module WorldDb
|
24
|
+
module TagHelper
|
25
|
+
|
26
|
+
def find_tags( value )
|
27
|
+
# logger.debug " found tags: >>#{value}<<"
|
28
|
+
|
29
|
+
tag_keys = value.split('|')
|
30
|
+
|
31
|
+
## unify; replace _w/ space; remove leading n trailing whitespace
|
32
|
+
tag_keys = tag_keys.map do |key|
|
33
|
+
key = key.gsub( '_', ' ' )
|
34
|
+
key = key.strip
|
35
|
+
key
|
36
|
+
end
|
37
|
+
|
38
|
+
tag_keys # return tag keys as ary
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_tags_in_hash!( h )
|
42
|
+
# NB: will remove :tags from hash
|
43
|
+
|
44
|
+
if h[:tags].present?
|
45
|
+
tag_keys = find_tags( h[:tags] )
|
46
|
+
h.delete(:tags)
|
47
|
+
tag_keys # return tag keys as ary
|
48
|
+
else
|
49
|
+
[] # nothing found; return empty ary
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # module
|
54
|
+
end # module WorldDb
|
data/lib/worlddb/version.rb
CHANGED
data/lib/worlddb.rb
CHANGED
@@ -26,6 +26,7 @@ require 'textutils'
|
|
26
26
|
|
27
27
|
require 'worlddb/version'
|
28
28
|
|
29
|
+
require 'worlddb/utils'
|
29
30
|
require 'worlddb/models/prop'
|
30
31
|
require 'worlddb/models/continent'
|
31
32
|
require 'worlddb/models/country'
|
@@ -36,7 +37,6 @@ require 'worlddb/models/tagging'
|
|
36
37
|
require 'worlddb/models/lang'
|
37
38
|
require 'worlddb/models/usage'
|
38
39
|
require 'worlddb/schema' # NB: requires worlddb/models (include WorldDB::Models)
|
39
|
-
require 'worlddb/utils'
|
40
40
|
require 'worlddb/reader'
|
41
41
|
require 'worlddb/deleter'
|
42
42
|
require 'worlddb/stats'
|
data/test/helper.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
## $:.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
## minitest setup
|
5
|
+
|
6
|
+
# require 'minitest/unit'
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
# include MiniTest::Unit # lets us use TestCase instead of MiniTest::Unit::TestCase
|
10
|
+
|
11
|
+
|
12
|
+
# ruby stdlibs
|
13
|
+
|
14
|
+
require 'json'
|
15
|
+
require 'uri'
|
16
|
+
require 'pp'
|
17
|
+
|
18
|
+
# ruby gems
|
19
|
+
|
20
|
+
require 'active_record'
|
21
|
+
|
22
|
+
# our own code
|
23
|
+
|
24
|
+
require 'worlddb'
|
25
|
+
require 'logutils/db' # NB: explict require required for LogDb (not automatic)
|
26
|
+
|
27
|
+
Country = WorldDb::Models::Country
|
28
|
+
Region = WorldDb::Models::Region
|
29
|
+
City = WorldDb::Models::City
|
30
|
+
|
31
|
+
|
32
|
+
def setup_in_memory_db
|
33
|
+
# Database Setup & Config
|
34
|
+
|
35
|
+
db_config = {
|
36
|
+
adapter: 'sqlite3',
|
37
|
+
database: ':memory:'
|
38
|
+
}
|
39
|
+
|
40
|
+
pp db_config
|
41
|
+
|
42
|
+
ActiveRecord::Base.logger = Logger.new( STDOUT )
|
43
|
+
## ActiveRecord::Base.colorize_logging = false - no longer exists - check new api/config setting?
|
44
|
+
|
45
|
+
## NB: every connect will create a new empty in memory db
|
46
|
+
ActiveRecord::Base.establish_connection( db_config )
|
47
|
+
|
48
|
+
|
49
|
+
## build schema
|
50
|
+
|
51
|
+
LogDb.create
|
52
|
+
WorldDb.create
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
setup_in_memory_db()
|
data/test/test_values.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_helper.rb
|
6
|
+
# or better
|
7
|
+
# rake test
|
8
|
+
|
9
|
+
require 'helper'
|
10
|
+
|
11
|
+
class TestValues < MiniTest::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
# delete all countries, regions, cities in in-memory only db
|
15
|
+
WorldDb.delete!
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_load_country_values
|
19
|
+
|
20
|
+
new_attributes = {
|
21
|
+
key: 'at',
|
22
|
+
title: 'Austria',
|
23
|
+
synonyms: ''
|
24
|
+
}
|
25
|
+
|
26
|
+
values = [
|
27
|
+
'AUT',
|
28
|
+
'83_871',
|
29
|
+
'8_414_638',
|
30
|
+
'un|fifa|uefa|eu|euro|schengen|central_europe|western_europe'
|
31
|
+
]
|
32
|
+
|
33
|
+
c = Country.create_or_update_from_values( new_attributes, values )
|
34
|
+
|
35
|
+
c2 = Country.find_by_key!( new_attributes[:key] )
|
36
|
+
assert( c.id == c2.id )
|
37
|
+
|
38
|
+
assert( c.title == new_attributes[:title] )
|
39
|
+
assert( c.pop == 8_414_638 )
|
40
|
+
assert( c.area == 83_871 )
|
41
|
+
## todo: assert tag count; add supra:eu etc.
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_load_region_values
|
45
|
+
|
46
|
+
at = Country.create!( key: 'at',
|
47
|
+
title: 'Austria',
|
48
|
+
code: 'AUT',
|
49
|
+
pop: 8_414_638,
|
50
|
+
area: 83_871 )
|
51
|
+
|
52
|
+
new_attributes = {
|
53
|
+
key: 'w',
|
54
|
+
title: 'Wien',
|
55
|
+
synonyms: '',
|
56
|
+
country_id: at.id
|
57
|
+
}
|
58
|
+
|
59
|
+
values = [
|
60
|
+
'415 km²',
|
61
|
+
'eastern austria'
|
62
|
+
]
|
63
|
+
|
64
|
+
r = Region.create_or_update_from_values( new_attributes, values )
|
65
|
+
|
66
|
+
r2 = Region.find_by_key!( new_attributes[:key] )
|
67
|
+
assert( r.id == r2.id )
|
68
|
+
|
69
|
+
assert( r.title == new_attributes[:title] )
|
70
|
+
assert( r.area == 415 )
|
71
|
+
## todo: assert country_id & country.title for assoc
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_load_city_values
|
75
|
+
|
76
|
+
at = Country.create!( key: 'at',
|
77
|
+
title: 'Austria',
|
78
|
+
code: 'AUT',
|
79
|
+
pop: 8_414_638,
|
80
|
+
area: 83_871 )
|
81
|
+
|
82
|
+
w = Region.create!( key: 'w',
|
83
|
+
title: 'Wien',
|
84
|
+
country_id: at.id )
|
85
|
+
|
86
|
+
new_attributes = {
|
87
|
+
key: 'wien',
|
88
|
+
title: 'Wien',
|
89
|
+
synonyms: '',
|
90
|
+
country_id: at.id
|
91
|
+
}
|
92
|
+
|
93
|
+
values = [
|
94
|
+
'W',
|
95
|
+
'1_731_236',
|
96
|
+
'm:1_724_000'
|
97
|
+
]
|
98
|
+
|
99
|
+
c = City.create_or_update_from_values( new_attributes, values )
|
100
|
+
|
101
|
+
c2 = City.find_by_key!( new_attributes[:key] )
|
102
|
+
assert( c.id == c2.id )
|
103
|
+
|
104
|
+
assert( c.title == new_attributes[:title] )
|
105
|
+
assert( c.pop == 1_731_236 )
|
106
|
+
assert( c.popm == 1_724_000 )
|
107
|
+
assert( c.m == true )
|
108
|
+
assert( c.region_id == w.id )
|
109
|
+
assert( c.country_id == at.id )
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
end # class TestValues
|
114
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: worlddb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: textutils
|
16
|
-
requirement: &
|
16
|
+
requirement: &83860400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.5'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *83860400
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: commander
|
27
|
-
requirement: &
|
27
|
+
requirement: &83860180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 4.1.3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *83860180
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activerecord
|
38
|
-
requirement: &
|
38
|
+
requirement: &83876350 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '3.2'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *83876350
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdoc
|
49
|
-
requirement: &
|
49
|
+
requirement: &83876130 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '3.10'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *83876130
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: hoe
|
60
|
-
requirement: &
|
60
|
+
requirement: &83875910 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '3.3'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *83875910
|
69
69
|
description: worlddb - world.db command line tool
|
70
70
|
email: opensport@googlegroups.com
|
71
71
|
executables:
|
@@ -99,6 +99,9 @@ files:
|
|
99
99
|
- lib/worlddb/stats.rb
|
100
100
|
- lib/worlddb/utils.rb
|
101
101
|
- lib/worlddb/version.rb
|
102
|
+
- test/helper.rb
|
103
|
+
- test/test_values.rb
|
104
|
+
- .gemtest
|
102
105
|
homepage: https://github.com/geraldb/world.db.ruby
|
103
106
|
licenses:
|
104
107
|
- Public Domain
|
@@ -126,4 +129,5 @@ rubygems_version: 1.8.17
|
|
126
129
|
signing_key:
|
127
130
|
specification_version: 3
|
128
131
|
summary: worlddb - world.db command line tool
|
129
|
-
test_files:
|
132
|
+
test_files:
|
133
|
+
- test/test_values.rb
|