Repository navigation
Expand file tree
/
Copy pathdatabase_schema.sql
More file actions
136 lines (112 loc) · 4.37 KB
/
Copy pathdatabase_schema.sql
File metadata and controls
136 lines (112 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
DROP TRIGGER IF EXISTS location_path_update ON location;
DROP TRIGGER IF EXISTS location_update_descendants ON location;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE TABLE IF NOT EXISTS source_category(
id bigserial PRIMARY KEY,
name varchar(255) NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS location(
id bigserial PRIMARY KEY,
name text NOT NULL UNIQUE,
parent_id bigint REFERENCES location(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS source_tag(
id bigserial PRIMARY KEY,
name text NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS source_submission(
id bigserial PRIMARY KEY,
submitted_at timestamptz NOT NULL DEFAULT NOW(),
title text NOT NULL,
description text,
link text
);
CREATE TABLE IF NOT EXISTS source(
id bigserial PRIMARY KEY,
title text NOT NULL,
description text,
link text,
category_id bigint REFERENCES source_category(id) ON DELETE SET NULL,
);
ALTER TABLE source
ADD COLUMN IF NOT EXISTS created_at timestamptz NOT NULL DEFAULT NOW();
ALTER TABLE source
ADD COLUMN IF NOT EXISTS title_en text;
ALTER TABLE source
ADD COLUMN IF NOT EXISTS description_en text;
CREATE TABLE IF NOT EXISTS user_message(
id bigserial PRIMARY KEY,
message text NOT NULL,
reply_to text,
related_source_id bigint REFERENCES source(id) ON DELETE SET NULL,
handled boolean NOT NULL DEFAULT FALSE,
created_at timestamptz NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS notification(
id bigserial PRIMARY KEY,
message text NOT NULL,
created_at timestamptz NOT NULL DEFAULT NOW(),
last_pushed_at timestamptz
);
CREATE TABLE IF NOT EXISTS notification_recipient(
id bigserial PRIMARY KEY,
email varchar(255) NOT NULL UNIQUE,
enabled boolean NOT NULL DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS event_log(
event_type varchar(100) NOT NULL,
event_data jsonb NOT NULL DEFAULT '{}',
event_time timestamptz NOT NULL DEFAULT NOW(),
event_related_user bigint REFERENCES app_user(id) ON DELETE SET NULL,
event_related_source bigint REFERENCES source(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS source_tags(
source_id bigint REFERENCES source(id) ON DELETE CASCADE,
tag_id bigint REFERENCES source_tag(id) ON DELETE CASCADE,
PRIMARY KEY (source_id, tag_id)
);
CREATE TABLE IF NOT EXISTS source_locations(
source_id bigint REFERENCES source(id) ON DELETE CASCADE,
location_id bigint REFERENCES location(id) ON DELETE CASCADE,
PRIMARY KEY (source_id, location_id)
);
CREATE TABLE IF NOT EXISTS app_user(
id bigserial PRIMARY KEY,
username varchar(255) NOT NULL UNIQUE,
password_hash text NOT NULL,
permissions text[] NOT NULL DEFAULT ARRAY[]::text[]
);
CREATE TABLE IF NOT EXISTS audit_log(
id bigserial PRIMARY KEY,
user_id bigint REFERENCES app_user(id) ON DELETE SET NULL,
action text NOT NULL,
metadata jsonb,
timestamp timestamptz NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_audit_log_user_timestamp ON audit_log(user_id, timestamp);
-- 2. LITHUANIAN / DEFAULT INDEXES
-- These speed up: WHERE title ILIKE $1 OR description ILIKE $1
CREATE INDEX IF NOT EXISTS idx_source_title_trgm ON source USING GIN(title gin_trgm_ops);
CREATE INDEX IF NOT EXISTS idx_source_description_trgm ON source USING GIN(description gin_trgm_ops);
-- 3. ENGLISH / FALLBACK FUNCTIONAL INDEXES
-- These speed up: WHERE COALESCE(title_en, title) ILIKE $1
CREATE INDEX IF NOT EXISTS idx_source_title_en_coalesce_trgm ON source USING GIN(COALESCE(title_en, title) gin_trgm_ops);
CREATE INDEX IF NOT EXISTS idx_source_desc_en_coalesce_trgm ON source USING GIN(COALESCE(description_en, description) gin_trgm_ops);
-- -- Optional Grafana Account stuff, can be run if needed
-- do
-- $$
-- begin
-- if not exists (select * from pg_user where usename = 'grafanareader') then
-- CREATE USER grafanareader WITH PASSWORD 'grafana';
-- end if;
-- end
-- $$;
-- GRANT USAGE ON SCHEMA public TO grafanareader;
-- GRANT SELECT ON public.event_log TO grafanareader;
-- GRANT SELECT ON public.location TO grafanareader;
-- GRANT SELECT ON public.source TO grafanareader;
-- GRANT SELECT ON public.source_category TO grafanareader;
-- GRANT SELECT ON public.source_submission TO grafanareader;
-- GRANT SELECT ON public.source_tag TO grafanareader;
-- GRANT SELECT ON public.user_message TO grafanareader;
-- GRANT SELECT ON public.app_user TO grafanareader;