@@ -9,18 +9,19 @@ def self.call(file_name)
99
1010 def initialize
1111 @cities = { }
12- @buses = { }
13- @buses_services = { }
14- @services = { }
12+ @buses = Hash . new { |h , k | h [ k ] = { } }
13+ @services = Service ::SERVICES . map . with_index ( 1 ) . to_h
14+ @services_buses = @services . map { |_ , index | [ index , [ ] ] } . to_h
15+ @next_bus_id = 0
1516 end
1617
1718 def call ( file_name )
1819 ActiveRecord ::Base . transaction do
1920 truncate
21+ copy_services
2022 copy_trips ( file_name )
2123 copy_cities
2224 copy_buses
23- copy_services
2425 copy_buses_services
2526 end
2627 end
@@ -59,12 +60,12 @@ def copy_trips(file_name)
5960 trip = FastJsonparser . parse ( str )
6061
6162 copy (
62- fetch_city_id ( trip , :from ) ,
63- fetch_city_id ( trip , :to ) ,
64- trip [ :start_time ] ,
65- trip [ :duration_minutes ] ,
66- trip [ :price_cents ] ,
67- fetch_bus_id ( trip [ :bus ] )
63+ fetch_city_id ( trip [ :from ] ) . to_s << ';' <<
64+ fetch_city_id ( trip [ :to ] ) . to_s << ';' <<
65+ trip [ :start_time ] . to_s << ';' <<
66+ trip [ :duration_minutes ] . to_s << ';' <<
67+ trip [ :price_cents ] . to_s << ';' <<
68+ fetch_bus_id ( trip [ :bus ] ) . to_s << " \n "
6869 )
6970
7071 str . clear
@@ -77,37 +78,25 @@ def copy_trips(file_name)
7778 end
7879 end
7980
80- def fetch_city_id ( trip , key )
81- id = @cities [ trip [ key ] ]
81+ def fetch_city_id ( key )
82+ id = @cities [ key ]
8283 if !id
8384 id = @cities . size + 1
84- @cities [ trip [ key ] ] = id
85+ @cities [ key ] = id
8586 end
8687
8788 id
8889 end
8990
9091 def fetch_bus_id ( bus )
91- bus_key = [ bus [ :model ] , bus [ :number ] ]
92- bus_id = @buses [ bus_key ]
92+ bus_id = @buses [ bus [ :model ] ] [ bus [ :number ] ]
9393
9494 if !bus_id
95- bus_id = @buses . size + 1
96- @buses [ bus_key ] = bus_id
95+ bus_id = @next_bus_id += 1
96+ @buses [ bus [ :model ] ] [ bus [ :number ] ] = bus_id
9797
9898 bus [ :services ] . each do |service |
99- service_id = @services [ service ]
100-
101- if !service_id
102- service_id = @services . size + 1
103- @services [ service ] ||= service_id
104- end
105-
106- buses_service_id = @buses_services [ [ bus_id , service_id ] ]
107- if !buses_service_id
108- buses_service_id = @buses_services . size + 1
109- @buses_services [ [ bus_id , service_id ] ] = buses_service_id
110- end
99+ @services_buses [ @services [ service ] ] << bus_id
111100 end
112101 end
113102
@@ -121,11 +110,9 @@ def copy_cities
121110
122111 ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
123112 @cities . each do |name , id |
124- copy ( id , name )
113+ copy ( id . to_s << ';' << name << " \n " )
125114 end
126115 end
127-
128- @cities . clear
129116 end
130117
131118 def copy_buses
@@ -134,12 +121,12 @@ def copy_buses
134121 SQL
135122
136123 ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
137- @buses . each do |( model , number ) , id |
138- copy ( id , model , number )
124+ @buses . each do |model , numbers |
125+ numbers . each do |number , id |
126+ copy ( id . to_s << ';' << model << ';' << number << "\n " )
127+ end
139128 end
140129 end
141-
142- @buses . clear
143130 end
144131
145132 def copy_services
@@ -149,29 +136,27 @@ def copy_services
149136
150137 ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
151138 @services . each do |name , id |
152- copy ( id , name )
139+ copy ( id . to_s << ';' << name << " \n " )
153140 end
154141 end
155-
156- @services . clear
157142 end
158143
159144 def copy_buses_services
160145 sql = <<~SQL
161- copy buses_services (id, bus_id, service_id) from stdin with csv delimiter ';'
146+ copy buses_services (bus_id, service_id) from stdin with csv delimiter ';'
162147 SQL
163148
164149 ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
165- @buses_services . each do |( bus_id , service_id ) , id |
166- copy ( id , bus_id , service_id )
150+ @services_buses . each do |service_id , bus_ids |
151+ bus_ids . each do |bus_id |
152+ copy ( bus_id . to_s << ';' << service_id . to_s << "\n " )
153+ end
167154 end
168155 end
169-
170- @buses_services . clear
171156 end
172157
173- def copy ( * values )
158+ def copy ( values )
174159 # стримим подготовленный чанк данных в postgres
175- ActiveRecord ::Base . connection . raw_connection . put_copy_data ( values . join ( ';' ) << " \n " )
160+ ActiveRecord ::Base . connection . raw_connection . put_copy_data ( values )
176161 end
177162end
0 commit comments