From 36563bf1e787db9fd7f7bca9c8c62d0712dfc84c Mon Sep 17 00:00:00 2001 From: KeepingRunning <1599949878@qq.com> Date: Tue, 3 Jun 2025 02:20:12 +0800 Subject: [PATCH] doc: add dbdocs --- .gitignore | 1 + Makefile | 15 ++++-- db/migration/000002_add_users.down.sql | 2 +- doc/db.dbml | 64 +++++++++++++++++++++++ doc/schema.sql | 72 ++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 .gitignore create mode 100644 doc/db.dbml create mode 100644 doc/schema.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf0824e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.log \ No newline at end of file diff --git a/Makefile b/Makefile index 5da42af..0416d15 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +DB_URL=postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable postgres: docker run --name postgres12 --network bank-network -p 5432:5432 -e POSTGRES_USER=root -e POSTGRES_PASSWORD=secret -d postgres:12-alpine @@ -8,16 +9,20 @@ dropdb: docker exec -it postgres12 dropdb simple_bank migrateup: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up + migrate -path db/migration -database "$(DB_URL)" -verbose up migrateup1: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up 1 + migrate -path db/migration -database "$(DB_URL)" -verbose up 1 migratedown: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down + migrate -path db/migration -database "$(DB_URL)" -verbose down migratredown1: - migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down 1 + migrate -path db/migration -database "$(DB_URL)" -verbose down 1 +db_docs: + dbdocs build doc/db.dbml +db_schema: + dbml2sql -o db/schema.sql doc/db.dbml sqlc: sqlc generate @@ -27,4 +32,4 @@ server: go run main.go mock: mockgen -package mockdb -destination db/mock/store.go SimpleBank/db/sqlc Store -.PHONY: createdb dropdb postgres migratedown migrateup migratedown1 migrateup1 sqlc test server mock \ No newline at end of file +.PHONY: createdb dropdb postgres migratedown migrateup migratedown1 migrateup1 db_docs db_schema sqlc test server mock \ No newline at end of file diff --git a/db/migration/000002_add_users.down.sql b/db/migration/000002_add_users.down.sql index 48c7909..9c61760 100644 --- a/db/migration/000002_add_users.down.sql +++ b/db/migration/000002_add_users.down.sql @@ -1,5 +1,5 @@ ALTER TABLE IF EXISTS "accounts" DROP CONSTRAINT IF EXISTS "owner_currency_key"; -ALTER TABLE IF EXISTS "accounts" DROP CONSTRAINT IF EXISTS "owner_currency_fkey"; +ALTER TABLE IF EXISTS "accounts" DROP CONSTRAINT IF EXISTS "accounts_owner_fkey"; DROP TABLE IF EXISTS "users"; \ No newline at end of file diff --git a/doc/db.dbml b/doc/db.dbml new file mode 100644 index 0000000..eeca77c --- /dev/null +++ b/doc/db.dbml @@ -0,0 +1,64 @@ +Project simple_bank { + database_type: 'PostgreSQL' + Note: ''' + # Simple Bank Database + ''' +} + +Table users as U { + username varchar [pk] + hashed_password varchar [not null] + full_name varchar [not null] + email varchar [unique, not null] + password_changed_at timestamptz [not null, default: '0001-01-01'] + created_at timestamptz [not null, default: `now()`] +} + +Table accounts as A { + id bigserial [pk] + owner varchar [ref: > U.username, not null] + balance bigint [not null] + currency varchar [not null] + created_at timestamptz [not null, default: `now()`] + + Indexes { + owner + (owner, currency) [unique] + } +} + +Table entries { + id bigserial [pk] + account_id bigint [ref: > A.id, not null] + amount bigint [not null, note: 'can be negative or positive'] + created_at timestamptz [not null, default: `now()`] + + Indexes { + account_id + } +} + +Table transfers { + id bigserial [pk] + from_account_id bigint [ref: > A.id, not null] + to_account_id bigint [ref: > A.id, not null] + amount bigint [not null, note: 'must be positive'] + created_at timestamptz [not null, default: `now()`] + + Indexes { + from_account_id + to_account_id + (from_account_id, to_account_id) + } +} + +Table sessions { + id uuid [pk] + username varchar [ref: > U.username, not null] + refresh_token varchar [not null] + user_agent varchar [not null] + client_ip varchar [not null] + is_blocked boolean [not null, default: false] + expires_at timestamptz [not null] + created_at timestamptz [not null, default: `now()`] +} diff --git a/doc/schema.sql b/doc/schema.sql new file mode 100644 index 0000000..439340a --- /dev/null +++ b/doc/schema.sql @@ -0,0 +1,72 @@ +-- SQL dump generated using DBML (dbml.dbdiagram.io) +-- Database: PostgreSQL +-- Generated at: 2025-06-02T18:05:21.143Z + +CREATE TABLE "users" ( + "username" varchar PRIMARY KEY, + "hashed_password" varchar NOT NULL, + "full_name" varchar NOT NULL, + "email" varchar UNIQUE NOT NULL, + "password_changed_at" timestamptz NOT NULL DEFAULT '0001-01-01', + "created_at" timestamptz NOT NULL DEFAULT (now()) +); + +CREATE TABLE "accounts" ( + "id" bigserial PRIMARY KEY, + "owner" varchar NOT NULL, + "balance" bigint NOT NULL, + "currency" varchar NOT NULL, + "created_at" timestamptz NOT NULL DEFAULT (now()) +); + +CREATE TABLE "entries" ( + "id" bigserial PRIMARY KEY, + "account_id" bigint NOT NULL, + "amount" bigint NOT NULL, + "created_at" timestamptz NOT NULL DEFAULT (now()) +); + +CREATE TABLE "transfers" ( + "id" bigserial PRIMARY KEY, + "from_account_id" bigint NOT NULL, + "to_account_id" bigint NOT NULL, + "amount" bigint NOT NULL, + "created_at" timestamptz NOT NULL DEFAULT (now()) +); + +CREATE TABLE "sessions" ( + "id" uuid PRIMARY KEY, + "username" varchar NOT NULL, + "refresh_token" varchar NOT NULL, + "user_agent" varchar NOT NULL, + "client_ip" varchar NOT NULL, + "is_blocked" boolean NOT NULL DEFAULT false, + "expires_at" timestamptz NOT NULL, + "created_at" timestamptz NOT NULL DEFAULT (now()) +); + +CREATE INDEX ON "accounts" ("owner"); + +CREATE UNIQUE INDEX ON "accounts" ("owner", "currency"); + +CREATE INDEX ON "entries" ("account_id"); + +CREATE INDEX ON "transfers" ("from_account_id"); + +CREATE INDEX ON "transfers" ("to_account_id"); + +CREATE INDEX ON "transfers" ("from_account_id", "to_account_id"); + +COMMENT ON COLUMN "entries"."amount" IS 'can be negative or positive'; + +COMMENT ON COLUMN "transfers"."amount" IS 'must be positive'; + +ALTER TABLE "accounts" ADD FOREIGN KEY ("owner") REFERENCES "users" ("username"); + +ALTER TABLE "entries" ADD FOREIGN KEY ("account_id") REFERENCES "accounts" ("id"); + +ALTER TABLE "transfers" ADD FOREIGN KEY ("from_account_id") REFERENCES "accounts" ("id"); + +ALTER TABLE "transfers" ADD FOREIGN KEY ("to_account_id") REFERENCES "accounts" ("id"); + +ALTER TABLE "sessions" ADD FOREIGN KEY ("username") REFERENCES "users" ("username");