fix: support sqlx 0.9
This commit is contained in:
parent
deefd10a71
commit
7563250809
8 changed files with 28 additions and 17 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
[tools]
|
[tools]
|
||||||
rust = { version = "1.93", components = "rustfmt,clippy,rust-analyzer,rust-src" }
|
rust = { version = "1.94", components = "rustfmt,clippy,rust-analyzer,rust-src" }
|
||||||
node = "latest"
|
node = "latest"
|
||||||
uv = "latest"
|
uv = "latest"
|
||||||
prek = "latest"
|
prek = "latest"
|
||||||
|
|
|
||||||
11
Dockerfile
11
Dockerfile
|
|
@ -4,16 +4,23 @@
|
||||||
# Uses chisel to create a minimal Ubuntu rootfs for the runtime image.
|
# Uses chisel to create a minimal Ubuntu rootfs for the runtime image.
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Builder — Ubuntu with Rust toolchain pre-installed
|
# Builder — Ubuntu with Rust toolchain installed
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
FROM ubuntu/rust:1.93-26.04_edge AS builder
|
FROM ubuntu:26.04 AS builder
|
||||||
|
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||||
|
CARGO_HOME=/usr/local/cargo \
|
||||||
|
PATH=/usr/local/cargo/bin:${PATH}
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
build-essential \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
mold \
|
mold \
|
||||||
binutils \
|
binutils \
|
||||||
curl \
|
curl \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN curl -sSf https://sh.rustup.rs \
|
||||||
|
| sh -s -- -y --profile minimal --default-toolchain 1.94.1
|
||||||
|
|
||||||
# Install tailwindcss standalone (needed by build.rs)
|
# Install tailwindcss standalone (needed by build.rs)
|
||||||
RUN mkdir -p /usr/local/bin \
|
RUN mkdir -p /usr/local/bin \
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use anyhow::{Context, bail};
|
||||||
use chrono::{DateTime, NaiveDate, Utc};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{from_str, to_string};
|
use serde_json::{from_str, to_string};
|
||||||
|
use sqlx::AssertSqlSafe;
|
||||||
|
|
||||||
use crate::domain::bags::Bag;
|
use crate::domain::bags::Bag;
|
||||||
use crate::domain::brews::{Brew, QuickNote};
|
use crate::domain::brews::{Brew, QuickNote};
|
||||||
|
|
@ -175,7 +176,7 @@ impl BackupService {
|
||||||
|
|
||||||
for table in tables {
|
for table in tables {
|
||||||
let query = format!("DELETE FROM {table}");
|
let query = format!("DELETE FROM {table}");
|
||||||
sqlx::query(&query)
|
sqlx::query(AssertSqlSafe(query))
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed to delete from {table}"))?;
|
.with_context(|| format!("failed to delete from {table}"))?;
|
||||||
|
|
@ -316,7 +317,7 @@ impl BackupService {
|
||||||
|
|
||||||
for table in tables {
|
for table in tables {
|
||||||
let query = format!("SELECT COUNT(*) as count FROM {table}");
|
let query = format!("SELECT COUNT(*) as count FROM {table}");
|
||||||
let row: (i64,) = sqlx::query_as(&query)
|
let row: (i64,) = sqlx::query_as(AssertSqlSafe(query))
|
||||||
.fetch_one(&self.pool)
|
.fetch_one(&self.pool)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed to check table {table}"))?;
|
.with_context(|| format!("failed to check table {table}"))?;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::{DateTime, NaiveDate, Utc};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
use sqlx::{QueryBuilder, query_as};
|
use sqlx::{AssertSqlSafe, QueryBuilder, query_as};
|
||||||
|
|
||||||
use crate::domain::RepositoryError;
|
use crate::domain::RepositoryError;
|
||||||
use crate::domain::bags::{Bag, BagFilter, BagSortKey, BagWithRoast, NewBag, UpdateBag};
|
use crate::domain::bags::{Bag, BagFilter, BagSortKey, BagWithRoast, NewBag, UpdateBag};
|
||||||
|
|
@ -119,7 +119,7 @@ impl BagRepository for SqlBagRepository {
|
||||||
async fn get_with_roast(&self, id: BagId) -> Result<BagWithRoast, RepositoryError> {
|
async fn get_with_roast(&self, id: BagId) -> Result<BagWithRoast, RepositoryError> {
|
||||||
let query = format!("{BASE_SELECT} WHERE b.id = ?");
|
let query = format!("{BASE_SELECT} WHERE b.id = ?");
|
||||||
|
|
||||||
let record = query_as::<_, BagWithRoastRecord>(&query)
|
let record = query_as::<_, BagWithRoastRecord>(AssertSqlSafe(query))
|
||||||
.bind(id.into_inner())
|
.bind(id.into_inner())
|
||||||
.fetch_optional(&self.pool)
|
.fetch_optional(&self.pool)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use sqlx::{QueryBuilder, query_as};
|
use sqlx::{AssertSqlSafe, QueryBuilder, query_as};
|
||||||
|
|
||||||
use crate::domain::RepositoryError;
|
use crate::domain::RepositoryError;
|
||||||
use crate::domain::brews::{
|
use crate::domain::brews::{
|
||||||
|
|
@ -189,7 +189,7 @@ impl BrewRepository for SqlBrewRepository {
|
||||||
async fn get_with_details(&self, id: BrewId) -> Result<BrewWithDetails, RepositoryError> {
|
async fn get_with_details(&self, id: BrewId) -> Result<BrewWithDetails, RepositoryError> {
|
||||||
let query = format!("{BASE_SELECT} WHERE br.id = ?");
|
let query = format!("{BASE_SELECT} WHERE br.id = ?");
|
||||||
|
|
||||||
let record = query_as::<_, BrewWithDetailsRecord>(&query)
|
let record = query_as::<_, BrewWithDetailsRecord>(AssertSqlSafe(query))
|
||||||
.bind(id.into_inner())
|
.bind(id.into_inner())
|
||||||
.fetch_optional(&self.pool)
|
.fetch_optional(&self.pool)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use sqlx::{QueryBuilder, query, query_as};
|
use sqlx::{AssertSqlSafe, QueryBuilder, query, query_as};
|
||||||
|
|
||||||
use crate::domain::RepositoryError;
|
use crate::domain::RepositoryError;
|
||||||
use crate::domain::cups::{Cup, CupFilter, CupSortKey, CupWithDetails, NewCup, UpdateCup};
|
use crate::domain::cups::{Cup, CupFilter, CupSortKey, CupWithDetails, NewCup, UpdateCup};
|
||||||
|
|
@ -113,7 +113,7 @@ impl CupRepository for SqlCupRepository {
|
||||||
async fn get_with_details(&self, id: CupId) -> Result<CupWithDetails, RepositoryError> {
|
async fn get_with_details(&self, id: CupId) -> Result<CupWithDetails, RepositoryError> {
|
||||||
let query = format!("{BASE_SELECT} WHERE c.id = ?");
|
let query = format!("{BASE_SELECT} WHERE c.id = ?");
|
||||||
|
|
||||||
let record = query_as::<_, CupWithDetailsRecord>(&query)
|
let record = query_as::<_, CupWithDetailsRecord>(AssertSqlSafe(query))
|
||||||
.bind(id.into_inner())
|
.bind(id.into_inner())
|
||||||
.fetch_optional(&self.pool)
|
.fetch_optional(&self.pool)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use sqlx::{FromRow, QueryBuilder, query_scalar};
|
use sqlx::{AssertSqlSafe, FromRow, QueryBuilder, query_scalar};
|
||||||
|
|
||||||
use crate::domain::RepositoryError;
|
use crate::domain::RepositoryError;
|
||||||
use crate::domain::listing::{ListRequest, Page, PageSize, SortKey};
|
use crate::domain::listing::{ListRequest, Page, PageSize, SortKey};
|
||||||
|
|
@ -102,7 +102,7 @@ where
|
||||||
qb.push(" OFFSET ");
|
qb.push(" OFFSET ");
|
||||||
qb.push_bind(offset);
|
qb.push_bind(offset);
|
||||||
}
|
}
|
||||||
qb.build_query_as()
|
qb.build_query_as::<R>()
|
||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| RepositoryError::unexpected(err.to_string()))
|
.map_err(|err| RepositoryError::unexpected(err.to_string()))
|
||||||
|
|
@ -117,13 +117,13 @@ async fn fetch_count(
|
||||||
let mut qb = QueryBuilder::new(count_query);
|
let mut qb = QueryBuilder::new(count_query);
|
||||||
append_search_condition(&mut qb, count_query, sf);
|
append_search_condition(&mut qb, count_query, sf);
|
||||||
let row: (i64,) = qb
|
let row: (i64,) = qb
|
||||||
.build_query_as()
|
.build_query_as::<(i64,)>()
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| RepositoryError::unexpected(err.to_string()))?;
|
.map_err(|err| RepositoryError::unexpected(err.to_string()))?;
|
||||||
Ok(row.0)
|
Ok(row.0)
|
||||||
} else {
|
} else {
|
||||||
query_scalar(count_query)
|
query_scalar(AssertSqlSafe(count_query))
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| RepositoryError::unexpected(err.to_string()))
|
.map_err(|err| RepositoryError::unexpected(err.to_string()))
|
||||||
|
|
@ -131,7 +131,7 @@ async fn fetch_count(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_search_condition(
|
fn append_search_condition(
|
||||||
qb: &mut QueryBuilder<'_, DatabaseDriver>,
|
qb: &mut QueryBuilder<DatabaseDriver>,
|
||||||
base_sql: &str,
|
base_sql: &str,
|
||||||
search: &SearchFilter,
|
search: &SearchFilter,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,10 @@ async fn checkin_with_new_cafe_and_scanned_roast() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
prompt_input.send_keys(Key::Enter).await.unwrap();
|
prompt_input.send_keys(Key::Enter).await.unwrap();
|
||||||
|
|
||||||
// Wait for scan to complete — step 3 becomes visible with the submit button
|
// Wait for scan to complete and populate the review before submitting.
|
||||||
|
wait_for_text(&session.driver, "body", "Kiandu AA")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let submit_btn = wait_for_visible(&session.driver, "button[type='submit']")
|
let submit_btn = wait_for_visible(&session.driver, "button[type='submit']")
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue