@@ -23,40 +23,26 @@ defmodule Location.PostalCode do
2323 { :decentralized_counters , false }
2424 ] )
2525
26+ @ ets_table_by_id =
27+ :ets . new ( @ ets_table_by_id , [
28+ :set ,
29+ :named_table ,
30+ :public ,
31+ :compressed ,
32+ { :write_concurrency , true } ,
33+ { :read_concurrency , true } ,
34+ { :decentralized_counters , false }
35+ ] )
36+
2637 source_file ( )
2738 |> File . stream! ( )
2839 |> Stream . chunk_every ( 15_000 )
2940 |> Task . async_stream (
3041 fn chunk ->
3142 chunk
32- |> LocationCSV . parse_stream ( )
33- |> Stream . each ( fn [
34- country_code ,
35- postal_code ,
36- city_name ,
37- _state_name ,
38- state_code ,
39- _municipality ,
40- _municipality_code ,
41- _admin_name3 ,
42- _admin_code3 ,
43- latitude ,
44- longitude ,
45- _accuracy
46- ] ->
47- country_code = String . trim ( country_code )
48-
49- true =
50- :ets . insert (
51- @ ets_table_by_lookup ,
52- { { country_code , state_code , city_name } , { postal_code , latitude , longitude } }
53- )
54-
55- true =
56- :ets . insert (
57- @ ets_table_by_id ,
58- { postal_code , { country_code , state_code , city_name , latitude , longitude } }
59- )
43+ |> PostCodeCSV . parse_stream ( )
44+ |> Stream . each ( fn data ->
45+ __MODULE__ . parse ( data )
6046 end )
6147 |> Stream . run ( )
6248 end ,
@@ -65,6 +51,125 @@ defmodule Location.PostalCode do
6551 |> Stream . run ( )
6652 end
6753
54+ def parse ( data ) do
55+ case data do
56+ [
57+ country_code ,
58+ postal_code ,
59+ city_name ,
60+ _state_name ,
61+ state_code ,
62+ _municipality ,
63+ _municipality_code ,
64+ _admin_name3 ,
65+ _admin_code3 ,
66+ latitude ,
67+ longitude ,
68+ _accuracy ,
69+ _ ,
70+ _
71+ ] ->
72+ country_code = String . trim ( country_code )
73+
74+ true =
75+ :ets . insert (
76+ @ ets_table_by_lookup ,
77+ { { country_code , state_code , city_name } , { postal_code , latitude , longitude } }
78+ )
79+
80+ true =
81+ :ets . insert (
82+ @ ets_table_by_id ,
83+ { postal_code , { country_code , state_code , city_name , latitude , longitude } }
84+ )
85+
86+ [
87+ country_code ,
88+ postal_code ,
89+ city_name ,
90+ _state_name ,
91+ state_code ,
92+ _municipality ,
93+ _municipality_code ,
94+ _admin_name3 ,
95+ _admin_code3 ,
96+ latitude ,
97+ longitude ,
98+ _accuracy ,
99+ _
100+ ] ->
101+ country_code = String . trim ( country_code )
102+
103+ true =
104+ :ets . insert (
105+ @ ets_table_by_lookup ,
106+ { { country_code , state_code , city_name } , { postal_code , latitude , longitude } }
107+ )
108+
109+ true =
110+ :ets . insert (
111+ @ ets_table_by_id ,
112+ { postal_code , { country_code , state_code , city_name , latitude , longitude } }
113+ )
114+
115+ [
116+ country_code ,
117+ postal_code ,
118+ city_name ,
119+ _state_name ,
120+ state_code ,
121+ _municipality ,
122+ _municipality_code ,
123+ _admin_name3 ,
124+ _admin_code3 ,
125+ latitude ,
126+ longitude ,
127+ _accuracy
128+ ] ->
129+ country_code = String . trim ( country_code )
130+
131+ true =
132+ :ets . insert (
133+ @ ets_table_by_lookup ,
134+ { { country_code , state_code , city_name } , { postal_code , latitude , longitude } }
135+ )
136+
137+ true =
138+ :ets . insert (
139+ @ ets_table_by_id ,
140+ { postal_code , { country_code , state_code , city_name , latitude , longitude } }
141+ )
142+
143+ [
144+ country_code ,
145+ postal_code ,
146+ city_name ,
147+ _state_name ,
148+ state_code ,
149+ _municipality ,
150+ _municipality_code ,
151+ _admin_name3 ,
152+ _admin_code3 ,
153+ latitude ,
154+ longitude
155+ ] ->
156+ true =
157+ :ets . insert (
158+ @ ets_table_by_lookup ,
159+ { { country_code , state_code , city_name } , { postal_code , latitude , longitude } }
160+ )
161+
162+ true =
163+ :ets . insert (
164+ @ ets_table_by_id ,
165+ { postal_code , { country_code , state_code , city_name , latitude , longitude } }
166+ )
167+
168+ _data ->
169+ :ok
170+ end
171+ end
172+
68173 @ doc """
69174 Finds postal_code information by postal code.
70175 """
@@ -99,6 +204,15 @@ defmodule Location.PostalCode do
99204 end
100205 end
101206
207+ @ spec get_postal_codes ( ) :: % __MODULE__ { } | nil
208+ def get_postal_codes ( ) do
209+ :ets . tab2list ( @ ets_table_by_id )
210+ |> Enum . map ( fn x ->
211+ { { country_code , state_code , city_name } , { postal_code , latitude , longitude } } = x
212+ to_struct ( postal_code , country_code , state_code , city_name , latitude , longitude )
213+ end )
214+ end
215+
102216 defp source_file ( ) do
103217 default = Application . app_dir ( :location , "/priv/postal_codes.csv" )
104218 Application . get_env ( :location , :postal_codes_source_file , default )
0 commit comments