Compare commits

...

3 Commits

Author SHA1 Message Date
brian
39e656ef91 feat: axum + diesel 2025-05-23 23:50:20 +08:00
acx
7a58035d0c temp 2024-11-24 11:29:18 +08:00
acx
3fa7649877 feat: operations model 2024-11-05 00:19:27 +08:00
20 changed files with 428 additions and 168 deletions

1
.env.template Normal file
View File

@@ -0,0 +1 @@
DATABASE_URL=postgres://username:password@localhost/diesel_demo

195
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@@ -60,14 +60,14 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.7.5" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
dependencies = [ dependencies = [
"async-trait",
"axum-core", "axum-core",
"axum-macros", "axum-macros 0.5.0",
"bytes", "bytes",
"form_urlencoded",
"futures-util", "futures-util",
"http", "http",
"http-body", "http-body",
@@ -85,9 +85,9 @@ dependencies = [
"serde_json", "serde_json",
"serde_path_to_error", "serde_path_to_error",
"serde_urlencoded", "serde_urlencoded",
"sync_wrapper 1.0.1", "sync_wrapper",
"tokio", "tokio",
"tower", "tower 0.5.2",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@@ -95,20 +95,19 @@ dependencies = [
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.4.3" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
dependencies = [ dependencies = [
"async-trait",
"bytes", "bytes",
"futures-util", "futures-core",
"http", "http",
"http-body", "http-body",
"http-body-util", "http-body-util",
"mime", "mime",
"pin-project-lite", "pin-project-lite",
"rustversion", "rustversion",
"sync_wrapper 0.1.2", "sync_wrapper",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
@@ -116,9 +115,9 @@ dependencies = [
[[package]] [[package]]
name = "axum-extra" name = "axum-extra"
version = "0.9.3" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733" checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d"
dependencies = [ dependencies = [
"axum", "axum",
"axum-core", "axum-core",
@@ -130,11 +129,11 @@ dependencies = [
"http-body-util", "http-body-util",
"mime", "mime",
"pin-project-lite", "pin-project-lite",
"rustversion",
"serde", "serde",
"tower", "tower 0.5.2",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing",
] ]
[[package]] [[package]]
@@ -149,6 +148,17 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "axum-macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.73" version = "0.3.73"
@@ -239,7 +249,7 @@ dependencies = [
"num-traits", "num-traits",
"serde", "serde",
"wasm-bindgen", "wasm-bindgen",
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@@ -544,7 +554,7 @@ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"axum-extra", "axum-extra",
"axum-macros", "axum-macros 0.4.1",
"chrono", "chrono",
"deadpool-diesel", "deadpool-diesel",
"diesel", "diesel",
@@ -557,7 +567,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
"tower", "tower 0.4.13",
"tower-http", "tower-http",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@@ -656,6 +666,8 @@ dependencies = [
"hyper", "hyper",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
"tower 0.4.13",
"tower-service",
] ]
[[package]] [[package]]
@@ -725,9 +737,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@@ -756,9 +768,9 @@ dependencies = [
[[package]] [[package]]
name = "matchit" name = "matchit"
version = "0.7.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]] [[package]]
name = "memchr" name = "memchr"
@@ -783,13 +795,13 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.8.11" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
@@ -887,7 +899,7 @@ dependencies = [
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec",
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@@ -1068,7 +1080,7 @@ dependencies = [
"libc", "libc",
"spin", "spin",
"untrusted", "untrusted",
"windows-sys 0.52.0", "windows-sys",
] ]
[[package]] [[package]]
@@ -1213,7 +1225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys",
] ]
[[package]] [[package]]
@@ -1245,12 +1257,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]] [[package]]
name = "sync_wrapper" name = "sync_wrapper"
version = "1.0.1" version = "1.0.1"
@@ -1320,28 +1326,27 @@ dependencies = [
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.38.0" version = "1.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
"libc", "libc",
"mio", "mio",
"num_cpus",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.48.0", "windows-sys",
] ]
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "2.3.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1364,6 +1369,22 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "tower-http" name = "tower-http"
version = "0.5.2" version = "0.5.2"
@@ -1383,15 +1404,15 @@ dependencies = [
[[package]] [[package]]
name = "tower-layer" name = "tower-layer"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]] [[package]]
name = "tower-service" name = "tower-service"
version = "0.3.2" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]] [[package]]
name = "tracing" name = "tracing"
@@ -1579,16 +1600,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [ dependencies = [
"windows-targets 0.52.6", "windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
] ]
[[package]] [[package]]
@@ -1597,22 +1609,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets 0.52.6", "windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
] ]
[[package]] [[package]]
@@ -1621,46 +1618,28 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.52.6", "windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.52.6", "windows_aarch64_msvc",
"windows_i686_gnu 0.52.6", "windows_i686_gnu",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc 0.52.6", "windows_i686_msvc",
"windows_x86_64_gnu 0.52.6", "windows_x86_64_gnu",
"windows_x86_64_gnullvm 0.52.6", "windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.52.6", "windows_x86_64_msvc",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@@ -1673,48 +1652,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"

View File

@@ -7,8 +7,8 @@ edition = "2021"
[dependencies] [dependencies]
async-trait = "0.1.81" async-trait = "0.1.81"
axum = {version = "0.7.5", features = ["macros"]} axum = {version = "0.8", features = ["macros"]}
axum-extra = { version = "0.9.3", features = ["typed-header"] } axum-extra = { version = "0.10", features = ["typed-header"] }
chrono = {version = "0.4", features = ["serde"]} chrono = {version = "0.4", features = ["serde"]}
deadpool-diesel = {version ="0.6.1", features = ["postgres"]} deadpool-diesel = {version ="0.6.1", features = ["postgres"]}
diesel = { version = "2", features = ["postgres", "chrono"] } diesel = { version = "2", features = ["postgres", "chrono"] }

View File

@@ -2,8 +2,8 @@
# see https://diesel.rs/guides/configuring-diesel-cli # see https://diesel.rs/guides/configuring-diesel-cli
[print_schema] [print_schema]
file = "src/schema.rs" file = "src/model/schema.rs"
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
[migrations_directory] [migrations_directory]
dir = "/data/codes/helios-server-rs/migrations" dir = "./migrations"

View File

@@ -7,5 +7,6 @@ DROP TABLE IF EXISTS "transactions";
DROP TABLE IF EXISTS "transaction_tag_rels"; DROP TABLE IF EXISTS "transaction_tag_rels";
DROP TABLE IF EXISTS "accounts"; DROP TABLE IF EXISTS "accounts";
DROP TABLE IF EXISTS "amounts"; DROP TABLE IF EXISTS "amounts";
DROP TABLE IF EXISTS "users"; DROP TABLE IF EXISTS "users";
DROP TABLE IF EXISTS "operations";
DROP TABLE IF EXISTS "operation_snapshots";

View File

@@ -1,5 +1,4 @@
-- Your SQL goes here -- Your SQL goes here
-- Your SQL goes here
CREATE TABLE "categories" ( CREATE TABLE "categories" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"uid" BIGINT NOT NULL, "uid" BIGINT NOT NULL,
@@ -7,6 +6,7 @@ CREATE TABLE "categories" (
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"level" INT NOT NULL DEFAULT 0, "level" INT NOT NULL DEFAULT 0,
"parent_category_id" BIGINT NOT NULL DEFAULT 0, "parent_category_id" BIGINT NOT NULL DEFAULT 0,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -19,6 +19,7 @@ CREATE TABLE "tags" (
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"level" INT NOT NULL DEFAULT 0, "level" INT NOT NULL DEFAULT 0,
"parent_tag_id" BIGINT NOT NULL DEFAULT 0, "parent_tag_id" BIGINT NOT NULL DEFAULT 0,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -28,6 +29,7 @@ CREATE TABLE "books" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"uid" BIGINT NOT NULL, "uid" BIGINT NOT NULL,
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -39,6 +41,7 @@ CREATE TABLE "transactions" (
"book_id" BIGINT NOT NULL, "book_id" BIGINT NOT NULL,
"description" TEXT NOT NULL, "description" TEXT NOT NULL,
"category_id" BIGINT NOT NULL, "category_id" BIGINT NOT NULL,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT current_timestamp, "time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT current_timestamp,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
@@ -50,6 +53,7 @@ CREATE TABLE "transaction_tag_rels" (
"uid" BIGINT NOT NULL, "uid" BIGINT NOT NULL,
"transaction_id" BIGINT NOT NULL, "transaction_id" BIGINT NOT NULL,
"tag_id" BIGINT NOT NULL, "tag_id" BIGINT NOT NULL,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -60,6 +64,7 @@ CREATE TABLE "accounts" (
"uid" BIGINT NOT NULL, "uid" BIGINT NOT NULL,
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"account_type" BIGINT NOT NULL DEFAULT 0, "account_type" BIGINT NOT NULL DEFAULT 0,
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -73,6 +78,7 @@ CREATE TABLE "amounts" (
"value" BIGINT NOT NULL DEFAULT 0, "value" BIGINT NOT NULL DEFAULT 0,
"expo" BIGINT NOT NULL DEFAULT 5, "expo" BIGINT NOT NULL DEFAULT 5,
"currency" TEXT NOT NULL DEFAULT '', "currency" TEXT NOT NULL DEFAULT '',
"op_id" BIGINT NOT NULL DEFAULT 0,
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE, "is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
@@ -87,3 +93,20 @@ CREATE TABLE "users" (
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp, "create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp "update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
); );
CREATE TABLE "operations" (
"id" BIGSERIAL PRIMARY KEY,
"uid" BIGINT NOT NULL,
"entity_type" BIGINT NOT NULL,
"entity_id" BIGINT NOT NULL,
"action" BIGINT NOT NULL,
"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
);

View File

@@ -35,7 +35,7 @@ pub struct CreateAccountResponse {
pub fn get_nest_handlers() -> Router<crate::AppState> { pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new() Router::new()
.route("/", post(create_account).get(get_all_accounts)) .route("/", post(create_account).get(get_all_accounts))
.route("/:id", post(update_account).get(get_account)) .route("/{id}", post(update_account).get(get_account))
} }
#[debug_handler] #[debug_handler]

View File

@@ -32,7 +32,7 @@ pub struct CreateBookResponse {
pub fn get_nest_handlers() -> Router<crate::AppState> { pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new() Router::new()
.route("/", post(create_book).get(get_all_books)) .route("/", post(create_book).get(get_all_books))
.route("/:id", post(update_book).get(get_book)) .route("/{id}", post(update_book).get(get_book))
} }
#[debug_handler] #[debug_handler]

View File

@@ -1,3 +1,6 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
// use std::sync::Arc; // use std::sync::Arc;
use axum::routing::{get, post}; use axum::routing::{get, post};
use axum::{ use axum::{
@@ -12,6 +15,7 @@ use serde::{Deserialize, Serialize};
// use serde_json::to_string; // use serde_json::to_string;
use crate::model::db_model; use crate::model::db_model;
use crate::model::schema; use crate::model::schema;
use crate::model::schema::categories::parent_category_id;
use crate::util; use crate::util;
// use crate::model::schema::categories::dsl::categories; // use crate::model::schema::categories::dsl::categories;
use crate::util::req::CommonResp; use crate::util::req::CommonResp;
@@ -19,28 +23,29 @@ use chrono::prelude::*;
use tracing::info; use tracing::info;
use crate::middleware::auth; use crate::middleware::auth;
use crate::middleware::auth::Claims; use crate::middleware::auth::Claims;
use crate::model::db_model::Category;
#[derive(Serialize)] use crate::util::operation::{
pub struct CreateCategoryResponse { EntityType, ENTITY_CATEGORY,
id: i64, ActionType, ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE,
name: String, };
level: i32,
parent_category_id: i64,
book_id: i64,
}
pub fn get_nest_handlers() -> Router<crate::AppState> { pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new() Router::new()
.route("/", post(create_category).get(get_all_categories)) .route("/", post(create_category).get(get_all_categories))
.route("/:id", post(update_category).get(get_category)) .route("/{id}", post(update_category).get(get_category))
} }
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct CreateCategoryRequest { pub struct CreateCategoryRequest {
name: String, name: String,
level: i32, level: String,
parent_category_id: i64, parent_category_id: String,
book_id: i64, book_id: String,
}
#[derive(Serialize)]
pub struct CreateCategoryResponse {
id: i64,
} }
#[debug_handler] #[debug_handler]
@@ -48,9 +53,35 @@ pub async fn create_category(
State(app_state): State<crate::AppState>, State(app_state): State<crate::AppState>,
claims: Claims, claims: Claims,
Json(payload): Json<CreateCategoryRequest>, 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 uid: i64 = claims.uid.clone();
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()}; let level: i32 = match payload.level.parse() {
Ok(level) => level,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid level".to_string(),
))
}
};
let parent_cid: i64 = match payload.parent_category_id.parse(){
Ok(id) => id,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid parent_category_id".to_string(),
))
}
};
let book_id: i64 = match payload.book_id.parse() {
Ok(id) => id,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid book_id".to_string(),
))
}
};
let conn = app_state let conn = app_state
.db .db
.get() .get()
@@ -59,22 +90,69 @@ pub async fn create_category(
let new_category = db_model::CategoryForm { let new_category = db_model::CategoryForm {
name: payload.name, name: payload.name,
uid: uid, uid: uid,
level: payload.level, level: level,
parent_category_id: payload.parent_category_id, parent_category_id: parent_cid,
book_id: payload.book_id, book_id: 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,
};
// Check if book exists under current user
let book_exists = conn
.interact(move |conn| { .interact(move |conn| {
diesel::insert_into(schema::categories::table) schema::books::table
.values(&new_category) .select(diesel::dsl::exists(db_model::Category.as_select().filter(schema::books::id.eq(book_id))))
.returning(db_model::Category::as_returning()) // .filter(schema::books::uid.eq(uid))(schema::books::id.eq(book_id))))
.get_result(conn) .get_result::<bool>(conn)
}) })
.await .await
.map_err(util::req::internal_error)? .map_err(util::req::internal_error)?
.map_err(util::req::internal_error)?; .map_err(util::req::internal_error)?;
// let ret = CreateCategoryResponse{id: res.id, name: res.name};
Ok(Json(res)) if !book_exists {
return Err((StatusCode::NOT_FOUND, "Book not found for the user".to_string()));
}
let cuid = uid;
let create_result = conn
.interact(move |conn| {
conn.transaction(|conn| {
let category = diesel::insert_into(schema::categories::table)
.values(&new_category)
.returning(db_model::Category::as_returning())
.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((category.id))
})
// 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)?;
create_response.id = create_result;
Ok(Json(create_response))
} }
pub async fn update_category( pub async fn update_category(
@@ -83,8 +161,35 @@ pub async fn update_category(
claims: Claims, claims: Claims,
Json(payload): Json<CreateCategoryRequest>, Json(payload): Json<CreateCategoryRequest>,
) -> Result<Json<CommonResp>, (StatusCode, String)> { ) -> Result<Json<CommonResp>, (StatusCode, String)> {
let uid: i64 = claims.uid.clone(); // TODO replace with actual user id. let uid: i64 = claims.uid.clone();
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()}; let level: i32 = match payload.level.parse() {
Ok(level) => level,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid level".to_string(),
))
}
};
let parent_cid: i64 = match payload.parent_category_id.parse(){
Ok(id) => id,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid parent_category_id".to_string(),
))
}
};
let book_id: i64 = match payload.book_id.parse() {
Ok(id) => id,
Err(_) => {
return Err((
StatusCode::BAD_REQUEST,
"Invalid book_id".to_string(),
))
}
};
let conn = app_state let conn = app_state
.db .db
.get() .get()
@@ -98,8 +203,8 @@ pub async fn update_category(
.filter(schema::categories::uid.eq(uid)) .filter(schema::categories::uid.eq(uid))
.set(( .set((
schema::categories::name.eq(payload.name), schema::categories::name.eq(payload.name),
schema::categories::level.eq(payload.level), schema::categories::level.eq(level),
schema::categories::parent_category_id.eq(payload.parent_category_id), schema::categories::parent_category_id.eq(parent_cid),
schema::categories::update_at.eq(now), schema::categories::update_at.eq(now),
)) ))
.execute(conn) .execute(conn)

View File

@@ -3,3 +3,4 @@ pub mod tag;
pub mod book; pub mod book;
pub mod account; pub mod account;
pub mod transaction; pub mod transaction;
pub mod operation;

81
src/ledger/operation.rs Normal file
View File

@@ -0,0 +1,81 @@
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::util;
#[derive(Serialize)]
pub struct GetOperationsResponse {
start: i64,
end: i64,
total: i64,
operations: Vec<db_model::Operation>,
}
#[derive(Deserialize)]
pub struct GetOperationsParam {
start: i64,
limit: i32,
}
pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new()
.route("/", get(get_operations))
}
// get_single_operation
pub async fn get_operations(
query_param: Query<GetOperationsParam>,
State(app_state): State<crate::AppState>,
claims: Claims,
) -> Result<Json<GetOperationsResponse>, (StatusCode, String)> {
let uid: i64 = claims.uid.clone();
let start: i64 = match query_param.start {
..0 => 0,
_ => query_param.start
};
let limit: i32 = match query_param.limit {
..0 => 0,
crate::model::req::MAX_QUERY_LIMIT.. => crate::model::req::MAX_QUERY_LIMIT,
_ => query_param.limit
};
let conn = app_state
.db
.get()
.await
.map_err(util::req::internal_error)?;
let mut res = conn
.interact(move |conn| {
schema::operations::table
.filter(schema::operations::uid.eq(uid))
.filter(schema::operations::id.ge(start))
.limit(limit as i64)
.select(Operation::as_select())
.load(conn)
})
.await
.map_err(util::req::internal_error)?
.map_err(util::req::internal_error)?;
res.sort_by(|a,b| a.id.cmp(&b.id));
let res_start: i64 = match res.first() {
Some(r) => r.id,
None => 0,
};
let res_end = match res.last() {
Some(r) => r.id,
None => 0,
};
let resp = GetOperationsResponse{
start: res_start,
end: res_end,
total: res.len() as i64,
operations: res,
};
Ok(Json(resp))
// Ok(Json(res))
}

View File

@@ -39,7 +39,7 @@ pub struct CreateTagResponse {
pub fn get_nest_handlers() -> Router<crate::AppState> { pub fn get_nest_handlers() -> Router<crate::AppState> {
Router::new() Router::new()
.route("/", post(create_tag).get(get_all_tags)) .route("/", post(create_tag).get(get_all_tags))
.route("/:id", post(update_tag).get(get_tag)) .route("/{id}", post(update_tag).get(get_tag))
} }
#[debug_handler] #[debug_handler]

View File

@@ -72,7 +72,7 @@ pub fn get_nest_handlers() -> Router<crate::AppState> {
post(create_transaction) // create new transaction entry with amount post(create_transaction) // create new transaction entry with amount
.get(get_all_transactions),// get all transactions with entry .get(get_all_transactions),// get all transactions with entry
) )
.route("/entry/:id", get(get_transaction)) // get transaction entry .route("/entry/{id}", get(get_transaction)) // get transaction entry
.route("/amount/by_transaction_id", get(get_amounts_by_tid)) .route("/amount/by_transaction_id", get(get_amounts_by_tid))
.route("/amount/batch_get_by_transaction_id", post(batch_get_amounts_by_tid)) .route("/amount/batch_get_by_transaction_id", post(batch_get_amounts_by_tid))
.route("/amount", get(get_all_amounts_by_tid_range)) .route("/amount", get(get_all_amounts_by_tid_range))

