feat: category crud
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,4 +2,4 @@
|
|||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.env
|
||||||
|
|||||||
1332
Cargo.lock
generated
Normal file
1332
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@@ -6,3 +6,13 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
axum = {version = "0.7.5", features = ["macros"]}
|
||||||
|
chrono = {version = "0.4", features = ["serde"]}
|
||||||
|
deadpool-diesel = {version ="0.6.1", features = ["postgres"]}
|
||||||
|
diesel = { version = "2", features = ["postgres", "chrono"] }
|
||||||
|
dotenvy = "0.15"
|
||||||
|
serde = { version = "1.0.202", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|||||||
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "/data/codes/helios-server-rs/migrations"
|
||||||
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||||
|
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
||||||
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Sets up a trigger for the given table to automatically set a column called
|
||||||
|
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||||
|
-- in the modified columns)
|
||||||
|
--
|
||||||
|
-- # Example
|
||||||
|
--
|
||||||
|
-- ```sql
|
||||||
|
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||||
|
--
|
||||||
|
-- SELECT diesel_manage_updated_at('users');
|
||||||
|
-- ```
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||||
|
BEGIN
|
||||||
|
IF (
|
||||||
|
NEW IS DISTINCT FROM OLD AND
|
||||||
|
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||||
|
) THEN
|
||||||
|
NEW.updated_at := current_timestamp;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
11
migrations/2024-07-07-151037_base_schema/down.sql
Normal file
11
migrations/2024-07-07-151037_base_schema/down.sql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE IF EXISTS "categories";
|
||||||
|
DROP TABLE IF EXISTS "tags";
|
||||||
|
DROP TABLE IF EXISTS "books";
|
||||||
|
DROP TABLE IF EXISTS "transactions";
|
||||||
|
DROP TABLE IF EXISTS "transaction_tag_rels";
|
||||||
|
DROP TABLE IF EXISTS "accounts";
|
||||||
|
DROP TABLE IF EXISTS "amounts";
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "users";
|
||||||
81
migrations/2024-07-07-151037_base_schema/up.sql
Normal file
81
migrations/2024-07-07-151037_base_schema/up.sql
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE "categories" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "tags" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "books" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "transactions" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"book_id" BIGINT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"category_id" BIGINT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT current_timestamp,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "transaction_tag_rels" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"transaction_id" BIGINT NOT NULL,
|
||||||
|
"tag_id" BIGINT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "accounts" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"type" BIGINT NOT NULL DEFAULT 0,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "amounts" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"transaction_id" BIGINT NOT NULL,
|
||||||
|
"value" BIGINT NOT NULL DEFAULT 0,
|
||||||
|
"expo" BIGINT NOT NULL DEFAULT 5,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "users" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"username" TEXT NOT NULL,
|
||||||
|
"password" TEXT NOT NULL,
|
||||||
|
"mail" TEXT NOT NULL,
|
||||||
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
124
src/category/handler.rs
Normal file
124
src/category/handler.rs
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// use std::sync::Arc;
|
||||||
|
use axum::{http::StatusCode, extract::{State,Path}, Json, Router};
|
||||||
|
use axum::routing::{get, post};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
// use diesel::update;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
// use serde_json::to_string;
|
||||||
|
use crate::util;
|
||||||
|
use crate::model::schema;
|
||||||
|
use crate::model::db_model;
|
||||||
|
// use crate::model::schema::categories::dsl::categories;
|
||||||
|
use crate::util::req::CommonResp;
|
||||||
|
use chrono::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct CreateCategoryResponse {
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||||
|
Router::new()
|
||||||
|
.route("/", post(create_category).get(get_all_categories))
|
||||||
|
.route("/:id", post(update_category).get(get_category))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CreateCategoryRequest {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_category(
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
Json(Payload): Json<CreateCategoryRequest>,
|
||||||
|
) -> Result<Json<db_model::Category>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = 123214124; // TODO replace with actual user id.
|
||||||
|
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()};
|
||||||
|
let conn = app_state.db.get().await.map_err(util::req::internal_error)?;
|
||||||
|
let new_category = db_model::CategoryForm{
|
||||||
|
name: Payload.name,
|
||||||
|
uid: uid,
|
||||||
|
};
|
||||||
|
let res = conn
|
||||||
|
.interact(move |conn| {
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_category(
|
||||||
|
Path(id): Path<i64>,
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
Json(Payload): Json<CreateCategoryRequest>,
|
||||||
|
) -> Result<Json<CommonResp>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = 123214124; // TODO replace with actual user id.
|
||||||
|
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()};
|
||||||
|
let conn = app_state.db.get().await.map_err(util::req::internal_error)?;
|
||||||
|
let now = Utc::now().naive_utc();
|
||||||
|
let res = conn
|
||||||
|
.interact(move |conn| {
|
||||||
|
diesel::update(schema::categories::table)
|
||||||
|
.filter(schema::categories::id.eq(id))
|
||||||
|
.filter(schema::categories::uid.eq(uid))
|
||||||
|
.set((
|
||||||
|
schema::categories::name.eq(Payload.name),
|
||||||
|
schema::categories::update_at.eq(now),
|
||||||
|
))
|
||||||
|
.execute(conn)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
// let ret = CreateCategoryResponse{id: res.id, name: res.name};
|
||||||
|
let resp = util::req::CommonResp{
|
||||||
|
code: 0,
|
||||||
|
};
|
||||||
|
Ok(Json(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_category(
|
||||||
|
Path(id): Path<i64>,
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
) -> Result<Json<db_model::Category>, (StatusCode, String)>{
|
||||||
|
let uid: i64 = 123214124; // TODO replace with actual user id.
|
||||||
|
let conn = app_state.db.get().await.map_err(util::req::internal_error)?;
|
||||||
|
let res = conn
|
||||||
|
.interact(move |conn| {
|
||||||
|
schema::categories::table
|
||||||
|
.filter(schema::categories::id.eq(id))
|
||||||
|
.filter(schema::categories::uid.eq(uid))
|
||||||
|
.select(db_model::Category::as_select())
|
||||||
|
.limit(1)
|
||||||
|
.get_result(conn)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
Ok(Json(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_all_categories(
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
) -> Result<Json<Vec<db_model::Category>>, (StatusCode, String)>{
|
||||||
|
let uid: i64 = 123214124; // TODO replace with actual user id.
|
||||||
|
let conn = app_state.db.get().await.map_err(util::req::internal_error)?;
|
||||||
|
let res = conn
|
||||||
|
.interact(move |conn| {
|
||||||
|
schema::categories::table
|
||||||
|
.filter(schema::categories::uid.eq(uid))
|
||||||
|
.select(db_model::Category::as_select())
|
||||||
|
.load(conn)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
Ok(Json(res))
|
||||||
|
}
|
||||||
1
src/category/mod.rs
Normal file
1
src/category/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod handler;
|
||||||
47
src/main.rs
47
src/main.rs
@@ -1,3 +1,46 @@
|
|||||||
fn main() {
|
use axum::{
|
||||||
println!("Hello, world!");
|
// http::StatusCode,
|
||||||
|
// routing::{get, post},
|
||||||
|
// Json,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tracing::info;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
// Project modules
|
||||||
|
mod category;
|
||||||
|
mod model;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
// Passed App State
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AppState{
|
||||||
|
db: deadpool_diesel::postgres::Pool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
dotenvy::dotenv().unwrap();
|
||||||
|
tracing_subscriber::registry().with(tracing_subscriber::fmt::layer()).init();
|
||||||
|
// initialize db connection
|
||||||
|
let db_url = std::env::var("DATABASE_URL").unwrap();
|
||||||
|
|
||||||
|
let manager = deadpool_diesel::postgres::Manager::new(db_url, deadpool_diesel::Runtime::Tokio1);
|
||||||
|
let pool = deadpool_diesel::postgres::Pool::builder(manager)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
let shared_state = AppState {db: pool,};
|
||||||
|
|
||||||
|
// Register routers
|
||||||
|
let app = Router::new()
|
||||||
|
// V1 apis
|
||||||
|
.nest("/api/v1/category", category::handler::get_nest_handlers())
|
||||||
|
.with_state(shared_state);
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:8987").await.unwrap();
|
||||||
|
info!("starting server on 0.0.0.0:8987");
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/model/db_model.rs
Normal file
22
src/model/db_model.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
use diesel::prelude::*;
|
||||||
|
use crate::model::schema;
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable)]
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
|
#[diesel(table_name = schema::categories)]
|
||||||
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
|
pub struct Category {
|
||||||
|
id: i64,
|
||||||
|
uid: i64,
|
||||||
|
name: String,
|
||||||
|
is_delete: bool,
|
||||||
|
create_at: chrono::NaiveDateTime,
|
||||||
|
update_at: chrono::NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, Insertable)]
|
||||||
|
#[diesel(table_name = schema::categories)]
|
||||||
|
pub struct CategoryForm {
|
||||||
|
pub uid: i64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
2
src/model/mod.rs
Normal file
2
src/model/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod schema;
|
||||||
|
pub mod db_model;
|
||||||
109
src/model/schema.rs
Normal file
109
src/model/schema.rs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
accounts (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
#[sql_name = "type"]
|
||||||
|
type_ -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
amounts (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
transaction_id -> Int8,
|
||||||
|
value -> Int8,
|
||||||
|
expo -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
books (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
categories (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
tags (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
transaction_tag_rels (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
transaction_id -> Int8,
|
||||||
|
tag_id -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
transactions (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
book_id -> Int8,
|
||||||
|
description -> Text,
|
||||||
|
category_id -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
time -> Timestamptz,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
users (id) {
|
||||||
|
id -> Int8,
|
||||||
|
username -> Text,
|
||||||
|
password -> Text,
|
||||||
|
mail -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
|
accounts,
|
||||||
|
amounts,
|
||||||
|
books,
|
||||||
|
categories,
|
||||||
|
tags,
|
||||||
|
transaction_tag_rels,
|
||||||
|
transactions,
|
||||||
|
users,
|
||||||
|
);
|
||||||
109
src/schema.rs
Normal file
109
src/schema.rs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
accounts (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
#[sql_name = "type"]
|
||||||
|
type_ -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
amounts (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
transaction_id -> Int8,
|
||||||
|
value -> Int8,
|
||||||
|
expo -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
books (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
categories (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
tags (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
name -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
transaction_tag_rels (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
transaction_id -> Int8,
|
||||||
|
tag_id -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
transactions (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
book_id -> Int8,
|
||||||
|
description -> Text,
|
||||||
|
category_id -> Int8,
|
||||||
|
is_delete -> Bool,
|
||||||
|
time -> Timestamptz,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
users (id) {
|
||||||
|
id -> Int8,
|
||||||
|
username -> Text,
|
||||||
|
password -> Text,
|
||||||
|
mail -> Text,
|
||||||
|
is_delete -> Bool,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
|
accounts,
|
||||||
|
amounts,
|
||||||
|
books,
|
||||||
|
categories,
|
||||||
|
tags,
|
||||||
|
transaction_tag_rels,
|
||||||
|
transactions,
|
||||||
|
users,
|
||||||
|
);
|
||||||
1
src/util/mod.rs
Normal file
1
src/util/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod req;
|
||||||
14
src/util/req.rs
Normal file
14
src/util/req.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use axum::http::StatusCode;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct CommonResp {
|
||||||
|
pub code: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn internal_error<E>(err: E) -> (StatusCode, String)
|
||||||
|
where
|
||||||
|
E: std::error::Error,
|
||||||
|
{
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user