All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
130 lines
6.9 KiB
SQL
130 lines
6.9 KiB
SQL
-- v0.3.55-beta: doorzoekbare afbeeldingscatalogus met meervoudige thema's,
|
|
-- map-paden, eigenaarschap en instelbare opslagquota.
|
|
|
|
ALTER TABLE users
|
|
ADD COLUMN IF NOT EXISTS image_quota_bytes BIGINT
|
|
CHECK (image_quota_bytes IS NULL OR image_quota_bytes >= -1);
|
|
ALTER TABLE schools
|
|
ADD COLUMN IF NOT EXISTS image_quota_bytes BIGINT
|
|
CHECK (image_quota_bytes IS NULL OR image_quota_bytes >= -1);
|
|
|
|
CREATE TABLE IF NOT EXISTS image_themes (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
key TEXT UNIQUE,
|
|
scope TEXT NOT NULL CHECK (scope IN ('global','school','personal')),
|
|
school_id BIGINT REFERENCES schools(id) ON DELETE CASCADE,
|
|
owner_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
|
folder TEXT NOT NULL DEFAULT '',
|
|
name_nl TEXT NOT NULL,
|
|
name_en TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (
|
|
(scope = 'global' AND school_id IS NULL) OR
|
|
(scope = 'school' AND school_id IS NOT NULL AND owner_id IS NOT NULL) OR
|
|
(scope = 'personal' AND owner_id IS NOT NULL)
|
|
)
|
|
);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_themes_global_name
|
|
ON image_themes (lower(name_nl)) WHERE scope = 'global';
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_themes_school_name
|
|
ON image_themes (school_id, lower(name_nl)) WHERE scope = 'school';
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_themes_personal_name
|
|
ON image_themes (owner_id, lower(name_nl)) WHERE scope = 'personal';
|
|
|
|
CREATE TABLE IF NOT EXISTS image_folders (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
scope TEXT NOT NULL CHECK (scope IN ('global','school','personal')),
|
|
school_id BIGINT REFERENCES schools(id) ON DELETE CASCADE,
|
|
owner_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
|
path TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (
|
|
(scope = 'global' AND school_id IS NULL) OR
|
|
(scope = 'school' AND school_id IS NOT NULL AND owner_id IS NOT NULL) OR
|
|
(scope = 'personal' AND owner_id IS NOT NULL)
|
|
)
|
|
);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_folders_global_path
|
|
ON image_folders (path) WHERE scope = 'global';
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_folders_school_path
|
|
ON image_folders (school_id, path) WHERE scope = 'school';
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_image_folders_personal_path
|
|
ON image_folders (owner_id, path) WHERE scope = 'personal';
|
|
|
|
CREATE TABLE IF NOT EXISTS image_assets (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
key TEXT NOT NULL UNIQUE,
|
|
scope TEXT NOT NULL CHECK (scope IN ('global','school','personal')),
|
|
school_id BIGINT REFERENCES schools(id) ON DELETE CASCADE,
|
|
owner_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
|
folder TEXT NOT NULL DEFAULT '',
|
|
name TEXT NOT NULL,
|
|
original_name TEXT,
|
|
mime_type TEXT NOT NULL,
|
|
size_bytes BIGINT NOT NULL DEFAULT 0 CHECK (size_bytes >= 0),
|
|
storage_key TEXT UNIQUE,
|
|
public_path TEXT UNIQUE,
|
|
tags TEXT[] NOT NULL DEFAULT '{}',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK ((storage_key IS NULL) <> (public_path IS NULL)),
|
|
CHECK (
|
|
(scope = 'global' AND school_id IS NULL) OR
|
|
(scope = 'school' AND school_id IS NOT NULL AND owner_id IS NOT NULL) OR
|
|
(scope = 'personal' AND owner_id IS NOT NULL)
|
|
)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_image_assets_owner ON image_assets(owner_id);
|
|
CREATE INDEX IF NOT EXISTS idx_image_assets_school ON image_assets(school_id);
|
|
CREATE INDEX IF NOT EXISTS idx_image_assets_folder ON image_assets(scope, folder);
|
|
|
|
CREATE TABLE IF NOT EXISTS image_asset_themes (
|
|
asset_id BIGINT NOT NULL REFERENCES image_assets(id) ON DELETE CASCADE,
|
|
theme_id BIGINT NOT NULL REFERENCES image_themes(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (asset_id, theme_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_image_asset_themes_theme ON image_asset_themes(theme_id);
|
|
|
|
INSERT INTO image_themes (key, scope, name_nl, name_en)
|
|
VALUES
|
|
('builtin-money', 'global', 'Geld', 'Money'),
|
|
('builtin-coins', 'global', 'Munten', 'Coins'),
|
|
('builtin-banknotes', 'global', 'Briefgeld', 'Banknotes')
|
|
ON CONFLICT (key) DO NOTHING;
|
|
|
|
INSERT INTO image_folders (scope, path)
|
|
VALUES ('global','Rekenen'), ('global','Rekenen/Geld'),
|
|
('global','Rekenen/Geld/Munten'), ('global','Rekenen/Geld/Briefgeld')
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
INSERT INTO image_assets (key, scope, folder, name, mime_type, public_path, tags)
|
|
VALUES
|
|
('builtin-money-coin-1', 'global', 'Rekenen/Geld/Munten', '1 cent', 'image/png', '/img/money/coin-1.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-2', 'global', 'Rekenen/Geld/Munten', '2 cent', 'image/png', '/img/money/coin-2.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-5', 'global', 'Rekenen/Geld/Munten', '5 cent', 'image/png', '/img/money/coin-5.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-10', 'global', 'Rekenen/Geld/Munten', '10 cent', 'image/png', '/img/money/coin-10.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-20', 'global', 'Rekenen/Geld/Munten', '20 cent', 'image/png', '/img/money/coin-20.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-50', 'global', 'Rekenen/Geld/Munten', '50 cent', 'image/png', '/img/money/coin-50.png', ARRAY['geld','money','munt','coin','cent']),
|
|
('builtin-money-coin-100', 'global', 'Rekenen/Geld/Munten', '1 euro', 'image/png', '/img/money/coin-100.png', ARRAY['geld','money','munt','coin','euro']),
|
|
('builtin-money-coin-200', 'global', 'Rekenen/Geld/Munten', '2 euro', 'image/png', '/img/money/coin-200.png', ARRAY['geld','money','munt','coin','euro']),
|
|
('builtin-money-note-500', 'global', 'Rekenen/Geld/Briefgeld', '5 euro', 'image/jpeg', '/img/money/note-500.jpg', ARRAY['geld','money','briefgeld','banknote','euro']),
|
|
('builtin-money-note-1000', 'global', 'Rekenen/Geld/Briefgeld', '10 euro', 'image/jpeg', '/img/money/note-1000.jpg', ARRAY['geld','money','briefgeld','banknote','euro']),
|
|
('builtin-money-note-2000', 'global', 'Rekenen/Geld/Briefgeld', '20 euro', 'image/jpeg', '/img/money/note-2000.jpg', ARRAY['geld','money','briefgeld','banknote','euro']),
|
|
('builtin-money-note-5000', 'global', 'Rekenen/Geld/Briefgeld', '50 euro', 'image/jpeg', '/img/money/note-5000.jpg', ARRAY['geld','money','briefgeld','banknote','euro'])
|
|
ON CONFLICT (key) DO NOTHING;
|
|
|
|
INSERT INTO image_asset_themes (asset_id, theme_id)
|
|
SELECT a.id, t.id
|
|
FROM image_assets a
|
|
JOIN image_themes t ON t.key = 'builtin-money'
|
|
WHERE a.key LIKE 'builtin-money-%'
|
|
ON CONFLICT DO NOTHING;
|
|
|
|
INSERT INTO image_asset_themes (asset_id, theme_id)
|
|
SELECT a.id, t.id
|
|
FROM image_assets a
|
|
JOIN image_themes t ON t.key = CASE
|
|
WHEN a.key LIKE 'builtin-money-coin-%' THEN 'builtin-coins'
|
|
ELSE 'builtin-banknotes'
|
|
END
|
|
WHERE a.key LIKE 'builtin-money-%'
|
|
ON CONFLICT DO NOTHING;
|