worlddb 1.6.4 → 1.6.5
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/.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
|