@@ -9,18 +9,19 @@ def self.call(file_name)
9
9
10
10
def initialize
11
11
@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
15
16
end
16
17
17
18
def call ( file_name )
18
19
ActiveRecord ::Base . transaction do
19
20
truncate
21
+ copy_services
20
22
copy_trips ( file_name )
21
23
copy_cities
22
24
copy_buses
23
- copy_services
24
25
copy_buses_services
25
26
end
26
27
end
@@ -59,12 +60,12 @@ def copy_trips(file_name)
59
60
trip = FastJsonparser . parse ( str )
60
61
61
62
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 "
68
69
)
69
70
70
71
str . clear
@@ -77,37 +78,25 @@ def copy_trips(file_name)
77
78
end
78
79
end
79
80
80
- def fetch_city_id ( trip , key )
81
- id = @cities [ trip [ key ] ]
81
+ def fetch_city_id ( key )
82
+ id = @cities [ key ]
82
83
if !id
83
84
id = @cities . size + 1
84
- @cities [ trip [ key ] ] = id
85
+ @cities [ key ] = id
85
86
end
86
87
87
88
id
88
89
end
89
90
90
91
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 ] ]
93
93
94
94
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
97
97
98
98
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
111
100
end
112
101
end
113
102
@@ -121,11 +110,9 @@ def copy_cities
121
110
122
111
ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
123
112
@cities . each do |name , id |
124
- copy ( id , name )
113
+ copy ( id . to_s << ';' << name << " \n " )
125
114
end
126
115
end
127
-
128
- @cities . clear
129
116
end
130
117
131
118
def copy_buses
@@ -134,12 +121,12 @@ def copy_buses
134
121
SQL
135
122
136
123
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
139
128
end
140
129
end
141
-
142
- @buses . clear
143
130
end
144
131
145
132
def copy_services
@@ -149,29 +136,27 @@ def copy_services
149
136
150
137
ActiveRecord ::Base . connection . raw_connection . copy_data ( sql ) do
151
138
@services . each do |name , id |
152
- copy ( id , name )
139
+ copy ( id . to_s << ';' << name << " \n " )
153
140
end
154
141
end
155
-
156
- @services . clear
157
142
end
158
143
159
144
def copy_buses_services
160
145
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 ';'
162
147
SQL
163
148
164
149
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
167
154
end
168
155
end
169
-
170
- @buses_services . clear
171
156
end
172
157
173
- def copy ( * values )
158
+ def copy ( values )
174
159
# стримим подготовленный чанк данных в postgres
175
- ActiveRecord ::Base . connection . raw_connection . put_copy_data ( values . join ( ';' ) << " \n " )
160
+ ActiveRecord ::Base . connection . raw_connection . put_copy_data ( values )
176
161
end
177
162
end
0 commit comments