is-coursework/report/data-model/sql/generate.sql
2025-11-18 17:52:54 +03:00

258 lines
6.8 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

BEGIN;
CREATE OR REPLACE FUNCTION generate_ipv4()
RETURNS text
LANGUAGE plpgsql
AS $$
DECLARE
ip text;
BEGIN
SELECT (trunc(50+random()*200))::int || '.' || (trunc(1+random()*250))::int || '.' || (trunc(1+random()*250))::int || '.' || (trunc(1+random()*250))::int
INTO ip;
RETURN ip;
END $$;
DO $$
DECLARE
users_cnt int := 100_000;
domains_cnt int := 1_000_000;
carts_cnt int := 42_000;
orders_cnt int := 1_100_000;
BEGIN
-- Зоны
INSERT INTO zone2(name, price)
SELECT name, price FROM (
VALUES
('com', 150000),
('net', 130000),
('org', 120000),
('io', 390000),
('app', 250000),
('dev', 220000),
('ai', 590000),
('ru', 70000),
('by', 80000),
('site', 110000)
) AS t(name, price)
ORDER BY price DESC
ON CONFLICT DO NOTHING;
-- Пользователи
INSERT INTO app_user(email, password_hash, email_confirmed, is_admin, created_at)
SELECT
'user' || gs || '@example.com',
md5(random()::text),
random() < 0.95,
random() < 0.01,
now() - random() * interval '120 days'
FROM generate_series(1, users_cnt) gs;
-- 2FA
INSERT INTO auth_factor(user_id, kind, public_data)
SELECT id, 'TOTP', '{"secret":"test"}'
FROM app_user
WHERE random() < 0.7;
-- Email tokens
INSERT INTO email_validation_token(token, user_id, created_at, expires_at, status)
SELECT
md5(random()::text),
id,
now() - random() * interval '10 days',
now() + (1 + random() * 10)::int * interval '1 day',
(ARRAY['VERIFY_EMAIL','RESET_PASSWORD'])[1 + (random()*1)::int]::email_token_status
FROM app_user
WHERE random() < 0.3;
-- Зоны готовы, теперь домены
INSERT INTO domain(fqdn, zone2_id, activated_at, expires_at, created_at)
SELECT
left(md5(random()::text), 8) || '.' || z.name,
z.id,
CASE WHEN random() < 0.95 THEN now() - random() * interval '90 days' END,
now() + (10 + random() * 700)::int * interval '1 day',
now() - random() * interval '200 days'
FROM zone2 z
CROSS JOIN generate_series(1, domains_cnt) gs
LIMIT domains_cnt
ON CONFLICT DO NOTHING;
-- DNS записи
INSERT INTO dns_record(domain_id, type, name, value, ttl)
SELECT
d.id,
'A',
'@',
generate_ipv4(),
3600
FROM domain d
WHERE random() < 0.9;
-- NS
INSERT INTO ns_delegation(domain_id, ns_servers)
SELECT d.id,
jsonb_build_array('ns1.example.net','ns2.example.net')
FROM domain d;
-- Корзины
INSERT INTO cart(user_id)
SELECT id FROM app_user ORDER BY random() LIMIT carts_cnt;
-- Товары в корзине
INSERT INTO cart_item(cart_id, action, term, fqdn, price)
SELECT
c.id,
(ARRAY['register','renew'])[1 + (random()*1)::int]::item_action,
(ARRAY['monthly','yearly'])[1 + (random()*1)::int]::item_term,
(SELECT fqdn FROM domain ORDER BY random() LIMIT 1),
(10000 + (random()*600000))::bigint
FROM cart c
JOIN generate_series(1,2) g ON TRUE
ON CONFLICT DO NOTHING;
-- Заказы
INSERT INTO app_order(user_id, status, total_amount, created_at, paid_at)
SELECT
id,
(ARRAY['created','pending_payment','paid','cancelled','failed'])[1 + (random()*4)::int]::order_status,
(100000 + random()*1000000)::bigint,
now() - random() * interval '60 days',
CASE WHEN random() < 0.5 THEN now() - random() * interval '30 days' END
FROM app_user
ORDER BY random()
LIMIT domains_cnt
ON CONFLICT DO NOTHING;
-- Позиции заказа
INSERT INTO app_order_item(order_id, action, term, domain_id)
SELECT
o.id,
(ARRAY['register','renew'])[1 + (random()*1)::int]::item_action,
(ARRAY['monthly','yearly'])[1 + (random()*1)::int]::item_term,
(SELECT id FROM domain ORDER BY random() LIMIT 1)
FROM app_order o
JOIN generate_series(1,2) g ON true;
-- Платёжные операции
INSERT INTO payment_operation(order_id, operation_id, payment_link, amount, status_raw, status_mapped, with_receipt)
SELECT
o.id,
'op_' || left(md5(random()::text), 8),
'https://enter.tochka.com/'||o.id,
o.total_amount,
'CREATED',
'CREATED',
random() < 0.5
FROM app_order o
WHERE random() < 0.9
ON CONFLICT DO NOTHING;
-- Платёжные статусы
INSERT INTO payment_status(payment_operation_id, status_raw, status_mapped)
SELECT id, 'CREATED', 'CREATED' FROM payment_operation;
-- Возвраты
INSERT INTO refund(payment_operation_id, provider_refund_id, amount, status)
SELECT id, 'rf_'||left(md5(random()::text), 8), amount, 'SUCCESS'
FROM payment_operation
WHERE random() < 0.2;
-- Вебхуки
INSERT INTO webhook_event(payload_hash, raw_payload, webhook_type, amount, status_after)
SELECT
md5(random()::text),
'payload',
'payment',
100000 + random()*500000,
'APPROVED'
FROM generate_series(1,orders_cnt*0.7);
-- Сессии
INSERT INTO user_session(user_id, jwt_id, access, refresh, issued_at, expires_at)
SELECT
id,
gen_random_uuid(),
md5(random()::text),
md5(random()::text),
now() - random() * interval '10 days',
now() + random() * interval '30 days'
FROM app_user;
INSERT INTO domain_member(user_id, domain_id, role, created_at)
SELECT
u.id,
d.id,
'OWNER',
now() - random() * interval '100 days'
FROM app_user u
JOIN domain d ON random() < 0.05
LIMIT users_cnt*0.8;
-- Запрещённые имена
INSERT INTO forbidden_name(label)
SELECT
md5(random()::text)
FROM generate_series(1, 5000) g;
-- Зарезервированные имена
INSERT INTO reserved_name(label)
SELECT
md5(random()::text)
FROM generate_series(1, 5000) g;
-- Настройки уведомлений о продлении доменов
INSERT INTO expiry_email_pref(user_id, days_before, enabled, created_at, updated_at)
SELECT
id,
(ARRAY[1, 3, 7, 14, 30])[1 + (random()*4)::int],
random() < 0.9,
now() - random() * interval '30 days',
now() - random() * interval '10 days'
FROM app_user
WHERE random() < 0.3
ON CONFLICT (user_id, days_before) DO NOTHING;
-- email_validation_token
INSERT INTO email_validation_token(token, user_id, created_at, expires_at, status)
SELECT
md5(random()::text),
id,
now() - random() * interval '5 days',
now() + (1 + random() * 10) * interval '1 day',
(ARRAY['VERIFY_EMAIL','RESET_PASSWORD'])[1 + (random()*1)::int]::email_token_status
FROM app_user
WHERE random() < 0.2
ON CONFLICT DO NOTHING;
BEGIN
DECLARE
uids uuid[];
BEGIN
SELECT array_agg(id) INTO uids FROM app_user;
FOR months in 0..9 LOOP
FOR seconds in 1..10000 LOOP
INSERT INTO event(actor_type, actor_id, action, resource, ip, at)
SELECT
(ARRAY['user','admin','system'])[1 + (random()*2)::int],
uids[months + seconds],
(ARRAY['login', 'logout', 'create_payment', 'delete_dns_record'])[1 + (random()*3)::int],
(ARRAY[uids[months + seconds]::text, 'example.com'])[1 + (random()*1)::int],
generate_ipv4(),
now() + seconds * '1 second'::interval + months * '1 month'::interval;
END LOOP;
END LOOP;
END;
END;
END $$;
DROP FUNCTION IF EXISTS generate_ipv4;
COMMIT;
ANALYZE;
VACUUM;