DatabaseCreation: MajStore_DML.sql

File MajStore_DML.sql, 18.8 KB (added by 231049, 3 weeks ago)
Line 
1--user management and roles ---------------------------------------------------------------------------------------------------------
2
3-- Permission - import CSV
4
5insert into Role (role_name)
6values ('Admin'),
7 ('Client'),
8 ('Worker');
9
10-- Role_Permission - import CSV
11
12
13-- user ------------------------------------------------------------------------------------------------------------------------
14create table if not exists temp_names(name text); -- import CSV
15create table if not exists temp_surnames(surname text); -- import CSV
16
17create or replace procedure insert_users(batch_size INT, total INT) -- insert-от беше премногу спор на сервер, па употребивме процедура
18 language plpgsql
19as
20$$
21declare
22 i int := 0;
23begin
24 while i < total
25 loop
26 insert into "User" (first_name, last_name, username, email, password_hash)
27 select mn.name,
28 s.surname,
29 lower(mn.name) || '_' || lower(s.surname) || (i + gs),
30 lower(mn.name) || '.' || lower(s.surname) || (i + gs) || '@gmail.com',
31 md5(mn.name || s.surname || (i + gs))
32 from generate_series(1, batch_size) gs
33 cross join lateral (
34 select name
35 from temp_names
36 where random() + gs * 0 is not null
37 order by random()
38 limit 1
39 ) mn
40 cross join lateral (
41 select surname
42 from temp_surnames
43 where random() + gs * 0 is not null
44 order by random()
45 limit 1
46 ) s
47 order by random();
48
49 i := i + batch_size;
50
51 COMMIT;
52 raise notice 'Inserted % / %', i, total;
53 end loop;
54end;
55$$;
56
57call insert_users(15000, 240000);
58
59
60
61
62
63
64-- worker
65insert into User_Role (role_id, user_id)
66select 3, w.user_id
67from Worker w
68on conflict (user_id, role_id) do nothing;
69
70-- admin
71insert into User_Role (role_id, user_id)
72select 1, u.user_id
73from "User" u
74where u.user_id not in (
75 select user_id from User_Role
76)
77limit 20;
78
79-- user
80insert into User_Role (role_id, user_id)
81select 2, u.user_id
82from "User" u
83where not exists (
84 select 1
85 from User_Role ur
86 where ur.user_id = u.user_id
87);
88
89
90
91
92
93create table temp_Notification (
94 notification_id serial primary key,
95 message text not null,
96 is_read bool not null,
97 created_at timestamp not null ,
98 user_id int,
99 constraint fk_user foreign key (user_id) references "User"(user_id) ON DELETE CASCADE
100);
101
102insert into temp_Notification (message, is_read, created_at, user_id)
103select
104 'Your premium plan is activated',
105 (random() < 0.5),
106 pw.start_date,
107 w.user_id
108from premium_worker pw
109join Worker w on w.worker_id = pw.worker_id;
110
111insert into temp_Notification (message, is_read, created_at, user_id)
112select
113 case
114 when s.status_name = 'Accepted' then 'Your application was accepted'
115 when s.status_name = 'Rejected' then 'Your application was rejected'
116 end,
117 false,
118 a.created_at,
119 w.user_id
120from Application a
121join Application_Status s on s.status_id = a.status_id
122join Worker w on w.worker_id = a.worker_id
123where s.status_name in ('Accepted', 'Rejected');
124
125insert into temp_Notification (message, is_read, created_at, user_id)
126select
127 'New worker has sent you an application',
128 false,
129 a.created_at,
130 p.user_id
131from Application a
132join Post p on p.post_id = a.post_id;
133
134insert into Notification
135select *
136from temp_Notification
137order by random();
138
139
140
141-- Location - import CSV
142
143
144-- worker ------------------------------------------------------------------------------------------------------------------------
145
146create table if not exists temp_worker_bios(bio text); -- import CSV
147
148create or replace procedure insert_workers( batch_size int4, total int4) -- insert-от беше премногу спор на сервер, па употребивме процедура
149 language plpgsql
150as $$
151declare
152 i int := 0;
153begin
154 while i < total loop
155
156 insert into Worker (bio, works_remote, location_id, user_id)
157 select
158 b.bio,
159 (random() > 0.5) AS works_remote,
160 l.location_id,
161 u.user_id
162 from (
163 select user_id, random() AS r
164 from "User"
165 order by random()
166 limit batch_size
167 ) u
168 join lateral (
169 select location_id
170 from Location
171 order by (random() + u.r)
172 limit 1
173 ) l on true
174 join lateral (
175 select bio
176 from temp_worker_bios
177 order by (random() + u.r)
178 limit 1
179 ) b on true;
180
181 i := i + batch_size;
182 COMMIT;
183 raise notice 'Inserted % / %', i, total;
184
185 end loop;
186end;
187$$;
188
189call insert_workers(1000,100000);
190
191
192
193
194create or replace procedure insert_calendar(batch_size INT, total INT)
195 language plpgsql
196as
197$$
198declare
199 i INT := 0;
200begin
201 while i < total loop
202 insert into calendar (worker_id)
203 select
204 w.worker_id
205 from (
206 select worker_id
207 from Worker
208 order by worker_id
209 limit batch_size
210 offset i
211 ) w;
212 i := i + batch_size;
213
214 COMMIT;
215 raise notice 'Inserted % / % posts', i, total;
216 end loop;
217end;
218$$;
219
220call insert_calendar(5000,142000);
221
222
223
224
225
226insert into Day (day_name) values
227 ('Monday'),
228 ('Tuesday'),
229 ('Wednesday'),
230 ('Thursday'),
231 ('Friday'),
232 ('Saturday'),
233 ('Sunday');
234
235
236
237
238
239insert into Work_Day (start_time, end_time, calendar_id, day_id)
240with random_calendars as (
241 select calendar_id from Calendar
242),
243random_days as (
244 select day_id from Day
245),
246generated_slots as (
247 select
248 c.calendar_id,
249 d.day_id,
250 ( now() - interval '2 years'
251 + (random() * (interval '2 years 1 month'))
252 + interval '8 hours'
253 + (interval '1 hour' * floor(random() * 9))
254 ) as start_time,
255 (floor(random() * 5) + 1)::int as duration_hours
256 from random_calendars c
257 cross join random_days d
258 where random() < 0.7
259)
260select
261 gs.start_time,
262 gs.start_time + (interval '1 hour' * gs.duration_hours),
263 gs.calendar_id,
264 gs.day_id
265from generated_slots gs
266order by random()
267limit 1500000;
268
269
270
271
272
273
274create table temp_calendar_event(title text, description text); -- import CSV
275
276create or replace procedure insert_calendar_events(batch_size int, total int)
277 language plpgsql
278as $$
279declare
280 i int := 0;
281begin
282 while i < total loop
283 insert into calendar_event (title, description, start_time, end_time, calendar_id)
284 select
285 t.title,
286 t.description,
287 x.event_start as start_time,
288 x.event_start
289 + ((1 + floor(random() * 3)) * interval '1 hour') as end_time,
290 x.calendar_id
291 from (
292 select
293 calendar_id,
294 start_time + ((floor(random() * 3)) * interval '1 hour') as event_start,
295 row_number() over (order by random()) as rn
296 from work_day
297 order by random()
298 limit batch_size
299 ) x
300 join (
301 select
302 title,
303 description,
304 row_number() over (order by random()) as rn
305 from temp_calendar_event
306 order by random()
307 limit batch_size
308 ) t on t.rn = x.rn;
309
310 i := i + batch_size;
311 COMMIT;
312 raise notice 'inserted % / %', i, total;
313
314 end loop;
315end;
316$$;
317
318call insert_calendar_events(10000, 5000000);
319
320
321
322
323
324
325
326create table if not exists temp_cert_names(name text); -- import CSV
327create table if not exists temp_cert_issuers(issuer text); -- import CSV
328
329with cert_names as (
330 select name, row_number() over (order by random()) as rn
331 from temp_cert_names
332),
333 issuers as (
334 select issuer, row_number() over (order by random()) as rn
335 from temp_cert_issuers
336 ),
337 random_workers as (
338 select worker_id, row_number() over (order by random()) as rn
339 from worker
340 )
341insert into certificate (certificate_name, issuer, worker_id)
342select
343 c.name as certificate_name,
344 i.issuer as issuer,
345 w.worker_id
346from random_workers w
347 cross join cert_names c
348 cross join issuers i
349order by random()
350limit 20000;
351
352
353
354-- Specialty - import CSV
355
356
357
358create or replace procedure insert_worker_specialties(batch_size INT, total INT)
359 language plpgsql
360as
361$$
362declare
363 i INT := 0;
364begin
365 while i < total loop
366 insert into worker_specialty (worker_id, specialty_id)
367 select
368 w.worker_id,
369 s.specialty_id
370 from (
371 select worker_id
372 from Worker
373 order by worker_id
374 limit batch_size
375 offset i
376 ) w
377 join lateral (
378 select specialty_id
379 from Specialty
380 order by random()
381 limit (1 + floor(random() * 3))::int
382 ) s on true;
383
384 i := i + batch_size;
385 COMMIT;
386 raise notice 'Inserted % / % posts', i, total;
387
388 end loop;
389end;
390$$;
391
392call insert_worker_specialties(50, 100000);
393
394
395
396-- post ------------------------------------------------------------------------------------------------------------------------
397insert into Post_Status (status_name) values
398 ('Active'),
399 ('Deleted'),
400 ('Completed');
401
402
403
404create table if not exists temp_posts (title text, description text); -- import CSV
405
406create or replace procedure insert_posts(batch_size int, total int)
407 language plpgsql
408as $$
409declare
410 i int := 0;
411begin
412 while i < total loop
413
414 insert into post (title, description, user_id, location_id, status_id, created_at)
415 select
416 p.title,
417 p.description,
418 u.user_id,
419 l.location_id,
420 (1 + floor(random() * 3))::int,
421 (now() - interval '3 years' * random())::timestamp
422 from (
423 select title, description, row_number() over (order by random()) as rn
424 from temp_posts
425 order by random()
426 limit batch_size
427 ) p
428 join (
429 select user_id, row_number() over (order by random()) as rn
430 from "User"
431 order by random()
432 limit batch_size
433 ) u on u.rn = p.rn
434 join (
435 select location_id, row_number() over (order by random()) as rn
436 from location
437 order by random()
438 limit batch_size
439 ) l on l.rn = p.rn;
440
441 i := i + batch_size;
442 COMMIT;
443 raise notice 'Inserted % / %', i, total;
444 end loop;
445end;
446$$;
447
448call insert_posts(1000, 5000000);
449
450
451
452
453
454create table temp_post_images(image_url text); -- import CSV
455
456create or replace procedure public.insert_post_image(batch_size integer, total integer)
457 language plpgsql
458as $$
459declare
460 i INT := 0;
461begin
462 while i < total loop
463 insert into Post_Image (image_file, post_id)
464 select img.image_url::bytea, p.post_id
465 from (
466 select post_id
467 from Post
468 order by post_id
469 limit batch_size
470 offset i
471 ) p
472 cross join lateral (
473 select image_url
474 from temp_post_images
475 where random() + p.post_id * 0 is not null
476 order by random()
477 limit floor(random() * 4)::INT
478 ) img;
479
480 i := i + batch_size;
481
482 COMMIT;
483 raise notice 'Inserted % / %', i, total;
484 end loop;
485end;
486$$;
487
488call insert_post_image(10000,5000000);
489
490
491
492
493
494
495
496create or replace procedure insert_post_specialties(batch_size int, total int)
497 language plpgsql
498as
499$$
500declare
501 i int := 0;
502begin
503 while i < total loop
504 insert into Post_Specialty (post_id, specialty_id)
505 select p.post_id, s.specialty_id
506 from (
507 select post_id
508 from Post
509 order by post_id
510 limit batch_size
511 offset i
512 ) p
513 join lateral (
514 select specialty_id
515 from Specialty
516 order by random()
517 limit (1 + floor(random() * 3))::int
518 ) s on true;
519
520 i := i + batch_size;
521
522 COMMIT;
523 raise notice 'Inserted % / % posts', i, total;
524 end loop;
525end;
526$$;
527
528call insert_post_specialties(1000, 5000000);
529
530
531
532-- application ------------------------------------------------------------------------------------------------------------------------
533insert into Application_Status (status_name) values
534 ('Pending'),
535 ('Accepted'),
536 ('Deleted'),
537 ('Rejected');
538
539
540
541create table if not exists temp_application_messages(message text); -- import CSV
542
543create or replace procedure insert_apps(batch_size INT, total INT)
544language plpgsql
545as
546$$
547declare
548 i INT := 0;
549begin
550 while i < total loop
551 insert into Application (message, needed_time, expected_price, created_at, worker_id, post_id, status_id)
552 select
553 m.message,
554 (interval '1 hour' * (1 + floor(random() * 23)))::time as needed_time,
555 (10 + floor(random() * 990))::float as expected_price,
556 (p.created_at + interval '3 days' + interval '1 day' * floor(random() * 30)) as created_at,
557 w.worker_id,
558 p.post_id,
559 s.status_id
560 from (
561 select post_id, created_at
562 from Post
563 order by random()
564 limit batch_size
565 ) p
566 join lateral (
567 select worker_id
568 from Worker
569 order by random() + p.post_id * 0.0001
570 limit 1
571 ) w on true
572 join lateral (
573 select status_id
574 from Application_Status
575 order by random() + p.post_id * 0.0001
576 limit 1
577 ) s on true
578 join lateral (
579 select message
580 from temp_application_messages
581 order by random() + p.post_id * 0.0001
582 limit 1
583 ) m on true;
584
585 i := i + batch_size;
586 commit;
587 raise notice 'Inserted % / %', i, total;
588 end loop;
589end;
590$$;
591
592call insert_apps(10000, 5000000);
593
594
595
596
597-- reviews and ratings ------------------------------------------------------------------------------------------------------------------------
598
599create or replace procedure insert_reviews(batch_size int, total int)
600 language plpgsql
601as
602$$
603declare
604 i int := 0;
605begin
606 while i < total loop
607 insert into Review (grade, created_at, reviewer_id, worker_specialty_id)
608 select
609 floor(random() * 6)::int as grade,
610 (now() - interval '3 year' * random()) as created_at,
611 u.user_id,
612 ws.worker_specialty_id
613 from (
614 select worker_specialty_id, random() as r
615 from Worker_Specialty
616 order by random()
617 limit 1
618 ) ws
619 join lateral (
620 select user_id
621 from "User"
622 order by random()
623 limit floor(3 + random() * 5)::int
624 ) u on true;
625
626 i := i + batch_size;
627 COMMIT;
628 raise notice 'Inserted % / % ', i, total;
629 end loop;
630end;
631$$;
632
633call insert_reviews(1, 1000000);
634
635
636
637
638
639create table temp_positive_comments( comment text ); -- import CSV
640create table temp_negative_comments( comment text); -- import CSV
641
642insert into Review_Comment (review_id, reply)
643select r.review_id,
644 case
645 when r.grade in (4, 5) then (
646 select comment
647 from temp_positive_comments
648 order by random() * r.review_id
649 limit 1
650 )
651 else (
652 select comment
653 from temp_negative_comments
654 order by random() * r.review_id
655 limit 1
656 )
657 end as reply
658from review r
659where random() > 0.4;
660
661
662
663
664
665
666insert into Payment_Method (method_name, max_amount, tax) values
667 ('Credit Card', 50000, 0.02),
668 ('Debit Card', 20000, 0.015),
669 ('PayPal', 30000, 0.03),
670 ('Apple Pay', 25000, 0.02),
671 ('Google Pay', 25000, 0.02);
672
673
674
675
676insert into Worker_Method (worker_id, method_id)
677select w.worker_id, pm.method_id
678from (
679 select worker_id
680 from worker
681 order by random()
682 limit 50000
683) w
684join lateral (
685 select method_id
686 from payment_method
687 order by random() + w.worker_id
688 limit 1 + floor(random() * 3)
689) pm on true;
690
691
692
693
694insert into Payment_Status (status_name) values
695 ('Pending'),
696 ('Completed'),
697 ('Failed'),
698 ('Cancelled'),
699 ('Processing');
700
701
702
703insert into Payment (amount, payment_date, worker_method_id, payment_status, plan_id)
704select
705 (pp.price * (1 + wm.tax))::numeric(10,2) as amount,
706 now() - interval '2 years' * random() as payment_date,
707 wm.worker_method_id,
708 rs.status_id,
709 pp.plan_id
710from generate_series(1, 500000) gs
711cross join lateral (
712 select plan_id, price
713 from Premium_Plan
714 order by random() * gs
715 limit 1
716) pp
717cross join lateral (
718 select wm.worker_method_id, pm.tax
719 from Worker_Method wm
720 join Payment_Method pm on wm.method_id = pm.method_id
721 order by random() * gs
722 limit 1
723) wm
724cross join lateral (
725 select status_id
726 from Payment_Status
727 order by random() * gs
728 limit 1
729) rs
730order by payment_date;
731
732
733
734insert into Premium_Plan (name, price, duration_days, description) values
735 ('Recommended Boost', 49.99, 7, 'Appear in the recommended workers list for 1 week'),
736 ('Top Listing', 99.99, 14, 'Feature your profile at the top of search results for 2 weeks'),
737 ('Premium Highlight', 149.99, 30, 'Highlight your profile for a month with special badge'),
738 ('Monthly Spotlight', 199.99, 30, 'Your profile will appear in monthly spotlight section');
739
740
741
742
743insert into Premium_Worker (start_date, end_date, plan_id, worker_id, payment_id)
744select
745 p.payment_date as start_date,
746 p.payment_date + interval '1 day' * pp.duration_days as end_date,
747 pp.plan_id,
748 wm.worker_id,
749 p.payment_id
750from Payment p join Worker_Method wm on wm.worker_method_id = p.worker_method_id
751 join Premium_Plan pp on pp.plan_id = p.plan_id
752 join Payment_Status ps on p.payment_status = ps.status_id
753where ps.status_name = 'Completed';
754
755
756
757
758
759
760
761
762