View File

@@ -97,6 +97,7 @@ async fn main() {
.nest("/api/v1/account", ledger::account::get_nest_handlers()) .nest("/api/v1/account", ledger::account::get_nest_handlers())
.nest("/api/v1/transaction", ledger::transaction::get_nest_handlers()) .nest("/api/v1/transaction", ledger::transaction::get_nest_handlers())
.nest("/api/v1/user", user::handler::get_nest_handlers()) .nest("/api/v1/user", user::handler::get_nest_handlers())
.nest("/api/v1/operation", ledger::operation::get_nest_handlers())
.with_state(shared_state) .with_state(shared_state)
.layer(global_layer); .layer(global_layer);

View File

@@ -1,5 +1,4 @@
use axum::{ use axum::{
async_trait,
extract::FromRequestParts, extract::FromRequestParts,
http::{ http::{
request::Parts, request::Parts,
@@ -8,6 +7,7 @@ use axum::{
Json, RequestPartsExt, Json, RequestPartsExt,
response::{IntoResponse, Response}, response::{IntoResponse, Response},
}; };
use async_trait::async_trait;
use axum_extra::{ use axum_extra::{
headers::{authorization::Bearer, Authorization}, headers::{authorization::Bearer, Authorization},
TypedHeader, TypedHeader,
@@ -81,27 +81,25 @@ impl AuthBody {
} }
} }
#[async_trait]
impl<S> FromRequestParts<S> for Claims impl<S> FromRequestParts<S> for Claims
where where
S: Send + Sync, S: Send + Sync,
{ {
type Rejection = (StatusCode, String); type Rejection = AuthError;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> { async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
// Extract the token from the authorization header // Extract the token from the authorization header
let TypedHeader(Authorization(bearer)) = parts let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>() .extract::<TypedHeader<Authorization<Bearer>>>()
.await .await
.map_err(util::req::internal_error)?; .map_err(|_| AuthError::InvalidToken)?;
// Decode the user data // Decode the user data
let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default()) let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default())
.map_err(util::req::internal_error)?; .map_err(|_| AuthError::InvalidToken)?;
Ok(token_data.claims) Ok(token_data.claims)
} }
} }
impl IntoResponse for AuthError { impl IntoResponse for AuthError {
fn into_response(self) -> Response { fn into_response(self) -> Response {
let (status, error_message) = match self { let (status, error_message) = match self {

View File

@@ -1,18 +1,20 @@
use crate::model::schema; use crate::model::schema;
use diesel::prelude::*; use diesel::prelude::*;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use crate::model::schema::operations::entity_id;
#[derive(Queryable, Selectable, serde::Serialize, serde::Deserialize)] #[derive(Queryable, Selectable, serde::Serialize, serde::Deserialize)]
#[diesel(table_name = schema::categories)] #[diesel(table_name = schema::categories)]
#[diesel(check_for_backend(diesel::pg::Pg))] #[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Category { pub struct Category {
#[serde(with = "string")] #[serde(with = "string")]
id: i64, pub id: i64,
uid: i64, uid: i64,
name: String, name: String,
level: i32, level: i32,
parent_category_id: i64, parent_category_id: i64,
book_id: i64, book_id: i64,
op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -39,6 +41,7 @@ pub struct Tag {
name: String, name: String,
level: i32, level: i32,
parent_tag_id: i64, parent_tag_id: i64,
op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -63,6 +66,7 @@ pub struct Book {
id: i64, id: i64,
uid: i64, uid: i64,
name: String, name: String,
op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -84,6 +88,7 @@ pub struct Account {
uid: i64, uid: i64,
name: String, name: String,
account_type: i64, account_type: i64,
op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -111,6 +116,7 @@ pub struct Transaction {
#[serde(with = "string")] #[serde(with = "string")]
pub category_id: i64, pub category_id: i64,
pub time: chrono::DateTime<Utc>, pub time: chrono::DateTime<Utc>,
pub op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -139,6 +145,7 @@ pub struct Amount {
value: i64, value: i64,
expo: i64, expo: i64,
currency: String, currency: String,
pub op_id: i64,
#[serde(skip_serializing)] #[serde(skip_serializing)]
is_delete: bool, is_delete: bool,
create_at: chrono::NaiveDateTime, create_at: chrono::NaiveDateTime,
@@ -175,6 +182,26 @@ pub struct UserForm {
pub mail: String, pub mail: String,
} }
#[derive(Insertable,Queryable, Selectable, serde::Serialize)]
#[diesel(table_name = schema::operations)]
pub struct Operation {
pub id: i64,
pub uid: i64,
pub entity_type: i64,
pub entity_id: i64,
pub action: i64,
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 { mod string {
use std::fmt::Display; use std::fmt::Display;
use std::str::FromStr; use std::str::FromStr;

View File

@@ -6,6 +6,7 @@ diesel::table! {
uid -> Int8, uid -> Int8,
name -> Text, name -> Text,
account_type -> Int8, account_type -> Int8,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -21,6 +22,7 @@ diesel::table! {
value -> Int8, value -> Int8,
expo -> Int8, expo -> Int8,
currency -> Text, currency -> Text,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -32,6 +34,7 @@ diesel::table! {
id -> Int8, id -> Int8,
uid -> Int8, uid -> Int8,
name -> Text, name -> Text,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -46,12 +49,34 @@ diesel::table! {
name -> Text, name -> Text,
level -> Int4, level -> Int4,
parent_category_id -> Int8, parent_category_id -> Int8,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
} }
} }
diesel::table! {
operation_snapshots (id) {
id -> Int8,
uid -> Int8,
max_op_id -> Int8,
create_at -> Timestamp,
}
}
diesel::table! {
operations (id) {
id -> Int8,
uid -> Int8,
entity_type -> Int8,
entity_id -> Int8,
action -> Int8,
create_at -> Timestamp,
update_at -> Timestamp,
}
}
diesel::table! { diesel::table! {
tags (id) { tags (id) {
id -> Int8, id -> Int8,
@@ -60,6 +85,7 @@ diesel::table! {
name -> Text, name -> Text,
level -> Int4, level -> Int4,
parent_tag_id -> Int8, parent_tag_id -> Int8,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -72,6 +98,7 @@ diesel::table! {
uid -> Int8, uid -> Int8,
transaction_id -> Int8, transaction_id -> Int8,
tag_id -> Int8, tag_id -> Int8,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -85,6 +112,7 @@ diesel::table! {
book_id -> Int8, book_id -> Int8,
description -> Text, description -> Text,
category_id -> Int8, category_id -> Int8,
op_id -> Int8,
is_delete -> Bool, is_delete -> Bool,
time -> Timestamptz, time -> Timestamptz,
create_at -> Timestamp, create_at -> Timestamp,
@@ -109,6 +137,8 @@ diesel::allow_tables_to_appear_in_same_query!(
amounts, amounts,
books, books,
categories, categories,
operation_snapshots,
operations,
tags, tags,
transaction_tag_rels, transaction_tag_rels,
transactions, transactions,

View File

@@ -6,6 +6,7 @@ diesel::table! {
uid -> Int8, uid -> Int8,
name -> Text, name -> Text,
account_type -> Int8, account_type -> Int8,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -21,6 +22,7 @@ diesel::table! {
value -> Int8, value -> Int8,
expo -> Int8, expo -> Int8,
currency -> Text, currency -> Text,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -32,6 +34,7 @@ diesel::table! {
id -> Int8, id -> Int8,
uid -> Int8, uid -> Int8,
name -> Text, name -> Text,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -46,6 +49,7 @@ diesel::table! {
name -> Text, name -> Text,
level -> Int4, level -> Int4,
parent_category_id -> Int8, parent_category_id -> Int8,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -60,6 +64,7 @@ diesel::table! {
name -> Text, name -> Text,
level -> Int4, level -> Int4,
parent_tag_id -> Int8, parent_tag_id -> Int8,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -72,6 +77,7 @@ diesel::table! {
uid -> Int8, uid -> Int8,
transaction_id -> Int8, transaction_id -> Int8,
tag_id -> Int8, tag_id -> Int8,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
create_at -> Timestamp, create_at -> Timestamp,
update_at -> Timestamp, update_at -> Timestamp,
@@ -85,6 +91,7 @@ diesel::table! {
book_id -> Int8, book_id -> Int8,
description -> Text, description -> Text,
category_id -> Int8, category_id -> Int8,
version_v1 -> Int8,
is_delete -> Bool, is_delete -> Bool,
time -> Timestamptz, time -> Timestamptz,
create_at -> Timestamp, create_at -> Timestamp,
@@ -104,6 +111,18 @@ diesel::table! {
} }
} }
diesel::table! {
versions_v1 (id) {
id -> Int8,
uid -> Int8,
entity_type -> Int8,
entity_id -> Int8,
action -> Int8,
create_at -> Timestamp,
update_at -> Timestamp,
}
}
diesel::allow_tables_to_appear_in_same_query!( diesel::allow_tables_to_appear_in_same_query!(
accounts, accounts,
amounts, amounts,
@@ -113,4 +132,5 @@ diesel::allow_tables_to_appear_in_same_query!(
transaction_tag_rels, transaction_tag_rels,
transactions, transactions,
users, users,
versions_v1,
); );

View File

@@ -1,3 +1,4 @@
pub mod req; pub mod req;
pub mod pass; pub mod pass;
pub mod math; pub mod math;
pub mod operation;

16
src/util/operation.rs Normal file
View 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;