pilipinas 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -19
- data/Gemfile.lock +30 -29
- data/README.md +14 -0
- data/lib/generators/pilipinas/code_indexes_generator.rb +42 -0
- data/lib/generators/templates/add_pilipinas_code_indexes.rb +8 -0
- data/lib/pilipinas/loader.rb +98 -7
- data/lib/pilipinas/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c053d3fbf05daa1c3bd6298945223e06a0c8154962f9958e8681701738a808b
|
|
4
|
+
data.tar.gz: 5613bb74fb432f59980cb54067d2d5fb0c2229807df82471e73131b884e00452
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5b1fb8a1a22541315c95dddf2f8f027e88c9455a7fbcde7dd8af9a8483c844247224321aae75d627eab1a15121ef075df01430cfe9a50448dbf9191e83c53851
|
|
7
|
+
data.tar.gz: 453835a9b952e40983c10e50ba5f7321efc669c59b11db7442943c29553d37c5d5d79defb697382ac7eac11298f87dc92d7e8dc1e0ad26e7cf5262b532ac97ac
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.1.2] - 2026-06-12
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `rake pilipinas:load` now seeds the ActiveRecord tables from `lib/data/pilipinas_data.yml`, the complete bundled data source. Previously the loader used the compact file-backed YAML files, so database rows were populated with only `code` and `name` while columns such as `location_id`, `parent_id`, `lft`, `rgt`, coordinates, and classification fields remained `NULL`.
|
|
15
|
+
|
|
16
|
+
- Re-running `rake pilipinas:load` now removes stale compact rows created by earlier loader versions. This fixes cases where old rows such as provinces with `location_id: nil` remained in the database because their compact internal codes did not match the full PSA-style codes used by `pilipinas_data.yml`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Improved loader memory behavior by transforming rows directly from the parsed full-data table and keeping only the current insert batch in memory.
|
|
21
|
+
|
|
22
|
+
### Tests
|
|
23
|
+
|
|
24
|
+
- Added regression coverage for complete-column seeding, stale compact-row cleanup, legacy seed behavior, and exact batch-boundary inserts.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## [1.1.1] - 2026-06-11
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- `rails generate pilipinas:code_indexes` — new migration generator that adds `UNIQUE` indexes on the `code` column to all four `pilipinas_*` tables. Run this if your database was created with a pre-1.0 migration and `rake pilipinas:load` raises `ArgumentError: No unique index found for code`.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- `Loader.bulk_insert` now rescues the bare `ArgumentError` raised by `upsert_all` when the unique index on `code` is absent, and re-raises it as a descriptive `Pilipinas::Error` that tells the user exactly which commands to run (`rails generate pilipinas:code_indexes && rails db:migrate`). Previously the error surfaced as an unguided `ArgumentError` from deep inside ActiveRecord.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
10
40
|
## [1.1.0] - 2026-05-13
|
|
11
41
|
|
|
12
42
|
### Added
|
|
@@ -18,19 +48,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
18
48
|
self.enforce_readonly = false
|
|
19
49
|
end
|
|
20
50
|
```
|
|
21
|
-
- `lib/pilipinas/testing/rspec.rb` — a ready-made RSpec helper that disables
|
|
22
|
-
the read-only guard on all four DB models for the entire test suite.
|
|
23
|
-
Require it once in `rails_helper.rb`:
|
|
51
|
+
- `lib/pilipinas/testing/rspec.rb` — a ready-made RSpec helper that disables the read-only guard on all four DB models for the entire test suite. Require it once in `rails_helper.rb`:
|
|
24
52
|
```ruby
|
|
25
53
|
require 'pilipinas/testing/rspec'
|
|
26
54
|
```
|
|
27
|
-
- Spec coverage for `StaticRecord` — 8 examples covering default behaviour,
|
|
28
|
-
`enforce_readonly = false`, subclass inheritance, and class-level isolation.
|
|
55
|
+
- Spec coverage for `StaticRecord` — 8 examples covering default behaviour, `enforce_readonly = false`, subclass inheritance, and class-level isolation.
|
|
29
56
|
|
|
30
57
|
### Changed
|
|
31
58
|
|
|
32
|
-
- `readonly?` now gates on `self.class.enforce_readonly && !new_record?` instead
|
|
33
|
-
of unconditionally returning `!new_record?`.
|
|
59
|
+
- `readonly?` now gates on `self.class.enforce_readonly && !new_record?` instead of unconditionally returning `!new_record?`.
|
|
34
60
|
|
|
35
61
|
---
|
|
36
62
|
|
|
@@ -40,26 +66,20 @@ Complete rewrite of the gem. Zero runtime dependencies.
|
|
|
40
66
|
|
|
41
67
|
### Added
|
|
42
68
|
|
|
43
|
-
- In-memory layer with thread-safe `Pilipinas::Cache` (Mutex + double-checked
|
|
44
|
-
locking) and O(1) look-ups via separate code/name hash indices.
|
|
69
|
+
- In-memory layer with thread-safe `Pilipinas::Cache` (Mutex + double-checked locking) and O(1) look-ups via separate code/name hash indices.
|
|
45
70
|
- Immutable value objects — every entity instance is frozen.
|
|
46
|
-
- `Pilipinas::Region`, `Province`, `City`, `Barangay` with `.all`, `.count`,
|
|
47
|
-
`.first`, `.last`, `.find_by`, `.find_by_code`, `.find_by_name`.
|
|
71
|
+
- `Pilipinas::Region`, `Province`, `City`, `Barangay` with `.all`, `.count`, `.first`, `.last`, `.find_by`, `.find_by_code`, `.find_by_name`.
|
|
48
72
|
- Hierarchy traversal: `region.provinces`, `province.cities`, `city.barangays`.
|
|
49
|
-
- Optional ActiveRecord layer (`Pilipinas::Db::*`) with memory-efficient scopes
|
|
50
|
-
|
|
51
|
-
- `
|
|
52
|
-
read-only on persisted records.
|
|
53
|
-
- Migration generator (`rails generate pilipinas:migration`) and
|
|
54
|
-
`rake pilipinas:load` seeding task.
|
|
73
|
+
- Optional ActiveRecord layer (`Pilipinas::Db::*`) with memory-efficient scopes (`.lite`, `.by_code`, `.by_name`, `.find_lite_by_code`, `.find_lite_by_name`).
|
|
74
|
+
- `StaticRecord` concern: disables STI, adds lean SELECT scopes, enforces read-only on persisted records.
|
|
75
|
+
- Migration generator (`rails generate pilipinas:migration`) and `rake pilipinas:load` seeding task.
|
|
55
76
|
- Full RSpec suite (57 examples).
|
|
56
77
|
- GitHub Actions CI pipeline.
|
|
57
78
|
|
|
58
79
|
### Changed
|
|
59
80
|
|
|
60
81
|
- Requires Ruby ≥ 3.4 (developed against Ruby 4.0).
|
|
61
|
-
- Removed all runtime gem dependencies (previously depended on `yaml_db` and
|
|
62
|
-
others).
|
|
82
|
+
- Removed all runtime gem dependencies (previously depended on `yaml_db` and others).
|
|
63
83
|
|
|
64
84
|
---
|
|
65
85
|
|
|
@@ -74,6 +94,8 @@ Complete rewrite of the gem. Zero runtime dependencies.
|
|
|
74
94
|
- Rails generator for migrations.
|
|
75
95
|
- Railtie for automatic Rake task loading in Rails apps.
|
|
76
96
|
|
|
97
|
+
[1.1.2]: https://github.com/denmarkmeralpis/pilipinas/compare/v1.1.1...v1.1.2
|
|
98
|
+
[1.1.1]: https://github.com/denmarkmeralpis/pilipinas/compare/v1.1.0...v1.1.1
|
|
77
99
|
[1.1.0]: https://github.com/denmarkmeralpis/pilipinas/compare/v1.0.0...v1.1.0
|
|
78
100
|
[1.0.0]: https://github.com/denmarkmeralpis/pilipinas/compare/v0.0.1...v1.0.0
|
|
79
101
|
[0.0.1]: https://github.com/denmarkmeralpis/pilipinas/releases/tag/v0.0.1
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
pilipinas (1.1.
|
|
4
|
+
pilipinas (1.1.2)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
@@ -76,7 +76,7 @@ GEM
|
|
|
76
76
|
prism (>= 1.3.0)
|
|
77
77
|
rdoc (>= 4.0.0)
|
|
78
78
|
reline (>= 0.4.2)
|
|
79
|
-
json (2.19.
|
|
79
|
+
json (2.19.8)
|
|
80
80
|
language_server-protocol (3.17.0.5)
|
|
81
81
|
lint_roller (1.1.0)
|
|
82
82
|
logger (1.7.0)
|
|
@@ -110,7 +110,7 @@ GEM
|
|
|
110
110
|
prettyprint
|
|
111
111
|
prettyprint (0.2.0)
|
|
112
112
|
prism (1.9.0)
|
|
113
|
-
psych (5.
|
|
113
|
+
psych (5.4.0)
|
|
114
114
|
date
|
|
115
115
|
stringio
|
|
116
116
|
public_suffix (7.0.5)
|
|
@@ -162,7 +162,7 @@ GEM
|
|
|
162
162
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
163
163
|
rspec-support (~> 3.13.0)
|
|
164
164
|
rspec-support (3.13.7)
|
|
165
|
-
rubocop (1.
|
|
165
|
+
rubocop (1.87.0)
|
|
166
166
|
json (~> 2.3)
|
|
167
167
|
language_server-protocol (~> 3.17.0.2)
|
|
168
168
|
lint_roller (~> 1.1.0)
|
|
@@ -179,9 +179,10 @@ GEM
|
|
|
179
179
|
rubocop-rake (0.7.1)
|
|
180
180
|
lint_roller (~> 1.1)
|
|
181
181
|
rubocop (>= 1.72.1)
|
|
182
|
-
rubocop-rspec (3.
|
|
182
|
+
rubocop-rspec (3.10.2)
|
|
183
183
|
lint_roller (~> 1.1)
|
|
184
|
-
|
|
184
|
+
regexp_parser (>= 2.0)
|
|
185
|
+
rubocop (~> 1.86, >= 1.86.2)
|
|
185
186
|
ruby-progressbar (1.13.0)
|
|
186
187
|
securerandom (0.4.1)
|
|
187
188
|
shoulda-matchers (6.5.0)
|
|
@@ -196,14 +197,14 @@ GEM
|
|
|
196
197
|
terminal-table
|
|
197
198
|
simplecov-html (0.13.2)
|
|
198
199
|
simplecov_json_formatter (0.1.4)
|
|
199
|
-
sqlite3 (2.9.
|
|
200
|
-
sqlite3 (2.9.
|
|
201
|
-
sqlite3 (2.9.
|
|
202
|
-
sqlite3 (2.9.
|
|
203
|
-
sqlite3 (2.9.
|
|
204
|
-
sqlite3 (2.9.
|
|
205
|
-
sqlite3 (2.9.
|
|
206
|
-
sqlite3 (2.9.
|
|
200
|
+
sqlite3 (2.9.5-aarch64-linux-gnu)
|
|
201
|
+
sqlite3 (2.9.5-aarch64-linux-musl)
|
|
202
|
+
sqlite3 (2.9.5-arm-linux-gnu)
|
|
203
|
+
sqlite3 (2.9.5-arm-linux-musl)
|
|
204
|
+
sqlite3 (2.9.5-arm64-darwin)
|
|
205
|
+
sqlite3 (2.9.5-x86_64-darwin)
|
|
206
|
+
sqlite3 (2.9.5-x86_64-linux-gnu)
|
|
207
|
+
sqlite3 (2.9.5-x86_64-linux-musl)
|
|
207
208
|
stringio (3.2.0)
|
|
208
209
|
terminal-table (4.0.0)
|
|
209
210
|
unicode-display_width (>= 1.1.1, < 4)
|
|
@@ -221,7 +222,7 @@ GEM
|
|
|
221
222
|
addressable (>= 2.8.0)
|
|
222
223
|
crack (>= 0.3.2)
|
|
223
224
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
224
|
-
zeitwerk (2.
|
|
225
|
+
zeitwerk (2.8.2)
|
|
225
226
|
|
|
226
227
|
PLATFORMS
|
|
227
228
|
aarch64-linux-gnu
|
|
@@ -279,7 +280,7 @@ CHECKSUMS
|
|
|
279
280
|
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
|
|
280
281
|
io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
|
|
281
282
|
irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
|
|
282
|
-
json (2.19.
|
|
283
|
+
json (2.19.8) sha256=6354310fd76ef69b87d5bd1f38b40d730613baf90b6803d2d0a48f618d32dfaa
|
|
283
284
|
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
|
284
285
|
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
285
286
|
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
@@ -295,11 +296,11 @@ CHECKSUMS
|
|
|
295
296
|
nokogiri (1.19.3-x86_64-linux-musl) sha256=248c906d2166eca5efb56d52fdee5f9a1f51d69a72e2b64fdac647b4ce39ea3f
|
|
296
297
|
parallel (2.1.0) sha256=b35258865c2e31134c5ecb708beaaf6772adf9d5efae28e93e99260877b09356
|
|
297
298
|
parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54
|
|
298
|
-
pilipinas (1.1.
|
|
299
|
+
pilipinas (1.1.2)
|
|
299
300
|
pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
|
|
300
301
|
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
|
|
301
302
|
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
302
|
-
psych (5.
|
|
303
|
+
psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7
|
|
303
304
|
public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623
|
|
304
305
|
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
305
306
|
rack (3.2.6) sha256=5ed78e1f73b2e25679bec7d45ee2d4483cc4146eb1be0264fc4d94cb5ef212c2
|
|
@@ -320,10 +321,10 @@ CHECKSUMS
|
|
|
320
321
|
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
|
|
321
322
|
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
|
|
322
323
|
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
|
|
323
|
-
rubocop (1.
|
|
324
|
+
rubocop (1.87.0) sha256=b9d9ddf55116a513f8ef2c7ae660662d8b49301f118d3f0df61865b33a5c188d
|
|
324
325
|
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
|
|
325
326
|
rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
|
|
326
|
-
rubocop-rspec (3.
|
|
327
|
+
rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2
|
|
327
328
|
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
|
|
328
329
|
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
|
|
329
330
|
shoulda-matchers (6.5.0) sha256=ef6b572b2bed1ac4aba6ab2c5ff345a24b6d055a93a3d1c3bfc86d9d499e3f44
|
|
@@ -331,14 +332,14 @@ CHECKSUMS
|
|
|
331
332
|
simplecov-console (0.9.5) sha256=b1108bcfff5f210143e2b8301698c367b01586f20d25a73e95475a5df6fc6ff6
|
|
332
333
|
simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
|
|
333
334
|
simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
|
|
334
|
-
sqlite3 (2.9.
|
|
335
|
-
sqlite3 (2.9.
|
|
336
|
-
sqlite3 (2.9.
|
|
337
|
-
sqlite3 (2.9.
|
|
338
|
-
sqlite3 (2.9.
|
|
339
|
-
sqlite3 (2.9.
|
|
340
|
-
sqlite3 (2.9.
|
|
341
|
-
sqlite3 (2.9.
|
|
335
|
+
sqlite3 (2.9.5-aarch64-linux-gnu) sha256=78075b6337d3d182c6d2b4691049ed45cd220826160c9ea18946bf6a1de200dc
|
|
336
|
+
sqlite3 (2.9.5-aarch64-linux-musl) sha256=18c801185deb4adc01ddb281e8f672a39e3d1729979ca91e39439cd3eac0402d
|
|
337
|
+
sqlite3 (2.9.5-arm-linux-gnu) sha256=1bdfca0c7d63998c60b0f4a8e3c8df2d33800ccc4abd2d612eddbbbc92a4c48b
|
|
338
|
+
sqlite3 (2.9.5-arm-linux-musl) sha256=bae1109d12b2e9f588455967729b008e1ff4feb7761749df695019c9079913c6
|
|
339
|
+
sqlite3 (2.9.5-arm64-darwin) sha256=d0cf444a70fc9395d513cfbcc1e6719e224aa645314e3824cb0474c721425aa2
|
|
340
|
+
sqlite3 (2.9.5-x86_64-darwin) sha256=8e9caae38bd7ebb29cbeee3e7ab1d12dc2327d9a1b92c7fcf0dda05589627a81
|
|
341
|
+
sqlite3 (2.9.5-x86_64-linux-gnu) sha256=233dbcb6714148dd23bc5aeb33e8efd6eac974969564ddd5794c23d5f52b231e
|
|
342
|
+
sqlite3 (2.9.5-x86_64-linux-musl) sha256=e7d3a7474e8af0f96150c21abc203fbab5437206bfcdf11deab7741c0ca516f2
|
|
342
343
|
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
|
|
343
344
|
terminal-table (4.0.0) sha256=f504793203f8251b2ea7c7068333053f0beeea26093ec9962e62ea79f94301d2
|
|
344
345
|
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
|
|
@@ -350,7 +351,7 @@ CHECKSUMS
|
|
|
350
351
|
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
|
|
351
352
|
useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844
|
|
352
353
|
webmock (3.26.2) sha256=774556f2ea6371846cca68c01769b2eac0d134492d21f6d0ab5dd643965a4c90
|
|
353
|
-
zeitwerk (2.
|
|
354
|
+
zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12
|
|
354
355
|
|
|
355
356
|
BUNDLED WITH
|
|
356
357
|
4.0.6
|
data/README.md
CHANGED
|
@@ -174,6 +174,20 @@ This creates four tables: `pilipinas_regions`, `pilipinas_provinces`, `pilipinas
|
|
|
174
174
|
rake pilipinas:load
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
> **Upgrading from an older version?**
|
|
178
|
+
>
|
|
179
|
+
> If `rake pilipinas:load` raises
|
|
180
|
+
> `Pilipinas::Error: pilipinas:load requires a unique index on the code column`,
|
|
181
|
+
> your database was created with an earlier migration that did not include those
|
|
182
|
+
> indexes. Add them with the dedicated generator:
|
|
183
|
+
>
|
|
184
|
+
> ```sh
|
|
185
|
+
> rails generate pilipinas:code_indexes
|
|
186
|
+
> rails db:migrate
|
|
187
|
+
> ```
|
|
188
|
+
>
|
|
189
|
+
> Then re-run `rake pilipinas:load`.
|
|
190
|
+
|
|
177
191
|
### 3. Use the AR models
|
|
178
192
|
|
|
179
193
|
```ruby
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators/base'
|
|
4
|
+
require 'rails/generators/active_record'
|
|
5
|
+
|
|
6
|
+
module Pilipinas
|
|
7
|
+
# Rails generator that adds unique indexes on the +code+ column to all four
|
|
8
|
+
# pilipinas_* tables.
|
|
9
|
+
#
|
|
10
|
+
# Run this if your database was created with an older version of the gem
|
|
11
|
+
# that did not include these indexes, and +rake pilipinas:load+ raises:
|
|
12
|
+
#
|
|
13
|
+
# ArgumentError: No unique index found for code
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
# rails generate pilipinas:code_indexes
|
|
17
|
+
# rails db:migrate
|
|
18
|
+
#
|
|
19
|
+
class CodeIndexesGenerator < Rails::Generators::Base
|
|
20
|
+
include Rails::Generators::Migration
|
|
21
|
+
|
|
22
|
+
source_root File.expand_path('..', __dir__)
|
|
23
|
+
|
|
24
|
+
def generate_migration
|
|
25
|
+
migration_template 'templates/add_pilipinas_code_indexes.rb',
|
|
26
|
+
'db/migrate/add_pilipinas_code_indexes.rb'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param _dir [String] unused (required by the interface)
|
|
30
|
+
# @return [String]
|
|
31
|
+
def self.next_migration_number(_dir)
|
|
32
|
+
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# @return [String] migration version bracket, e.g. "[8.0]"
|
|
38
|
+
def migration_version
|
|
39
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class AddPilipinasCodeIndexes < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def change
|
|
3
|
+
add_index :pilipinas_regions, :code, unique: true, if_not_exists: true
|
|
4
|
+
add_index :pilipinas_provinces, :code, unique: true, if_not_exists: true
|
|
5
|
+
add_index :pilipinas_cities, :code, unique: true, if_not_exists: true
|
|
6
|
+
add_index :pilipinas_barangays, :code, unique: true, if_not_exists: true
|
|
7
|
+
end
|
|
8
|
+
end
|
data/lib/pilipinas/loader.rb
CHANGED
|
@@ -9,8 +9,9 @@ module Pilipinas
|
|
|
9
9
|
# * **Idempotent** — uses +upsert_all+ (Rails 6.1+) so re-running the Rake
|
|
10
10
|
# task is safe. Falls back to +insert_all+ (Rails 6.0) or individual
|
|
11
11
|
# +create!+ calls on older versions.
|
|
12
|
-
# * **Memory-
|
|
13
|
-
# (default 500) so the process never holds a
|
|
12
|
+
# * **Memory-aware** — rows are transformed and inserted in batches of
|
|
13
|
+
# {BATCH_SIZE} (default 500) so the process never holds a full
|
|
14
|
+
# ActiveRecord insert payload in memory.
|
|
14
15
|
# * **Atomic** — all four tables are seeded inside a single transaction; a
|
|
15
16
|
# failure rolls back everything, leaving no partial data.
|
|
16
17
|
#
|
|
@@ -21,22 +22,102 @@ module Pilipinas
|
|
|
21
22
|
# Number of rows inserted per SQL statement.
|
|
22
23
|
# 500 balances SQL statement size against the number of round-trips.
|
|
23
24
|
BATCH_SIZE = 500
|
|
25
|
+
FULL_DATA_FILE = 'pilipinas_data.yml'
|
|
26
|
+
LOCATION_TABLE = 'pilipinas_locations'
|
|
27
|
+
|
|
28
|
+
FULL_DATA_SEEDS = [
|
|
29
|
+
['Region', 'Locations::Region', %w[location_id lft rgt code name longitude latitude]],
|
|
30
|
+
['Province', 'Locations::Province', %w[location_id parent_id lft rgt code name longitude latitude]],
|
|
31
|
+
[
|
|
32
|
+
'City',
|
|
33
|
+
'Locations::Town',
|
|
34
|
+
%w[location_id parent_id lft rgt code name city income_class urban_rural district longitude latitude]
|
|
35
|
+
],
|
|
36
|
+
['Barangay', 'Locations::Barangay', %w[location_id parent_id lft rgt code name urban_rural]]
|
|
37
|
+
].freeze
|
|
38
|
+
private_constant :FULL_DATA_FILE, :LOCATION_TABLE, :FULL_DATA_SEEDS
|
|
24
39
|
|
|
25
40
|
class << self
|
|
26
41
|
# Seed all four geographic tables inside a single transaction.
|
|
27
42
|
#
|
|
28
43
|
# @return [void]
|
|
29
44
|
def run
|
|
45
|
+
column_indexes, records = full_location_table
|
|
46
|
+
|
|
30
47
|
ActiveRecord::Base.transaction do
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
FULL_DATA_SEEDS.each do |model_name, type, attributes|
|
|
49
|
+
model = Db.const_get(model_name)
|
|
50
|
+
delete_stale_compact_rows(model)
|
|
51
|
+
seed_full_data(model, records, column_indexes, type, attributes)
|
|
52
|
+
end
|
|
35
53
|
end
|
|
36
54
|
end
|
|
37
55
|
|
|
38
56
|
private
|
|
39
57
|
|
|
58
|
+
# Load the full Rails fixture-style location dump bundled with the gem.
|
|
59
|
+
#
|
|
60
|
+
# The older per-table YAML files only contain +code+ and +name+ for the
|
|
61
|
+
# file-backed API. Database seeding needs the complete dump so lft/rgt,
|
|
62
|
+
# parent links, coordinates, and classification fields are populated.
|
|
63
|
+
#
|
|
64
|
+
# @return [Array(Hash, Array<Array>)]
|
|
65
|
+
def full_location_table
|
|
66
|
+
data = Psych.load_file(File.join(DATA_DIR, FULL_DATA_FILE)) || {}
|
|
67
|
+
table = data.fetch(LOCATION_TABLE)
|
|
68
|
+
columns = table.fetch('columns').map(&:to_s)
|
|
69
|
+
|
|
70
|
+
[columns.each_with_index.to_h, table.fetch('records')]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Insert or update rows for one split table from the full location dump.
|
|
74
|
+
#
|
|
75
|
+
# @param model [Class] ActiveRecord model class
|
|
76
|
+
# @param records [Array<Array>] full location dump rows
|
|
77
|
+
# @param column_indexes [Hash] source column names mapped to row indexes
|
|
78
|
+
# @param type [String] source STI type to select
|
|
79
|
+
# @param attributes [Array<String>] destination table attributes
|
|
80
|
+
# @return [void]
|
|
81
|
+
def seed_full_data(model, records, column_indexes, type, attributes)
|
|
82
|
+
type_index = column_indexes.fetch('type')
|
|
83
|
+
attribute_indexes = attributes.to_h { |attribute| [attribute, column_indexes.fetch(attribute)] }
|
|
84
|
+
now = timestamp
|
|
85
|
+
batch = []
|
|
86
|
+
|
|
87
|
+
records.each do |record|
|
|
88
|
+
next unless record[type_index] == type
|
|
89
|
+
|
|
90
|
+
batch << full_data_attributes(record, attribute_indexes, now)
|
|
91
|
+
|
|
92
|
+
next if batch.size < BATCH_SIZE
|
|
93
|
+
|
|
94
|
+
bulk_insert(model, batch)
|
|
95
|
+
batch = []
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
bulk_insert(model, batch) unless batch.empty?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @param record [Array] full location dump row
|
|
102
|
+
# @param attribute_indexes [Hash] destination attributes mapped to row indexes
|
|
103
|
+
# @param now [Time] timestamp shared by the current table seed
|
|
104
|
+
# @return [Hash]
|
|
105
|
+
def full_data_attributes(record, attribute_indexes, now)
|
|
106
|
+
attribute_indexes.to_h { |attribute, index| [attribute, record[index]] }
|
|
107
|
+
.merge('created_at' => now, 'updated_at' => now)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Older loader versions seeded compact file-backed rows with only +code+
|
|
111
|
+
# and +name+. Those rows cannot be upserted into the full-data records
|
|
112
|
+
# because their +code+ values differ from the PSA codes in
|
|
113
|
+
# +pilipinas_data.yml+, so remove them before inserting the canonical set.
|
|
114
|
+
#
|
|
115
|
+
# @param model [Class] ActiveRecord model class
|
|
116
|
+
# @return [void]
|
|
117
|
+
def delete_stale_compact_rows(model)
|
|
118
|
+
model.where(location_id: nil).delete_all
|
|
119
|
+
end
|
|
120
|
+
|
|
40
121
|
# Insert or update rows for one table from a YAML file.
|
|
41
122
|
#
|
|
42
123
|
# @param model [Class] ActiveRecord model class
|
|
@@ -73,7 +154,17 @@ module Pilipinas
|
|
|
73
154
|
# @return [void]
|
|
74
155
|
def bulk_insert(model, batch)
|
|
75
156
|
if model.respond_to?(:upsert_all)
|
|
76
|
-
|
|
157
|
+
begin
|
|
158
|
+
model.upsert_all(batch, unique_by: :code)
|
|
159
|
+
rescue ArgumentError
|
|
160
|
+
raise Pilipinas::Error,
|
|
161
|
+
'pilipinas:load requires a unique index on the `code` column, ' \
|
|
162
|
+
"which is missing from #{model.table_name}. " \
|
|
163
|
+
'Your database was likely created with an older version of the gem. ' \
|
|
164
|
+
"Run the following to add the missing indexes and retry:\n\n " \
|
|
165
|
+
"rails generate pilipinas:code_indexes\n " \
|
|
166
|
+
"rails db:migrate\n"
|
|
167
|
+
end
|
|
77
168
|
elsif model.respond_to?(:insert_all)
|
|
78
169
|
model.insert_all(batch)
|
|
79
170
|
else
|
data/lib/pilipinas/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pilipinas
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nujian Den Mark Meralpis
|
|
@@ -1909,7 +1909,9 @@ files:
|
|
|
1909
1909
|
- lib/data/regions/41165.yml
|
|
1910
1910
|
- lib/data/regions/6398.yml
|
|
1911
1911
|
- lib/data/regions/8808.yml
|
|
1912
|
+
- lib/generators/pilipinas/code_indexes_generator.rb
|
|
1912
1913
|
- lib/generators/pilipinas/migration_generator.rb
|
|
1914
|
+
- lib/generators/templates/add_pilipinas_code_indexes.rb
|
|
1913
1915
|
- lib/generators/templates/migration.rb
|
|
1914
1916
|
- lib/pilipinas.rb
|
|
1915
1917
|
- lib/pilipinas/barangay.rb
|