Initial commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
FROM postgres:13-alpine AS base
|
||||
|
||||
FROM base AS builder
|
||||
RUN apk add --update git make openssl-dev clang llvm13 krb5-dev g++
|
||||
WORKDIR /tmp
|
||||
RUN git clone https://github.com/EnterpriseDB/pldebugger.git
|
||||
WORKDIR /tmp/pldebugger
|
||||
ENV USE_PGXS=1
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
FROM base AS dist
|
||||
COPY --from=builder /usr/local/lib/postgresql/ /usr/local/lib/postgresql/
|
||||
COPY --from=builder /usr/local/share/postgresql/ /usr/local/share/postgresql/
|
||||
COPY --from=builder /usr/local/share/doc/postgresql/ /usr/local/share/doc/postgresql/
|
||||
COPY init /docker-entrypoint-initdb.d
|
||||
COPY debugger-setup.sh /docker-entrypoint-initdb.d
|
||||
|
||||
# Run below in DB to enable the extension:
|
||||
# CREATE EXTENSION pldbgapi;
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM postgres:13
|
||||
|
||||
ENV PG_MAJOR 13
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
postgresql-$PG_MAJOR-pldebugger
|
||||
|
||||
COPY init /docker-entrypoint-initdb.d
|
||||
COPY debugger-setup.sh /docker-entrypoint-initdb.d
|
||||
|
||||
# Run below in DB to enable the extension:
|
||||
# CREATE EXTENSION pldbgapi;
|
||||
@@ -0,0 +1 @@
|
||||
echo "shared_preload_libraries = 'plugin_debugger'" >> /var/lib/postgresql/data/postgresql.conf
|
||||
@@ -0,0 +1,95 @@
|
||||
DROP TABLE IF EXISTS dictionary_language;
|
||||
DROP TABLE IF EXISTS dictionary_domain_secondary;
|
||||
DROP TABLE IF EXISTS dictionary;
|
||||
DROP TABLE IF EXISTS language;
|
||||
DROP TABLE IF EXISTS domain_secondary;
|
||||
DROP TABLE IF EXISTS domain_primary;
|
||||
DROP TYPE IF EXISTS dictionary_status;
|
||||
|
||||
CREATE TABLE domain_primary (
|
||||
id SMALLINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name_sl VARCHAR NOT NULL UNIQUE,
|
||||
name_en VARCHAR NOT NULL UNIQUE,
|
||||
udk_code VARCHAR NOT NULL UNIQUE,
|
||||
cerif_name VARCHAR NOT NULL,
|
||||
cerif_code VARCHAR NOT NULL,
|
||||
eurovoc_name VARCHAR NOT NULL,
|
||||
eurovoc_code VARCHAR NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE domain_secondary (
|
||||
id SMALLINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name_sl VARCHAR NOT NULL,
|
||||
name_en VARCHAR NOT NULL,
|
||||
approved BOOL NOT NULL DEFAULT FALSE,
|
||||
UNIQUE (name_sl, name_en)
|
||||
);
|
||||
|
||||
CREATE TABLE language (
|
||||
id SMALLINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
code VARCHAR NOT NULL UNIQUE,
|
||||
name_sl VARCHAR NOT NULL UNIQUE,
|
||||
name_en VARCHAR NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
CREATE TYPE dictionary_status AS ENUM ('closed', 'reviewed', 'published');
|
||||
|
||||
CREATE TABLE dictionary (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name_sl VARCHAR NOT NULL,
|
||||
name_sl_short VARCHAR NOT NULL,
|
||||
name_en VARCHAR NOT NULL,
|
||||
author VARCHAR[],
|
||||
issn VARCHAR,
|
||||
domain_primary_id SMALLINT NOT NULL REFERENCES domain_primary,
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_modified TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Include updating this one on changing related link tables.
|
||||
time_content_modified TIMESTAMPTZ, -- This one is updated manually and not through triggers.
|
||||
time_published TIMESTAMPTZ,
|
||||
status dictionary_status NOT NULL DEFAULT 'closed',
|
||||
count_entries INT NOT NULL DEFAULT 0, -- This one is updated manually and not through triggers.
|
||||
count_comments INT,
|
||||
description VARCHAR,
|
||||
entries_have_domain_labels BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_label BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_definition BOOL NOT NULL DEFAULT TRUE,
|
||||
entries_have_synonyms BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_links BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_other BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_foreign_languages BOOL NOT NULL DEFAULT TRUE,
|
||||
entries_have_foreign_definitions BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_foreign_synonyms BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_images BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_audio BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_videos BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_terminology_review_flag BOOL NOT NULL DEFAULT FALSE,
|
||||
entries_have_language_review_flag BOOL NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE dictionary_domain_secondary (
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
domain_secondary_id SMALLINT REFERENCES domain_secondary,
|
||||
PRIMARY KEY (dictionary_id, domain_secondary_id)
|
||||
);
|
||||
|
||||
CREATE TABLE dictionary_language (
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
language_id SMALLINT REFERENCES language,
|
||||
selection_order SMALLINT,
|
||||
PRIMARY KEY (dictionary_id, language_id)
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_time_modified()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.time_modified = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER dictionary_update_time_modified
|
||||
BEFORE UPDATE
|
||||
ON dictionary
|
||||
FOR EACH ROW
|
||||
WHEN (current_setting('term_portal.skip_update_time_modified', TRUE) IS DISTINCT FROM 'TRUE')
|
||||
EXECUTE FUNCTION update_time_modified();
|
||||
@@ -0,0 +1,70 @@
|
||||
INSERT INTO domain_primary (name_sl, name_en, udk_code, cerif_name, cerif_code, eurovoc_name, eurovoc_code)
|
||||
VALUES
|
||||
('Agronomija', 'Agronomy', '63', 'Agronomija', 'B 006', 'Agriculture, forestry and fisheries', '56'),
|
||||
('Arheologija', 'Archeology', '902', 'Arheologija', 'H 340', 'Natural and applied sciences', '3606'),
|
||||
('Arhitektura', 'Architecture', '72', 'Arhitektura, oblikovanje notranjosti', 'T 240', 'Humanities', '3611'),
|
||||
('Astronomija', 'Astronomy', '52', 'Astronomija', 'P 007', 'Natural and applied sciences', '3606'),
|
||||
('Bibliotekarstvo in informacijska znanost', 'Librarianship and information science', '02', 'Dokumentalistika, informacijska znanost, bibliotekarstvo, arhivistika', 'H 100', 'Information and information processing', '3231'),
|
||||
('Biologija', 'Biology', '57', 'Zgodovina in filozofija biomedicinskih ved, teoretična biologija, splošni vidiki evolucije', 'B 100', 'Natural and applied sciences', '3606'),
|
||||
('Biotehnologija', 'Biotechnology', '60', 'Biotehnologija', 'T 490', 'Natural and applied sciences', '3606'),
|
||||
('Botanika', 'Botany', '58', 'Botanika', 'B 004', 'Natural and applied sciences', '3606'),
|
||||
('Družboslovje', 'Social science', '30', 'Družboslovje', 'S 000', 'Social questions', '28'),
|
||||
('Ekonomija', 'Economy', '33', 'Ekonomija, ekonometrija, ekonomska teorija, ekonomski sistemi, ekonomska politika', 'S 180', 'Economics', '16'),
|
||||
('Elektrotehnika', 'Electrical engineering', '621.3', 'Elektronika in elektriška tehnologija', 'T 001', 'Electronics and electrical engineering', '6826'),
|
||||
('Energetika in energija', 'Energetics and energy', '620', 'Energijske raziskave', 'T 140', 'Energy', '66'),
|
||||
('Etnologija in antropologija', 'Ethnology and anthropology', '39', 'Kulturna antropologija, etnologija', 'S 220', 'Humanities', '3611'),
|
||||
('Farmacija', 'Pharmacy', '615', 'Farmakološke vede, farmakognozija, farmacija, toksikologija', 'B 740', 'Health', '2841'),
|
||||
('Filmska umetnost', 'Film arts', '791', 'Dramska umetnost', 'H 330', 'Culture and religion', '2831'),
|
||||
('Filozofija', 'Philosophy', '1', 'Filozofija', 'H 001', 'Humanities', '3611'),
|
||||
('Finance in bančništvo', 'Finance and banking', '336', 'Finančna veda', 'S 181', 'Finance', '24'),
|
||||
('Fizika', 'Physics', '53', 'Fizika', 'P 002', 'Natural and applied sciences', '3606'),
|
||||
('Fotografija', 'Photography', '77', 'Upodabljanje, obdelava podob', 'T 111', 'Culture and religion', '2831'),
|
||||
('Geodezija', 'Geodesy', '528', 'Geodezija', 'P 515', 'Natural and applied sciences', '3606'),
|
||||
('Geografija', 'Geography', '91', 'Fizična geografija, geomorfologija, pedologija, kartografija, klimatologija', 'P 510', 'Natural and applied sciences', '3606'),
|
||||
('Geologija in seizmologija', 'Geology and seismology', '55', 'Geologija, fizična geografija', 'P 005', 'Natural and applied sciences', '3606'),
|
||||
('Glasba', 'Music', '78', 'Muzikologija', 'H 320', 'Culture and religion', '2831'),
|
||||
('Gledališče', 'Theater', '792', 'Dramska umetnost', 'H 330', 'Culture and religion', '2831'),
|
||||
('Gozdarstvo in lesarstvo', 'Forestry and wood industry', '630', 'Gozdarstvo, gozdovi, gozdarska tehnologija', 'B 430', 'Forestry', '5636'),
|
||||
('Gradbeništvo', 'Building industry', '624', 'Gradbeništvo, hidravlika, priobalna tehnologija, mehanika zemljin', 'T 220', 'Building and public works', '6831'),
|
||||
('Javna uprava in delovanje države', 'Public administration and state governing', '35', 'Državno pravo', 'S 140', 'Politics', '4'),
|
||||
('Jezikoslovje', 'Linguistics', '80', 'Jezikoslovje', 'H 350', 'Humanities', '3611'),
|
||||
('Kemija', 'Chemistry', '54', 'Kemija', 'P 003', 'Natural and applied sciences', '3606'),
|
||||
('Književnost', 'Literature', '82', 'Splošna in primerjalna književnost, literarna kritika, literarna teorija', 'H 390', 'Culture and religion', '2831'),
|
||||
('Likovna umetnost', 'Fine Arts', '73/76', 'Slikarstvo', 'H 311', 'Culture and religion', '2831'),
|
||||
('Matematika', 'Mathematics', '51', 'Matematika', 'P 001', 'Natural and applied sciences', '3606'),
|
||||
('Medicina in zdravstvo', 'Medicine and health system', '61', 'Medicina (človek in vretenčarji)', 'B 007', 'Health', '2841'),
|
||||
('Metalurgija', 'Metalurgy', '669', 'Kovinska tehnologija, metalurgija, kovinski izdelki', 'T 450', 'Iron, steel and other metal industries', '6816'),
|
||||
('Meteorologija', 'Meteorology', '551', 'Geofizika, fizična oceanografija, meteorologija', 'P 500', 'Natural and applied sciences', '3606'),
|
||||
('Mikrobiologija', 'Microbiology', '579', 'Mikrobiologija, bakteriologija, virologija, mikologija', 'B 230', 'Natural and applied sciences', '3606'),
|
||||
('Naravoslovje', 'Natural science', '5', 'Naravoslovno-matematične vede', 'P 000', 'Natural and applied sciences', '3606'),
|
||||
('Novinarstvo in mediji', 'Journalism and media', '070', 'Tisk in komunikacijske vede', 'S 265', 'Communications', '3226'),
|
||||
('Oblačila in moda', 'Clothes and fashion', '646/67', 'Tekstilna tehnologija', 'T 470', 'Culture and religion', '2831'),
|
||||
('Obrt in rokodelstvo', 'Craft industry and handicraft', '67', 'Tehnologija ostalih izdelkov', 'T 480', 'Miscellaneous industries', '6846'),
|
||||
('Odnosi z javnostmi', 'Public relations', '354', 'Tisk in komunikacijske vede', 'S 265', 'Marketing', '2031'),
|
||||
('Okoljevarstvo', 'Ecology', '502', 'Okoljska tehnologija, nadzor onesnaženja', 'T 270', 'Environment', '52'),
|
||||
('Paleontologija', 'Palaeontology', '56', 'Paleontologija', 'P 006', 'Natural and applied sciences', '3606'),
|
||||
('Politika in politične vede', 'Politics and political science', '32', 'Politične in upravne vede', 'S 170', 'Politics', '4'),
|
||||
('Pravo', 'Law', '34', 'Pravo', 'S 110', 'Law', '12'),
|
||||
('Prevajanje', 'Translation', '81', 'Teorija prevajanja', 'H 365', 'Miscellaneous industries', '6846'),
|
||||
('Promet in vozila', 'Transport and vehicles', '656', 'Transportna tehnologija', 'T 003', 'Transport', '48'),
|
||||
('Psihologija', 'Psychology', '159.9', 'Psihologija', 'S 260', 'Humanities', '3611'),
|
||||
('Računalništvo in informatika', 'Computer and Information Science', '004', 'Računalništvo, numerična analiza, sistemi, kontrola', 'P 170', 'Information technology and data processing', '3236'),
|
||||
('Rudarstvo', 'Mining industries', '622', 'Rudarstvo', 'T 340', 'Coal and mining industries', '6611'),
|
||||
('Socialno delo', 'Social work', '36', 'Družbeni problemi in blagostanje, socialno skrbstvo', 'S 215', 'Social affairs', '2826'),
|
||||
('Sociologija', 'Sociology', '316', 'Sociologija', 'S 210', 'Humanities', '3611'),
|
||||
('Strojništvo', 'Mechanical engineering', '621', 'Strojništvo, hidravlika, vakuumska tehnologija, vibracije in akustično inženirstvo', 'T 210', 'Mechanical engineering', '6821'),
|
||||
('Šport in igre', 'Sports and games', '796/799', 'Telesna kultura, motorično učenje, šport', 'S 273', 'Social affairs', '2826'),
|
||||
('Trgovina', 'Trade', '339', 'Tržna in industrijska ekonomika', 'S 185', 'Trade', '2016'),
|
||||
('Turizem', 'Tourism', '338', 'Družbena geografija', 'S 230', 'Social affairs', '2826'),
|
||||
('Umetnost in umetnostna zgodovina', 'Arts and art history', '7', 'Umetnostna zgodovina', 'H 310', 'Culture and religion', '2831'),
|
||||
('Urbanizem', 'Urban study', '711', 'Prostorsko planiranje', 'T 260', 'Construction and town planning', '2846'),
|
||||
('Varnost, zaščita in reševanje', 'Safety, protection and rescue', '614', 'Varnostna tehnologija', 'T 500', 'Politics and public safety', '431'),
|
||||
('Verstva in teologija', 'Religion and theology', '2', 'Teologija', 'H 002', 'Culture and religion', '2831'),
|
||||
('Vojaška in obveščevalna dejavnost', 'Army and intelligence', '355', 'Vojaška veda in tehnologija', 'T 330', 'Defence', '821'),
|
||||
('Vzgoja in izobraževanje', 'Education and schooling', '37', 'Pedagogika in didaktika', 'S 270', 'Education', '3206'),
|
||||
('Zavarovalništvo', 'Insurance', '347', 'Zakon o zavarovanjih', 'S 137', 'Insurance', '2431'),
|
||||
('Zgodovina', 'History', '93/94', 'Zgodovina in umetnost', 'H 003', 'Humanities', '3611'),
|
||||
('Zoologija', 'Zoology', '59', 'Zoologija', 'B 005', 'Natural and applied sciences', '3606'),
|
||||
('Zootehnika in veterina', 'Zootechnics and veterinary medicine', '636', 'Zootehnika, živinoreja, vzreja', 'B 400', 'Health', '2841'),
|
||||
('Živilstvo in kulinarika', 'Food industry and culinary', '641', 'Tehnologija hrane in pijač', 'T 430', 'Foodstuff', '6026'),
|
||||
('Neopredeljeno', 'Undefined', '', '', '', '', '');
|
||||
@@ -0,0 +1,155 @@
|
||||
INSERT INTO domain_secondary (name_sl, name_en, approved)
|
||||
VALUES
|
||||
('aerobatika', 'aerobatics', TRUE),
|
||||
('aerobika', 'aerobics', TRUE),
|
||||
('aikido', 'aikido', FALSE),
|
||||
('airsoft', 'airsoft', FALSE),
|
||||
('alpinizem', 'mountaineering', TRUE),
|
||||
('alpska kombinacija', 'alpine combination', FALSE),
|
||||
('alpsko smučanje', 'alpine skiing', FALSE),
|
||||
('ameriški nogomet', 'American football', FALSE),
|
||||
('atletika', 'athletics', TRUE),
|
||||
('badminton', 'badminton', TRUE),
|
||||
('balinanje', 'bowling', FALSE),
|
||||
('balonarstvo', 'ballooning', FALSE),
|
||||
('bejzbol', 'baseball', FALSE),
|
||||
('biatlon', 'biathlon', TRUE),
|
||||
('bilijard', 'billiards', FALSE),
|
||||
('bob', 'bob', FALSE),
|
||||
('bodibilding', 'bodybuilding', FALSE),
|
||||
('boks', 'boxing', TRUE),
|
||||
('borilni športi', 'martial arts', FALSE),
|
||||
('bowling', 'bowling', FALSE),
|
||||
('bungee jumping', 'bungee jumping', FALSE),
|
||||
('cestno kolesarstvo', 'road cycling', FALSE),
|
||||
('curling', 'curling', FALSE),
|
||||
('deskanje', 'surfing', TRUE),
|
||||
('deskanje na snegu', 'snowboarding', FALSE),
|
||||
('dirka s čolni', 'boat race', FALSE),
|
||||
('dirka z avtomobili', 'car race', FALSE),
|
||||
('dirka z motorji', 'motorcycle race', FALSE),
|
||||
('dirkališčno kolesarstvo (velodrom)', 'racing cycling (velodrome)', FALSE),
|
||||
('dresurno jahanje', 'dressage riding', TRUE),
|
||||
('drsanje in rolanje', 'skating and rollerblading', FALSE),
|
||||
('dviganje uteži', 'weight lifting', TRUE),
|
||||
('džu džitsu', 'ju jitsu', FALSE),
|
||||
('ekstremni športi', 'extreme sports', FALSE),
|
||||
('floorball', 'floorball', FALSE),
|
||||
('formula 1', 'formula 1', FALSE),
|
||||
('gimnastika', 'gymnastics', TRUE),
|
||||
('golf', 'golf', TRUE),
|
||||
('gorništvo', 'mountaineering', FALSE),
|
||||
('gorsko kolesarstvo', 'mountain biking', FALSE),
|
||||
('hitra hoja', 'brisk walking', TRUE),
|
||||
('hitrostno drsanje', 'speed skating', TRUE),
|
||||
('hitrostno potapljanje in plavanje s plavutmi', 'speed diving and fin swimming', FALSE),
|
||||
('hokej na kotalkah', 'roller hockey', FALSE),
|
||||
('hokej na ledu', 'ice hockey', TRUE),
|
||||
('hokej na rolerjih', 'roller hockey', FALSE),
|
||||
('hokej na travi', 'field hockey', FALSE),
|
||||
('jadralno letalstvo', 'gliding', FALSE),
|
||||
('jadralno padalstvo', 'paragliding', FALSE),
|
||||
('jadralstvo', 'sailing', FALSE),
|
||||
('jamarstvo', 'caving', FALSE),
|
||||
('judo', 'judo', TRUE),
|
||||
('kajakaštvo', 'kayaking', TRUE),
|
||||
('karate', 'karate', TRUE),
|
||||
('karting', 'karting', FALSE),
|
||||
('kasaštvo', 'kasachstvo', FALSE),
|
||||
('kegljanje', 'bowling', FALSE),
|
||||
('kendo', 'kendo', FALSE),
|
||||
('kmečki biljard', 'peasant billiards', FALSE),
|
||||
('kockboxing', 'kockboxing', FALSE),
|
||||
('kolesarstvo', 'cycling', TRUE),
|
||||
('košarka', 'basketball', TRUE),
|
||||
('kriket', 'cricket', FALSE),
|
||||
('kros', 'cross', FALSE),
|
||||
('kung-fu', 'kung fu', FALSE),
|
||||
('lacrosse', 'lacrosse', FALSE),
|
||||
('lokostrelstvo', 'archery', TRUE),
|
||||
('maraton', 'marathon', TRUE),
|
||||
('met diska', 'with disk', TRUE),
|
||||
('met kladiva', 'hammer throw', TRUE),
|
||||
('met kopja', 'javelin throw', TRUE),
|
||||
('metanje podkve', 'throwing a horseshoe', FALSE),
|
||||
('meti', 'target', FALSE),
|
||||
('modelarstvo', 'modeling', FALSE),
|
||||
('motokros', 'motocross', TRUE),
|
||||
('motorizirani športi', 'motorized sports', FALSE),
|
||||
('namizni nogomet', 'table football', FALSE),
|
||||
('namizni tenis', 'table tennis', FALSE),
|
||||
('nogomet', 'football', TRUE),
|
||||
('nordijska kombinacija', 'Nordic combination', TRUE),
|
||||
('nordijsko smučanje', 'Nordic skiing', FALSE),
|
||||
('odbojka', 'volleyball', TRUE),
|
||||
('odbojka na mivki', 'beach volleyball', TRUE),
|
||||
('orientacija', 'orientation', FALSE),
|
||||
('padalstvo', 'parachuting', FALSE),
|
||||
('paeyball', 'paeyball', FALSE),
|
||||
('paintball', 'paintball', FALSE),
|
||||
('paralelni slalom', 'parallel slalom', FALSE),
|
||||
('pasja dirka', 'dog race', FALSE),
|
||||
('petanke', 'petanque', FALSE),
|
||||
('petelinja bitka', 'rooster battle', FALSE),
|
||||
('pikado', 'darts', FALSE),
|
||||
('plavanje', 'swimming', TRUE),
|
||||
('podvodni hokej', 'underwater hockey', FALSE),
|
||||
('polaganje rok', 'laying hands', FALSE),
|
||||
('polo', 'polo', FALSE),
|
||||
('potapljaštvo', 'diving', FALSE),
|
||||
('preskakovanje ovir', 'jumping over obstacles', FALSE),
|
||||
('ritmična gimnastika', 'rhythmic gymnastics', TRUE),
|
||||
('rokoborba', 'wrestling', TRUE),
|
||||
('rokomet', 'handball', TRUE),
|
||||
('rolanje', 'rollerblading', FALSE),
|
||||
('rolkanje', 'skateboarding', FALSE),
|
||||
('rugby', 'rugby', TRUE),
|
||||
('sabljanje', 'fencing', TRUE),
|
||||
('sankanje', 'sledding', TRUE),
|
||||
('savate', 'savate', FALSE),
|
||||
('sinhrono plavanje', 'synchronous swimming', TRUE),
|
||||
('skok ob palici', 'pole vault', TRUE),
|
||||
('skok v višino', 'high jump', TRUE),
|
||||
('skoki', 'jumps', FALSE),
|
||||
('skoki v vodo', 'jumps into the water', FALSE),
|
||||
('skoki v vodo z velikih višin', 'jumping into the water from great heights', FALSE),
|
||||
('skupinski športi', 'group sports', FALSE),
|
||||
('skvoš', 'squash', FALSE),
|
||||
('slalom', 'slalom', TRUE),
|
||||
('smuk', 'smuk', TRUE),
|
||||
('smučanje', 'skiing', TRUE),
|
||||
('smučanje in zimski športi', 'skiing and winter sports', FALSE),
|
||||
('smučarski skoki', 'ski jumping', TRUE),
|
||||
('softball', 'softball', FALSE),
|
||||
('streljanje', 'shooting', TRUE),
|
||||
('sumo', 'sumo', FALSE),
|
||||
('superveleslalom', 'super giant slalom', TRUE),
|
||||
('surfanje', 'surfing', FALSE),
|
||||
('suvanje krogle', 'pushing the ball', TRUE),
|
||||
('taekwondo', 'taekwondo', FALSE),
|
||||
('tek na dolge proge', 'running long distances', FALSE),
|
||||
('tek na smučeh', 'cross-country skiing', TRUE),
|
||||
('tek na srednje proge', 'only on the middle lanes', FALSE),
|
||||
('tek čez ovire', 'running over obstacles', TRUE),
|
||||
('teki', 'teki', FALSE),
|
||||
('tekma kamel', 'camel match', FALSE),
|
||||
('telemark smučanje', 'telemark skiing', FALSE),
|
||||
('tenis', 'tennis', TRUE),
|
||||
('trampolin', 'trampoline', FALSE),
|
||||
('triatlon', 'triathlon', TRUE),
|
||||
('troskok', 'troskok', TRUE),
|
||||
('turno smučanje', 'ski touring', FALSE),
|
||||
('ultimate frizbi', 'ultimate frisbee', FALSE),
|
||||
('vaterpolo', 'water polo', TRUE),
|
||||
('veleslalom', 'giant slalom', TRUE),
|
||||
('vertikalno rolkanje', 'vertical skateboarding', FALSE),
|
||||
('vodni športi', 'water sports', FALSE),
|
||||
('zunanji športi', 'outdoor sports', FALSE),
|
||||
('športi moči', 'power sports', FALSE),
|
||||
('športi s tarčami', 'target sports', FALSE),
|
||||
('športi z loparji', 'racket sports', FALSE),
|
||||
('športi z živalmi', 'animal sports', FALSE),
|
||||
('športna akrobatika', 'sports acrobatics', FALSE),
|
||||
('športna gimnastika', 'gymnastics', FALSE),
|
||||
('športno plezanje', 'sport climbing', TRUE),
|
||||
('šprint', 'sprint', FALSE);
|
||||
@@ -0,0 +1,39 @@
|
||||
INSERT INTO language (code, name_sl, name_en)
|
||||
VALUES
|
||||
('ar', 'arabščina', 'Arabic'),
|
||||
('be', 'beloruščina', 'Belarusian'),
|
||||
('bg', 'bolgarščina', 'Bulgarian'),
|
||||
('bs', 'bosanščina', 'Bosnian'),
|
||||
('cs', 'češčina', 'Czech'),
|
||||
('da', 'danščina', 'Danish'),
|
||||
('de', 'nemščina', 'German'),
|
||||
('el', 'grščina', 'Greek'),
|
||||
('en', 'angleščina', 'English'),
|
||||
('es', 'španščina', 'Spanish'),
|
||||
('et', 'estonščina', 'Estonian'),
|
||||
('fi', 'finščina', 'Finnish'),
|
||||
('fr', 'francoščina', 'French'),
|
||||
('ga', 'irščina', 'Irish'),
|
||||
('hr', 'hrvaščina', 'Croatian'),
|
||||
('hu', 'madžarščina', 'Hungarian'),
|
||||
('is', 'islandščina', 'Icelandic'),
|
||||
('it', 'italijanščina', 'Italian'),
|
||||
('la', 'latinščina', 'Latin'),
|
||||
('lt', 'litovščina', 'Lithuanian'),
|
||||
('lv', 'latvijščina', 'Latvian'),
|
||||
('mk', 'makedonščina', 'Macedonian'),
|
||||
('mo', 'moldavščina', 'Moldavian'),
|
||||
('mt', 'malteščina', 'Maltese'),
|
||||
('nl', 'nizozemščina', 'Dutch'),
|
||||
('no', 'norveščina', 'Norwegian'),
|
||||
('pl', 'poljščina', 'Polish'),
|
||||
('pt', 'portugalščina', 'Portuguese'),
|
||||
('ro', 'romunščina', 'Romanian'),
|
||||
('ru', 'ruščina', 'Russian'),
|
||||
('sk', 'slovaščina', 'Slovak'),
|
||||
('sl', 'slovenščina', 'Slovenian'),
|
||||
('sq', 'albanščina', 'Albanian'),
|
||||
('sr', 'srbščina', 'Serbian'),
|
||||
('sv', 'švedščina', 'Swedish'),
|
||||
('tr', 'turščina', 'Turkish'),
|
||||
('uk', 'ukrajinščina', 'Ukrainian');
|
||||
@@ -0,0 +1,15 @@
|
||||
-- INSERT INTO dictionary (name_sl, name_sl_short, name_en, author, issn, domain_primary_id, count_comments)
|
||||
-- VALUES
|
||||
-- ('Testni slovar', 'Testić', 'Testie', '{"Luka", "Miro"}', 'ISSN koda', 12, 0),
|
||||
-- ('Še en testni slovar', 'Še', 'another', '{"Aljaž"}', NULL, 3, 0),
|
||||
-- ('Pa ne še en testni slovar', 'Pa še', 'and another', '{"Jure"}', NULL, 14, 0);
|
||||
|
||||
-- INSERT INTO dictionary_domain_secondary (dictionary_id, domain_secondary_id)
|
||||
-- VALUES
|
||||
-- (1, 1),
|
||||
-- (1, 2);
|
||||
|
||||
-- INSERT INTO dictionary_language (dictionary_id, language_id, selection_order)
|
||||
-- VALUES
|
||||
-- (1, 1, 2),
|
||||
-- (1, 3, 1);
|
||||
@@ -0,0 +1,71 @@
|
||||
DROP TABLE IF EXISTS user_role CASCADE;
|
||||
DROP TABLE IF EXISTS user_token_remember_me;
|
||||
DROP TABLE IF EXISTS user_token_activation;
|
||||
DROP TABLE IF EXISTS "user" CASCADE;
|
||||
DROP TYPE IF EXISTS user_role_name;
|
||||
DROP TYPE IF EXISTS user_hits_per_page;
|
||||
DROP TYPE IF EXISTS user_status;
|
||||
|
||||
CREATE TYPE user_status AS ENUM ('registered', 'active');
|
||||
|
||||
CREATE TYPE user_hits_per_page AS ENUM ('10', '20', '50', '100');
|
||||
|
||||
CREATE TYPE user_role_name AS ENUM ('portal admin', 'dictionaries admin', 'consultancy admin', 'consultant', 'editor');
|
||||
|
||||
CREATE TABLE "user" (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
username VARCHAR NOT NULL UNIQUE,
|
||||
first_name VARCHAR NOT NULL,
|
||||
last_name VARCHAR NOT NULL,
|
||||
email VARCHAR NOT NULL UNIQUE,
|
||||
status user_status NOT NULL DEFAULT 'registered',
|
||||
bcrypt_hash VARCHAR NOT NULL,
|
||||
time_registered TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_activated TIMESTAMPTZ,
|
||||
hits_per_page user_hits_per_page NOT NULL DEFAULT '10'
|
||||
);
|
||||
|
||||
CREATE TABLE user_token_activation (
|
||||
token VARCHAR PRIMARY KEY,
|
||||
user_id INT NOT NULL REFERENCES "user",
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE user_token_remember_me (
|
||||
token VARCHAR PRIMARY KEY,
|
||||
user_id INT NOT NULL REFERENCES "user",
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE user_role (
|
||||
user_id INT NOT NULL REFERENCES "user",
|
||||
role_name user_role_name NOT NULL,
|
||||
domains VARCHAR,
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
administration BOOL,
|
||||
editing BOOL,
|
||||
terminology_review BOOL,
|
||||
language_review BOOL,
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN role_name != 'consultant'
|
||||
THEN domains IS NULL
|
||||
ELSE TRUE
|
||||
END
|
||||
),
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN role_name = 'editor'
|
||||
THEN dictionary_id IS NOT NULL
|
||||
AND administration IS NOT NULL
|
||||
AND editing IS NOT NULL
|
||||
AND terminology_review IS NOT NULL
|
||||
AND language_review IS NOT NULL
|
||||
ELSE dictionary_id IS NULL
|
||||
AND administration IS NULL
|
||||
AND editing IS NULL
|
||||
AND terminology_review IS NULL
|
||||
AND language_review IS NULL
|
||||
END
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,110 @@
|
||||
DROP TABLE IF EXISTS import_file_job;
|
||||
DROP TYPE IF EXISTS import_file_status;
|
||||
DROP TYPE IF EXISTS import_file_format;
|
||||
DROP TABLE IF EXISTS process;
|
||||
DROP TYPE IF EXISTS process_type;
|
||||
DROP TABLE IF EXISTS entry_link;
|
||||
DROP TABLE IF EXISTS entry_domain_label;
|
||||
DROP TABLE IF EXISTS entry_foreign;
|
||||
DROP TABLE IF EXISTS entry;
|
||||
DROP TABLE IF EXISTS dictionary_domain;
|
||||
DROP TABLE IF EXISTS domain_label;
|
||||
DROP TYPE IF EXISTS entry_status;
|
||||
DROP TYPE IF EXISTS entry_link_type;
|
||||
DROP TYPE IF EXISTS headword_status;
|
||||
|
||||
CREATE TYPE headword_status AS ENUM ('no content', 'unverified', 'unconfirmed', 'confirmed');
|
||||
|
||||
CREATE TYPE entry_link_type AS ENUM ('related', 'broader', 'narrow');
|
||||
|
||||
CREATE TYPE entry_status AS ENUM ('suggestion', 'in_edit', 'complete');
|
||||
|
||||
CREATE TABLE domain_label (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR NOT NULL,
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
is_visible BOOL NOT NULL DEFAULT TRUE,
|
||||
UNIQUE (name, dictionary_id)
|
||||
);
|
||||
|
||||
CREATE TABLE entry (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
dictionary_id INT NOT NULL REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since you're making queries with it in a WHERE clause and since deletion of rows from dictionary will require a scan of this table for references.
|
||||
is_valid BOOL NOT NULL DEFAULT FALSE,
|
||||
is_published BOOL NOT NULL DEFAULT FALSE,
|
||||
is_terminology_reviewed BOOL NOT NULL DEFAULT FALSE,
|
||||
is_language_reviewed BOOL NOT NULL DEFAULT FALSE,
|
||||
status entry_status NOT NULL DEFAULT 'suggestion',
|
||||
term VARCHAR,
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_modified TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
version SMALLINT NOT NULL DEFAULT 1,
|
||||
version_author INT REFERENCES "user" ON DELETE SET NULL, -- Consider indexing this one, since deletion of rows from user will require a scan of this table for references.
|
||||
homonym_sort SMALLINT,
|
||||
wordforms headword_status NOT NULL DEFAULT 'no content',
|
||||
accent headword_status NOT NULL DEFAULT 'no content',
|
||||
pronunciation headword_status NOT NULL DEFAULT 'no content',
|
||||
label VARCHAR,
|
||||
definition VARCHAR,
|
||||
synonym VARCHAR[],
|
||||
other VARCHAR,
|
||||
image VARCHAR[],
|
||||
audio VARCHAR[],
|
||||
video VARCHAR[],
|
||||
time_most_recent_comment TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE entry_foreign (
|
||||
entry_id INT REFERENCES entry ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from entry will require a scan of this table for references.
|
||||
language_id SMALLINT NOT NULL REFERENCES language,
|
||||
term VARCHAR[],
|
||||
definition VARCHAR,
|
||||
synonym VARCHAR[],
|
||||
PRIMARY KEY (entry_id, language_id)
|
||||
);
|
||||
|
||||
CREATE TABLE entry_domain_label (
|
||||
entry_id INT REFERENCES entry ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from entry will require a scan of this table for references.
|
||||
domain_label_id INT REFERENCES domain_label ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from domain_label_id will require a scan of this table for references.
|
||||
PRIMARY KEY (entry_id, domain_label_id)
|
||||
);
|
||||
|
||||
CREATE TABLE entry_link (
|
||||
entry_id INT REFERENCES entry ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from entry will require a scan of this table for references.
|
||||
type entry_link_type NOT NULL DEFAULT 'related',
|
||||
link VARCHAR NOT NULL,
|
||||
PRIMARY KEY (entry_id, type, link)
|
||||
);
|
||||
|
||||
CREATE TYPE process_type AS ENUM ('import', 'export'); -- + 'index'?
|
||||
|
||||
CREATE TABLE process (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
type process_type NOT NULL,
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE SET NULL, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
time_started TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_ended TIMESTAMPTZ,
|
||||
report VARCHAR
|
||||
);
|
||||
|
||||
CREATE TYPE import_file_format AS ENUM ('xml', 'csv', 'tsv');
|
||||
|
||||
CREATE TYPE import_file_status AS ENUM ('in progress', 'error', 'done');
|
||||
|
||||
CREATE TABLE import_file_job (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
time_started TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
status import_file_status NOT NULL DEFAULT 'in progress',
|
||||
dictionary_id INT REFERENCES dictionary ON DELETE SET NULL, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
delete_existing_entries BOOL NOT NULL,
|
||||
file_format import_file_format NOT NULL,
|
||||
count_valid_entries INT NOT NULL DEFAULT 0,
|
||||
count_invalid_entries INT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TRIGGER entry_update_time_modified
|
||||
BEFORE UPDATE
|
||||
ON entry
|
||||
FOR EACH ROW
|
||||
WHEN (current_setting('term_portal.skip_update_time_modified', TRUE) IS DISTINCT FROM 'TRUE')
|
||||
EXECUTE FUNCTION update_time_modified();
|
||||
@@ -0,0 +1,119 @@
|
||||
CREATE OR REPLACE FUNCTION json_to_array (json)
|
||||
RETURNS TEXT[]
|
||||
AS $$
|
||||
SELECT COALESCE(array_agg(x),
|
||||
CASE WHEN $1 IS NULL THEN NULL ELSE ARRAY[]::TEXT[] END)
|
||||
FROM json_array_elements_text($1) t(x);
|
||||
$$ LANGUAGE SQL IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION entry_new (
|
||||
_dictionary_id entry.dictionary_id%type,
|
||||
_is_valid entry.is_valid%type,
|
||||
_status entry.status%type,
|
||||
_term entry.term%type,
|
||||
_version_author entry.version_author%type,
|
||||
_homonym_sort entry.homonym_sort%type,
|
||||
_wordforms entry.wordforms%type,
|
||||
_accent entry.accent%type,
|
||||
_pronunciation entry.pronunciation%type,
|
||||
_domain_label_name_list VARCHAR[],
|
||||
_label entry.label%type,
|
||||
_definition entry.definition%type,
|
||||
_synonym entry.synonym%type,
|
||||
_link_list JSON[],
|
||||
_other entry.other%type,
|
||||
_foreign_language_content_list JSON[],
|
||||
_image entry.image%type,
|
||||
_audio entry.audio%type,
|
||||
_video entry.video%type,
|
||||
OUT _entry_id entry.id%type
|
||||
)
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
_domain_label_id_list INT[] := ARRAY[]::INT[];
|
||||
_domain_label_name_to_associate domain_label.name%type;
|
||||
_domain_label_id_to_associate domain_label.id%type;
|
||||
_link_to_associate JSON;
|
||||
_foreign_language_content JSON;
|
||||
_foreign_language_id_to_associate language.id%type;
|
||||
|
||||
BEGIN
|
||||
-- Create new entry.
|
||||
INSERT INTO entry (
|
||||
dictionary_id,
|
||||
is_valid,
|
||||
status,
|
||||
term,
|
||||
version_author,
|
||||
homonym_sort,
|
||||
wordforms,
|
||||
accent,
|
||||
pronunciation,
|
||||
label,
|
||||
definition,
|
||||
synonym,
|
||||
other,
|
||||
image,
|
||||
audio,
|
||||
video
|
||||
)
|
||||
VALUES (
|
||||
_dictionary_id,
|
||||
_is_valid,
|
||||
_status,
|
||||
_term,
|
||||
_version_author,
|
||||
_homonym_sort,
|
||||
-- It would be better if instead of hardcoding the string, it said:
|
||||
-- If value is NULL, insert the default value.
|
||||
COALESCE(_wordforms, 'no content'),
|
||||
COALESCE(_accent, 'no content'),
|
||||
COALESCE(_pronunciation, 'no content'),
|
||||
_label,
|
||||
_definition,
|
||||
_synonym,
|
||||
_other,
|
||||
_image,
|
||||
_audio,
|
||||
_video
|
||||
)
|
||||
RETURNING id
|
||||
INTO _entry_id;
|
||||
|
||||
-- Create new domain labels, if any.
|
||||
FOREACH _domain_label_name_to_associate IN ARRAY _domain_label_name_list LOOP
|
||||
_domain_label_id_to_associate := (SELECT id FROM domain_label WHERE name = _domain_label_name_to_associate);
|
||||
IF _domain_label_id_to_associate IS NULL THEN
|
||||
INSERT INTO domain_label (name, dictionary_id) VALUES (_domain_label_name_to_associate, _dictionary_id)
|
||||
returning id
|
||||
INTO _domain_label_id_to_associate;
|
||||
END IF;
|
||||
_domain_label_id_list := _domain_label_id_list || _domain_label_id_to_associate;
|
||||
END LOOP;
|
||||
|
||||
-- Associate domain labels, if any.
|
||||
FOREACH _domain_label_id_to_associate IN ARRAY _domain_label_id_list LOOP
|
||||
INSERT INTO entry_domain_label (entry_id, domain_label_id)
|
||||
VALUES (_entry_id, _domain_label_id_to_associate);
|
||||
END LOOP;
|
||||
|
||||
-- Associate links, if any.
|
||||
FOREACH _link_to_associate IN ARRAY _link_list LOOP
|
||||
INSERT INTO entry_link (entry_id, type, link)
|
||||
VALUES (_entry_id, (_link_to_associate ->> 'type')::entry_link_type, _link_to_associate ->> 'link');
|
||||
END LOOP;
|
||||
|
||||
-- Associate languages, if any.
|
||||
FOREACH _foreign_language_content IN ARRAY _foreign_language_content_list LOOP
|
||||
_foreign_language_id_to_associate := (SELECT id FROM language WHERE code = _foreign_language_content ->> 'language');
|
||||
INSERT INTO entry_foreign (entry_id, language_id, term, definition, synonym)
|
||||
VALUES (
|
||||
_entry_id, _foreign_language_id_to_associate,
|
||||
json_to_array(_foreign_language_content -> 'terms'),
|
||||
_foreign_language_content ->> 'definition',
|
||||
json_to_array(_foreign_language_content -> 'synonyms')
|
||||
);
|
||||
END LOOP;
|
||||
|
||||
END
|
||||
$$
|
||||
@@ -0,0 +1,113 @@
|
||||
CREATE OR REPLACE FUNCTION entry_update (
|
||||
_entry_id entry.id%type,
|
||||
_is_valid entry.is_valid%type,
|
||||
_is_published entry.is_published%type,
|
||||
_is_terminology_reviewed entry.is_terminology_reviewed%type,
|
||||
_is_language_reviewed entry.is_language_reviewed%type,
|
||||
_status entry.status%type,
|
||||
_term entry.term%type,
|
||||
_version_author entry.version_author%type,
|
||||
_homonym_sort entry.homonym_sort%type,
|
||||
_domain_label_name_list VARCHAR[],
|
||||
_label entry.label%type,
|
||||
_definition entry.definition%type,
|
||||
_synonym entry.synonym%type,
|
||||
_link_list JSON[],
|
||||
_other entry.other%type,
|
||||
_foreign_language_content_list JSON[],
|
||||
_image entry.image%type,
|
||||
_audio entry.audio%type,
|
||||
_video entry.video%type,
|
||||
OUT _dictionary_id entry.dictionary_id%type
|
||||
)
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
_domain_label_id_list INT[] := ARRAY[]::INT[];
|
||||
_domain_label_name_to_associate domain_label.name%type;
|
||||
_domain_label_id_to_associate domain_label.id%type;
|
||||
_link_to_associate JSON;
|
||||
_foreign_language_content JSON;
|
||||
_foreign_language_id_to_associate language.id%type;
|
||||
|
||||
BEGIN
|
||||
-- Get associated dictionary's id.
|
||||
SELECT dictionary_id
|
||||
INTO _dictionary_id
|
||||
FROM entry
|
||||
WHERE id = _entry_id;
|
||||
|
||||
-- Update entry table.
|
||||
UPDATE entry
|
||||
SET
|
||||
is_valid = _is_valid,
|
||||
is_published = _is_published,
|
||||
is_terminology_reviewed = _is_terminology_reviewed,
|
||||
is_language_reviewed = _is_language_reviewed,
|
||||
status = _status,
|
||||
term = _term,
|
||||
version_author = _version_author,
|
||||
homonym_sort = _homonym_sort,
|
||||
wordforms = 'no content',
|
||||
accent = 'no content',
|
||||
pronunciation = 'no content',
|
||||
label = _label,
|
||||
definition = _definition,
|
||||
synonym = _synonym,
|
||||
other = _other,
|
||||
image = _image,
|
||||
audio = _audio,
|
||||
video = _video
|
||||
WHERE id = _entry_id;
|
||||
|
||||
-- Delete all existing domain label associations.
|
||||
DELETE
|
||||
FROM entry_domain_label
|
||||
WHERE entry_id = _entry_id;
|
||||
|
||||
-- Create new domain labels, if any.
|
||||
FOREACH _domain_label_name_to_associate IN ARRAY _domain_label_name_list LOOP
|
||||
_domain_label_id_to_associate := (SELECT id FROM domain_label WHERE name = _domain_label_name_to_associate);
|
||||
IF _domain_label_id_to_associate IS NULL THEN
|
||||
INSERT INTO domain_label (name, dictionary_id) VALUES (_domain_label_name_to_associate, _dictionary_id)
|
||||
returning id
|
||||
INTO _domain_label_id_to_associate;
|
||||
END IF;
|
||||
_domain_label_id_list := _domain_label_id_list || _domain_label_id_to_associate;
|
||||
END LOOP;
|
||||
|
||||
-- Associate domain labels, if any.
|
||||
FOREACH _domain_label_id_to_associate IN ARRAY _domain_label_id_list LOOP
|
||||
INSERT INTO entry_domain_label (entry_id, domain_label_id)
|
||||
VALUES (_entry_id, _domain_label_id_to_associate);
|
||||
END LOOP;
|
||||
|
||||
-- Delete all existing links.
|
||||
DELETE
|
||||
FROM entry_link
|
||||
WHERE entry_id = _entry_id;
|
||||
|
||||
-- Associate links, if any.
|
||||
FOREACH _link_to_associate IN ARRAY _link_list LOOP
|
||||
INSERT INTO entry_link (entry_id, type, link)
|
||||
VALUES (_entry_id, (_link_to_associate ->> 'type')::entry_link_type, _link_to_associate ->> 'link');
|
||||
END LOOP;
|
||||
|
||||
-- Delete all existing associated foreign content.
|
||||
DELETE
|
||||
FROM entry_foreign
|
||||
WHERE entry_id = _entry_id;
|
||||
|
||||
-- Associate new foreign content, if any.
|
||||
FOREACH _foreign_language_content IN ARRAY _foreign_language_content_list LOOP
|
||||
_foreign_language_id_to_associate := (SELECT id FROM language WHERE code = _foreign_language_content ->> 'language');
|
||||
INSERT INTO entry_foreign (entry_id, language_id, term, definition, synonym)
|
||||
VALUES (
|
||||
_entry_id, _foreign_language_id_to_associate,
|
||||
json_to_array(_foreign_language_content -> 'terms'),
|
||||
_foreign_language_content ->> 'definition',
|
||||
json_to_array(_foreign_language_content -> 'synonyms')
|
||||
);
|
||||
END LOOP;
|
||||
|
||||
END
|
||||
$$
|
||||
@@ -0,0 +1,123 @@
|
||||
-- Creates new own dictionary.
|
||||
CREATE OR REPLACE FUNCTION dictionary_new (
|
||||
_name_sl dictionary.name_sl%type,
|
||||
_name_sl_short dictionary.name_sl_short%type,
|
||||
_name_en dictionary.name_en%type,
|
||||
_author dictionary.author%type,
|
||||
_issn dictionary.issn%type,
|
||||
_domain_primary_id dictionary.domain_primary_id%type,
|
||||
_entries_have_domain_labels dictionary.entries_have_domain_labels%type,
|
||||
_entries_have_label dictionary.entries_have_label%type,
|
||||
_entries_have_definition dictionary.entries_have_definition%type,
|
||||
_entries_have_synonyms dictionary.entries_have_synonyms%type,
|
||||
_entries_have_links dictionary.entries_have_links%type,
|
||||
_entries_have_other dictionary.entries_have_other%type,
|
||||
_entries_have_foreign_languages dictionary.entries_have_foreign_languages%type,
|
||||
_entries_have_foreign_definitions dictionary.entries_have_foreign_definitions%type,
|
||||
_entries_have_foreign_synonyms dictionary.entries_have_foreign_synonyms%type,
|
||||
_entries_have_images dictionary.entries_have_images%type,
|
||||
_entries_have_audio dictionary.entries_have_audio%type,
|
||||
_entries_have_videos dictionary.entries_have_videos%type,
|
||||
_domain_secondary smallint[],
|
||||
_domain_secondary_new_name_sl varchar[],
|
||||
_domain_secondary_new_name_en varchar[],
|
||||
_language int[],
|
||||
_creator_id user_role.user_id%type,
|
||||
OUT _dictionary_id dictionary.id%type
|
||||
)
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
_domain_secondary_id domain_secondary.id%type;
|
||||
_secondary_domain_id domain_secondary.id%type;
|
||||
|
||||
BEGIN
|
||||
-- Check uniqueness of names within own dictionaries.
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM dictionary
|
||||
WHERE
|
||||
count_comments IS NOT NULL AND -- Indicator of own dictionaries.
|
||||
(
|
||||
name_sl = _name_sl OR
|
||||
name_sl_short = _name_sl_short OR
|
||||
name_en = _name_en
|
||||
)
|
||||
) THEN
|
||||
RAISE EXCEPTION 'One of dictionary names not unique among own dictionaries.';
|
||||
END IF;
|
||||
|
||||
-- Create new dictionary.
|
||||
INSERT INTO dictionary (
|
||||
name_sl,
|
||||
name_sl_short,
|
||||
name_en,
|
||||
author,
|
||||
issn,
|
||||
domain_primary_id,
|
||||
count_comments,
|
||||
entries_have_domain_labels,
|
||||
entries_have_label,
|
||||
entries_have_definition,
|
||||
entries_have_synonyms,
|
||||
entries_have_links,
|
||||
entries_have_other,
|
||||
entries_have_foreign_languages,
|
||||
entries_have_foreign_definitions,
|
||||
entries_have_foreign_synonyms,
|
||||
entries_have_images,
|
||||
entries_have_audio,
|
||||
entries_have_videos
|
||||
)
|
||||
VALUES (
|
||||
_name_sl,
|
||||
_name_sl_short,
|
||||
_name_en,
|
||||
_author,
|
||||
_issn,
|
||||
_domain_primary_id,
|
||||
0,
|
||||
_entries_have_domain_labels,
|
||||
_entries_have_label,
|
||||
_entries_have_definition,
|
||||
_entries_have_synonyms,
|
||||
_entries_have_links,
|
||||
_entries_have_other,
|
||||
_entries_have_foreign_languages,
|
||||
_entries_have_foreign_definitions,
|
||||
_entries_have_foreign_synonyms,
|
||||
_entries_have_images,
|
||||
_entries_have_audio,
|
||||
_entries_have_videos
|
||||
)
|
||||
RETURNING id
|
||||
INTO _dictionary_id;
|
||||
|
||||
-- Create new secondary domains, if any.
|
||||
FOR i IN 1..COALESCE(array_length(_domain_secondary_new_name_sl, 1), 0) LOOP
|
||||
INSERT INTO domain_secondary (name_sl, name_en)
|
||||
VALUES
|
||||
(_domain_secondary_new_name_sl[i], _domain_secondary_new_name_en[i])
|
||||
RETURNING id
|
||||
INTO _domain_secondary_id;
|
||||
|
||||
_domain_secondary := _domain_secondary || _domain_secondary_id;
|
||||
END LOOP;
|
||||
|
||||
-- Associate secondary domains, if any.
|
||||
FOREACH _secondary_domain_id IN ARRAY _domain_secondary LOOP
|
||||
INSERT INTO dictionary_domain_secondary (dictionary_id, domain_secondary_id)
|
||||
VALUES (_dictionary_id, _secondary_domain_id);
|
||||
END LOOP;
|
||||
|
||||
-- Associate languages, if any.
|
||||
FOR i IN 1..COALESCE(array_length(_language, 1), 0) LOOP
|
||||
INSERT INTO dictionary_language (dictionary_id, language_id, selection_order)
|
||||
VALUES (_dictionary_id, _language[i], i);
|
||||
END LOOP;
|
||||
|
||||
-- Make the creator its administrator.
|
||||
INSERT INTO user_role (user_id, role_name, dictionary_id, administration, editing, terminology_review, language_review)
|
||||
VALUES (_creator_id, 'editor', _dictionary_id, TRUE, TRUE, TRUE, TRUE);
|
||||
|
||||
END
|
||||
$$
|
||||
@@ -0,0 +1,69 @@
|
||||
DROP TABLE IF EXISTS comment;
|
||||
DROP TYPE IF EXISTS comment_status;
|
||||
DROP TYPE IF EXISTS comment_context_type;
|
||||
|
||||
CREATE TYPE comment_context_type AS ENUM (
|
||||
'portal',
|
||||
'dictionary',
|
||||
'consultancy',
|
||||
'entry_dict_int',
|
||||
'entry_dict_ext',
|
||||
'entry_consult_int'
|
||||
-- 'entry_consult_ext'
|
||||
);
|
||||
|
||||
CREATE TYPE comment_status AS ENUM ('visible', 'hidden');
|
||||
|
||||
CREATE TABLE comment (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
message VARCHAR NOT NULL,
|
||||
author_id INT NOT NULL REFERENCES "user",
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
context_type comment_context_type NOT NULL,
|
||||
context_id INT,
|
||||
status comment_status NOT NULL DEFAULT 'visible',
|
||||
quoted_comment_id INT REFERENCES comment,
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN context_type IN (
|
||||
'portal',
|
||||
'consultancy'
|
||||
) THEN context_id IS NULL
|
||||
ELSE context_id IS NOT NULL
|
||||
END
|
||||
)
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_time_most_recent_comment()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
-- Disable trigger from updating time_modified.
|
||||
SET LOCAL term_portal.skip_update_time_modified TO 'TRUE';
|
||||
-- Disable trigger from creating version history snapshot.
|
||||
SET LOCAL term_portal.skip_create_version_history_snapshot TO 'TRUE';
|
||||
|
||||
UPDATE entry
|
||||
SET time_most_recent_comment =
|
||||
CASE
|
||||
WHEN TG_OP = 'INSERT' AND NEW.status = 'visible' THEN NEW.time_created
|
||||
ELSE (
|
||||
SELECT MAX(time_created)
|
||||
FROM comment
|
||||
WHERE
|
||||
context_type IN ('entry_dict_int', 'entry_dict_ext')
|
||||
AND context_id = NEW.context_id
|
||||
AND status = 'visible'
|
||||
)
|
||||
END
|
||||
WHERE id = NEW.context_id;
|
||||
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER entry_update_time_most_recent_comment
|
||||
AFTER INSERT OR UPDATE
|
||||
ON comment
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.context_type IN ('entry_dict_int', 'entry_dict_ext'))
|
||||
EXECUTE FUNCTION update_time_most_recent_comment();
|
||||
@@ -0,0 +1,32 @@
|
||||
DROP TABLE IF EXISTS consultancy_entry_consultant;
|
||||
DROP TABLE IF EXISTS consultancy_entry;
|
||||
DROP TYPE IF EXISTS consultancy_entry_status;
|
||||
|
||||
CREATE TYPE consultancy_entry_status AS ENUM ('new', 'rejected', 'in progress', 'review', 'published');
|
||||
|
||||
CREATE TABLE consultancy_entry (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
id_external INT UNIQUE,
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
status consultancy_entry_status NOT NULL DEFAULT 'new',
|
||||
author_id INT REFERENCES "user",
|
||||
institution VARCHAR,
|
||||
description VARCHAR,
|
||||
domain_primary_id_initial SMALLINT REFERENCES domain_primary,
|
||||
existing_solutions VARCHAR,
|
||||
examples_of_use VARCHAR,
|
||||
time_published TIMESTAMPTZ,
|
||||
title VARCHAR,
|
||||
question VARCHAR,
|
||||
answer VARCHAR,
|
||||
path VARCHAR,
|
||||
answer_authors VARCHAR[],
|
||||
domain_primary_id SMALLINT REFERENCES domain_primary
|
||||
);
|
||||
|
||||
CREATE TABLE consultancy_entry_consultant (
|
||||
entry_id INT NOT NULL REFERENCES consultancy_entry,
|
||||
user_id INT NOT NULL REFERENCES "user",
|
||||
is_moderator BOOL NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY (entry_id, user_id)
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
DROP TABLE IF EXISTS linked_dictionary;
|
||||
DROP TABLE IF EXISTS linked_portals;
|
||||
|
||||
CREATE TABLE linked_portal (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR NOT NULL UNIQUE,
|
||||
code CHAR(2) NOT NULL UNIQUE,
|
||||
is_enabled BOOL NOT NULL DEFAULT FALSE,
|
||||
url_update VARCHAR NOT NULL UNIQUE,
|
||||
url_index VARCHAR UNIQUE, -- Initial comment: 'url for obtaining list of available dictionaries'.
|
||||
time_last_synced TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE linked_dictionary (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR NOT NULL,
|
||||
linked_portal_id INT NOT NULL,
|
||||
source_dictionary_id VARCHAR NOT NULL,
|
||||
target_dictionary_id INT NOT NULL REFERENCES dictionary ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from dictionary will require a scan of this table for references.
|
||||
is_enabled BOOL NOT NULL DEFAULT FALSE,
|
||||
time_last_synced TIMESTAMPTZ,
|
||||
UNIQUE (linked_portal_id, source_dictionary_id)
|
||||
);
|
||||
@@ -0,0 +1,56 @@
|
||||
-- changing data type for external_id field
|
||||
ALTER TABLE IF EXISTS public.entry DROP COLUMN IF EXISTS external_id;
|
||||
ALTER TABLE IF EXISTS public.entry
|
||||
ADD COLUMN external_id character varying(50) COLLATE pg_catalog."C";
|
||||
COMMENT ON COLUMN public.entry.external_id
|
||||
IS 'Used for identifying imported entries. NULL for own.';
|
||||
|
||||
-- changing data type for external_url field
|
||||
ALTER TABLE IF EXISTS public.entry DROP COLUMN IF EXISTS external_url;
|
||||
ALTER TABLE IF EXISTS public.entry
|
||||
ADD COLUMN external_url character varying(255) COLLATE pg_catalog."C";
|
||||
COMMENT ON COLUMN public.entry.external_url
|
||||
IS 'url where original imported entry is available. ';
|
||||
|
||||
-- cleaning up entry indexes
|
||||
DROP INDEX IF EXISTS public.ux_entry_dictionary_external_id;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_entry_dictionary_external_id
|
||||
ON public.entry USING btree
|
||||
(dictionary_id ASC NULLS LAST, external_id COLLATE pg_catalog."C" ASC NULLS LAST)
|
||||
TABLESPACE pg_default;
|
||||
|
||||
DROP INDEX IF EXISTS public.ux_entry_forign_entry_id_language_id;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_entry_forign_entry_id_language_id
|
||||
ON public.entry_foreign USING btree
|
||||
(entry_id ASC NULLS LAST, language_id ASC NULLS LAST)
|
||||
TABLESPACE pg_default;
|
||||
|
||||
DROP INDEX IF EXISTS public.ux_language_code;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_language_code
|
||||
ON public.language USING btree
|
||||
(code COLLATE pg_catalog."C" ASC NULLS LAST)
|
||||
TABLESPACE pg_default;
|
||||
|
||||
-- adding batch procesing
|
||||
CREATE TABLE IF NOT EXISTS public.batch
|
||||
(
|
||||
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
||||
job_name character varying(255) COLLATE pg_catalog."C" NOT NULL,
|
||||
job_state character(1) COLLATE pg_catalog."C" NOT NULL,
|
||||
started timestamp(3) with time zone NOT NULL DEFAULT now(),
|
||||
thread character varying(36) COLLATE pg_catalog."C" NOT NULL,
|
||||
report text COLLATE pg_catalog."default",
|
||||
changed timestamp(3) with time zone,
|
||||
ended timestamp(3) with time zone,
|
||||
CONSTRAINT batch_pkey PRIMARY KEY (id)
|
||||
)
|
||||
|
||||
TABLESPACE pg_default;
|
||||
ALTER TABLE IF EXISTS public.batch OWNER to postgres;
|
||||
COMMENT ON TABLE public.batch IS 'batch processing status';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "IX_BATCH_NAME_STARTED_STATE"
|
||||
ON public.batch USING btree
|
||||
(job_name COLLATE pg_catalog."C" ASC NULLS LAST, started ASC NULLS LAST)
|
||||
TABLESPACE pg_default;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
DROP TABLE IF EXISTS instance_settings;
|
||||
|
||||
CREATE TABLE instance_settings (
|
||||
name VARCHAR PRIMARY KEY,
|
||||
value VARCHAR NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO instance_settings (name, value)
|
||||
VALUES
|
||||
('portal_name', 'Terminološki portal'),
|
||||
('portal_code', 'XX'),
|
||||
('portal_description', 'Terminološki portal je samostojna, odprto dostopna spletna storitev, v katero so vključeni terminološki viri na portalu. Registriranim uporabnikom je na voljo tudi luščilnik terminoloških kandidatov iz specializiranih korpusov, konkordančnik za pregledovanje izbranih besedil, označevalnik terminov v izbranih besedilih, urejevalnik terminoloških virov, terminološka svetovalnica in stran s pomočjo in navodili za uporabo posameznih funkcij portala. Terminološki portal je moderiran.'),
|
||||
('is_extraction_enabled', 'T'),
|
||||
('is_dictionaries_enabled', 'T'),
|
||||
('is_consultancy_enabled', 'T'),
|
||||
('min_entries_per_dictionary', '1'),
|
||||
('dictionary_publish_approval', 'F'),
|
||||
('keep_num_of_exports_per_dictionary', '-1'),
|
||||
('dictionary_auto_save_frequency', 'disabled'), -- The other kinds being 'monthly' and 'yearly'.
|
||||
('num_of_history_entires_per_entry', '-1'),
|
||||
('can_publish_entries_in_edit', 'F'),
|
||||
('consultancy_type', 'own'), -- The other kind would be 'ZRC'.
|
||||
('zrc_email', 'termin@zrc-sazu.si'),
|
||||
('zrc_url', 'https://zrc-sazu.si/sites/default/files/xml/term-exp.xml');
|
||||
|
||||
CREATE OR REPLACE FUNCTION generate_short_name()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.name_sl_short := (SELECT value FROM instance_settings WHERE name = 'portal_code') || NEW.id;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER dictionary_generate_short_name
|
||||
BEFORE INSERT
|
||||
ON dictionary
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.name_sl_short IS NULL)
|
||||
EXECUTE FUNCTION generate_short_name();
|
||||
@@ -0,0 +1,273 @@
|
||||
CREATE OR REPLACE FUNCTION jsonb_array_to_text_array(_js jsonb)
|
||||
RETURNS text[]
|
||||
LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
|
||||
$$SELECT CASE WHEN _js = 'null' THEN NULL ELSE ARRAY(SELECT jsonb_array_elements_text(_js)) END$$;
|
||||
|
||||
-- Creates new dictionary from remote instance.
|
||||
CREATE OR REPLACE FUNCTION dictionary_remote_new (_dictionary JSONB, OUT _dictionary_id dictionary.id%type)
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
_domain_secondary_names JSONB[] := jsonb_array_to_text_array(_dictionary -> 'domain_secondary_names')::JSONB[];
|
||||
_domain_secondary_name JSONB;
|
||||
_domain_secondary_id domain_secondary.id%type;
|
||||
_language_codes VARCHAR[] := jsonb_array_to_text_array(_dictionary -> 'language_codes');
|
||||
_language_id language.id%type;
|
||||
|
||||
BEGIN
|
||||
-- Disable trigger from updating time_modified.
|
||||
SET LOCAL term_portal.skip_update_time_modified TO 'TRUE';
|
||||
|
||||
-- Create new dictionary.
|
||||
INSERT INTO dictionary (
|
||||
name_sl,
|
||||
name_sl_short,
|
||||
name_en,
|
||||
author,
|
||||
issn,
|
||||
domain_primary_id,
|
||||
time_created,
|
||||
time_modified,
|
||||
time_content_modified,
|
||||
status,
|
||||
description,
|
||||
entries_have_domain_labels,
|
||||
entries_have_label,
|
||||
entries_have_definition,
|
||||
entries_have_synonyms,
|
||||
entries_have_links,
|
||||
entries_have_other,
|
||||
entries_have_foreign_languages,
|
||||
entries_have_foreign_definitions,
|
||||
entries_have_foreign_synonyms,
|
||||
entries_have_images,
|
||||
entries_have_audio,
|
||||
entries_have_videos,
|
||||
entries_have_terminology_review_flag,
|
||||
entries_have_language_review_flag
|
||||
)
|
||||
VALUES (
|
||||
_dictionary ->> 'name_sl',
|
||||
_dictionary ->> 'name_sl_short',
|
||||
_dictionary ->> 'name_en',
|
||||
jsonb_array_to_text_array(_dictionary -> 'author'),
|
||||
_dictionary ->> 'issn',
|
||||
COALESCE(
|
||||
(SELECT id FROM domain_primary WHERE name_sl = _dictionary ->> 'domain_primary_name_sl'),
|
||||
(SELECT id FROM domain_primary WHERE name_sl = 'Neopredeljeno')
|
||||
),
|
||||
(_dictionary ->> 'time_created')::TIMESTAMPTZ,
|
||||
(_dictionary ->> 'time_modified')::TIMESTAMPTZ,
|
||||
(_dictionary ->> 'time_content_modified')::TIMESTAMPTZ,
|
||||
'published',
|
||||
_dictionary ->> 'description',
|
||||
(_dictionary ->> 'entries_have_domain_labels')::BOOL,
|
||||
(_dictionary ->> 'entries_have_label')::BOOL,
|
||||
(_dictionary ->> 'entries_have_definition')::BOOL,
|
||||
(_dictionary ->> 'entries_have_synonyms')::BOOL,
|
||||
(_dictionary ->> 'entries_have_links')::BOOL,
|
||||
(_dictionary ->> 'entries_have_other')::BOOL,
|
||||
(_dictionary ->> 'entries_have_foreign_languages')::BOOL,
|
||||
(_dictionary ->> 'entries_have_foreign_definitions')::BOOL,
|
||||
(_dictionary ->> 'entries_have_foreign_synonyms')::BOOL,
|
||||
(_dictionary ->> 'entries_have_images')::BOOL,
|
||||
(_dictionary ->> 'entries_have_audio')::BOOL,
|
||||
(_dictionary ->> 'entries_have_videos')::BOOL,
|
||||
(_dictionary ->> 'entries_have_terminology_review_flag')::BOOL,
|
||||
(_dictionary ->> 'entries_have_language_review_flag')::BOOL
|
||||
)
|
||||
RETURNING id
|
||||
INTO _dictionary_id;
|
||||
|
||||
-- Create and/or associate secondary domains.
|
||||
FOREACH _domain_secondary_name IN ARRAY _domain_secondary_names LOOP
|
||||
|
||||
SELECT id
|
||||
INTO _domain_secondary_id
|
||||
FROM domain_secondary
|
||||
WHERE name_sl = _domain_secondary_name ->> 'name_sl' AND name_en = _domain_secondary_name ->> 'name_en';
|
||||
|
||||
IF _domain_secondary_id IS NULL THEN
|
||||
INSERT INTO domain_secondary (name_sl, name_en)
|
||||
VALUES
|
||||
(_domain_secondary_name ->> 'name_sl', _domain_secondary_name ->> 'name_en')
|
||||
RETURNING id
|
||||
INTO _domain_secondary_id;
|
||||
END IF;
|
||||
|
||||
INSERT INTO dictionary_domain_secondary (dictionary_id, domain_secondary_id)
|
||||
VALUES (_dictionary_id, _domain_secondary_id);
|
||||
|
||||
END LOOP;
|
||||
|
||||
-- Associate languages.
|
||||
FOR i IN 1..COALESCE(array_length(_language_codes, 1), 0) LOOP
|
||||
|
||||
SELECT id INTO _language_id FROM language WHERE code = _language_codes[i];
|
||||
|
||||
IF _language_id IS NOT NULL THEN
|
||||
INSERT INTO dictionary_language (dictionary_id, language_id, selection_order)
|
||||
VALUES (_dictionary_id, _language_id, i);
|
||||
END IF;
|
||||
|
||||
END LOOP;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Updates dictionary from remote instance.
|
||||
CREATE OR REPLACE FUNCTION dictionary_remote_update (_dictionary_id dictionary.id%type, _dictionary JSONB)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
_domain_secondary_names JSONB[] := jsonb_array_to_text_array(_dictionary -> 'domain_secondary_names')::JSONB[];
|
||||
_domain_secondary_name JSONB;
|
||||
_domain_secondary_id domain_secondary.id%type;
|
||||
_language_codes VARCHAR[] := jsonb_array_to_text_array(_dictionary -> 'language_codes');
|
||||
_language_id language.id%type;
|
||||
|
||||
BEGIN
|
||||
-- Disable trigger from updating time_modified.
|
||||
SET LOCAL term_portal.skip_update_time_modified TO 'TRUE';
|
||||
|
||||
-- Update dictionary table.
|
||||
UPDATE dictionary
|
||||
SET
|
||||
name_sl = _dictionary ->> 'name_sl',
|
||||
name_sl_short = _dictionary ->> 'name_sl_short',
|
||||
name_en = _dictionary ->> 'name_en',
|
||||
author = jsonb_array_to_text_array(_dictionary -> 'author'),
|
||||
issn = _dictionary ->> 'issn',
|
||||
domain_primary_id = COALESCE(
|
||||
(SELECT id FROM domain_primary WHERE name_sl = _dictionary ->> 'domain_primary_name_sl'),
|
||||
(SELECT id FROM domain_primary WHERE name_sl = 'Neopredeljeno')
|
||||
),
|
||||
time_created = (_dictionary ->> 'time_created')::TIMESTAMPTZ,
|
||||
time_modified = (_dictionary ->> 'time_modified')::TIMESTAMPTZ,
|
||||
time_content_modified = (_dictionary ->> 'time_content_modified')::TIMESTAMPTZ,
|
||||
description = _dictionary ->> 'description',
|
||||
entries_have_domain_labels = (_dictionary ->> 'entries_have_domain_labels')::BOOL,
|
||||
entries_have_label = (_dictionary ->> 'entries_have_label')::BOOL,
|
||||
entries_have_definition = (_dictionary ->> 'entries_have_definition')::BOOL,
|
||||
entries_have_synonyms = (_dictionary ->> 'entries_have_synonyms')::BOOL,
|
||||
entries_have_links =(_dictionary ->> 'entries_have_links')::BOOL,
|
||||
entries_have_other = (_dictionary ->> 'entries_have_other')::BOOL,
|
||||
entries_have_foreign_languages = (_dictionary ->> 'entries_have_foreign_languages')::BOOL,
|
||||
entries_have_foreign_definitions = (_dictionary ->> 'entries_have_foreign_definitions')::BOOL,
|
||||
entries_have_foreign_synonyms = (_dictionary ->> 'entries_have_foreign_synonyms')::BOOL,
|
||||
entries_have_images = (_dictionary ->> 'entries_have_images')::BOOL,
|
||||
entries_have_audio = (_dictionary ->> 'entries_have_audio')::BOOL,
|
||||
entries_have_videos = (_dictionary ->> 'entries_have_videos')::BOOL,
|
||||
entries_have_terminology_review_flag = (_dictionary ->> 'entries_have_terminology_review_flag')::BOOL,
|
||||
entries_have_language_review_flag = (_dictionary ->> 'entries_have_language_review_flag')::BOOL
|
||||
WHERE id = _dictionary_id;
|
||||
|
||||
-- Delete all existing secondary domain associations.
|
||||
DELETE
|
||||
FROM dictionary_domain_secondary
|
||||
WHERE dictionary_id = _dictionary_id;
|
||||
|
||||
-- Create and/or associate new secondary domains, if any.
|
||||
FOREACH _domain_secondary_name IN ARRAY _domain_secondary_names LOOP
|
||||
|
||||
SELECT id
|
||||
INTO _domain_secondary_id
|
||||
FROM domain_secondary
|
||||
WHERE name_sl = _domain_secondary_name ->> 'name_sl' AND name_en = _domain_secondary_name ->> 'name_en';
|
||||
|
||||
IF _domain_secondary_id IS NULL THEN
|
||||
INSERT INTO domain_secondary (name_sl, name_en)
|
||||
VALUES
|
||||
(_domain_secondary_name ->> 'name_sl', _domain_secondary_name ->> 'name_en')
|
||||
RETURNING id
|
||||
INTO _domain_secondary_id;
|
||||
END IF;
|
||||
|
||||
INSERT INTO dictionary_domain_secondary (dictionary_id, domain_secondary_id)
|
||||
VALUES (_dictionary_id, _domain_secondary_id);
|
||||
|
||||
END LOOP;
|
||||
|
||||
-- Delete all existing language associations.
|
||||
DELETE
|
||||
FROM dictionary_language
|
||||
WHERE dictionary_id = _dictionary_id;
|
||||
|
||||
-- Associate new languages, if any.
|
||||
FOR i IN 1..COALESCE(array_length(_language_codes, 1), 0) LOOP
|
||||
|
||||
SELECT id INTO _language_id FROM language WHERE code = _language_codes[i];
|
||||
|
||||
IF _language_id IS NOT NULL THEN
|
||||
INSERT INTO dictionary_language (dictionary_id, language_id, selection_order)
|
||||
VALUES (_dictionary_id, _language_id, i);
|
||||
END IF;
|
||||
|
||||
END LOOP;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Sync remote dictionaries (but not entries).
|
||||
CREATE OR REPLACE FUNCTION sync_remote_dictionaries (
|
||||
_linked_portal_id linked_portal.id%type,
|
||||
_dictionaries JSONB[]
|
||||
)
|
||||
RETURNS void
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
DECLARE
|
||||
_dictionary JSONB;
|
||||
_source_dictionary_id linked_dictionary.source_dictionary_id%type;
|
||||
_target_dictionary_id linked_dictionary.target_dictionary_id%type;
|
||||
_remote_dictionary_ids VARCHAR[] := ARRAY[]::VARCHAR[];
|
||||
_time_modified_old dictionary.time_modified%type;
|
||||
_time_modified_new dictionary.time_modified%type;
|
||||
|
||||
BEGIN
|
||||
-- For each of the provided dictionaries: create | update | skip.
|
||||
FOREACH _dictionary IN ARRAY _dictionaries LOOP
|
||||
_source_dictionary_id := _dictionary ->> 'id';
|
||||
_remote_dictionary_ids = _remote_dictionary_ids || _source_dictionary_id;
|
||||
|
||||
SELECT target_dictionary_id INTO _target_dictionary_id FROM linked_dictionary WHERE source_dictionary_id = _source_dictionary_id;
|
||||
|
||||
-- Check if dictionary doesn't exist yet.
|
||||
IF _target_dictionary_id IS NULL THEN
|
||||
-- Create new dictionary.
|
||||
SELECT dictionary_remote_new(_dictionary) INTO _target_dictionary_id;
|
||||
|
||||
-- Create new linked dictionary.
|
||||
INSERT INTO linked_dictionary(name, linked_portal_id, source_dictionary_id, target_dictionary_id)
|
||||
VALUES (_dictionary ->> 'name_sl', _linked_portal_id, _source_dictionary_id, _target_dictionary_id);
|
||||
|
||||
ELSE
|
||||
-- Dictionary already exists.
|
||||
-- Compare modification times to determine if update is required.
|
||||
SELECT time_modified INTO _time_modified_old FROM dictionary WHERE id = _target_dictionary_id;
|
||||
_time_modified_new := _dictionary ->> 'time_modified';
|
||||
|
||||
-- Skip this dictionary, if modification times match.
|
||||
CONTINUE WHEN _time_modified_new = _time_modified_old;
|
||||
|
||||
-- Update dictionary.
|
||||
PERFORM dictionary_remote_update(_target_dictionary_id, _dictionary);
|
||||
|
||||
-- Update linked dictionary.
|
||||
UPDATE linked_dictionary
|
||||
SET name = _dictionary ->> 'name_sl'
|
||||
WHERE target_dictionary_id = _target_dictionary_id;
|
||||
|
||||
END IF;
|
||||
|
||||
END LOOP;
|
||||
|
||||
-- Delete any existing dictionaries that were not provided to be synced.
|
||||
DELETE FROM dictionary
|
||||
WHERE id IN (
|
||||
SELECT target_dictionary_id
|
||||
FROM linked_dictionary
|
||||
WHERE linked_portal_id = _linked_portal_id AND source_dictionary_id <> ALL (_remote_dictionary_ids)
|
||||
);
|
||||
|
||||
END
|
||||
$$;
|
||||
@@ -0,0 +1,105 @@
|
||||
DROP TABLE IF EXISTS entry_version_history;
|
||||
|
||||
CREATE TABLE entry_version_history (
|
||||
entry_id INT REFERENCES entry ON DELETE CASCADE,
|
||||
version SMALLINT,
|
||||
version_time TIMESTAMPTZ,
|
||||
version_snapshot JSONB NOT NULL,
|
||||
PRIMARY KEY (entry_id, version)
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION create_entry_version_snapshot()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
_num_of_history_entires_per_entry SMALLINT;
|
||||
BEGIN
|
||||
-- Create a snapshot of old entry data.
|
||||
INSERT INTO entry_version_history (entry_id, version, version_time, version_snapshot)
|
||||
VALUES (
|
||||
OLD.id,
|
||||
OLD.version,
|
||||
OLD.time_modified,
|
||||
(
|
||||
SELECT
|
||||
jsonb_strip_nulls(
|
||||
jsonb_build_object(
|
||||
'is_valid', e.is_valid,
|
||||
'is_published', e.is_published,
|
||||
'is_terminology_reviewed', e.is_terminology_reviewed,
|
||||
'is_language_reviewed', e.is_language_reviewed,
|
||||
'status', e.status,
|
||||
'term', e.term,
|
||||
'version', e.version,
|
||||
'version_author', e.version_author,
|
||||
'homonym_sort', e.homonym_sort,
|
||||
'label', e.label,
|
||||
'definition', e.definition,
|
||||
'synonyms', e.synonym,
|
||||
'other', e.other,
|
||||
'image', e.image,
|
||||
'audio', e.audio,
|
||||
'video', e.video,
|
||||
'domain_labels', ARRAY(
|
||||
SELECT name
|
||||
FROM entry_domain_label edl
|
||||
LEFT JOIN domain_label dl ON dl.id = edl.domain_label_id
|
||||
WHERE entry_id = e.id
|
||||
),
|
||||
'links', ARRAY(
|
||||
SELECT jsonb_build_object(
|
||||
'type', type,
|
||||
'link', link
|
||||
)
|
||||
FROM entry_link
|
||||
WHERE entry_id = e.id
|
||||
),
|
||||
'foreign_entries', ARRAY(
|
||||
SELECT jsonb_strip_nulls(
|
||||
jsonb_build_object(
|
||||
'language_id', language_id,
|
||||
'term', term,
|
||||
'definition', definition,
|
||||
'synonym', synonym
|
||||
)
|
||||
)
|
||||
FROM entry_foreign
|
||||
WHERE entry_id = e.id
|
||||
)
|
||||
)
|
||||
)
|
||||
FROM entry e
|
||||
WHERE e.id = OLD.id
|
||||
)
|
||||
);
|
||||
|
||||
-- Get the current limit of snapshots per entry.
|
||||
SELECT value::smallint
|
||||
INTO _num_of_history_entires_per_entry
|
||||
FROM instance_settings
|
||||
WHERE name = 'num_of_history_entires_per_entry';
|
||||
|
||||
-- Prune any (oldest) snapshots of this entry over the limit.
|
||||
IF _num_of_history_entires_per_entry >= 0 THEN
|
||||
DELETE FROM entry_version_history
|
||||
WHERE entry_id = OLD.id AND version IN (
|
||||
SELECT version
|
||||
FROM entry_version_history
|
||||
WHERE entry_id = OLD.id
|
||||
ORDER BY version DESC
|
||||
OFFSET _num_of_history_entires_per_entry
|
||||
);
|
||||
END IF;
|
||||
|
||||
-- Increase version.
|
||||
NEW.version = OLD.version + 1;
|
||||
|
||||
RETURN NEW;
|
||||
END
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER entry_version_history_create_snapshot
|
||||
BEFORE UPDATE
|
||||
ON entry
|
||||
FOR EACH ROW
|
||||
WHEN (current_setting('term_portal.skip_create_version_history_snapshot', TRUE) IS DISTINCT FROM 'TRUE')
|
||||
EXECUTE FUNCTION create_entry_version_snapshot();
|
||||
@@ -0,0 +1,47 @@
|
||||
CREATE TYPE extraction_status AS ENUM ('new', 'in progress', 'failed', 'finished');
|
||||
|
||||
CREATE TYPE extraction_job_type AS ENUM ('doc to conllu', 'conllus to term candidates', 'concordancer', 'oss term candidates');
|
||||
|
||||
CREATE TYPE extraction_job_status AS ENUM ('pending', 'in progress', 'failed', 'finished');
|
||||
|
||||
CREATE TABLE extraction (
|
||||
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
user_id INT NOT NULL REFERENCES "user",
|
||||
name VARCHAR NOT NULL,
|
||||
status extraction_status NOT NULL DEFAULT 'new',
|
||||
corpus_id UUID,
|
||||
oss_params JSONB,
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_started TIMESTAMPTZ,
|
||||
time_finished TIMESTAMPTZ,
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN oss_params IS NULL AND status = 'finished' THEN corpus_id IS NOT NULL
|
||||
ELSE corpus_id IS NULL
|
||||
END
|
||||
)
|
||||
);
|
||||
|
||||
CREATE TABLE extraction_job (
|
||||
extraction_id INT REFERENCES extraction ON DELETE CASCADE, -- Consider indexing this one, since deletion of rows from extraction will require a scan of this table for references.
|
||||
job_type extraction_job_type,
|
||||
filename VARCHAR,
|
||||
remote_job_id BIGINT,
|
||||
status extraction_job_status NOT NULL DEFAULT 'pending',
|
||||
time_created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
time_started TIMESTAMPTZ,
|
||||
time_finished TIMESTAMPTZ,
|
||||
PRIMARY KEY (extraction_id, job_type, filename),
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN job_type = 'doc to conllu' THEN filename != ''
|
||||
ELSE filename = ''
|
||||
END
|
||||
),
|
||||
CHECK (
|
||||
CASE
|
||||
WHEN job_type = 'concordancer' OR status = 'pending' THEN remote_job_id IS NULL
|
||||
ELSE remote_job_id IS NOT NULL
|
||||
END
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
REVOKE ALL ON schema public FROM public;
|
||||
|
||||
\set pwd_express `echo $POSTGRES_EXPRESS_PASSWORD`
|
||||
CREATE USER express WITH ENCRYPTED PASSWORD :'pwd_express';
|
||||
-- GRANT ALL PRIVILEGES ON DATABASE term_portal TO express;
|
||||
GRANT ALL ON schema public TO express;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO express;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO express;
|
||||
-- GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO express;
|
||||
|
||||
\set pwd_concordancer `echo $POSTGRES_CONCORDANCER_PASSWORD`
|
||||
CREATE USER concordancer WITH ENCRYPTED PASSWORD :'pwd_concordancer';
|
||||
ALTER ROLE concordancer WITH CREATEDB;
|
||||
@@ -0,0 +1,6 @@
|
||||
# Inicializacijske skripte za Postgres
|
||||
|
||||
- _000_init_db.sql_ je začetni Mihov/Juretov dump
|
||||
- sledeče datoteke so osnova za korektnejšo zasnovo baze (v fazi razvoja)
|
||||
- _500_init_user.sql_ ureja uporabnika, ki ga bo uporabljala Express aplikacija in njegove pravice
|
||||
- kasneje bo vsebina tega direktorija korenito reorganizirana
|
||||
@@ -0,0 +1,73 @@
|
||||
-- Script to set portal for importing dictionaries from Termania (Amebis)
|
||||
-- Script inserts linked_portal, linked_dictionary & dictionary records.
|
||||
-- After running this script the batch job batch_update_linked.js will be importing from Termania.
|
||||
|
||||
do $$
|
||||
DECLARE
|
||||
linkedTermaniaId INT;
|
||||
linkedDictId INT;
|
||||
rsdoDictId INT;
|
||||
zd RECORD;
|
||||
author VARCHAR[] := ARRAY['ZRC'];
|
||||
|
||||
BEGIN
|
||||
-- if portal entry doesnt exist for ZrcTerm create one and remember its ID
|
||||
SELECT id INTO linkedTermaniaId FROM public.linked_portal WHERE code='AT';
|
||||
IF linkedTermaniaId IS NULL THEN
|
||||
INSERT INTO public.linked_portal(
|
||||
is_enabled, time_last_synced, code, name, url_update/*, url_index*/)
|
||||
VALUES (true, NULL, 'AT', 'Amebis/Termania', 'https://api-demo.termania.net/rsdo/1.0/dictionaries/$SOURCE_ID/entries?lastSynced=$SINCE'/*, 'https://api-demo.termania.net/rsdo/1.0/dictionaries'*/)
|
||||
RETURNING id into linkedTermaniaId;
|
||||
END IF;
|
||||
RAISE NOTICE 'Termania linked portal id = %', linkedTermaniaId;
|
||||
|
||||
-- for each ZrcTerm dictionary create an enttry in dictionariies and one in linked dictionaries
|
||||
-- we need to remeber both ID's
|
||||
-- we create a temporary table for looping through ZrcTem dictionaries
|
||||
DROP TABLE IF EXISTS importDict;
|
||||
CREATE TEMP TABLE importDict(
|
||||
source_id VARCHAR(50),
|
||||
code VARCHAR(50),
|
||||
description VARCHAR,
|
||||
author VARCHAR,
|
||||
domain_udk_code VARCHAR,
|
||||
CONSTRAINT importDict_pkey PRIMARY KEY (source_id)
|
||||
);
|
||||
INSERT INTO importDict (source_id, code, description, author, domain_udk_code) VALUES
|
||||
('OBRSLO', 'ATOBRSLO', 'Vojaški slovar študentov obramboslovja', 'Fakulteta za družbene vede', '355'),
|
||||
('1000102', 'AT1000102', 'Angleško-slovenski astronomski slovar', 'Raziskovalni program Astrofizika in fizika atmosfere na Fakulteti za matematiko in fiziko Univerze v Ljubljani ', '52'),
|
||||
('1000126', 'AT1000126', 'Angleško-slovenski glosar s področja konjeništva', 'Sintia Marič', '796/799'),
|
||||
('1000268', 'AT1000268', 'Terminološki slovar elektronskega kajenja ', 'Žiga Krajnc', '');
|
||||
|
||||
FOR zd IN SELECT z.*, d.id AS domain_id
|
||||
FROM importDict AS z
|
||||
LEFT JOIN public.domain_primary AS d ON d.udk_code = z.domain_udk_code
|
||||
LOOP
|
||||
IF zd.domain_id IS NULL THEN
|
||||
RAISE NOTICE 'domain not found for %', zd.source_id;
|
||||
CONTINUE WHEN TRUE;
|
||||
END IF;
|
||||
SELECT id INTO linkedDictId FROM public.linked_dictionary
|
||||
WHERE source_dictionary_id=zd.source_id AND linked_portal_id = linkedTermaniaId;
|
||||
IF linkedDictId IS NULL THEN
|
||||
RAISE NOTICE 'inserting %, domain = %', zd.source_id, zd.domain_id;
|
||||
--CONTINUE WHEN TRUE;
|
||||
INSERT INTO public.dictionary(
|
||||
name_sl, name_sl_short, name_en,
|
||||
author, issn, domain_primary_id, status
|
||||
)
|
||||
VALUES (
|
||||
zd.description, zd.code, zd.description,
|
||||
ARRAY[zd.author], null, zd.domain_id, 'published'
|
||||
) RETURNING id into rsdoDictId;
|
||||
INSERT INTO public.linked_dictionary(
|
||||
name, linked_portal_id, target_dictionary_id, is_enabled, time_last_synced, source_dictionary_id)
|
||||
VALUES (zd.description, linkedTermaniaId, rsdoDictId, TRUE, NULL, zd.source_id);
|
||||
COMMIT;
|
||||
ELSE
|
||||
RAISE NOTICE 'updating %', zd.source_id;
|
||||
CONTINUE WHEN TRUE;
|
||||
END IF;
|
||||
END LOOP;
|
||||
DROP TABLE IF EXISTS importDict;
|
||||
end; $$
|
||||
@@ -0,0 +1,83 @@
|
||||
-- Script to set portal for importing dictionaries from Terminologišče (ZRC-SAZU)
|
||||
-- Script inserts linked_portal, linked_dictionary & dictionary records.
|
||||
-- After running this script the batch job batch_update_linked.js will be importing from Terminologišče.
|
||||
|
||||
do $$
|
||||
DECLARE
|
||||
linkedZrcTermId INT;
|
||||
linkedDictId INT;
|
||||
rsdoDictId INT;
|
||||
zd RECORD;
|
||||
author VARCHAR[] := ARRAY['ZRC'];
|
||||
|
||||
BEGIN
|
||||
-- if portal entry doesnt exist for ZrcTerm create one and remember its ID
|
||||
SELECT id INTO linkedZrcTermId FROM public.linked_portal WHERE code='ZT';
|
||||
IF linkedZrcTermId IS NULL THEN
|
||||
INSERT INTO public.linked_portal(
|
||||
is_enabled, time_last_synced, code, name, url_update/*, url_index*/)
|
||||
VALUES (true, NULL, 'ZT', 'ZRC-SAZU/Terminologišče', 'https://iskalnik4ts.zrc-sazu.si/rsdo/updates?dictionaryId=$SOURCE_ID&since=$SINCE'/*, 'https://iskalnik4ts.zrc-sazu.si/rsdo/dictionaries'*/)
|
||||
RETURNING id into linkedZrcTermId;
|
||||
END IF;
|
||||
RAISE NOTICE 'ZrcTerm linked portal id = %', linkedZrcTermId;
|
||||
|
||||
-- for each ZrcTerm dictionary create an enttry in dictionariies and one in linked dictionaries
|
||||
-- we need to remeber both ID's
|
||||
-- we create a temporary table for looping through ZrcTem dictionaries
|
||||
DROP TABLE IF EXISTS zrcTermDic;
|
||||
CREATE TEMP TABLE zrcTermDic(
|
||||
source_id VARCHAR(50),
|
||||
code VARCHAR(50),
|
||||
description VARCHAR,
|
||||
domain_udk_code VARCHAR,
|
||||
CONSTRAINT dictionary_pkey PRIMARY KEY (source_id)
|
||||
);
|
||||
INSERT INTO zrcTermDic (source_id, code, description, domain_udk_code) VALUES
|
||||
('farmacija','ZTFARMAC','Farmacevtski terminološki slovar ZRC-SAZU/Terminologišče', '61'),
|
||||
('betonske_konstrukcije','ZTBETON','Terminološki slovar betonskih konstrukcij ZRC-SAZU/Terminologišče', '624'),
|
||||
('pravo','ZTPRAVO','Pravni terminološki slovar ZRC-SAZU/Terminologišče', '34'),
|
||||
('avtomatika','ZTAVTOMAT','Terminološki slovar avtomatike ZRC-SAZU/Terminologišče', '621.3'),
|
||||
('urbanizem','ZTURBAN','Urbanistični terminološki slovar ZRC-SAZU/Terminologišče', '711'),
|
||||
('umetnost','ZTUMETN','Terminološki slovar uporabne umetnosti – pohištvo, ure, orožje ZRC-SAZU/Terminologišče', '93/94'),
|
||||
('tolkala','ZTTOLKAL','Tolkalni terminološki slovar ZRC-SAZU/Terminologišče', '93/94'),
|
||||
('botanika','ZTBOTAN','Botanični terminološki slovar ZRC-SAZU/Terminologišče', '58'),
|
||||
('smucanje','ZTSMUČ','Slovenski smučarski slovar ZRC-SAZU/Terminologišče', '796/799'),
|
||||
('gledalisce','ZTGLED','Gledališki terminološki slovar ZRC-SAZU/Terminologišče', '93/94'),
|
||||
('cebelarstvo','ZTCEBEL','Čebelarski terminološki slovar ZRC-SAZU/Terminologišče', '59'),
|
||||
('geologija','ZTGEOLOG','Geološki terminološki slovar ZRC-SAZU/Terminologišče', '55'),
|
||||
('gemologija','ZTGEMOLOG','Gemološki terminološki slovar ZRC-SAZU/Terminologišče', '622'),
|
||||
('geografija','ZTGEOGRAF','Geografski terminološki slovar ZRC-SAZU/Terminologišče', '338'),
|
||||
('planinstvo','ZTPLANIN','Planinski terminološki slovar ZRC-SAZU/Terminologišče', '796/799');
|
||||
|
||||
FOR zd IN SELECT z.*, d.id AS domain_id
|
||||
FROM zrcTermDic AS z
|
||||
LEFT JOIN public.domain_primary AS d ON d.udk_code = z.domain_udk_code
|
||||
LOOP
|
||||
IF zd.domain_id IS NULL THEN
|
||||
RAISE NOTICE 'domain not found for %', zd.source_id;
|
||||
CONTINUE WHEN TRUE;
|
||||
END IF;
|
||||
SELECT id INTO linkedDictId FROM public.linked_dictionary
|
||||
WHERE source_dictionary_id=zd.source_id AND linked_portal_id = linkedZrcTermId;
|
||||
IF linkedDictId IS NULL THEN
|
||||
RAISE NOTICE 'inserting %, domain = %', zd.source_id, zd.domain_id;
|
||||
--CONTINUE WHEN TRUE;
|
||||
INSERT INTO public.dictionary(
|
||||
name_sl, name_sl_short, name_en,
|
||||
author, issn, domain_primary_id, status
|
||||
)
|
||||
VALUES (
|
||||
zd.description, zd.code, zd.description,
|
||||
author, null, zd.domain_id, 'published'
|
||||
) RETURNING id into rsdoDictId;
|
||||
INSERT INTO public.linked_dictionary(
|
||||
name, linked_portal_id, target_dictionary_id, is_enabled, time_last_synced, source_dictionary_id)
|
||||
VALUES (zd.description, linkedZrcTermId, rsdoDictId, TRUE, NULL, zd.source_id);
|
||||
COMMIT;
|
||||
ELSE
|
||||
RAISE NOTICE 'updating %', zd.source_id;
|
||||
CONTINUE WHEN TRUE;
|
||||
END IF;
|
||||
END LOOP;
|
||||
DROP TABLE IF EXISTS zrcTermDic;
|
||||
end; $$
|
||||
Reference in New Issue
Block a user