Skip to content

Commit fdce0db

Browse files
committed
Add offline queries for sqlx
1 parent 990e0fa commit fdce0db

7 files changed

+135
-40
lines changed

.sqlx/query-346e9c4fc581481844fba6fb48ae0a7d0fcd1c240c9178ebb88525203f878ff6.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-43f71b38b4757a5ba87f17382c3c4ed46931a76e5a5784dff5370ff92c498927.json

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-cc717d00824389698175325ababa574668afccc7996b3635a6d525a0c48da9b0.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-e56b2c36df7837da008092f632b3d406558231138384fb057a9ab103893db65a.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ edition = "2021"
66
license = "MIT OR Apache-2.0"
77
publish = false
88

9+
[lib]
10+
path = "src/lib.rs"
11+
12+
[[bin]]
13+
name = "supermarket-tracker"
14+
path = "src/main.rs"
15+
916
[dependencies]
1017
reqwest = { version = "0.11.22", default-features = false, features = [
1118
"gzip",

scripts/prepare_offline.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -x
3+
set -eo pipefail
4+
5+
if ! [ -x "$(command -v sqlx)" ]; then
6+
echo >&2 "Error: sqlx is not installed."
7+
echo >&2 "Use:"
8+
echo >&2 " cargo install sqlx-cli \
9+
--no-default-features --features rustls,postgres"
10+
echo >&2 "to install it."
11+
exit 1
12+
fi
13+
14+
cargo sqlx prepare --workspace

src/countdown/run.rs

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{collections::HashMap, fs};
22

33
use error_stack::{Report, ResultExt};
4-
use sqlx::{postgres::PgRow, PgPool, Row};
4+
use sqlx::{PgPool, Row};
55

66
use crate::{
77
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
6363
let new_products_ids = if no_insert {
6464
vec![]
6565
} 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());
6969

7070
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());
7474
}
7575

76-
sqlx::query(
76+
sqlx::query!(
7777
r"INSERT INTO countdown_products (
7878
name, barcode, sku
79-
) SELECT * FROM UNNEST($1, $2, $3)
79+
) SELECT * FROM UNNEST($1::text[], $2::text[], $3::text[])
8080
ON CONFLICT (sku) DO NOTHING
8181
RETURNING sku, id
8282
",
83+
&names[..],
84+
&barcodes[..],
85+
&skus[..]
8386
)
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-
})
9387
.fetch_all(&connection)
9488
.await
9589
.change_context(ApplicationError::NewProductsInsertionError)?
@@ -99,8 +93,8 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
9993
// Map<sku, countdown_id>
10094
let mut new_skus = new_products_ids.into_iter().fold(
10195
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);
10498
map
10599
},
106100
);
@@ -110,12 +104,12 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
110104
.iter()
111105
.filter_map(|p| new_skus.remove(&p.sku))
112106
.collect::<Vec<_>>();
113-
sqlx::query(
107+
sqlx::query!(
114108
r"INSERT INTO PRODUCTS (
115109
countdown_id
116-
) SELECT * FROM UNNEST($1)",
110+
) SELECT * FROM UNNEST($1::integer[])",
111+
&new_products[..]
117112
)
118-
.bind(new_products)
119113
.execute(&connection)
120114
.await
121115
.change_context(ApplicationError::NewProductsInsertionError)?;
@@ -125,18 +119,12 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
125119

126120
// upload all price data
127121
{
128-
let mapped_product_ids = sqlx::query(
122+
let mapped_product_ids = sqlx::query!(
129123
r"SELECT products.id, countdown_products.sku FROM products
130124
INNER JOIN countdown_products
131125
ON products.countdown_id = countdown_products.id
132126
WHERE countdown_id IS NOT NULL",
133127
)
134-
.map(|row: PgRow| {
135-
let id: i32 = row.get(0);
136-
let sku: String = row.get(1);
137-
138-
(id, sku)
139-
})
140128
.fetch_all(&connection)
141129
.await
142130
.change_context(ApplicationError::PriceDataInsertionError)?;
@@ -151,18 +139,18 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
151139
}
152140

153141
let mut lost_skus = vec![];
154-
for (product_id, sku) in mapped_product_ids {
142+
for mapped_product in mapped_product_ids {
155143
// 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);
157145

158146
// find the product
159147
match product_cost {
160148
Some(cost) => {
161-
product_ids.push(product_id);
149+
product_ids.push(mapped_product.id);
162150
cost_in_cents.push(cost);
163-
supermarket.push("countdown");
151+
supermarket.push("countdown".to_string());
164152
}
165-
None => lost_skus.push(sku),
153+
None => lost_skus.push(mapped_product.sku),
166154
}
167155
}
168156

@@ -186,16 +174,16 @@ pub async fn run(connection: PgPool, no_insert: bool) -> Result<(), Report<Appli
186174
println!("Skipped inserting prices into database");
187175
} else {
188176
// now insert the rows
189-
sqlx::query(
177+
sqlx::query!(
190178
"INSERT INTO prices (
191179
product_id,
192180
cost_in_cents,
193181
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[..]
195186
)
196-
.bind(&product_ids)
197-
.bind(&cost_in_cents)
198-
.bind(&supermarket)
199187
.execute(&connection)
200188
.await
201189
.change_context(ApplicationError::PriceDataInsertionError)?;

0 commit comments

Comments
 (0)