Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/declarative-sql-review-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: SQL review on pull request with declarative release using bytebase-action image

on:
pull_request:
branches:
- main
paths:
- "schema/*.sql"

jobs:
check-release-on-prod:
permissions:
pull-requests: write # write permission required to allow the action writes the check results to the comment.
runs-on: ubuntu-latest # use self-hosted machines if your Bytebase runs in internal networks.
container:
image: bytebase/bytebase-action:latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # set GITHUB_TOKEN because the 'Check release' step needs it to comment the pull request with check results.
BYTEBASE_URL: https://demo.bytebase.com
BYTEBASE_SERVICE_ACCOUNT: [email protected] # set service account via environment variable
BYTEBASE_SERVICE_ACCOUNT_SECRET: ${{ secrets.BYTEBASE_SERVICE_ACCOUNT_SECRET }} # set service account secret via environment variable
BYTEBASE_PROJECT: "projects/hr"
BYTEBASE_TARGETS: "instances/prod-sample-instance/databases/hr_prod"
FILE_PATTERN: "schema/*.sql"
run: |
bytebase-action check --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --targets=${{ env.BYTEBASE_TARGETS }} --file-pattern=${{ env.FILE_PATTERN }} --declarative
176 changes: 84 additions & 92 deletions schema/schema.sql
Original file line number Diff line number Diff line change
@@ -1,120 +1,112 @@
CREATE TABLE public.employee (
emp_no SERIAL NOT NULL,
birth_date DATE NOT NULL,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
gender TEXT NOT NULL CHECK (gender IN('M', 'F')) NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no)
COMMENT ON SCHEMA "public" IS 'standard public schema';

CREATE TABLE "public"."audit" (
"id" serial,
"operation" text NOT NULL,
"query" text,
"user_name" text NOT NULL,
"changed_at" timestamp(6) with time zone DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "audit_pkey" PRIMARY KEY (id)
);

CREATE INDEX idx_employee_hire_date ON public.employee (hire_date);
CREATE INDEX "idx_audit_changed_at" ON ONLY "public"."audit" (changed_at);

CREATE INDEX "idx_audit_operation" ON ONLY "public"."audit" (operation);

CREATE INDEX "idx_audit_username" ON ONLY "public"."audit" (user_name);

CREATE TABLE "public"."department" (
"dept_no" text NOT NULL,
"dept_name" text NOT NULL,
CONSTRAINT "department_pkey" PRIMARY KEY (dept_no),
CONSTRAINT "department_dept_name_key" UNIQUE (dept_name)
);

