1
1
use std:: { collections:: HashMap , fs} ;
2
2
3
3
use error_stack:: { Report , ResultExt } ;
4
- use sqlx:: { postgres :: PgRow , PgPool , Row } ;
4
+ use sqlx:: { PgPool , Row } ;
5
5
6
6
use crate :: {
7
7
countdown:: { get_all_products, get_categories, COUNTDOWN_BASE_URL , DEFAULT_USER_AGENT } ,
@@ -63,33 +63,27 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
63
63
let new_products_ids = if no_insert {
64
64
vec ! [ ]
65
65
} else {
66
- let mut names: Vec < & str > = Vec :: with_capacity ( products. len ( ) ) ;
67
- let mut barcodes: Vec < & str > = Vec :: with_capacity ( products. len ( ) ) ;
68
- let mut skus: Vec < & str > = Vec :: with_capacity ( products. len ( ) ) ;
66
+ let mut names = Vec :: with_capacity ( products. len ( ) ) ;
67
+ let mut barcodes = Vec :: with_capacity ( products. len ( ) ) ;
68
+ let mut skus = Vec :: with_capacity ( products. len ( ) ) ;
69
69
70
70
for p in & products {
71
- names. push ( & p. name ) ;
72
- barcodes. push ( & p. barcode ) ;
73
- skus. push ( & p. sku ) ;
71
+ names. push ( p. name . clone ( ) ) ;
72
+ barcodes. push ( p. barcode . clone ( ) ) ;
73
+ skus. push ( p. sku . clone ( ) ) ;
74
74
}
75
75
76
- sqlx:: query (
76
+ sqlx:: query! (
77
77
r"INSERT INTO countdown_products (
78
78
name, barcode, sku
79
- ) SELECT * FROM UNNEST($1, $2, $3)
79
+ ) SELECT * FROM UNNEST($1::text[] , $2::text[] , $3::text[] )
80
80
ON CONFLICT (sku) DO NOTHING
81
81
RETURNING sku, id
82
82
" ,
83
+ & names[ ..] ,
84
+ & barcodes[ ..] ,
85
+ & skus[ ..]
83
86
)
84
- . bind ( names)
85
- . bind ( barcodes)
86
- . bind ( skus)
87
- . map ( |row| {
88
- let sku: String = row. get ( 0 ) ;
89
- let id: i32 = row. get ( 1 ) ;
90
-
91
- ( sku, id)
92
- } )
93
87
. fetch_all ( & connection)
94
88
. await
95
89
. change_context ( ApplicationError :: NewProductsInsertionError ) ?
@@ -99,8 +93,8 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
99
93
// Map<sku, countdown_id>
100
94
let mut new_skus = new_products_ids. into_iter ( ) . fold (
101
95
HashMap :: with_capacity ( product_count) ,
102
- |mut map, ( sku , countdown_id ) | {
103
- map. insert ( sku, countdown_id ) ;
96
+ |mut map, product | {
97
+ map. insert ( product . sku , product . id ) ;
104
98
map
105
99
} ,
106
100
) ;
@@ -110,12 +104,12 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
110
104
. iter ( )
111
105
. filter_map ( |p| new_skus. remove ( & p. sku ) )
112
106
. collect :: < Vec < _ > > ( ) ;
113
- sqlx:: query (
107
+ sqlx:: query! (
114
108
r"INSERT INTO PRODUCTS (
115
109
countdown_id
116
- ) SELECT * FROM UNNEST($1)" ,
110
+ ) SELECT * FROM UNNEST($1::integer[])" ,
111
+ & new_products[ ..]
117
112
)
118
- . bind ( new_products)
119
113
. execute ( & connection)
120
114
. await
121
115
. change_context ( ApplicationError :: NewProductsInsertionError ) ?;
@@ -125,18 +119,12 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
125
119
126
120
// upload all price data
127
121
{
128
- let mapped_product_ids = sqlx:: query (
122
+ let mapped_product_ids = sqlx:: query! (
129
123
r"SELECT products.id, countdown_products.sku FROM products
130
124
INNER JOIN countdown_products
131
125
ON products.countdown_id = countdown_products.id
132
126
WHERE countdown_id IS NOT NULL" ,
133
127
)
134
- . map ( |row : PgRow | {
135
- let id: i32 = row. get ( 0 ) ;
136
- let sku: String = row. get ( 1 ) ;
137
-
138
- ( id, sku)
139
- } )
140
128
. fetch_all ( & connection)
141
129
. await
142
130
. change_context ( ApplicationError :: PriceDataInsertionError ) ?;
@@ -151,18 +139,18 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
151
139
}
152
140
153
141
let mut lost_skus = vec ! [ ] ;
154
- for ( product_id , sku ) in mapped_product_ids {
142
+ for mapped_product in mapped_product_ids {
155
143
// retrieve the cost associated with this sku
156
- let product_cost = mapped_products. remove ( & sku) ;
144
+ let product_cost = mapped_products. remove ( & mapped_product . sku ) ;
157
145
158
146
// find the product
159
147
match product_cost {
160
148
Some ( cost) => {
161
- product_ids. push ( product_id ) ;
149
+ product_ids. push ( mapped_product . id ) ;
162
150
cost_in_cents. push ( cost) ;
163
- supermarket. push ( "countdown" ) ;
151
+ supermarket. push ( "countdown" . to_string ( ) ) ;
164
152
}
165
- None => lost_skus. push ( sku) ,
153
+ None => lost_skus. push ( mapped_product . sku ) ,
166
154
}
167
155
}
168
156
@@ -186,16 +174,16 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
186
174
println ! ( "Skipped inserting prices into database" ) ;
187
175
} else {
188
176
// now insert the rows
189
- sqlx:: query (
177
+ sqlx:: query! (
190
178
"INSERT INTO prices (
191
179
product_id,
192
180
cost_in_cents,
193
181
supermarket
194
- ) SELECT * FROM UNNEST($1, $2, $3)" ,
182
+ ) SELECT * FROM UNNEST($1::integer[], $2::integer[], $3::text[])" ,
183
+ & product_ids[ ..] ,
184
+ & cost_in_cents[ ..] ,
185
+ & supermarket[ ..]
195
186
)
196
- . bind ( & product_ids)
197
- . bind ( & cost_in_cents)
198
- . bind ( & supermarket)
199
187
. execute ( & connection)
200
188
. await
201
189
. change_context ( ApplicationError :: PriceDataInsertionError ) ?;
0 commit comments