temp
This commit is contained in:
@@ -9,3 +9,4 @@ DROP TABLE IF EXISTS "accounts";
|
||||
DROP TABLE IF EXISTS "amounts";
|
||||
DROP TABLE IF EXISTS "users";
|
||||
DROP TABLE IF EXISTS "operations";
|
||||
DROP TABLE IF EXISTS "operation_snapshots";
|
||||
|
||||
@@ -103,3 +103,10 @@ CREATE TABLE "operations" (
|
||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
CREATE TABLE "operation_snapshots" (
|
||||
"id" BIGSERIAL PRIMARY KEY,
|
||||
"uid" BIGINT NOT NULL,
|
||||
"max_op_id" BIGINT NOT NULL,
|
||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||
);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
// use std::sync::Arc;
|
||||
use axum::routing::{get, post};
|
||||
use axum::{
|
||||
@@ -19,15 +22,13 @@ use chrono::prelude::*;
|
||||
use tracing::info;
|
||||
use crate::middleware::auth;
|
||||
use crate::middleware::auth::Claims;
|
||||
use crate::model::db_model::Category;
|
||||
use crate::util::operation::{
|
||||
EntityType, ENTITY_CATEGORY,
|
||||
ActionType, ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE,
|
||||
};
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CreateCategoryResponse {
|
||||
id: i64,
|
||||
name: String,
|
||||
level: i32,
|
||||
parent_category_id: i64,
|
||||
book_id: i64,
|
||||
}
|
||||
|
||||
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||
Router::new()
|
||||
@@ -43,12 +44,17 @@ pub struct CreateCategoryRequest {
|
||||
book_id: i64,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CreateCategoryResponse {
|
||||
id: i64,
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn create_category(
|
||||
State(app_state): State<crate::AppState>,
|
||||
claims: Claims,
|
||||
Json(payload): Json<CreateCategoryRequest>,
|
||||
) -> Result<Json<db_model::Category>, (StatusCode, String)> {
|
||||
) -> Result<Json<CreateCategoryResponse>, (StatusCode, String)> {
|
||||
let uid: i64 = claims.uid.clone(); // TODO replace with actual user id.
|
||||
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()};
|
||||
let conn = app_state
|
||||
@@ -63,18 +69,48 @@ pub async fn create_category(
|
||||
parent_category_id: payload.parent_category_id,
|
||||
book_id: payload.book_id,
|
||||
};
|
||||
let res = conn
|
||||
let new_operation = db_model::CreateOperation{
|
||||
uid: uid,
|
||||
entity_type: ENTITY_CATEGORY,
|
||||
entity_id: 0,
|
||||
action: ACTION_CREATE,
|
||||
};
|
||||
let mut create_response = CreateCategoryResponse{
|
||||
id: 0,
|
||||
};
|
||||
let cuid = uid;
|
||||
conn
|
||||
.interact(move |conn| {
|
||||
diesel::insert_into(schema::categories::table)
|
||||
conn.transaction(|conn| {
|
||||
let category = diesel::insert_into(schema::categories::table)
|
||||
.values(&new_category)
|
||||
.returning(db_model::Category::as_returning())
|
||||
.get_result(conn)
|
||||
.get_result(conn)?;
|
||||
let operation = diesel::insert_into(schema::operations::table)
|
||||
.values(&new_operation)
|
||||
.returning(db_model::Operation::as_returning())
|
||||
.get_result(conn)?;
|
||||
diesel::update(schema::categories::table)
|
||||
.filter(schema::categories::id.eq(category.id))
|
||||
.filter(schema::categories::uid.eq(cuid))
|
||||
.set((schema::categories::op_id.eq(operation.id)))
|
||||
.execute(conn)?;
|
||||
diesel::update(schema::operations::table)
|
||||
.filter(schema::operations::id.eq(operation.id))
|
||||
.filter(schema::operations::uid.eq(cuid))
|
||||
.set((schema::operations::entity_id.eq(category.id)))
|
||||
.execute(conn)?;
|
||||
diesel::result::QueryResult::Ok(())
|
||||
})
|
||||
// diesel::insert_into(schema::categories::table)
|
||||
// .values(&new_category)
|
||||
// .returning(db_model::Category::as_returning())
|
||||
// .get_result(conn)
|
||||
})
|
||||
.await
|
||||
.map_err(util::req::internal_error)?
|
||||
.map_err(util::req::internal_error)?;
|
||||
// let ret = CreateCategoryResponse{id: res.id, name: res.name};
|
||||
Ok(Json(res))
|
||||
Ok(Json(create_response))
|
||||
}
|
||||
|
||||
pub async fn update_category(
|
||||
|
||||
@@ -2,9 +2,11 @@ use diesel::prelude::*;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use axum::{extract::{Path, State, Query}, http::StatusCode, Json, Router};
|
||||
use axum::routing::get;
|
||||
use diesel::dsl::max;
|
||||
use crate::model::{db_model, schema};
|
||||
use crate::middleware::auth::Claims;
|
||||
use crate::model::db_model::Operation;
|
||||
use crate::model::schema::operation_snapshots::max_op_id;
|
||||
use crate::util;
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -77,5 +79,33 @@ pub async fn get_operations(
|
||||
};
|
||||
Ok(Json(resp))
|
||||
// Ok(Json(res))
|
||||
|
||||
}
|
||||
|
||||
struct GetOperationSnapshotResponse {
|
||||
max_op_id: i64,
|
||||
}
|
||||
pub async fn get_operation_snapshot(
|
||||
State(app_state): State<crate::AppState>,
|
||||
claims: Claims,
|
||||
) -> Result<Json<GetOperationSnapshotResponse>, (StatusCode, String)> {
|
||||
let uid: i64 = claims.uid.clone();
|
||||
let conn = app_state
|
||||
.db
|
||||
.get()
|
||||
.await
|
||||
.map_err(util::req::internal_error)?;
|
||||
let res = conn.interact(move |conn| {
|
||||
schema::operation_snapshots::table
|
||||
.filter(schema::operation_snapshots::uid.eq(uid))
|
||||
.select(max(schema::operation_snapshots::max_op_id))
|
||||
.limit(1)
|
||||
.get_result(conn)
|
||||
.map(|x| x as i64)
|
||||
}).await
|
||||
.map_err(util::req::internal_error)?
|
||||
.map_err(util::req::internal_error)?;
|
||||
let resp = GetOperationSnapshotResponse{
|
||||
max_op_id: res,
|
||||
};
|
||||
Ok(Json(resp))
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use crate::model::schema::operations::entity_id;
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct Category {
|
||||
#[serde(with = "string")]
|
||||
id: i64,
|
||||
pub id: i64,
|
||||
uid: i64,
|
||||
name: String,
|
||||
level: i32,
|
||||
@@ -193,6 +193,15 @@ pub struct Operation {
|
||||
create_at: chrono::NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Insertable)]
|
||||
#[diesel(table_name = schema::operations)]
|
||||
pub struct CreateOperation {
|
||||
pub uid: i64,
|
||||
pub entity_type: i64,
|
||||
pub entity_id: i64,
|
||||
pub action: i64,
|
||||
}
|
||||
|
||||
mod string {
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -56,6 +56,15 @@ diesel::table! {
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
operation_snapshots (id) {
|
||||
id -> Int8,
|
||||
uid -> Int8,
|
||||
max_op_id -> Int8,
|
||||
create_at -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
operations (id) {
|
||||
id -> Int8,
|
||||
@@ -128,6 +137,7 @@ diesel::allow_tables_to_appear_in_same_query!(
|
||||
amounts,
|
||||
books,
|
||||
categories,
|
||||
operation_snapshots,
|
||||
operations,
|
||||
tags,
|
||||
transaction_tag_rels,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod req;
|
||||
pub mod pass;
|
||||
pub mod math;
|
||||
pub mod operation;
|
||||
|
||||
16
src/util/operation.rs
Normal file
16
src/util/operation.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
pub type EntityType = i64;
|
||||
|
||||
pub const ENTITY_CATEGORY: EntityType = 1;
|
||||
pub const ENTITY_TAG: EntityType = 2;
|
||||
pub const ENTITY_BOOK: EntityType = 3;
|
||||
pub const ENTITY_ACCOUNT: EntityType = 4;
|
||||
pub const ENTITY_TRANSACTION: EntityType = 5;
|
||||
pub const ENTITY_AMOUNT: EntityType = 6;
|
||||
|
||||
|
||||
pub type ActionType = i64;
|
||||
|
||||
pub const ACTION_CREATE: ActionType = 1;
|
||||
pub const ACTION_UPDATE: ActionType = 2;
|
||||
pub const ACTION_DELETE: ActionType = 3;
|
||||
Reference in New Issue
Block a user