CREATE TABLE public.department (
dept_no TEXT NOT NULL,
dept_name TEXT NOT NULL,
PRIMARY KEY (dept_no),
UNIQUE (dept_name)
CREATE TABLE "public"."dept_emp" (
"emp_no" integer NOT NULL,
"dept_no" text NOT NULL,
"from_date" date NOT NULL,
"to_date" date NOT NULL,
CONSTRAINT "dept_emp_pkey" PRIMARY KEY (emp_no, dept_no),
CONSTRAINT "dept_emp_dept_no_fkey" FOREIGN KEY ("dept_no") REFERENCES "public"."department" ("dept_no") ON DELETE CASCADE,
CONSTRAINT "dept_emp_emp_no_fkey" FOREIGN KEY ("emp_no") REFERENCES "public"."employee" ("emp_no") ON DELETE CASCADE
);

CREATE TABLE public.dept_manager (
emp_no INT NOT NULL,
dept_no TEXT NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employee (emp_no) ON DELETE CASCADE,
FOREIGN KEY (dept_no) REFERENCES department (dept_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, dept_no)
CREATE TABLE "public"."dept_manager" (
"emp_no" integer NOT NULL,
"dept_no" text NOT NULL,
"from_date" date NOT NULL,
"to_date" date NOT NULL,
CONSTRAINT "dept_manager_pkey" PRIMARY KEY (emp_no, dept_no),
CONSTRAINT "dept_manager_dept_no_fkey" FOREIGN KEY ("dept_no") REFERENCES "public"."department" ("dept_no") ON DELETE CASCADE,
CONSTRAINT "dept_manager_emp_no_fkey" FOREIGN KEY ("emp_no") REFERENCES "public"."employee" ("emp_no") ON DELETE CASCADE
);

CREATE TABLE public.dept_emp (
emp_no INT NOT NULL,
dept_no TEXT NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employee (emp_no) ON DELETE CASCADE,
FOREIGN KEY (dept_no) REFERENCES department (dept_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, dept_no)
CREATE TABLE "public"."employee" (
"emp_no" serial,
"birth_date" date NOT NULL,
"first_name" text NOT NULL,
"last_name" text NOT NULL,
"gender" text NOT NULL,
"hire_date" date NOT NULL,
CONSTRAINT "employee_pkey" PRIMARY KEY (emp_no),
CONSTRAINT "employee_gender_check" CHECK (gender = ANY (ARRAY['M'::text, 'F'::text]))
);

CREATE TABLE public.title (
emp_no INT NOT NULL,
title TEXT NOT NULL,
from_date DATE NOT NULL,
to_date DATE,
FOREIGN KEY (emp_no) REFERENCES employee (emp_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, title, from_date)
);

CREATE TABLE public.salary (
emp_no INT NOT NULL,
amount INT NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employee (emp_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, from_date)
CREATE INDEX "idx_employee_hire_date" ON ONLY "public"."employee" (hire_date);

CREATE TABLE "public"."salary" (
"emp_no" integer NOT NULL,
"amount" integer NOT NULL,
"from_date" date NOT NULL,
"to_date" date NOT NULL,
CONSTRAINT "salary_pkey" PRIMARY KEY (emp_no, from_date),
CONSTRAINT "salary_emp_no_fkey" FOREIGN KEY ("emp_no") REFERENCES "public"."employee" ("emp_no") ON DELETE CASCADE
);

CREATE INDEX idx_salary_amount ON public.salary (amount);
CREATE INDEX "idx_salary_amount" ON ONLY "public"."salary" (amount);

CREATE TABLE public.audit (
id SERIAL PRIMARY KEY,
operation TEXT NOT NULL,
query TEXT,
user_name TEXT NOT NULL,
changed_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
CREATE TABLE "public"."title" (
"emp_no" integer NOT NULL,
"title" text NOT NULL,
"from_date" date NOT NULL,
"to_date" date,
CONSTRAINT "title_pkey" PRIMARY KEY (emp_no, title, from_date),
CONSTRAINT "title_emp_no_fkey" FOREIGN KEY ("emp_no") REFERENCES "public"."employee" ("emp_no") ON DELETE CASCADE
);

CREATE INDEX idx_audit_operation ON public.audit (operation);
CREATE INDEX idx_audit_username ON public.audit (user_name);
CREATE INDEX idx_audit_changed_at ON public.audit (changed_at);
CREATE VIEW "public"."current_dept_emp" AS SELECT l.emp_no,
d.dept_no,
l.from_date,
l.to_date
FROM (public.dept_emp d
JOIN public.dept_emp_latest_date l ON (((d.emp_no = l.emp_no) AND (d.from_date = l.from_date) AND (l.to_date = d.to_date))));

CREATE OR REPLACE FUNCTION public.log_dml_operations() RETURNS TRIGGER AS $$
CREATE VIEW "public"."dept_emp_latest_date" AS SELECT emp_no,
max(from_date) AS from_date,
max(to_date) AS to_date
FROM public.dept_emp
GROUP BY emp_no;

CREATE OR REPLACE FUNCTION public.log_dml_operations()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF (TG_OP = 'INSERT') THEN
INSERT INTO public.audit (operation, query, user_name)
INSERT INTO audit (operation, query, user_name)
VALUES ('INSERT', current_query(), current_user);
RETURN NEW;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO public.audit (operation, query, user_name)
INSERT INTO audit (operation, query, user_name)
VALUES ('UPDATE', current_query(), current_user);
RETURN NEW;
ELSIF (TG_OP = 'DELETE') THEN
INSERT INTO public.audit (operation, query, user_name)
INSERT INTO audit (operation, query, user_name)
VALUES ('DELETE', current_query(), current_user);
RETURN OLD;
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- only log update and delete, otherwise, it will cause too much change.
CREATE TRIGGER salary_log_trigger
AFTER UPDATE OR DELETE ON public.salary
FOR EACH ROW
EXECUTE FUNCTION public.log_dml_operations();

CREATE OR REPLACE VIEW public.dept_emp_latest_date AS
SELECT
emp_no,
MAX(
from_date) AS from_date,
MAX(
to_date) AS to_date
FROM
public.dept_emp
GROUP BY
emp_no;

-- shows only the current department for each employee
CREATE OR REPLACE VIEW public.current_dept_emp AS
SELECT
l.emp_no,
dept_no,
l.from_date,
l.to_date
FROM
public.dept_emp d
INNER JOIN public.dept_emp_latest_date l ON d.emp_no = l.emp_no
AND d.from_date = l.from_date
AND l.to_date = d.to_date;
$function$;

5 changes: 0 additions & 5 deletions schema/users.sql

This file was deleted.