4 data
This commit is contained in:
1
4/.gitignore
vendored
1
4/.gitignore
vendored
@ -1 +1,2 @@
|
||||
data.sql
|
||||
env.sh
|
||||
|
||||
260
4/data.js
260
4/data.js
@ -0,0 +1,260 @@
|
||||
import * as crypto from 'node:crypto'
|
||||
import * as fs from 'node:fs'
|
||||
|
||||
const GenMaxUInt = (max) => Math.floor(Math.random() * max)
|
||||
const GenInt = (from, to) => Math.floor(Math.random() * (to - from) + from)
|
||||
|
||||
const male_full_name = [
|
||||
"Семенов Дмитрий Романович",
|
||||
"Захаров Сергей Григорьевич",
|
||||
"Панов Артём Маркович",
|
||||
"Исаев Владимир Елисеевич",
|
||||
"Кириллов Степан Дмитриевич",
|
||||
"Никитин Георгий Егорович",
|
||||
"Терехов Даниил Давидович",
|
||||
"Николаев Роман Артёмович",
|
||||
"Соболев Сергей Васильевич",
|
||||
"Афанасьев Серафим Тимофеевич",
|
||||
]
|
||||
|
||||
const female_full_name = [
|
||||
"Макарова Виктория Глебовна",
|
||||
"Фролова Александра Владимировна",
|
||||
"Сычева Валерия Дмитриевна",
|
||||
"Плотникова Милана Марковна",
|
||||
"Носкова Таисия Тимуровна",
|
||||
"Чернышева Алиса Михайловна",
|
||||
"Михайлова Мария Яковлевна",
|
||||
"Никитина Ева Владимировна",
|
||||
"Лобанова Василиса Тимофеевна",
|
||||
"Князева Анна Данииловна",
|
||||
]
|
||||
|
||||
function GenFullName() {
|
||||
const sex = GenMaxUInt(2) ? 'male' : 'female'
|
||||
|
||||
|
||||
let full_name
|
||||
|
||||
if (sex == 'male') {
|
||||
full_name = male_full_name
|
||||
} else {
|
||||
full_name = female_full_name
|
||||
}
|
||||
const l = full_name.length
|
||||
const name_i = GenMaxUInt(l)
|
||||
const surname_i = GenMaxUInt(l)
|
||||
const middle_name_i = GenMaxUInt(l)
|
||||
const [name] = full_name[name_i].split(' ')
|
||||
const [, surname] = full_name[surname_i].split(' ')
|
||||
const [, , middle_name] = full_name[middle_name_i].split(' ')
|
||||
|
||||
return `'${name} ${surname} ${middle_name}'`
|
||||
}
|
||||
|
||||
const food_product_names = [
|
||||
'хлеб',
|
||||
'картофель',
|
||||
'яйца',
|
||||
'лук',
|
||||
'чеснок',
|
||||
'соль',
|
||||
'сахар',
|
||||
'масло',
|
||||
'макароны',
|
||||
'молоко',
|
||||
]
|
||||
|
||||
const drug_names = [
|
||||
"парацетамол",
|
||||
"ибупрофен",
|
||||
"аспирин",
|
||||
"левомеколь",
|
||||
"активированный уголь",
|
||||
"но-шпа",
|
||||
"цитрамон",
|
||||
"лоратадин",
|
||||
"кагоцел",
|
||||
"амоксициллин",
|
||||
]
|
||||
|
||||
const street_names = [
|
||||
"Улица Ленина",
|
||||
"Проспект Мира",
|
||||
"Улица Гагарина",
|
||||
"Набережная Реки Фонтанки",
|
||||
"Бульвар Космонавтов",
|
||||
"Переулок Строителей",
|
||||
"Проезд Шевченко",
|
||||
"Улица 8 Марта",
|
||||
"Микрорайон Солнечный",
|
||||
"Шоссе Энтузиастов",
|
||||
]
|
||||
|
||||
function GenPassport() {
|
||||
let res = ''
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
res += GenMaxUInt(10)
|
||||
}
|
||||
return `'` + res.slice(0, 4) + ' ' + res.slice(4) + `'`
|
||||
}
|
||||
|
||||
function GenAddress() {
|
||||
return `'` + street_names[GenMaxUInt(street_names.length)] + ' ' + GenMaxUInt(100) + `'`
|
||||
}
|
||||
|
||||
function GenPasswdHash() {
|
||||
return `decode('${crypto.randomBytes(32).toString('base64')}', 'base64')`
|
||||
}
|
||||
|
||||
function GenEmail() {
|
||||
return `'${GenMaxUInt(1000)}@mephi.ru'`
|
||||
}
|
||||
|
||||
function GenPhone() {
|
||||
let res = `'+7`
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
res += GenMaxUInt(10)
|
||||
}
|
||||
return res + `'`
|
||||
}
|
||||
|
||||
const billing = [
|
||||
'сбербанк',
|
||||
'тинкофф',
|
||||
'ипб',
|
||||
]
|
||||
|
||||
function GenBillingAccount() {
|
||||
return `'${billing[GenMaxUInt(billing.length)]}'`
|
||||
}
|
||||
|
||||
function GenTimestamp() {
|
||||
const start = new Date(2024, 0, 1).getTime()
|
||||
const end = new Date(2026, 0, 1).getTime()
|
||||
|
||||
return `'${new Date(GenInt(start, end)).toISOString()}'`
|
||||
}
|
||||
|
||||
function GenIntervalHours(max = 6) {
|
||||
return `'${GenInt(1, max)} hours'`
|
||||
}
|
||||
|
||||
function GenPrice(max = 1000) {
|
||||
return (Math.random() * max + 10).toFixed(2)
|
||||
}
|
||||
|
||||
const ClassTypes = ['Theory', 'Practice']
|
||||
const RegistrationStatuses = ['NotPaid', 'Paid']
|
||||
const EquipmentUsageTypes = ['PayOnce', 'PayMonthly']
|
||||
|
||||
function Values(callback) {
|
||||
let res = 'VALUES\n'
|
||||
const count = 5
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
res += callback()
|
||||
|
||||
if (i == count - 1) {
|
||||
res += ';\n\n'
|
||||
} else {
|
||||
res += ',\n'
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
// Master
|
||||
let script = 'INSERT INTO "Master" (full_name, passwd_hash, passport, readme) ' + Values(() => {
|
||||
return `(${GenFullName()}, ${GenPasswdHash()}, ${GenPassport()}, 'aboba')`
|
||||
})
|
||||
|
||||
// Client
|
||||
script += 'INSERT INTO "Client" (full_name, passwd_hash, phone, email, billing_account) ' + Values(() => {
|
||||
return `(${GenFullName()}, ${GenPasswdHash()}, ${GenPassport()}, ${GenPhone()}, ${GenBillingAccount()})`
|
||||
})
|
||||
|
||||
// Studio
|
||||
script += 'INSERT INTO "Studio" (address, capacity, begin_date, duration) ' + Values(() => {
|
||||
return `(${GenAddress()}, ${GenInt(10, 80)}, ${GenTimestamp()}, ${GenIntervalHours(12)})`
|
||||
})
|
||||
|
||||
// Course
|
||||
script += 'INSERT INTO "Course" ("Master_id", name, price, duration) ' + Values(() => {
|
||||
return `(${GenInt(1, 6)}, 'курс ${GenMaxUInt(100)}', ${GenPrice()}, ${GenIntervalHours(20)})`
|
||||
})
|
||||
|
||||
// Class
|
||||
script += 'INSERT INTO "Class" (begin_date, "Course_id", "Studio_id", name, type, duration) ' + Values(() => {
|
||||
return `(${GenTimestamp()}, ${GenInt(1, 6)}, ${GenInt(1, 6)}, 'занятие ${GenMaxUInt(100)}', '${ClassTypes[GenMaxUInt(ClassTypes.length)]}', ${GenIntervalHours()})`
|
||||
})
|
||||
|
||||
// Class_Master
|
||||
script += `INSERT INTO "Class_Master" ("Class_begin_date", "Class_Course_id", "Master_id")
|
||||
SELECT begin_date, "Course_id", ${GenInt(1, 6)} FROM "Class" LIMIT 1;\n\n`
|
||||
|
||||
// Registration
|
||||
script += 'INSERT INTO "Registration" ("Client_id", "Course_id", date, status) ' + Values(() => {
|
||||
return `(${GenInt(6, 11)}, ${GenInt(1, 6)}, ${GenTimestamp()}, '${RegistrationStatuses[GenMaxUInt(RegistrationStatuses.length)]}')`
|
||||
})
|
||||
|
||||
// FoodProductEnum
|
||||
script += 'INSERT INTO "FoodProductEnum" (name, avg_price) ' + Values(() => {
|
||||
return `('${food_product_names[GenMaxUInt(food_product_names.length)]}', ${GenPrice(200)})`
|
||||
})
|
||||
|
||||
// FoodProduct
|
||||
script += `INSERT INTO "FoodProduct" ("FoodProductEnum_id", "Class_begin_date", "Class_Course_id", buy_price, buy_date, delivery_price, delivery_date, expires_date)
|
||||
SELECT ${GenInt(1, 6)}, begin_date, "Course_id", ${GenPrice()}, ${GenTimestamp()}, ${GenPrice()}, ${GenTimestamp()}, ${GenTimestamp()} FROM "Class" LIMIT 1;\n\n`
|
||||
|
||||
// Equipment
|
||||
script += 'INSERT INTO "Equipment" ("Studio_id", name, usage_price, usage_type, delivery_price, delivery_date) ' + Values(() => {
|
||||
return `(${GenInt(1, 6)}, 'оборудование ${GenMaxUInt(100)}', ${GenPrice(300)}, '${EquipmentUsageTypes[GenMaxUInt(EquipmentUsageTypes.length)]}', ${GenPrice(200)}, ${GenTimestamp()})`
|
||||
})
|
||||
|
||||
// Class_Equipment
|
||||
script += `INSERT INTO "Class_Equipment" ("Class_begin_date", "Class_Course_id", "Equipment_id")
|
||||
SELECT begin_date, "Course_id", ${GenInt(1, 6)} FROM "Class" LIMIT 1;\n\n`
|
||||
|
||||
// DrugEnum
|
||||
script += 'INSERT INTO "DrugEnum" (name, avg_price) ' + Values(() => {
|
||||
return `('${drug_names[GenMaxUInt(drug_names.length)]}', ${GenPrice(500)})`
|
||||
})
|
||||
|
||||
// Drug
|
||||
script += 'INSERT INTO "Drug" ("DrugEnum_id", "Course_id", buy_price, buy_date, delivery_price, delivery_date, expires_date) ' + Values(() => {
|
||||
return `(${GenInt(1, 6)}, ${GenInt(1, 6)}, ${GenPrice()}, ${GenTimestamp()}, ${GenPrice()}, ${GenTimestamp()}, ${GenTimestamp()})`
|
||||
})
|
||||
|
||||
// ActivityLog
|
||||
script += 'INSERT INTO "ActivityLog" ("Person_id", action) ' + Values(() => {
|
||||
return `(${GenInt(1, 10)}, 'login')`
|
||||
})
|
||||
|
||||
const tables = [
|
||||
'Person',
|
||||
'Client',
|
||||
'Master',
|
||||
'Studio',
|
||||
'Course',
|
||||
'Class',
|
||||
'Class_Master',
|
||||
'Registration',
|
||||
'FoodProductEnum',
|
||||
'FoodProduct',
|
||||
'Equipment',
|
||||
'Class_Equipment',
|
||||
'DrugEnum',
|
||||
'Drug',
|
||||
'DrugIntolerance',
|
||||
'ActivityLog'
|
||||
]
|
||||
|
||||
for (const table of tables) {
|
||||
script += `SELECT * FROM "${table}";\n`
|
||||
}
|
||||
|
||||
fs.writeFileSync('data.sql', script)
|
||||
|
||||
12
4/deploy.sh
12
4/deploy.sh
@ -2,12 +2,6 @@
|
||||
|
||||
set -exu
|
||||
|
||||
SERVER=root@185.103.252.32
|
||||
PSQL="sudo -u postgres psql"
|
||||
DB=db2026
|
||||
|
||||
scp schema.sql data.sql "$SERVER:/tmp/$DB/"
|
||||
ssh $SERVER \
|
||||
"chmod -R 777 /tmp/$DB;" \
|
||||
"$PSQL -d $DB -e -q -f /tmp/$DB/schema.sql;" \
|
||||
"$PSQL -d $DB -e -q -f /tmp/$DB/data.sql;"
|
||||
source env.sh
|
||||
psql -e -q -f schema.sql
|
||||
psql -e -q -f data.sql
|
||||
|
||||
28
4/report.md
28
4/report.md
@ -23,3 +23,31 @@
|
||||
* SQL-скрипт начального наполнения;
|
||||
* скрипт генерации тестовых данных (Python или другой удобный вам язык);
|
||||
* инструкция по запуску.
|
||||
|
||||
# schema.sql - SQL-скрипт создания схемы;
|
||||
# data.js - скрипт генерации тестовых данных;
|
||||
## инструкция по запуску:
|
||||
|
||||
```{sh}
|
||||
node data.js
|
||||
```
|
||||
|
||||
## инструкция по деплою:
|
||||
|
||||
создать файл env.sh
|
||||
|
||||
```{sh}
|
||||
export PGUSER=""
|
||||
export PGDATABASE=""
|
||||
export PGPASSWORD=""
|
||||
export PGHOST=""
|
||||
export PGPORT=""
|
||||
```
|
||||
|
||||
запустить
|
||||
|
||||
```{sh}
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
# data.sql - SQL-скрипт начального наполнения;
|
||||
|
||||
141
4/schema.sql
141
4/schema.sql
@ -1,10 +1,14 @@
|
||||
DROP TABLE IF EXISTS "Person" CASCADE;
|
||||
DROP SEQUENCE IF EXISTS "PersonId";
|
||||
|
||||
|
||||
CREATE SEQUENCE "PersonId";
|
||||
|
||||
|
||||
CREATE TABLE "Person" (
|
||||
id int PRIMARY KEY,
|
||||
id int PRIMARY KEY DEFAULT nextval('"PersonId"'),
|
||||
full_name text NOT NULL,
|
||||
passwd_hash char(64) NOT NULL
|
||||
passwd_hash bytea NOT NULL
|
||||
);
|
||||
|
||||
|
||||
@ -28,8 +32,10 @@ CREATE TABLE "Master" (
|
||||
DROP TABLE IF EXISTS "Studio", "Course", "Class", "Class_Master", "Registration", "FoodProductEnum", "FoodProduct", "Equipment", "Class_Equipment", "DrugEnum", "Drug", "DrugIntolerance", "ActivityLog";
|
||||
|
||||
|
||||
DROP TYPE IF EXISTS "ClassType", "RegistrationStatus", "EquipmentUsageType";
|
||||
|
||||
CREATE TABLE "Studio" (
|
||||
id int PRIMARY KEY,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
address text UNIQUE NOT NULL,
|
||||
capacity int NOT NULL CHECK (capacity > 0),
|
||||
begin_date timestamptz NOT NULL,
|
||||
@ -38,187 +44,206 @@ CREATE TABLE "Studio" (
|
||||
|
||||
|
||||
CREATE TABLE "Course" (
|
||||
id int PRIMARY KEY,
|
||||
Master_id int,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
"Master_id" int,
|
||||
name text NOT NULL,
|
||||
price real NOT NULL CHECK (price > 0),
|
||||
duration interval NOT NULL,
|
||||
|
||||
FOREIGN KEY (Master_id) REFERENCES "Master" (id)
|
||||
FOREIGN KEY ("Master_id") REFERENCES "Master" (id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TYPE "ClassType" AS ENUM (
|
||||
'Theory',
|
||||
'Practice'
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Class" (
|
||||
begin_date timestamptz,
|
||||
Course_id int,
|
||||
Studio_id int,
|
||||
"Course_id" int,
|
||||
"Studio_id" int,
|
||||
name text NOT NULL,
|
||||
type int NOT NULL,
|
||||
type "ClassType" NOT NULL,
|
||||
duration interval NOT NULL,
|
||||
|
||||
PRIMARY KEY (begin_date, Course_id),
|
||||
PRIMARY KEY (begin_date, "Course_id"),
|
||||
|
||||
FOREIGN KEY (Course_id) REFERENCES "Course" (id)
|
||||
FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
FOREIGN KEY (Studio_id) REFERENCES "Studio" (id)
|
||||
FOREIGN KEY ("Studio_id") REFERENCES "Studio" (id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Class_Master" (
|
||||
Class_begin_date timestamptz,
|
||||
Class_Course_id int,
|
||||
Master_id int,
|
||||
"Class_begin_date" timestamptz,
|
||||
"Class_Course_id" int,
|
||||
"Master_id" int,
|
||||
|
||||
PRIMARY KEY (Class_begin_date, Class_Course_id, Master_id),
|
||||
PRIMARY KEY ("Class_begin_date", "Class_Course_id", "Master_id"),
|
||||
|
||||
FOREIGN KEY (Master_id) REFERENCES "Master" (id)
|
||||
FOREIGN KEY ("Master_id") REFERENCES "Master" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
FOREIGN KEY (Class_begin_date, Class_Course_id) REFERENCES "Class" (begin_date, Course_id)
|
||||
FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TYPE "RegistrationStatus" AS ENUM (
|
||||
'NotPaid',
|
||||
'Paid'
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Registration" (
|
||||
Client_id int,
|
||||
Course_id int,
|
||||
"Client_id" int,
|
||||
"Course_id" int,
|
||||
date timestamptz NOT NULL,
|
||||
status int NOT NULL,
|
||||
status "RegistrationStatus" NOT NULL,
|
||||
|
||||
PRIMARY KEY (Client_id, Course_id),
|
||||
PRIMARY KEY ("Client_id", "Course_id"),
|
||||
|
||||
FOREIGN KEY (Client_id) REFERENCES "Client" (id)
|
||||
FOREIGN KEY ("Client_id") REFERENCES "Client" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
FOREIGN KEY (Course_id) REFERENCES "Course" (id)
|
||||
FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "FoodProductEnum" (
|
||||
id int PRIMARY KEY,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name text NOT NULL,
|
||||
avg_price real NOT NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "FoodProduct" (
|
||||
id int,
|
||||
FoodProductEnum_id int,
|
||||
Class_begin_date timestamptz,
|
||||
Class_Course_id int,
|
||||
id int GENERATED ALWAYS AS IDENTITY,
|
||||
"FoodProductEnum_id" int,
|
||||
"Class_begin_date" timestamptz,
|
||||
"Class_Course_id" int,
|
||||
buy_price real NOT NULL,
|
||||
buy_date timestamptz NOT NULL,
|
||||
delivery_price real NOT NULL,
|
||||
delivery_date timestamptz NOT NULL,
|
||||
expires_date timestamptz NOT NULL,
|
||||
|
||||
PRIMARY KEY (id, FoodProductEnum_id),
|
||||
PRIMARY KEY (id, "FoodProductEnum_id"),
|
||||
|
||||
FOREIGN KEY (FoodProductEnum_id) REFERENCES "FoodProductEnum" (id)
|
||||
FOREIGN KEY ("FoodProductEnum_id") REFERENCES "FoodProductEnum" (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE RESTRICT,
|
||||
|
||||
FOREIGN KEY (Class_begin_date, Class_Course_id) REFERENCES "Class" (begin_date, Course_id)
|
||||
FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TYPE "EquipmentUsageType" AS ENUM (
|
||||
'PayOnce',
|
||||
'PayMonthly'
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Equipment" (
|
||||
id int PRIMARY KEY,
|
||||
Studio_id int,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
"Studio_id" int,
|
||||
name text NOT NULL,
|
||||
usage_price real NOT NULL,
|
||||
usage_type int NOT NULL,
|
||||
usage_type "EquipmentUsageType" NOT NULL,
|
||||
delivery_price real NOT NULL,
|
||||
delivery_date timestamptz NOT NULL,
|
||||
|
||||
FOREIGN KEY (Studio_id) REFERENCES "Studio" (id)
|
||||
FOREIGN KEY ("Studio_id") REFERENCES "Studio" (id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Class_Equipment" (
|
||||
Class_begin_date timestamptz,
|
||||
Class_Course_id int,
|
||||
Equipment_id int,
|
||||
"Class_begin_date" timestamptz,
|
||||
"Class_Course_id" int,
|
||||
"Equipment_id" int,
|
||||
|
||||
PRIMARY KEY (Class_begin_date, Class_Course_id, Equipment_id),
|
||||
PRIMARY KEY ("Class_begin_date", "Class_Course_id", "Equipment_id"),
|
||||
|
||||
FOREIGN KEY (Class_begin_date, Class_course_id) REFERENCES "Class" (begin_date, Course_id)
|
||||
FOREIGN KEY ("Class_begin_date", "Class_Course_id") REFERENCES "Class" (begin_date, "Course_id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
FOREIGN KEY (Equipment_id) REFERENCES "Equipment" (id)
|
||||
FOREIGN KEY ("Equipment_id") REFERENCES "Equipment" (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "DrugEnum" (
|
||||
id int PRIMARY KEY,
|
||||
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name text NOT NULL,
|
||||
avg_price real NOT NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "Drug" (
|
||||
id int,
|
||||
DrugEnum_id int,
|
||||
Course_id int,
|
||||
id int GENERATED ALWAYS AS IDENTITY,
|
||||
"DrugEnum_id" int,
|
||||
"Course_id" int,
|
||||
buy_price real NOT NULL,
|
||||
buy_date timestamptz NOT NULL,
|
||||
delivery_price real NOT NULL,
|
||||
delivery_date timestamptz NOT NULL,
|
||||
expires_date timestamptz NOT NULL,
|
||||
|
||||
PRIMARY KEY (id, DrugEnum_id),
|
||||
PRIMARY KEY (id, "DrugEnum_id"),
|
||||
|
||||
FOREIGN KEY (DrugEnum_id) REFERENCES "DrugEnum" (id)
|
||||
FOREIGN KEY ("DrugEnum_id") REFERENCES "DrugEnum" (id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE RESTRICT,
|
||||
|
||||
FOREIGN KEY (Course_id) REFERENCES "Course" (id)
|
||||
FOREIGN KEY ("Course_id") REFERENCES "Course" (id)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "DrugIntolerance" (
|
||||
Person_id int,
|
||||
DrugEnum_id int,
|
||||
"Person_id" int,
|
||||
"DrugEnum_id" int,
|
||||
|
||||
PRIMARY KEY (Person_id, DrugEnum_id),
|
||||
PRIMARY KEY ("Person_id", "DrugEnum_id"),
|
||||
|
||||
FOREIGN KEY (Person_id) REFERENCES "Person" (id)
|
||||
FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
FOREIGN KEY (DrugEnum_id) REFERENCES "DrugEnum" (id)
|
||||
FOREIGN KEY ("DrugEnum_id") REFERENCES "DrugEnum" (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "ActivityLog" (
|
||||
id int,
|
||||
Person_id int,
|
||||
id int GENERATED ALWAYS AS IDENTITY,
|
||||
"Person_id" int,
|
||||
action text NOT NULL,
|
||||
|
||||
PRIMARY KEY (id, Person_id),
|
||||
PRIMARY KEY (id, "Person_id"),
|
||||
|
||||
FOREIGN KEY (Person_id) REFERENCES "Person" (id)
|
||||
FOREIGN KEY ("Person_id") REFERENCES "Person" (id)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user