Added functionality to added article.
This commit is contained in:
Generated
+16
@@ -399,6 +399,7 @@ name = "common"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
@@ -1881,6 +1882,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
@@ -2351,6 +2353,20 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ sqlx = { version = "0.8.6", features = [ "runtime-async-std-native-tls", "postgr
|
|||||||
|
|
||||||
# Etc.
|
# Etc.
|
||||||
chrono = { version = "0.4.42", features = [ "serde" ] }
|
chrono = { version = "0.4.42", features = [ "serde" ] }
|
||||||
|
log = "0.4.29"
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::FromRow;
|
use sqlx::{FromRow, PgPool};
|
||||||
use crate::models::origin::Origin;
|
use crate::models::origin::Origin;
|
||||||
use crate::models::variant::Variant;
|
use crate::models::variant::Variant;
|
||||||
|
use sqlx::{Arguments, Pool, Row, Postgres, Error};
|
||||||
|
use sqlx::postgres::{PgArguments, PgQueryResult, PgRow};
|
||||||
|
use log::{debug, info};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, FromRow)]
|
#[derive(Debug, Deserialize, Serialize, Clone, FromRow)]
|
||||||
pub struct Article {
|
pub struct Article {
|
||||||
@@ -13,3 +16,25 @@ pub struct Article {
|
|||||||
pub ingredients: Option<String>,
|
pub ingredients: Option<String>,
|
||||||
pub variants: Vec<Variant>,
|
pub variants: Vec<Variant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn insert_article(article: &Article, pool: PgPool) {
|
||||||
|
let mut args = PgArguments::default();
|
||||||
|
args.add(&article.name);
|
||||||
|
args.add(&article.bio);
|
||||||
|
args.add(&article.origin);
|
||||||
|
args.add(&article.description);
|
||||||
|
args.add(&article.ingredients);
|
||||||
|
|
||||||
|
// Add to price history:
|
||||||
|
let statement = format!(
|
||||||
|
"INSERT INTO {} (name, bio, origin, description, ingredients) VALUES ($1, $2, $3, $4, $5)",
|
||||||
|
"article",
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = sqlx::query_with(
|
||||||
|
statement.as_str(),
|
||||||
|
args)
|
||||||
|
.execute(&pool).await.unwrap();
|
||||||
|
|
||||||
|
info!("{:#?}", res);
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,15 +6,22 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Deserialize, Serialize, Copy, Clone, PartialEq, sqlx::Type)]
|
#[derive(Deserialize, Serialize, Copy, Clone, PartialEq, sqlx::Type)]
|
||||||
pub enum Origin {
|
pub enum Origin {
|
||||||
EU,
|
EU,
|
||||||
NEU,
|
NonEU,
|
||||||
EUnEU,
|
EUnonEU,
|
||||||
|
}
|
||||||
|
impl Origin {
|
||||||
|
pub const VEC: &'static [Origin] = &[Origin::EU, Origin::NonEU, Origin::EUnonEU];
|
||||||
|
|
||||||
|
pub fn position(&self) -> usize {
|
||||||
|
Origin::VEC.iter().position(|r| *r == *self).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string(unit: Origin, f: &mut Formatter) -> fmt::Result {
|
fn to_string(unit: Origin, f: &mut Formatter) -> fmt::Result {
|
||||||
match unit {
|
match unit {
|
||||||
Origin::EU => write!(f, "EU"),
|
Origin::EU => write!(f, "EU"),
|
||||||
Origin::NEU => write!(f, "Nicht EU"),
|
Origin::NonEU => write!(f, "Nicht EU"),
|
||||||
Origin::EUnEU => write!(f, "EU / Nicht EU"),
|
Origin::EUnonEU => write!(f, "EU / Nicht EU"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
let origins: Origin[] = [
|
let origins: Origin[] = [
|
||||||
Origin.EU,
|
Origin.EU,
|
||||||
Origin.NEU,
|
Origin.NonEU,
|
||||||
Origin.EUnEU
|
Origin.EUnonEU
|
||||||
];
|
];
|
||||||
|
|
||||||
async function create() {
|
async function create() {
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="2">
|
<v-col cols="2">
|
||||||
<v-checkbox
|
<v-checkbox
|
||||||
v-model.="bio"
|
v-model="bio"
|
||||||
label="BIO"
|
label="BIO"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export enum Origin {
|
export enum Origin {
|
||||||
EU = "EU",
|
EU = "EU",
|
||||||
NEU = "Nicht - EU",
|
NonEU = "NonEU",
|
||||||
EUnEU= "EU / Nicht EU",
|
EUnonEU= "EUnonEU",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
runtimeConfig: {
|
||||||
|
public: {
|
||||||
|
url: process.env.URL || 'http://localhost:9090',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
compatibilityDate: '2025-07-15',
|
compatibilityDate: '2025-07-15',
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ common = {path = "../common"}
|
|||||||
axum = "0.8.8"
|
axum = "0.8.8"
|
||||||
tokio = { version = "1.49.0", default-features = false, features = ["full"] }
|
tokio = { version = "1.49.0", default-features = false, features = ["full"] }
|
||||||
http = "1.4.0"
|
http = "1.4.0"
|
||||||
|
tower-http = {version = "0.6.8", features = ["cors"]}
|
||||||
tracing = "=0.1.44"
|
tracing = "=0.1.44"
|
||||||
tracing-subscriber = "0.3.22"
|
tracing-subscriber = "0.3.22"
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,49 @@
|
|||||||
-- Add migration script here
|
-- Add migration script here
|
||||||
|
CREATE TABLE origin
|
||||||
|
(
|
||||||
|
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 0 MINVALUE 0 ),
|
||||||
|
name text NOT NULL,
|
||||||
|
CONSTRAINT origin_id PRIMARY KEY (id)
|
||||||
|
INCLUDE(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE article
|
||||||
|
(
|
||||||
|
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 ),
|
||||||
|
name text NOT NULL,
|
||||||
|
bio boolean NOT NULL,
|
||||||
|
origin bigint NOT NULL,
|
||||||
|
description text,
|
||||||
|
ingredients text,
|
||||||
|
CONSTRAINT article_id PRIMARY KEY (id)
|
||||||
|
INCLUDE(id),
|
||||||
|
FOREIGN KEY (origin)
|
||||||
|
REFERENCES origin (id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
NOT VALID
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE variant
|
||||||
|
(
|
||||||
|
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 ),
|
||||||
|
article_id bigint NOT NULL,
|
||||||
|
weight text NOT NULL,
|
||||||
|
ean text NOT NULL,
|
||||||
|
name text NOT NULL,
|
||||||
|
description text NOT NULL,
|
||||||
|
ingredients text NOT NULL,
|
||||||
|
CONSTRAINT variant_id PRIMARY KEY (id)
|
||||||
|
INCLUDE(id),
|
||||||
|
FOREIGN KEY (article_id)
|
||||||
|
REFERENCES article (id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
NOT VALID
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Insert origin options
|
||||||
|
INSERT INTO origin (name) VALUES ('EU');
|
||||||
|
INSERT INTO origin (name) VALUES ('Nicht EU');
|
||||||
|
INSERT INTO origin (name) VALUES ('EU / Nicht EU');
|
||||||
|
|||||||
+26
-5
@@ -7,9 +7,14 @@ use axum::{
|
|||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use env_logger::fmt::style::Reset;
|
use env_logger::fmt::style::Reset;
|
||||||
use common::models::article::Article;
|
use http::{header, Method};
|
||||||
|
use common::models::article::{insert_article, Article};
|
||||||
use common::models::origin::Origin;
|
use common::models::origin::Origin;
|
||||||
use sqlx::{ postgres::PgPoolOptions, PgPool };
|
use sqlx::{ postgres::PgPoolOptions, PgPool };
|
||||||
|
use tower_http::cors::{AllowOrigin, Any, CorsLayer};
|
||||||
|
use tracing::info;
|
||||||
|
use http::header::{AUTHORIZATION, ACCEPT, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE, ACCESS_CONTROL_ALLOW_CREDENTIALS};
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@@ -23,24 +28,36 @@ async fn main() {
|
|||||||
|
|
||||||
// initialize tracing
|
// initialize tracing
|
||||||
tracing_subscriber::fmt().init();
|
tracing_subscriber::fmt().init();
|
||||||
|
/*
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_max_level(tracing::Level::INFO)
|
||||||
|
.init();
|
||||||
|
*/
|
||||||
|
|
||||||
let pool = PgPoolOptions::new()
|
let pool = PgPoolOptions::new()
|
||||||
.max_connections(50)
|
.max_connections(50)
|
||||||
.connect(&database)
|
.connect(&database)
|
||||||
.await
|
.await
|
||||||
.expect(&format!("Can't connect to database: {}", &database));
|
.expect(&format!("Can't connect to database: {}", &database));
|
||||||
|
|
||||||
sqlx::migrate!().run(&pool).await.expect("Migrations failed");
|
sqlx::migrate!().run(&pool).await.expect("Migrations failed");
|
||||||
|
|
||||||
|
let cors = CorsLayer::new()
|
||||||
|
.allow_methods([Method::GET, Method::POST])
|
||||||
|
.allow_headers([ACCEPT, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE])
|
||||||
|
.allow_origin(AllowOrigin::any());
|
||||||
|
|
||||||
// build our application with a route
|
// build our application with a route
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
// `GET /` goes to `root`
|
// `GET /` goes to `root`
|
||||||
.route("/", get(root))
|
.route("/", get(root))
|
||||||
// `POST /users` goes to `create_user`
|
|
||||||
.route("/article", post(create_article))
|
.route("/article", post(create_article))
|
||||||
.with_state(pool);
|
.with_state(pool)
|
||||||
|
.layer(cors);
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
||||||
|
info!("Server started on: {}", &addr);
|
||||||
|
|
||||||
// run our app with hyper, listening globally on port 3000
|
|
||||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +71,8 @@ async fn create_article(
|
|||||||
State(pool): State<PgPool>,
|
State(pool): State<PgPool>,
|
||||||
Json(payload): Json<Article>,
|
Json(payload): Json<Article>,
|
||||||
) -> (StatusCode, Json<Article>) {
|
) -> (StatusCode, Json<Article>) {
|
||||||
|
info!("Test");
|
||||||
|
|
||||||
let article = Article {
|
let article = Article {
|
||||||
id: payload.id,
|
id: payload.id,
|
||||||
name: payload.name,
|
name: payload.name,
|
||||||
@@ -64,5 +83,7 @@ async fn create_article(
|
|||||||
variants: payload.variants,
|
variants: payload.variants,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
insert_article(&article, pool).await;
|
||||||
|
|
||||||
(StatusCode::CREATED, Json(article))
|
(StatusCode::CREATED, Json(article))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user