interior_refs -> interior_ref_lists, finish insert

This commit is contained in:
Tyler Hallada 2020-07-23 00:13:31 -04:00
parent 0275143559
commit 29eadabc8a
10 changed files with 2271 additions and 2468 deletions

View File

@ -20,7 +20,7 @@ pub fn migration() -> String {
m.create_table("shops", |t| { m.create_table("shops", |t| {
t.add_column("id", types::primary().indexed(true)); t.add_column("id", types::primary().indexed(true));
t.add_column("name", types::varchar(255)); t.add_column("name", types::varchar(255));
t.add_column("owner_id", types::foreign("owners", "id")); t.add_column("owner_id", types::foreign("owners", "id").indexed(true));
t.add_column("description", types::text().nullable(true)); t.add_column("description", types::text().nullable(true));
t.add_column("is_not_sell_buy", types::boolean().default(true)); t.add_column("is_not_sell_buy", types::boolean().default(true));
t.add_column("sell_buy_list_id", types::integer().default(0)); t.add_column("sell_buy_list_id", types::integer().default(0));
@ -36,7 +36,7 @@ pub fn migration() -> String {
m.create_table("merchandise", |t| { m.create_table("merchandise", |t| {
t.add_column("id", types::primary().indexed(true)); t.add_column("id", types::primary().indexed(true));
t.add_column("shop_id", types::foreign("shops", "id")); t.add_column("shop_id", types::foreign("shops", "id").indexed(true));
t.add_column("mod_name", types::varchar(255)); t.add_column("mod_name", types::varchar(255));
t.add_column("local_form_id", types::integer()); t.add_column("local_form_id", types::integer());
t.add_column("quantity", types::integer()); t.add_column("quantity", types::integer());
@ -50,7 +50,7 @@ pub fn migration() -> String {
m.create_table("transactions", |t| { m.create_table("transactions", |t| {
t.add_column("id", types::primary().indexed(true)); t.add_column("id", types::primary().indexed(true));
t.add_column("shop_id", types::foreign("shops", "id")); t.add_column("shop_id", types::foreign("shops", "id").indexed(true));
t.add_column("merchandise_id", types::foreign("merchandise", "id")); t.add_column("merchandise_id", types::foreign("merchandise", "id"));
t.add_column("customer_name", types::varchar(255)); t.add_column("customer_name", types::varchar(255));
t.add_column("is_customer_npc", types::boolean()); t.add_column("is_customer_npc", types::boolean());
@ -60,12 +60,10 @@ pub fn migration() -> String {
t.add_column("created_at", types::custom("timestamp(3)")); t.add_column("created_at", types::custom("timestamp(3)"));
}); });
// TODO: rename to interior_reflist or similar? m.create_table("interior_ref_lists", |t| {
// TODO: index shop_id col
m.create_table("interior_refs", |t| {
t.add_column("id", types::primary().indexed(true)); t.add_column("id", types::primary().indexed(true));
t.add_column("shop_id", types::foreign("shops", "id")); t.add_column("shop_id", types::foreign("shops", "id").indexed(true));
t.add_column("references", types::custom("jsonb")); t.add_column("ref_list", types::custom("jsonb"));
t.add_column("created_at", types::custom("timestamp(3)")); t.add_column("created_at", types::custom("timestamp(3)"));
t.add_column("updated_at", types::custom("timestamp(3)")); t.add_column("updated_at", types::custom("timestamp(3)"));
}); });

View File

@ -3,7 +3,7 @@ use std::convert::Infallible;
use warp::{Filter, Rejection, Reply}; use warp::{Filter, Rejection, Reply};
use super::handlers; use super::handlers;
use super::models::{InteriorRef, ListParams, Owner, Shop}; use super::models::{InteriorRefList, ListParams, Owner, Shop};
use super::Environment; use super::Environment;
pub fn get_shop(env: Environment) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { pub fn get_shop(env: Environment) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
@ -61,43 +61,43 @@ pub fn list_owners(
.and_then(handlers::list_owners) .and_then(handlers::list_owners)
} }
pub fn get_interior_ref( pub fn get_interior_ref_list(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path!("interior_refs" / i32) warp::path!("interior_ref_lists" / i32)
.and(warp::get()) .and(warp::get())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::get_interior_ref) .and_then(handlers::get_interior_ref_list)
} }
pub fn create_interior_ref( pub fn create_interior_ref_list(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path!("interior_refs") warp::path!("interior_ref_lists")
.and(warp::post()) .and(warp::post())
.and(json_body::<InteriorRef>()) .and(json_body::<InteriorRefList>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::create_interior_ref) .and_then(handlers::create_interior_ref_list)
} }
pub fn list_interior_refs( pub fn list_interior_ref_lists(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path!("interior_refs") warp::path!("interior_ref_lists")
.and(warp::get()) .and(warp::get())
.and(warp::query::<ListParams>()) .and(warp::query::<ListParams>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::list_interior_refs) .and_then(handlers::list_interior_ref_lists)
} }
pub fn bulk_create_interior_refs( pub fn bulk_create_interior_ref_lists(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path!("interior_refs" / "bulk") warp::path!("interior_ref_lists" / "bulk")
.and(warp::post()) .and(warp::post())
.and(json_body::<Vec<InteriorRef>>()) .and(json_body::<Vec<InteriorRefList>>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::bulk_create_interior_refs) .and_then(handlers::bulk_create_interior_ref_lists)
} }
fn with_env(env: Environment) -> impl Filter<Extract = (Environment,), Error = Infallible> + Clone { fn with_env(env: Environment) -> impl Filter<Extract = (Environment,), Error = Infallible> + Clone {

View File

@ -4,7 +4,7 @@ use warp::http::StatusCode;
use warp::reply::{json, with_header, with_status}; use warp::reply::{json, with_header, with_status};
use warp::{Rejection, Reply}; use warp::{Rejection, Reply};
use super::models::{InteriorRef, ListParams, Model, Owner, Shop}; use super::models::{InteriorRefList, ListParams, Model, Owner, Shop};
use super::problem::reject_anyhow; use super::problem::reject_anyhow;
use super::Environment; use super::Environment;
@ -75,44 +75,49 @@ pub async fn create_owner(
Ok(reply) Ok(reply)
} }
pub async fn get_interior_ref(id: i32, env: Environment) -> Result<impl Reply, Rejection> { pub async fn get_interior_ref_list(id: i32, env: Environment) -> Result<impl Reply, Rejection> {
let interior_ref = InteriorRef::get(&env.db, id).await.map_err(reject_anyhow)?; let interior_ref_list = InteriorRefList::get(&env.db, id)
let reply = json(&interior_ref); .await
.map_err(reject_anyhow)?;
let reply = json(&interior_ref_list);
let reply = with_status(reply, StatusCode::OK); let reply = with_status(reply, StatusCode::OK);
Ok(reply) Ok(reply)
} }
pub async fn list_interior_refs( pub async fn list_interior_ref_lists(
list_params: ListParams, list_params: ListParams,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let interior_refs = InteriorRef::list(&env.db, list_params) let interior_ref_lists = InteriorRefList::list(&env.db, list_params)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
let reply = json(&interior_refs); let reply = json(&interior_ref_lists);
let reply = with_status(reply, StatusCode::OK); let reply = with_status(reply, StatusCode::OK);
Ok(reply) Ok(reply)
} }
pub async fn create_interior_ref( pub async fn create_interior_ref_list(
interior_ref: InteriorRef, interior_ref_list: InteriorRefList,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let saved_interior_ref = interior_ref.save(&env.db).await.map_err(reject_anyhow)?; let saved_interior_ref_list = interior_ref_list
let url = saved_interior_ref .save(&env.db)
.await
.map_err(reject_anyhow)?;
let url = saved_interior_ref_list
.url(&env.api_url) .url(&env.api_url)
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
let reply = json(&saved_interior_ref); let reply = json(&saved_interior_ref_list);
let reply = with_header(reply, "Location", url.as_str()); let reply = with_header(reply, "Location", url.as_str());
let reply = with_status(reply, StatusCode::CREATED); let reply = with_status(reply, StatusCode::CREATED);
Ok(reply) Ok(reply)
} }
pub async fn bulk_create_interior_refs( pub async fn bulk_create_interior_ref_lists(
interior_refs: Vec<InteriorRef>, interior_ref_lists: Vec<InteriorRefList>,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
InteriorRef::bulk_save(&env.db, interior_refs) InteriorRefList::bulk_save(&env.db, interior_ref_lists)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
Ok(StatusCode::CREATED) Ok(StatusCode::CREATED)

View File

@ -77,10 +77,10 @@ async fn main() -> Result<()> {
let get_owner = filters::get_owner(env.clone()); let get_owner = filters::get_owner(env.clone());
let create_owner = filters::create_owner(env.clone()); let create_owner = filters::create_owner(env.clone());
let list_owners = filters::list_owners(env.clone()); let list_owners = filters::list_owners(env.clone());
let get_interior_ref = filters::get_interior_ref(env.clone()); let get_interior_ref_list = filters::get_interior_ref_list(env.clone());
let create_interior_ref = filters::create_interior_ref(env.clone()); let create_interior_ref_list = filters::create_interior_ref_list(env.clone());
let list_interior_refs = filters::list_interior_refs(env.clone()); let list_interior_ref_lists = filters::list_interior_ref_lists(env.clone());
let bulk_create_interior_refs = filters::bulk_create_interior_refs(env.clone()); let bulk_create_interior_ref_lists = filters::bulk_create_interior_ref_lists(env.clone());
let routes = base let routes = base
.and( .and(
create_shop create_shop
@ -89,10 +89,10 @@ async fn main() -> Result<()> {
.or(create_owner) .or(create_owner)
.or(get_owner) .or(get_owner)
.or(list_owners) .or(list_owners)
.or(create_interior_ref) .or(create_interior_ref_list)
.or(get_interior_ref) .or(get_interior_ref_list)
.or(list_interior_refs) .or(list_interior_ref_lists)
.or(bulk_create_interior_refs), .or(bulk_create_interior_ref_lists),
) )
.recover(problem::unpack_problem) .recover(problem::unpack_problem)
.with(warp::compression::gzip()) .with(warp::compression::gzip())

View File

@ -2,25 +2,24 @@ use anyhow::Result;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::prelude::*; use chrono::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use super::ListParams; use super::ListParams;
use super::Model; use super::Model;
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct InteriorRef { pub struct InteriorRefList {
pub id: Option<i32>, pub id: Option<i32>,
pub shop_id: i32, pub shop_id: i32,
pub references: serde_json::value::Value, pub ref_list: serde_json::value::Value,
pub created_at: Option<NaiveDateTime>, pub created_at: Option<NaiveDateTime>,
pub updated_at: Option<NaiveDateTime>, pub updated_at: Option<NaiveDateTime>,
} }
#[async_trait] #[async_trait]
impl Model for InteriorRef { impl Model for InteriorRefList {
fn resource_name() -> &'static str { fn resource_name() -> &'static str {
"interior_ref" "interior_ref_list"
} }
fn pk(&self) -> Option<i32> { fn pk(&self) -> Option<i32> {
@ -29,32 +28,32 @@ impl Model for InteriorRef {
async fn get(db: &PgPool, id: i32) -> Result<Self> { async fn get(db: &PgPool, id: i32) -> Result<Self> {
let timer = std::time::Instant::now(); let timer = std::time::Instant::now();
let result = sqlx::query_as!(Self, "SELECT * FROM interior_refs WHERE id = $1", id) let result = sqlx::query_as!(Self, "SELECT * FROM interior_ref_lists WHERE id = $1", id)
.fetch_one(db) .fetch_one(db)
.await?; .await?;
let elapsed = timer.elapsed(); let elapsed = timer.elapsed();
debug!("SELECT * FROM interior_refs ... {:.3?}", elapsed); debug!("SELECT * FROM interior_ref_lists ... {:.3?}", elapsed);
Ok(result) Ok(result)
} }
async fn save(self, db: &PgPool) -> Result<Self> { async fn save(self, db: &PgPool) -> Result<Self> {
let timer = std::time::Instant::now(); let timer = std::time::Instant::now();
// TODO: // TODO:
// * Actually save the references list to the jsonb column
// * Decide if I'll need to make the same changes to merchandise and transactions // * Decide if I'll need to make the same changes to merchandise and transactions
// - answer depends on how many rows of each I expect to insert in one go // - answer depends on how many rows of each I expect to insert in one go
let result = sqlx::query_as!( let result = sqlx::query_as!(
Self, Self,
"INSERT INTO interior_refs "INSERT INTO interior_ref_lists
(shop_id, created_at, updated_at) (shop_id, ref_list, created_at, updated_at)
VALUES ($1, now(), now()) VALUES ($1, $2, now(), now())
RETURNING *", RETURNING *",
self.shop_id, self.shop_id,
self.ref_list,
) )
.fetch_one(db) .fetch_one(db)
.await?; .await?;
let elapsed = timer.elapsed(); let elapsed = timer.elapsed();
debug!("INSERT INTO interior_refs ... {:.3?}", elapsed); debug!("INSERT INTO interior_ref_lists ... {:.3?}", elapsed);
Ok(result) Ok(result)
} }
@ -63,7 +62,7 @@ impl Model for InteriorRef {
let result = if let Some(order_by) = list_params.get_order_by() { let result = if let Some(order_by) = list_params.get_order_by() {
sqlx::query_as!( sqlx::query_as!(
Self, Self,
"SELECT * FROM interior_refs "SELECT * FROM interior_ref_lists
ORDER BY $1 ORDER BY $1
LIMIT $2 LIMIT $2
OFFSET $3", OFFSET $3",
@ -76,7 +75,7 @@ impl Model for InteriorRef {
} else { } else {
sqlx::query_as!( sqlx::query_as!(
Self, Self,
"SELECT * FROM interior_refs "SELECT * FROM interior_ref_lists
LIMIT $1 LIMIT $1
OFFSET $2", OFFSET $2",
list_params.limit.unwrap_or(10), list_params.limit.unwrap_or(10),
@ -86,7 +85,7 @@ impl Model for InteriorRef {
.await? .await?
}; };
let elapsed = timer.elapsed(); let elapsed = timer.elapsed();
debug!("SELECT * FROM interior_refs ... {:.3?}", elapsed); debug!("SELECT * FROM interior_ref_lists ... {:.3?}", elapsed);
Ok(result) Ok(result)
} }
} }

View File

@ -1,15 +1,15 @@
use serde::Deserialize; use serde::Deserialize;
use std::fmt; use std::fmt;
pub mod interior_ref_list;
pub mod model; pub mod model;
pub mod owner; pub mod owner;
pub mod shop; pub mod shop;
pub mod interior_ref;
pub use interior_ref_list::InteriorRefList;
pub use model::Model; pub use model::Model;
pub use owner::Owner; pub use owner::Owner;
pub use shop::Shop; pub use shop::Shop;
pub use interior_ref::InteriorRef;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub enum Order { pub enum Order {

View File

@ -2,7 +2,6 @@ use anyhow::Result;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::prelude::*; use chrono::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use super::ListParams; use super::ListParams;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,5 @@
"is_not_sell_buy": true, "is_not_sell_buy": true,
"sell_buy_list_id": 1, "sell_buy_list_id": 1,
"vendor_id": 1, "vendor_id": 1,
"vendor_gold": 0, "vendor_gold": 0
"interior_refs": []
} }