| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103 |
- --
- -- PostgreSQL database dump
- --
- \restrict fMX8pe7fyPeennYB6eeK17lVC7rkBp0LxzYWCFMQgMflMYdB3BYjGmqxfiz2Aj2
- -- Dumped from database version 18.0
- -- Dumped by pg_dump version 18.4
- -- Started on 2026-06-30 18:28:52 MSK
- SET statement_timeout = 0;
- SET lock_timeout = 0;
- SET idle_in_transaction_session_timeout = 0;
- SET transaction_timeout = 0;
- SET client_encoding = 'UTF8';
- SET standard_conforming_strings = on;
- SELECT pg_catalog.set_config('search_path', '', false);
- SET check_function_bodies = false;
- SET xmloption = content;
- SET client_min_messages = warning;
- SET row_security = off;
- --
- -- TOC entry 16 (class 2615 OID 442818)
- -- Name: dyachkov_ya; Type: SCHEMA; Schema: -; Owner: dyachkov_ya
- --
- CREATE SCHEMA dyachkov_ya;
- ALTER SCHEMA dyachkov_ya OWNER TO dyachkov_ya;
- --
- -- TOC entry 1403 (class 1255 OID 443423)
- -- Name: add_user_with_phones(character varying, character varying, integer, integer, integer, character varying, real, integer, character varying, character varying); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.add_user_with_phones(IN p_lastname character varying, IN p_name character varying, IN p_year_b integer, IN p_groups integer, IN p_age integer, IN p_category character varying DEFAULT NULL::character varying, IN p_debt real DEFAULT 0, IN p_level integer DEFAULT 1, IN p_home_phone character varying DEFAULT NULL::character varying, IN p_mobile_phone character varying DEFAULT NULL::character varying)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_has_phone BOOLEAN;
- BEGIN
- BEGIN
- -- Проверка наличия хотя бы одного телефона
- v_has_phone := (p_home_phone IS NOT NULL AND p_home_phone != '') OR
- (p_mobile_phone IS NOT NULL AND p_mobile_phone != '');
-
- IF NOT v_has_phone THEN
- RAISE EXCEPTION 'Необходимо указать хотя бы один телефон (домашний или мобильный) для связи с читателем';
- END IF;
-
- -- Вставка пользователя
- INSERT INTO users (lastname, name, year_b, groups, age, category, debt, level, home_phone, mobile_phone)
- VALUES (p_lastname, p_name, p_year_b, p_groups, p_age, p_category, p_debt, p_level, p_home_phone, p_mobile_phone);
-
- COMMIT;
- RAISE NOTICE 'Пользователь "% %" успешно добавлен', p_lastname, p_name;
- RAISE NOTICE 'Телефоны: дом.%, моб.%',
- COALESCE(p_home_phone, 'не указан'),
- COALESCE(p_mobile_phone, 'не указан');
-
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- RAISE NOTICE 'ОШИБКА: %', SQLERRM;
- END;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.add_user_with_phones(IN p_lastname character varying, IN p_name character varying, IN p_year_b integer, IN p_groups integer, IN p_age integer, IN p_category character varying, IN p_debt real, IN p_level integer, IN p_home_phone character varying, IN p_mobile_phone character varying) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1404 (class 1255 OID 443424)
- -- Name: authenticate_user(character varying, text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.authenticate_user(p_username character varying, p_password text) RETURNS TABLE(user_id integer, username character varying, decrypted_name text, role_name character varying, is_authenticated boolean)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_user_record RECORD;
- v_decrypted_name TEXT;
- BEGIN
- -- Поиск пользователя
- SELECT u.id, u.username, u.encrypted_name, u.password_hash, r.role_name
- INTO v_user_record
- FROM system_users u
- JOIN roles r ON u.role_id = r.id
- WHERE u.username = p_username AND u.is_active = TRUE;
-
- IF v_user_record.id IS NULL THEN
- RETURN QUERY SELECT NULL::INTEGER, NULL::VARCHAR, NULL::TEXT, NULL::VARCHAR, FALSE::BOOLEAN;
- RETURN;
- END IF;
-
- -- Проверка пароля
- IF v_user_record.password_hash = crypt(p_password, v_user_record.password_hash) THEN
- -- Расшифровываем имя
- BEGIN
- v_decrypted_name := convert_from(decrypt(decode(v_user_record.encrypted_name, 'base64'), 'master_key', 'aes'), 'UTF8');
- EXCEPTION WHEN OTHERS THEN
- v_decrypted_name := '[Ошибка расшифровки]';
- END;
-
- RETURN QUERY SELECT
- v_user_record.id,
- v_user_record.username,
- v_decrypted_name,
- v_user_record.role_name,
- TRUE::BOOLEAN;
- ELSE
- RETURN QUERY SELECT NULL::INTEGER, NULL::VARCHAR, NULL::TEXT, NULL::VARCHAR, FALSE::BOOLEAN;
- END IF;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.authenticate_user(p_username character varying, p_password text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1405 (class 1255 OID 443425)
- -- Name: autonomous_log(integer, real, real); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.autonomous_log(p_book_bshifr integer, p_old_price real, p_new_price real) RETURNS void
- LANGUAGE plpgsql
- AS $$
- BEGIN
- -- Имитация автономной транзакции
- BEGIN
- INSERT INTO logs (bk, cena_old, cena_new)
- VALUES (p_book_bshifr, p_old_price, p_new_price);
-
- -- Фиксируем лог независимо от основной транзакции
- COMMIT;
- RAISE NOTICE 'Лог сохранен автономно: книга bshifr=%, цена %.2f -> %.2f',
- p_book_bshifr, p_old_price, p_new_price;
- EXCEPTION
- WHEN OTHERS THEN
- RAISE NOTICE 'Не удалось сохранить лог: %', SQLERRM;
- END;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.autonomous_log(p_book_bshifr integer, p_old_price real, p_new_price real) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1406 (class 1255 OID 443426)
- -- Name: check_ticket_constraints(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.check_ticket_constraints() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- DECLARE
- user_exists BOOLEAN;
- book_exists BOOLEAN;
- BEGIN
- SELECT EXISTS (SELECT 1 FROM users WHERE id = NEW.user_id)
- INTO user_exists;
- IF NOT user_exists THEN
- RAISE EXCEPTION 'Ошибка: Пользователь с ID % не существует в таблице users. Запись в ticket не может быть добавлена.', NEW.user_id;
- END IF;
- SELECT EXISTS (SELECT 1 FROM book WHERE bshifr = NEW.book_id)
- INTO book_exists;
- IF NOT book_exists THEN
- RAISE EXCEPTION 'Ошибка: Книга с шифром % не существует в таблице book. Запись в ticket не может быть добавлена.', NEW.book_id;
- END IF;
- IF NEW.date_return IS NOT NULL AND NEW.date_of_issue IS NOT NULL THEN
- IF NEW.date_return < NEW.date_of_issue THEN
- RAISE EXCEPTION 'Ошибка: Дата возврата (%) не может быть раньше даты выдачи (%).', NEW.date_return, NEW.date_of_issue;
- END IF;
- END IF;
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.check_ticket_constraints() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1407 (class 1255 OID 443427)
- -- Name: check_user_access(character varying, character varying); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.check_user_access(p_username character varying, p_required_role character varying) RETURNS boolean
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_user_role VARCHAR(50);
- v_has_access BOOLEAN := FALSE;
- BEGIN
- -- Начинаем транзакцию
- BEGIN
- SELECT r.role_name INTO v_user_role
- FROM system_users u
- JOIN roles r ON u.role_id = r.id
- WHERE u.username = p_username AND u.is_active = TRUE;
-
- -- Проверка роли (admin имеет полный доступ)
- IF v_user_role = 'admin' OR v_user_role = p_required_role THEN
- v_has_access := TRUE;
- END IF;
-
- -- Логируем попытку доступа (в реальной системе)
- INSERT INTO access_log (username, access_time, has_access, required_role)
- VALUES (p_username, CURRENT_TIMESTAMP, v_has_access, p_required_role);
-
- COMMIT;
- EXCEPTION WHEN OTHERS THEN
- ROLLBACK;
- RAISE NOTICE 'Ошибка при проверке доступа: %', SQLERRM;
- v_has_access := FALSE;
- END;
-
- RETURN v_has_access;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.check_user_access(p_username character varying, p_required_role character varying) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1408 (class 1255 OID 443428)
- -- Name: check_user_by_email(text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.check_user_by_email(p_email text) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- user_exists INTEGER;
- decrypted_email TEXT;
- user_record RECORD;
- BEGIN
- user_exists := 0;
-
- -- Проходим по всем пользователям и расшифровываем email для сравнения
- FOR user_record IN SELECT id, email FROM users LOOP
- IF user_record.email IS NOT NULL THEN
- BEGIN
- decrypted_email := decrypt_email(user_record.email);
- IF decrypted_email = p_email THEN
- user_exists := 1;
- EXIT;
- END IF;
- EXCEPTION WHEN OTHERS THEN
- -- Пропускаем ошибки дешифрования
- CONTINUE;
- END;
- END IF;
- END LOOP;
-
- RETURN user_exists;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.check_user_by_email(p_email text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1409 (class 1255 OID 443429)
- -- Name: clean_string(text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.clean_string(input text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- BEGIN
- IF input IS NULL THEN
- RETURN NULL;
- END IF;
- -- Удаление лишних пробелов, замена нескольких пробелов на один
- RETURN TRIM(REGEXP_REPLACE(input, '\s+', ' ', 'g'));
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.clean_string(input text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1410 (class 1255 OID 443430)
- -- Name: count_books_by_user(character varying, character varying); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.count_books_by_user(p_lastname character varying, p_name character varying) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- books_count INTEGER := 0;
- BEGIN
- IF p_lastname IS NULL OR p_name IS NULL THEN
- RAISE EXCEPTION 'Фамилия и имя пользователя не могут быть NULL.';
- END IF;
- SELECT COUNT(t.id)
- INTO books_count
- FROM ticket t
- JOIN users u ON t.user_id = u.id
- WHERE u.lastname = p_lastname AND u.name = p_name;
- RETURN books_count;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.count_books_by_user(p_lastname character varying, p_name character varying) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1411 (class 1255 OID 443431)
- -- Name: count_unique_readers_in_month(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.count_unique_readers_in_month(p_month integer) RETURNS bigint
- LANGUAGE plpgsql
- AS $$
- DECLARE
- readers_count BIGINT := 0;
- BEGIN
- IF p_month IS NULL OR p_month < 1 OR p_month > 12 THEN
- RAISE EXCEPTION 'Номер месяца должен быть от 1 до 12.';
- END IF;
- SELECT COUNT(DISTINCT t.user_id)
- INTO readers_count
- FROM ticket t
- WHERE EXTRACT(MONTH FROM t.date_of_issue) = p_month; -- EXTRACT(MONTH FROM ...) извлекает номер месяца из даты
- RETURN readers_count;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.count_unique_readers_in_month(p_month integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1412 (class 1255 OID 443432)
- -- Name: days_since_issue(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.days_since_issue(p_ticket_id integer) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- issue_date DATE;
- days_elapsed INTEGER;
- BEGIN
- SELECT date_of_issue
- INTO issue_date
- FROM ticket
- WHERE id = p_ticket_id;
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Билет с ID % не найден.', p_ticket_id;
- END IF;
- days_elapsed := Kol_Dney(issue_date, CURRENT_DATE::date);
- RETURN days_elapsed;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.days_since_issue(p_ticket_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1413 (class 1255 OID 443433)
- -- Name: decrypt_data(text, text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.decrypt_data(p_encrypted text, p_key text DEFAULT 'default_key'::text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- result TEXT;
- BEGIN
- result := convert_from(decrypt(decode(p_encrypted, 'hex'), p_key, 'aes'), 'UTF8');
- RETURN result;
- EXCEPTION WHEN OTHERS THEN
- RETURN 'Ошибка дешифрования';
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.decrypt_data(p_encrypted text, p_key text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1414 (class 1255 OID 443435)
- -- Name: decrypt_email(text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.decrypt_email(encrypted_email text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- decrypted_email TEXT;
- BEGIN
- IF encrypted_email IS NULL THEN
- RETURN NULL;
- END IF;
-
- BEGIN
- decrypted_email := convert_from(decrypt(decode(encrypted_email, 'base64'), 'my_secret_key', 'aes'), 'UTF8');
- RETURN decrypted_email;
- EXCEPTION WHEN OTHERS THEN
- RETURN encrypted_email; -- Если не зашифровано, возвращаем как есть
- END;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.decrypt_email(encrypted_email text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1415 (class 1255 OID 443436)
- -- Name: delete_book(integer); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.delete_book(IN p_bshifr integer)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_title VARCHAR(25);
- v_vidano BOOLEAN;
- BEGIN
- BEGIN
- -- Получаем информацию о книге
- SELECT title, vidano INTO v_title, v_vidano
- FROM book WHERE bshifr = p_bshifr;
-
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Книга с bshifr=% не найдена', p_bshifr;
- END IF;
-
- -- Проверка: если книга на руках - запрещаем удаление
- IF v_vidano = TRUE THEN
- RAISE EXCEPTION 'Невозможно удалить книгу "%" - экземпляр находится на руках у читателя', v_title;
- END IF;
-
- -- Удаляем книгу
- DELETE FROM book WHERE bshifr = p_bshifr;
-
- COMMIT;
- RAISE NOTICE 'Книга "% (bshifr=%) успешно удалена', v_title, p_bshifr;
-
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- RAISE NOTICE 'ОШИБКА: %', SQLERRM;
- END;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.delete_book(IN p_bshifr integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1416 (class 1255 OID 443437)
- -- Name: delete_reader(integer); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.delete_reader(IN p_user_id integer)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_books_count INTEGER;
- v_username VARCHAR(50);
- v_books_list TEXT;
- BEGIN
- BEGIN
- -- Получаем имя пользователя
- SELECT lastname || ' ' || name INTO v_username
- FROM users WHERE id = p_user_id;
-
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Пользователь с ID % не найден', p_user_id;
- END IF;
-
- -- Подсчет книг на руках
- SELECT COUNT(*) INTO v_books_count
- FROM ticket
- WHERE user_id = p_user_id
- AND (date_of_return IS NULL OR date_of_return > CURRENT_DATE);
-
- -- Если есть книги - формируем список и выдаем ошибку
- IF v_books_count > 0 THEN
- SELECT STRING_AGG(b.title, ', ') INTO v_books_list
- FROM ticket t
- JOIN book b ON t.book_id = b.bshifr
- WHERE t.user_id = p_user_id
- AND (t.date_of_return IS NULL OR t.date_of_return > CURRENT_DATE);
-
- RAISE EXCEPTION 'Невозможно удалить читателя "%". У него на руках % книг: %',
- v_username, v_books_count, v_books_list;
- END IF;
-
- -- Удаляем пользователя
- DELETE FROM users WHERE id = p_user_id;
-
- COMMIT;
- RAISE NOTICE 'Читатель "% (ID: %) успешно удален', v_username, p_user_id;
-
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- RAISE NOTICE 'ОШИБКА: %', SQLERRM;
- END;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.delete_reader(IN p_user_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1417 (class 1255 OID 443438)
- -- Name: encrypt_data(text, text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.encrypt_data(p_data text, p_key text DEFAULT 'default_key'::text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- BEGIN
- RETURN encode(encrypt(p_data::bytea, p_key, 'aes'), 'hex');
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.encrypt_data(p_data text, p_key text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1418 (class 1255 OID 443439)
- -- Name: encrypt_email(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.encrypt_email() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- BEGIN
- IF NEW.email IS NOT NULL AND NEW.email != '' THEN
- -- Используем симметричное шифрование с ключом 'secret_key'
- NEW.email := encode(encrypt(NEW.email::bytea, 'my_secret_key', 'aes'), 'base64');
- END IF;
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.encrypt_email() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1419 (class 1255 OID 443440)
- -- Name: generate_random_id_for_usernew(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.generate_random_id_for_usernew() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- DECLARE
- new_id INTEGER;
- is_unique BOOLEAN := FALSE;
- max_attempts INTEGER := 100; -- Количество попыток генерации ID
- current_attempt INTEGER := 0;
- BEGIN
- -- Если ID уже предоставлен (НЕ NULL), оставляем его.
- IF NEW.id IS NOT NULL THEN
- RETURN NEW;
- END IF;
- -- Генерируем новый ID, пока он не станет уникальным.
- WHILE NOT is_unique LOOP
- -- Генерируем случайное число (диапазон 1 - 1000000).
- new_id := floor(random() * 1000000 + 1);
- -- Проверяем уникальность ID.
- IF NOT EXISTS (SELECT 1 FROM usernew WHERE id = new_id) THEN
- is_unique := TRUE;
- END IF;
-
- current_attempt := current_attempt + 1;
- -- Защита от бесконечного цикла.
- IF current_attempt > max_attempts THEN
- RAISE EXCEPTION 'Не удалось сгенерировать уникальный ID для usernew после % попыток.', max_attempts;
- END IF;
- END LOOP;
-
- -- Присваиваем сгенерированный ID.
- NEW.id := new_id;
-
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.generate_random_id_for_usernew() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1420 (class 1255 OID 443441)
- -- Name: generate_sentence_from_dict(integer, text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.generate_sentence_from_dict(p_word_count integer, p_separator text DEFAULT ' '::text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_words TEXT[];
- v_sentence TEXT := '';
- v_capitalized_word TEXT;
- i INTEGER;
- BEGIN
- -- Получаем случайные слова
- v_words := get_random_words(p_word_count);
-
- -- Формируем предложение
- FOR i IN 1..array_length(v_words, 1) LOOP
- IF i = 1 THEN
- -- Первое слово с заглавной буквы
- v_sentence := v_sentence || initcap(v_words[i]);
- ELSE
- v_sentence := v_sentence || p_separator || lower(v_words[i]);
- END IF;
- END LOOP;
-
- -- Добавляем точку в конце
- v_sentence := v_sentence || '.';
-
- RETURN v_sentence;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.generate_sentence_from_dict(p_word_count integer, p_separator text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1421 (class 1255 OID 443442)
- -- Name: generate_uuid_and_time(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.generate_uuid_and_time() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- BEGIN
- IF NEW.uuid IS NULL THEN
- NEW.uuid := gen_random_uuid();
- END IF;
- NEW.time_created := CURRENT_TIMESTAMP;
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.generate_uuid_and_time() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1849 (class 1255 OID 444742)
- -- Name: get_exhibit_count_by_author(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.get_exhibit_count_by_author(author_id integer) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- exhibit_count INTEGER;
- BEGIN
- SELECT COUNT(*) INTO exhibit_count
- FROM Exhibit
- WHERE id_creator = author_id;
-
- RETURN exhibit_count;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.get_exhibit_count_by_author(author_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1422 (class 1255 OID 443443)
- -- Name: get_most_expensive_book_by_author(character varying); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.get_most_expensive_book_by_author(p_author_lastname character varying) RETURNS character varying
- LANGUAGE plpgsql
- AS $$
- DECLARE
- book_title_result VARCHAR(255);
- BEGIN
- IF p_author_lastname IS NULL THEN
- RAISE EXCEPTION 'Фамилия автора не может быть NULL.';
- END IF;
- SELECT b.title
- INTO book_title_result
- FROM book b
- JOIN author a ON b.id_author = a.id
- WHERE a.lastname = p_author_lastname
- ORDER BY b.price DESC
- LIMIT 1;
- IF NOT FOUND THEN
- RAISE NOTICE 'Автор "%" не найден или у него нет книг в базе.', p_author_lastname;
- RETURN NULL; -- Возвращаем NULL, если ничего не найдено.
- END IF;
- RETURN book_title_result;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.get_most_expensive_book_by_author(p_author_lastname character varying) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1423 (class 1255 OID 443444)
- -- Name: get_random_sentence(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.get_random_sentence(word_count integer DEFAULT 5) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- words TEXT[];
- sentence TEXT := '';
- i INTEGER;
- BEGIN
- words := get_random_words(word_count);
-
- FOR i IN 1..array_length(words, 1) LOOP
- IF i > 1 THEN
- sentence := sentence || ' ';
- END IF;
- sentence := sentence || words[i];
- END LOOP;
-
- RETURN sentence || '.';
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.get_random_sentence(word_count integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1424 (class 1255 OID 443445)
- -- Name: get_random_words(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.get_random_words(word_count integer DEFAULT 1) RETURNS text[]
- LANGUAGE plpgsql
- AS $$
- DECLARE
- words_array TEXT[];
- result_array TEXT[] := '{}';
- i INTEGER;
- random_index INTEGER;
- BEGIN
- -- Пытаемся прочитать файл со словами
- BEGIN
- SELECT string_to_array(pg_read_file('/usr/share/dict/words', 0, 1000000), E'\n') INTO words_array;
- EXCEPTION WHEN OTHERS THEN
- -- Если файл не доступен, используем встроенный словарь
- words_array := ARRAY['apple', 'table', 'chair', 'house', 'computer', 'program', 'database', 'security', 'encryption', 'hash'];
- END;
-
- -- Проверяем, что массив не пустой
- IF array_length(words_array, 1) IS NULL THEN
- words_array := ARRAY['apple', 'table', 'chair', 'house', 'computer'];
- END IF;
-
- -- Выбираем случайные слова
- FOR i IN 1..word_count LOOP
- random_index := 1 + floor(random() * array_length(words_array, 1))::INTEGER;
- result_array := array_append(result_array, words_array[random_index]);
- END LOOP;
-
- RETURN result_array;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.get_random_words(word_count integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1425 (class 1255 OID 443446)
- -- Name: get_ticket_details_refcursor(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.get_ticket_details_refcursor(p_ticket_id integer) RETURNS refcursor
- LANGUAGE plpgsql
- AS $$
- DECLARE
- ticket_cur REFCURSOR;
- BEGIN
- IF p_ticket_id IS NULL THEN
- RAISE EXCEPTION 'ID билета не может быть NULL.';
- END IF;
- OPEN ticket_cur FOR
- SELECT
- u.lastname AS user_lastname,
- b.title AS book_title,
- t.date_of_issue AS ticket_date
- FROM ticket t
- JOIN users u ON t.user_id = u.id
- JOIN book b ON t.book_id = b.bshifr
- WHERE t.id = p_ticket_id;
- RETURN ticket_cur;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.get_ticket_details_refcursor(p_ticket_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1838 (class 1255 OID 444504)
- -- Name: getaverageratingforexhibit(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.getaverageratingforexhibit(exhibit_id integer) RETURNS numeric
- LANGUAGE plpgsql
- AS $$
- DECLARE
- avg_rating DECIMAL(3,2);
- BEGIN
- SELECT AVG(exhibit_rating) INTO avg_rating
- FROM Viewing
- WHERE id_exhibit = exhibit_id;
-
- RETURN COALESCE(avg_rating, 0);
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.getaverageratingforexhibit(exhibit_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1836 (class 1255 OID 444502)
- -- Name: getexhibitcountbyauthor(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.getexhibitcountbyauthor(author_id integer) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- exhibit_count INT;
- BEGIN
- SELECT COUNT(*) INTO exhibit_count
- FROM Exhibit
- WHERE id_creator = author_id;
-
- RETURN exhibit_count;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.getexhibitcountbyauthor(author_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1837 (class 1255 OID 444503)
- -- Name: getexhibitsbyauthor(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.getexhibitsbyauthor(author_id integer) RETURNS TABLE(id_exhibit integer, type character varying, creation_date date, copy_price numeric, creation_cost numeric)
- LANGUAGE plpgsql
- AS $$
- BEGIN
- RETURN QUERY
- SELECT e.id_exhibit, e.type, e.creation_date, e.copy_price, e.creation_cost
- FROM Exhibit e
- WHERE e.id_creator = author_id;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.getexhibitsbyauthor(author_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1840 (class 1255 OID 444506)
- -- Name: getmuseumtotalvalue(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.getmuseumtotalvalue(museum_id integer) RETURNS numeric
- LANGUAGE plpgsql
- AS $$
- DECLARE
- total_value DECIMAL(15,2);
- BEGIN
- SELECT SUM(e.copy_price) INTO total_value
- FROM Exhibit e
- WHERE e.id_museum = museum_id;
-
- RETURN COALESCE(total_value, 0);
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.getmuseumtotalvalue(museum_id integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1839 (class 1255 OID 444505)
- -- Name: gettop5expensiveexhibits(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.gettop5expensiveexhibits() RETURNS TABLE(id_exhibit integer, type character varying, copy_price numeric, author_name character varying)
- LANGUAGE plpgsql
- AS $$
- BEGIN
- RETURN QUERY
- SELECT e.id_exhibit, e.type, e.copy_price, c.full_name
- FROM Exhibit e
- JOIN Creator c ON e.id_creator = c.id_creator
- ORDER BY e.copy_price DESC
- LIMIT 5;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.gettop5expensiveexhibits() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1426 (class 1255 OID 443447)
- -- Name: hash_password(text, text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.hash_password(p_password text, p_salt text DEFAULT NULL::text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- salt TEXT;
- hashed_password TEXT;
- BEGIN
- -- Генерируем соль, если не передана
- IF p_salt IS NULL THEN
- salt := gen_salt('bf'); -- Blowfish алгоритм
- ELSE
- salt := p_salt;
- END IF;
-
- -- Создаём хэш пароля
- hashed_password := crypt(p_password, salt);
- RETURN hashed_password;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.hash_password(p_password text, p_salt text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1427 (class 1255 OID 443448)
- -- Name: increase_price_by_cursor(); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.increase_price_by_cursor()
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_book RECORD;
- v_new_price REAL;
- v_increase REAL := 20; -- 20%
- v_max_price REAL := 10000;
- v_processed INTEGER := 0;
- v_updated INTEGER := 0;
- BEGIN
- -- Курсор для книг авторов, родившихся менее 1950 года
- FOR v_book IN
- SELECT b.bshifr, b.title, b.price, a.lastname, a.name, a.year_b
- FROM book b
- JOIN author a ON b.id_author = a.id
- WHERE a.year_b < 1950
- LOOP
- -- Создаем точку сохранения для каждой книги
- PERFORM 1;
-
- BEGIN
- -- Вычисляем новую цену (+20%)
- v_new_price := v_book.price * (1 + v_increase / 100);
-
- RAISE NOTICE 'Книга: "%", Автор: % % (род. %), Цена: % -> %',
- v_book.title, v_book.lastname, v_book.name,
- v_book.year_b, v_book.price, v_new_price;
-
- -- Проверка: не превышает ли новая цена 10000
- IF v_new_price <= v_max_price THEN
- UPDATE book SET price = v_new_price WHERE bshifr = v_book.bshifr;
- v_updated := v_updated + 1;
- RAISE NOTICE ' -> ЦЕНА УВЕЛИЧЕНА';
- ELSE
- -- Цена не изменяется, просто пропускаем
- RAISE NOTICE ' -> ЦЕНА НЕ ИЗМЕНЕНА (%.2f превысила бы лимит %.0f)', v_new_price, v_max_price;
- END IF;
-
- v_processed := v_processed + 1;
-
- EXCEPTION
- WHEN OTHERS THEN
- -- При ошибке просто пропускаем книгу
- RAISE NOTICE ' -> ОШИБКА при обработке книги "%": %', v_book.title, SQLERRM;
- END;
- END LOOP;
-
- RAISE NOTICE '=========================================';
- RAISE NOTICE 'Обработано книг: %, Обновлено: %', v_processed, v_updated;
- RAISE NOTICE '=========================================';
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.increase_price_by_cursor() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1428 (class 1255 OID 443449)
- -- Name: issue_book(integer, integer, date); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.issue_book(IN p_user_id integer, IN p_book_bshifr integer, IN p_date_issue date)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_books_count INTEGER;
- v_title VARCHAR(25);
- v_username VARCHAR(50);
- v_available BOOLEAN;
- BEGIN
- BEGIN
- -- Получаем имя пользователя
- SELECT lastname || ' ' || name INTO v_username
- FROM users WHERE id = p_user_id;
-
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Пользователь с ID % не найден', p_user_id;
- END IF;
-
- -- Получаем информацию о книге
- SELECT title, vidano INTO v_title, v_available
- FROM book WHERE bshifr = p_book_bshifr;
-
- IF NOT FOUND THEN
- RAISE EXCEPTION 'Книга с bshifr=% не найдена', p_book_bshifr;
- END IF;
-
- -- Проверка доступности книги
- IF v_available = TRUE THEN
- RAISE EXCEPTION 'Книга "%" уже выдана другому читателю', v_title;
- END IF;
-
- -- Подсчет книг на руках у читателя
- SELECT COUNT(*) INTO v_books_count
- FROM ticket
- WHERE user_id = p_user_id
- AND (date_of_return IS NULL OR date_of_return > CURRENT_DATE);
-
- RAISE NOTICE 'У читателя "%" на руках % книг', v_username, v_books_count;
-
- -- Проверка лимита (не более 3)
- IF v_books_count >= 3 THEN
- RAISE EXCEPTION 'Читатель "%" уже имеет % книг на руках (максимум 3)',
- v_username, v_books_count;
- END IF;
-
- -- Выдача книги
- INSERT INTO ticket (user_id, book_id, date_of_issue, date_of_return)
- VALUES (p_user_id, p_book_bshifr, p_date_issue, NULL);
-
- UPDATE book SET vidano = TRUE WHERE bshifr = p_book_bshifr;
-
- COMMIT;
- RAISE NOTICE 'Книга "%" выдана читателю "%"', v_title, v_username;
-
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- RAISE NOTICE 'ОШИБКА: %', SQLERRM;
- END;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.issue_book(IN p_user_id integer, IN p_book_bshifr integer, IN p_date_issue date) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1429 (class 1255 OID 443450)
- -- Name: kol_dney(date, date); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.kol_dney(date1 date, date2 date) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- num_days INTEGER;
- BEGIN
- IF date1 IS NULL OR date2 IS NULL THEN
- RAISE EXCEPTION 'Даты не могут быть NULL.';
- END IF;
- -- В PostgreSQL разница между двумя DATE автоматически возвращает количество дней.
- num_days := date2 - date1;
- RETURN num_days; -- Возвращаем разницу в днях
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.kol_dney(date1 date, date2 date) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1430 (class 1255 OID 443451)
- -- Name: month_name_by_number(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.month_name_by_number(month_num integer) RETURNS character varying
- LANGUAGE plpgsql
- AS $$
- BEGIN
- IF month_num IS NULL OR month_num < 1 OR month_num > 12 THEN
- RAISE EXCEPTION 'Номер месяца должен быть от 1 до 12.';
- END IF;
- RETURN CASE month_num
- WHEN 1 THEN 'Январь'
- WHEN 2 THEN 'Февраль'
- WHEN 3 THEN 'Март'
- WHEN 4 THEN 'Апрель'
- WHEN 5 THEN 'Май'
- WHEN 6 THEN 'Июнь'
- WHEN 7 THEN 'Июль'
- WHEN 8 THEN 'Август'
- WHEN 9 THEN 'Сентябрь'
- WHEN 10 THEN 'Октябрь'
- WHEN 11 THEN 'Ноябрь'
- WHEN 12 THEN 'Декабрь'
- ELSE 'Неизвестный месяц'
- END;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.month_name_by_number(month_num integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1431 (class 1255 OID 443452)
- -- Name: multi_hash(text, integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.multi_hash(p_value text, p_iterations integer DEFAULT 1) RETURNS text
- LANGUAGE plpgsql
- AS $$
- DECLARE
- hashed_value TEXT;
- i INTEGER;
- BEGIN
- IF p_value IS NULL THEN
- RETURN NULL;
- END IF;
-
- hashed_value := p_value;
-
- FOR i IN 1..p_iterations LOOP
- hashed_value := encode(digest(hashed_value, 'sha256'), 'hex');
- END LOOP;
-
- RETURN hashed_value;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.multi_hash(p_value text, p_iterations integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1432 (class 1255 OID 443453)
- -- Name: normalize_region(text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.normalize_region(region_name text) RETURNS text
- LANGUAGE plpgsql
- AS $$
- BEGIN
- RETURN CASE
- WHEN region_name ILIKE '%Санкт-Петербург%' OR region_name ILIKE '%СПб%' THEN 'Санкт-Петербург'
- WHEN region_name ILIKE '%Ленинградская%' THEN 'Ленинградская область'
- WHEN region_name ILIKE '%Новгород%' THEN 'Новгородская область'
- ELSE clean_string(region_name)
- END;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.normalize_region(region_name text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1433 (class 1255 OID 443454)
- -- Name: nvl(anyelement, anyelement); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.nvl(input_value anyelement, default_value anyelement) RETURNS anyelement
- LANGUAGE plpgsql
- AS $$
- BEGIN
- RETURN COALESCE(input_value, default_value);
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.nvl(input_value anyelement, default_value anyelement) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1434 (class 1255 OID 443455)
- -- Name: parse_salary(text); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.parse_salary(salary_text text) RETURNS TABLE(min_salary numeric, max_salary numeric)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- numbers NUMERIC[];
- BEGIN
- IF salary_text IS NULL THEN
- min_salary := NULL;
- max_salary := NULL;
- RETURN NEXT;
- RETURN;
- END IF;
-
- -- Извлечение чисел из строки
- SELECT ARRAY(
- SELECT REGEXP_MATCHES(salary_text, '(\d+[.,]?\d*)', 'g')
- ) INTO numbers;
-
- IF array_length(numbers, 1) >= 1 THEN
- min_salary := numbers[1]::NUMERIC;
- IF array_length(numbers, 1) >= 2 THEN
- max_salary := numbers[2]::NUMERIC;
- ELSE
- max_salary := min_salary;
- END IF;
- ELSE
- min_salary := NULL;
- max_salary := NULL;
- END IF;
-
- RETURN NEXT;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.parse_salary(salary_text text) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1435 (class 1255 OID 443456)
- -- Name: proizv(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.proizv(n integer) RETURNS bigint
- LANGUAGE plpgsql
- AS $$
- DECLARE
- i INTEGER;
- total_product BIGINT := 1; -- Инициализируем произведение единицей
- BEGIN
- IF n IS NULL OR n <= 0 THEN
- RAISE EXCEPTION 'Параметр n должен быть положительным целым числом.';
- END IF;
- -- Цикл от 1 до n
- FOR i IN 1..n LOOP
- total_product := total_product * i; -- Умножаем текущее число на произведение
- END LOOP;
- RETURN total_product; -- Возвращаем вычисленное произведение
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.proizv(n integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1436 (class 1255 OID 443457)
- -- Name: proverka(integer, integer, date, date); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.proverka(IN kodu integer, IN kodb integer, IN dvid date, IN dvoz date)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- rez VARCHAR(10) := 'ОК';
- pr INTEGER;
- v_last_id INTEGER;
- BEGIN
- -- Начинаем транзакцию
- BEGIN
- -- Ввод записи в таблицу ticket (она же bilet)
- INSERT INTO ticket (user_id, book_id, date_of_issue, date_of_return)
- VALUES (kodU, kodB, dVid, dVoz)
- RETURNING id INTO v_last_id;
-
- RAISE NOTICE 'Вставлена запись с ID: %', v_last_id;
-
- -- Вычисляем разницу между датой возврата и датой выдачи
- SELECT (date_of_return - date_of_issue) INTO pr
- FROM ticket WHERE id = v_last_id;
-
- RAISE NOTICE 'Разница между датами: % дней', pr;
-
- -- Проверка: если разница > 0, то фиксируем, иначе откатываем
- IF pr > 0 THEN
- COMMIT;
- rez := 'ОК';
- RAISE NOTICE 'Дата возврата корректна. Транзакция зафиксирована.';
- ELSE
- ROLLBACK;
- rez := 'No';
- RAISE NOTICE 'ОШИБКА: дата возврата (%) меньше или равна дате выдачи (%)', dVoz, dVid;
- RAISE NOTICE 'Транзакция откачена.';
- END IF;
-
- -- Выводим значение переменной rez
- RAISE NOTICE 'Результат: %', rez;
-
- EXCEPTION
- WHEN OTHERS THEN
- ROLLBACK;
- rez := 'Error';
- RAISE NOTICE 'Ошибка при выполнении: %', SQLERRM;
- END;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.proverka(IN kodu integer, IN kodb integer, IN dvid date, IN dvoz date) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1437 (class 1255 OID 443458)
- -- Name: register_user(character varying, text, text, character varying); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.register_user(p_username character varying, p_name text, p_password text, p_role_name character varying DEFAULT 'user'::character varying) RETURNS integer
- LANGUAGE plpgsql
- AS $$
- DECLARE
- v_salt TEXT;
- v_role_id INTEGER;
- v_encrypted_name TEXT;
- v_user_id INTEGER;
- BEGIN
- -- Получаем ID роли
- SELECT id INTO v_role_id FROM roles WHERE role_name = p_role_name;
- IF v_role_id IS NULL THEN
- RAISE EXCEPTION 'Роль "%" не существует', p_role_name;
- END IF;
-
- -- Генерируем соль
- v_salt := gen_salt('bf');
-
- -- Шифруем имя пользователя (используем AES)
- v_encrypted_name := encode(encrypt(p_name::bytea, 'master_key', 'aes'), 'base64');
-
- -- Вставляем пользователя
- INSERT INTO system_users (username, encrypted_name, password_hash, salt, role_id)
- VALUES (p_username, v_encrypted_name, crypt(p_password, v_salt), v_salt, v_role_id)
- RETURNING id INTO v_user_id;
-
- RETURN v_user_id;
- EXCEPTION WHEN unique_violation THEN
- RAISE EXCEPTION 'Пользователь с именем "%" уже существует', p_username;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.register_user(p_username character varying, p_name text, p_password text, p_role_name character varying) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1438 (class 1255 OID 443459)
- -- Name: summa(integer); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.summa(n integer) RETURNS bigint
- LANGUAGE plpgsql
- AS $$
- DECLARE
- i INTEGER;
- total_sum BIGINT := 0; -- Инициализируем сумму нулем
- BEGIN
- IF n IS NULL OR n <= 0 THEN
- RAISE EXCEPTION 'Параметр n должен быть положительным целым числом.';
- END IF;
- -- Цикл от 1 до n
- FOR i IN 1..n LOOP
- total_sum := total_sum + i; -- Добавляем текущее число к сумме
- END LOOP;
- RETURN total_sum; -- Возвращаем вычисленную сумму
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.summa(n integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1439 (class 1255 OID 443460)
- -- Name: tek_vr(integer); Type: PROCEDURE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE PROCEDURE dyachkov_ya.tek_vr(IN n integer)
- LANGUAGE plpgsql
- AS $$
- DECLARE
- i INTEGER;
- BEGIN
- IF n IS NULL OR n <= 0 THEN
- RAISE EXCEPTION 'Параметр N должен быть положительным числом.';
- END IF;
- RAISE NOTICE '--- Вывод текущего времени % раз ---', n;
-
- FOR i IN 1..n LOOP
- -- NOW() возвращает текущую дату и время
- RAISE NOTICE 'Итерация %: Текущее время: %', i, NOW();
- END LOOP;
- END;
- $$;
- ALTER PROCEDURE dyachkov_ya.tek_vr(IN n integer) OWNER TO dyachkov_ya;
- --
- -- TOC entry 1440 (class 1255 OID 443461)
- -- Name: ticket_insert_trigger(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.ticket_insert_trigger() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- BEGIN
- IF ( NEW.date_of_issue >= DATE '2024-01-01' AND NEW.date_of_issue < DATE '2024-02-01' ) THEN INSERT INTO ticket2024m1 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-02-01' AND NEW.date_of_issue < DATE '2024-03-01' ) THEN INSERT INTO ticket2024m2 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-03-01' AND NEW.date_of_issue < DATE '2024-04-01' ) THEN INSERT INTO ticket2024m3 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-04-01' AND NEW.date_of_issue < DATE '2024-05-01' ) THEN INSERT INTO ticket2024m4 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-05-01' AND NEW.date_of_issue < DATE '2024-06-01' ) THEN INSERT INTO ticket2024m5 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-06-01' AND NEW.date_of_issue < DATE '2024-07-01' ) THEN INSERT INTO ticket2024m6 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-07-01' AND NEW.date_of_issue < DATE '2024-08-01' ) THEN INSERT INTO ticket2024m7 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-08-01' AND NEW.date_of_issue < DATE '2024-09-01' ) THEN INSERT INTO ticket2024m8 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-09-01' AND NEW.date_of_issue < DATE '2024-10-01' ) THEN INSERT INTO ticket2024m9 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-10-01' AND NEW.date_of_issue < DATE '2024-11-01' ) THEN INSERT INTO ticket2024m10 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-11-01' AND NEW.date_of_issue < DATE '2024-12-01' ) THEN INSERT INTO ticket2024m11 VALUES (NEW.*);
- ELSIF ( NEW.date_of_issue >= DATE '2024-12-01' AND NEW.date_of_issue < DATE '2025-01-01' ) THEN INSERT INTO ticket2024m12 VALUES (NEW.*);
- ELSE RAISE EXCEPTION 'Date out of range for all partitions';
- END IF;
- RETURN NULL;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.ticket_insert_trigger() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1441 (class 1255 OID 443462)
- -- Name: track_price_change(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.track_price_change() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- BEGIN
- -- Если цена изменилась и новая цена > 1000 рублей
- IF OLD.price IS DISTINCT FROM NEW.price AND NEW.price > 1000 THEN
- -- Автономное логирование (сохранится даже при ROLLBACK)
- PERFORM autonomous_log(NEW.bshifr, OLD.price, NEW.price);
-
- RAISE NOTICE 'Зафиксирована попытка изменения цены книги bshifr=%: % -> %',
- NEW.bshifr, OLD.price, NEW.price;
- END IF;
-
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.track_price_change() OWNER TO dyachkov_ya;
- --
- -- TOC entry 1841 (class 1255 OID 444522)
- -- Name: update_museum_profit(); Type: FUNCTION; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE FUNCTION dyachkov_ya.update_museum_profit() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
- BEGIN
- -- Обновляем прибыль музея при добавлении нового экспоната
- UPDATE Museum
- SET profit = profit + (NEW.copy_price - NEW.creation_cost)
- WHERE id_museum = NEW.id_museum;
-
- RETURN NEW;
- END;
- $$;
- ALTER FUNCTION dyachkov_ya.update_museum_profit() OWNER TO dyachkov_ya;
- SET default_tablespace = '';
- SET default_table_access_method = heap;
- --
- -- TOC entry 720 (class 1259 OID 450407)
- -- Name: auditlog; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.auditlog (
- id_log integer NOT NULL,
- id_user integer,
- action character varying(255),
- table_name character varying(100),
- record_id integer,
- action_time timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
- ip_address character varying(45),
- details text
- );
- ALTER TABLE dyachkov_ya.auditlog OWNER TO dyachkov_ya;
- --
- -- TOC entry 719 (class 1259 OID 450406)
- -- Name: auditlog_id_log_seq; Type: SEQUENCE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE SEQUENCE dyachkov_ya.auditlog_id_log_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
- ALTER SEQUENCE dyachkov_ya.auditlog_id_log_seq OWNER TO dyachkov_ya;
- --
- -- TOC entry 6622 (class 0 OID 0)
- -- Dependencies: 719
- -- Name: auditlog_id_log_seq; Type: SEQUENCE OWNED BY; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER SEQUENCE dyachkov_ya.auditlog_id_log_seq OWNED BY dyachkov_ya.auditlog.id_log;
- --
- -- TOC entry 325 (class 1259 OID 444440)
- -- Name: creator; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.creator (
- id_creator integer NOT NULL,
- full_name character varying(100) NOT NULL,
- royalty numeric(10,2),
- phone character varying(20),
- address character varying(200)
- );
- ALTER TABLE dyachkov_ya.creator OWNER TO dyachkov_ya;
- --
- -- TOC entry 327 (class 1259 OID 444460)
- -- Name: exhibit; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.exhibit (
- id_exhibit integer NOT NULL,
- type character varying(50),
- creation_date date,
- copy_price numeric(10,2),
- creation_cost numeric(10,2),
- id_creator integer,
- id_museum integer
- );
- ALTER TABLE dyachkov_ya.exhibit OWNER TO dyachkov_ya;
- --
- -- TOC entry 324 (class 1259 OID 444434)
- -- Name: museum; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.museum (
- id_museum integer NOT NULL,
- area numeric(10,2),
- profit numeric(12,2),
- phone character varying(20),
- address character varying(200)
- );
- ALTER TABLE dyachkov_ya.museum OWNER TO dyachkov_ya;
- --
- -- TOC entry 716 (class 1259 OID 450373)
- -- Name: roles; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.roles (
- id_role integer NOT NULL,
- role_name character varying(50) NOT NULL,
- description text
- );
- ALTER TABLE dyachkov_ya.roles OWNER TO dyachkov_ya;
- --
- -- TOC entry 715 (class 1259 OID 450372)
- -- Name: roles_id_role_seq; Type: SEQUENCE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE SEQUENCE dyachkov_ya.roles_id_role_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
- ALTER SEQUENCE dyachkov_ya.roles_id_role_seq OWNER TO dyachkov_ya;
- --
- -- TOC entry 6623 (class 0 OID 0)
- -- Dependencies: 715
- -- Name: roles_id_role_seq; Type: SEQUENCE OWNED BY; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER SEQUENCE dyachkov_ya.roles_id_role_seq OWNED BY dyachkov_ya.roles.id_role;
- --
- -- TOC entry 718 (class 1259 OID 450386)
- -- Name: users; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.users (
- id_user integer NOT NULL,
- username character varying(50) NOT NULL,
- password_hash character varying(255) NOT NULL,
- salt character varying(100) NOT NULL,
- id_role integer NOT NULL,
- created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
- last_login timestamp without time zone,
- is_active boolean DEFAULT true
- );
- ALTER TABLE dyachkov_ya.users OWNER TO dyachkov_ya;
- --
- -- TOC entry 717 (class 1259 OID 450385)
- -- Name: users_id_user_seq; Type: SEQUENCE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE SEQUENCE dyachkov_ya.users_id_user_seq
- AS integer
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
- ALTER SEQUENCE dyachkov_ya.users_id_user_seq OWNER TO dyachkov_ya;
- --
- -- TOC entry 6624 (class 0 OID 0)
- -- Dependencies: 717
- -- Name: users_id_user_seq; Type: SEQUENCE OWNED BY; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER SEQUENCE dyachkov_ya.users_id_user_seq OWNED BY dyachkov_ya.users.id_user;
- --
- -- TOC entry 328 (class 1259 OID 444476)
- -- Name: viewing; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.viewing (
- id_ticket integer NOT NULL,
- id_exhibit integer NOT NULL,
- exhibit_rating integer,
- CONSTRAINT viewing_exhibit_rating_check CHECK (((exhibit_rating >= 1) AND (exhibit_rating <= 5)))
- );
- ALTER TABLE dyachkov_ya.viewing OWNER TO dyachkov_ya;
- --
- -- TOC entry 330 (class 1259 OID 444512)
- -- Name: v_exhibit_popularity; Type: VIEW; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE VIEW dyachkov_ya.v_exhibit_popularity AS
- SELECT e.id_exhibit,
- e.type,
- count(v.id_ticket) AS views_count,
- avg(v.exhibit_rating) AS average_rating
- FROM (dyachkov_ya.exhibit e
- LEFT JOIN dyachkov_ya.viewing v ON ((e.id_exhibit = v.id_exhibit)))
- GROUP BY e.id_exhibit, e.type
- ORDER BY (avg(v.exhibit_rating)) DESC;
- ALTER VIEW dyachkov_ya.v_exhibit_popularity OWNER TO dyachkov_ya;
- --
- -- TOC entry 329 (class 1259 OID 444507)
- -- Name: v_exhibits_with_authors; Type: VIEW; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE VIEW dyachkov_ya.v_exhibits_with_authors AS
- SELECT e.id_exhibit,
- e.type,
- e.creation_date,
- e.copy_price,
- e.creation_cost,
- c.full_name AS author_name,
- m.address AS museum_location
- FROM ((dyachkov_ya.exhibit e
- LEFT JOIN dyachkov_ya.creator c ON ((e.id_creator = c.id_creator)))
- LEFT JOIN dyachkov_ya.museum m ON ((e.id_museum = m.id_museum)));
- ALTER VIEW dyachkov_ya.v_exhibits_with_authors OWNER TO dyachkov_ya;
- --
- -- TOC entry 326 (class 1259 OID 444447)
- -- Name: visitor; Type: TABLE; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TABLE dyachkov_ya.visitor (
- id_ticket integer NOT NULL,
- full_name character varying(100) NOT NULL,
- phone character varying(20),
- visit_date date,
- museum_rating integer,
- id_museum integer,
- CONSTRAINT visitor_museum_rating_check CHECK (((museum_rating >= 1) AND (museum_rating <= 5)))
- );
- ALTER TABLE dyachkov_ya.visitor OWNER TO dyachkov_ya;
- --
- -- TOC entry 331 (class 1259 OID 444517)
- -- Name: v_museum_statistics; Type: VIEW; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE VIEW dyachkov_ya.v_museum_statistics AS
- SELECT m.id_museum,
- m.address,
- count(DISTINCT e.id_exhibit) AS exhibits_count,
- count(DISTINCT v.id_ticket) AS visitors_count,
- sum(e.copy_price) AS total_exhibits_value
- FROM ((dyachkov_ya.museum m
- LEFT JOIN dyachkov_ya.exhibit e ON ((m.id_museum = e.id_museum)))
- LEFT JOIN dyachkov_ya.visitor v ON ((m.id_museum = v.id_museum)))
- GROUP BY m.id_museum, m.address;
- ALTER VIEW dyachkov_ya.v_museum_statistics OWNER TO dyachkov_ya;
- --
- -- TOC entry 6329 (class 2604 OID 450410)
- -- Name: auditlog id_log; Type: DEFAULT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.auditlog ALTER COLUMN id_log SET DEFAULT nextval('dyachkov_ya.auditlog_id_log_seq'::regclass);
- --
- -- TOC entry 6325 (class 2604 OID 450376)
- -- Name: roles id_role; Type: DEFAULT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.roles ALTER COLUMN id_role SET DEFAULT nextval('dyachkov_ya.roles_id_role_seq'::regclass);
- --
- -- TOC entry 6326 (class 2604 OID 450389)
- -- Name: users id_user; Type: DEFAULT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.users ALTER COLUMN id_user SET DEFAULT nextval('dyachkov_ya.users_id_user_seq'::regclass);
- --
- -- TOC entry 6616 (class 0 OID 450407)
- -- Dependencies: 720
- -- Data for Name: auditlog; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.auditlog (id_log, id_user, action, table_name, record_id, action_time, ip_address, details) FROM stdin;
- \.
- --
- -- TOC entry 6607 (class 0 OID 444440)
- -- Dependencies: 325
- -- Data for Name: creator; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.creator (id_creator, full_name, royalty, phone, address) FROM stdin;
- 1 Иван Иванов 10000.00 +7-111-1111111 ул. Пушкина, 1
- 2 Мария Петрова 15000.00 +7-222-2222222 ул. Лермонтова, 2
- 3 Алексей Сидоров 12000.00 +7-333-3333333 ул. Гоголя, 3
- 4 Елена Васильева 18000.00 +7-444-4444444 ул. Толстого, 4
- \.
- --
- -- TOC entry 6609 (class 0 OID 444460)
- -- Dependencies: 327
- -- Data for Name: exhibit; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.exhibit (id_exhibit, type, creation_date, copy_price, creation_cost, id_creator, id_museum) FROM stdin;
- 101 Живопись 2020-01-15 200000.00 50000.00 1 1
- 102 Скульптура 2019-10-20 150000.00 40000.00 2 1
- 103 Графика 2021-05-10 80000.00 20000.00 1 2
- 104 Живопись 2018-07-22 250000.00 60000.00 3 1
- 105 Фотография 2022-03-15 50000.00 10000.00 2 2
- 106 Скульптура 2020-11-30 120000.00 35000.00 4 3
- 107 Икона 2017-09-05 300000.00 80000.00 1 1
- 108 Графика 2019-12-18 50000.00 15000.00 3 3
- \.
- --
- -- TOC entry 6606 (class 0 OID 444434)
- -- Dependencies: 324
- -- Data for Name: museum; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.museum (id_museum, area, profit, phone, address) FROM stdin;
- 1 1200.50 500000.00 +7-123-4567890 ул. Тверская, 5, Москва
- 3 1500.00 750000.00 +7-555-1234567 ул. Ленина, 15, Екатеринбург
- 2 800.00 400000.00 +7-987-6543210 пр. Невский, 10, Санкт-Петербург
- \.
- --
- -- TOC entry 6612 (class 0 OID 450373)
- -- Dependencies: 716
- -- Data for Name: roles; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.roles (id_role, role_name, description) FROM stdin;
- 1 Admin Полный доступ ко всем функциям
- 2 Curator Управление экспонатами и авторами
- 3 Cashier Работа с посетителями
- 4 Guest Только просмотр
- \.
- --
- -- TOC entry 6614 (class 0 OID 450386)
- -- Dependencies: 718
- -- Data for Name: users; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.users (id_user, username, password_hash, salt, id_role, created_at, last_login, is_active) FROM stdin;
- 9 curator 1bc936e86f9f3f3082b9e81e5489639dda3661522011f0586d74630d30aa9c2f wkcZ1ZKs7I9Fkrhs4V6P6uM0kx0IYbY8aRyYfa06+mE= 2 2026-06-01 16:30:13.375361 \N t
- 10 cashier 7f3c6eac18259fab2b0916dcd958ecbd6c5a7e1e11823fd64d23388852c57445 Yomt7dErmMWuTyE/Ut3HMN1gzzXuF9y0YFL8yVVObOU= 3 2026-06-01 16:30:13.402044 \N t
- 11 guest c09bbc66d7d00cbd91441685c4f0a23811d59d2d57754fc0b82f7271df245428 dAO2P8AgdohaItFZI4JpZ8PH/JH/AXbXJELFl4DPEmY= 4 2026-06-01 16:30:13.433068 \N t
- 8 admin 119e41ff69e6c9fd2133b72169dd666a9caf9d24765483274de2730f00d85f5a WLdeT8d1JEiq//inGEmb83MFydypm84/dldG8Bg366k= 1 2026-06-01 16:30:13.324373 2026-06-29 00:42:40.906973 t
- \.
- --
- -- TOC entry 6610 (class 0 OID 444476)
- -- Dependencies: 328
- -- Data for Name: viewing; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.viewing (id_ticket, id_exhibit, exhibit_rating) FROM stdin;
- 1001 101 5
- 1001 102 4
- 1001 103 5
- 1002 103 4
- 1002 105 5
- 1003 101 5
- 1003 104 4
- 1003 107 5
- 1004 106 3
- 1004 108 4
- 1005 103 5
- 1005 105 4
- 1006 101 5
- 1006 102 5
- 1006 104 4
- \.
- --
- -- TOC entry 6608 (class 0 OID 444447)
- -- Dependencies: 326
- -- Data for Name: visitor; Type: TABLE DATA; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- COPY dyachkov_ya.visitor (id_ticket, full_name, phone, visit_date, museum_rating, id_museum) FROM stdin;
- 1001 Петр Сидоров +7-123-4567890 2023-06-01 5 1
- 1002 Анна Ким +7-234-5678901 2023-06-02 4 2
- 1003 Олег Иванов +7-345-6789012 2023-06-03 5 1
- 1004 Наталья Смирнова +7-456-7890123 2023-06-04 3 3
- 1005 Дмитрий Петров +7-567-8901234 2023-06-05 4 2
- 1006 Екатерина Кузнецова +7-678-9012345 2023-06-06 5 1
- \.
- --
- -- TOC entry 6625 (class 0 OID 0)
- -- Dependencies: 719
- -- Name: auditlog_id_log_seq; Type: SEQUENCE SET; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- SELECT pg_catalog.setval('dyachkov_ya.auditlog_id_log_seq', 1, false);
- --
- -- TOC entry 6626 (class 0 OID 0)
- -- Dependencies: 715
- -- Name: roles_id_role_seq; Type: SEQUENCE SET; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- SELECT pg_catalog.setval('dyachkov_ya.roles_id_role_seq', 9, true);
- --
- -- TOC entry 6627 (class 0 OID 0)
- -- Dependencies: 717
- -- Name: users_id_user_seq; Type: SEQUENCE SET; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- SELECT pg_catalog.setval('dyachkov_ya.users_id_user_seq', 11, true);
- --
- -- TOC entry 6352 (class 2606 OID 450416)
- -- Name: auditlog auditlog_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.auditlog
- ADD CONSTRAINT auditlog_pkey PRIMARY KEY (id_log);
- --
- -- TOC entry 6336 (class 2606 OID 444446)
- -- Name: creator creator_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.creator
- ADD CONSTRAINT creator_pkey PRIMARY KEY (id_creator);
- --
- -- TOC entry 6340 (class 2606 OID 444465)
- -- Name: exhibit exhibit_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.exhibit
- ADD CONSTRAINT exhibit_pkey PRIMARY KEY (id_exhibit);
- --
- -- TOC entry 6334 (class 2606 OID 444439)
- -- Name: museum museum_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.museum
- ADD CONSTRAINT museum_pkey PRIMARY KEY (id_museum);
- --
- -- TOC entry 6344 (class 2606 OID 450382)
- -- Name: roles roles_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.roles
- ADD CONSTRAINT roles_pkey PRIMARY KEY (id_role);
- --
- -- TOC entry 6346 (class 2606 OID 450384)
- -- Name: roles roles_role_name_key; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.roles
- ADD CONSTRAINT roles_role_name_key UNIQUE (role_name);
- --
- -- TOC entry 6348 (class 2606 OID 450398)
- -- Name: users users_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.users
- ADD CONSTRAINT users_pkey PRIMARY KEY (id_user);
- --
- -- TOC entry 6350 (class 2606 OID 450400)
- -- Name: users users_username_key; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.users
- ADD CONSTRAINT users_username_key UNIQUE (username);
- --
- -- TOC entry 6342 (class 2606 OID 444485)
- -- Name: viewing viewing_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.viewing
- ADD CONSTRAINT viewing_pkey PRIMARY KEY (id_ticket, id_exhibit);
- --
- -- TOC entry 6338 (class 2606 OID 444454)
- -- Name: visitor visitor_pkey; Type: CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.visitor
- ADD CONSTRAINT visitor_pkey PRIMARY KEY (id_ticket);
- --
- -- TOC entry 6360 (class 2620 OID 444523)
- -- Name: exhibit after_exhibit_insert; Type: TRIGGER; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- CREATE TRIGGER after_exhibit_insert AFTER INSERT ON dyachkov_ya.exhibit FOR EACH ROW EXECUTE FUNCTION dyachkov_ya.update_museum_profit();
- --
- -- TOC entry 6359 (class 2606 OID 450417)
- -- Name: auditlog auditlog_id_user_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.auditlog
- ADD CONSTRAINT auditlog_id_user_fkey FOREIGN KEY (id_user) REFERENCES dyachkov_ya.users(id_user);
- --
- -- TOC entry 6354 (class 2606 OID 444466)
- -- Name: exhibit exhibit_id_creator_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.exhibit
- ADD CONSTRAINT exhibit_id_creator_fkey FOREIGN KEY (id_creator) REFERENCES dyachkov_ya.creator(id_creator);
- --
- -- TOC entry 6355 (class 2606 OID 444471)
- -- Name: exhibit exhibit_id_museum_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.exhibit
- ADD CONSTRAINT exhibit_id_museum_fkey FOREIGN KEY (id_museum) REFERENCES dyachkov_ya.museum(id_museum);
- --
- -- TOC entry 6358 (class 2606 OID 450401)
- -- Name: users users_id_role_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.users
- ADD CONSTRAINT users_id_role_fkey FOREIGN KEY (id_role) REFERENCES dyachkov_ya.roles(id_role);
- --
- -- TOC entry 6356 (class 2606 OID 444491)
- -- Name: viewing viewing_id_exhibit_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.viewing
- ADD CONSTRAINT viewing_id_exhibit_fkey FOREIGN KEY (id_exhibit) REFERENCES dyachkov_ya.exhibit(id_exhibit);
- --
- -- TOC entry 6357 (class 2606 OID 444486)
- -- Name: viewing viewing_id_ticket_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.viewing
- ADD CONSTRAINT viewing_id_ticket_fkey FOREIGN KEY (id_ticket) REFERENCES dyachkov_ya.visitor(id_ticket);
- --
- -- TOC entry 6353 (class 2606 OID 444455)
- -- Name: visitor visitor_id_museum_fkey; Type: FK CONSTRAINT; Schema: dyachkov_ya; Owner: dyachkov_ya
- --
- ALTER TABLE ONLY dyachkov_ya.visitor
- ADD CONSTRAINT visitor_id_museum_fkey FOREIGN KEY (id_museum) REFERENCES dyachkov_ya.museum(id_museum);
- -- Completed on 2026-06-30 18:28:57 MSK
- --
- -- PostgreSQL database dump complete
- --
- \unrestrict fMX8pe7fyPeennYB6eeK17lVC7rkBp0LxzYWCFMQgMflMYdB3BYjGmqxfiz2Aj2
|