Changes between Version 1 and Version 2 of AdvancedApplicationDevelopment


Ignore:
Timestamp:
06/25/25 10:32:24 (3 days ago)
Author:
223270
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedApplicationDevelopment

    v1 v2  
    22Имплементирани се сите случаи на употреба дефинирани во фаза 3.
    33
     4=== Примери на индекси
     5Индексите се користат за да се забрза извршувањето на често користени SELECT, JOIN и WHERE. Со оглед на тоа што во Travel Sage често пребаруваме активности според датум и корисник, се додаваат индекси врз тие колони.
     6
     7* За побрзо пребарување на активности во одреден период
     8{{{
     9CREATE INDEX idx_aktivnost_datum ON aktivnosti(datum_od, datum_do);
     10}}}
     11
     12* За побрз join и филтрирање по корисник при резервации
     13{{{
     14CREATE INDEX idx_rezervacii_korisnik ON rezervacii(idkorisnik);
     15}}}
     16
     17* За побрзо пребарување на дестинации по име на локација
     18{{{
     19CREATE INDEX idx_destinacii_lokacija ON destinacii(imelokacija);
     20}}}
     21
     22
     23=== Примери за тригери
     24Тригерите се користат за автоматска реакција на промена во базата. Во TravelSage, тие се применети за: контрола на интегритет (нема дупли препораки) и автоматска реакција на негативна рецензија.
     25
     261. Спречување дупли препораки
     27{{{
     28CREATE OR REPLACE FUNCTION prevent_duplicate_recommendation()
     29RETURNS TRIGGER AS $$
     30BEGIN
     31   IF EXISTS (
     32       SELECT 1 FROM preporaki
     33       WHERE idkorisnik = NEW.idkorisnik AND iddestinacija = NEW.iddestinacija
     34   ) THEN
     35       RAISE EXCEPTION 'User already has this destination in recommendations!';
     36   END IF;
     37   RETURN NEW;
     38END;
     39$$ LANGUAGE plpgsql;
     40
     41CREATE TRIGGER trg_check_duplicate_recommendation
     42BEFORE INSERT ON preporaki
     43FOR EACH ROW EXECUTE FUNCTION prevent_duplicate_recommendation();
     44}}}
     45
     462. Деактивирање дестинација со негативни рецензии
     47{{{
     48CREATE OR REPLACE FUNCTION check_negative_review()
     49RETURNS TRIGGER AS $$
     50BEGIN
     51   IF NEW.ocenka < 3 THEN
     52       UPDATE destinacii
     53       SET aktivna = FALSE
     54       WHERE iddest = NEW.iddest;
     55   END IF;
     56   RETURN NEW;
     57END;
     58$$ LANGUAGE plpgsql;
     59
     60CREATE TRIGGER trg_negative_review
     61AFTER INSERT ON recenzii
     62FOR EACH ROW EXECUTE FUNCTION check_negative_review();
     63}}}
     64
     65
     66=== Примери за прегледи
     67View се користи за да се поедностават комплексни пребарувања.
     681. Во TravelSage, прикажани се активности што се „најдобра вредност за пари“, базирано на цена и просечна оцена од рецензии.
     69{{{
     70CREATE VIEW best_value_activities AS
     71SELECT
     72    a.idaktivnost,
     73    a.ime,
     74    a.iznos,
     75    d.imelokacija,
     76    AVG(r.ocenka) AS avg_rating
     77FROM aktivnosti a
     78JOIN destinacii d ON a.iddest = d.iddest
     79JOIN recenzii r ON a.idaktivnost = r.idaktivnost
     80GROUP BY a.idaktivnost, a.ime, a.iznos, d.imelokacija
     81HAVING AVG(r.ocenka) > 4 AND a.iznos < 1000;
     82}}}
     832. Активности со најниски цени
     84{{{
     85 DB::statement("
     86            CREATE VIEW view_procent_cheap_destinations AS
     87            SELECT
     88                d.imelokacija,
     89                COUNT(CASE WHEN a.iznos < 500 THEN 1 END) * 100.0 / COUNT(*) AS procent_cheap
     90            FROM travel_sage.destinacii d
     91            JOIN travel_sage.aktivnosti a ON d.iddest = a.iddest
     92            GROUP BY d.iddest, d.imelokacija
     93            ORDER BY procent_cheap DESC
     94        ");
     95}}}
     96
     97
     98=== Трансакции
     991. Пример при резервација на активност
     100{{{
     101DB::transaction(function () use ($request) {
     102    DB::table('rezervacii')->insert([
     103        'idkorisnik' => auth()->id(),
     104        'idaktivnost' => $request->aktivnost_id,
     105        'datum' => now()
     106    ]);
     107
     108    DB::table('aktivnosti')
     109        ->where('idaktivnost', $request->aktivnost_id)
     110        ->decrement('kvota', 1);
     111});
     112}}}
     113Ако не успее било кој дел (резервација или ажурирање на квота), не се зачувува ништо – атомичност.
     114
     1152.
     116{{{
     117DB::transaction(function () use ($request) {
     118            $validatedData = $request->validate([
     119                'imepaket' => 'required|string|max:255',
     120                'cena' => 'required|numeric',
     121                'pochetok' => 'required|date_format:Y-m-d\TH:i',
     122                'kraj' => 'required|date_format:Y-m-d\TH:i|after_or_equal:pochetok',
     123            ]);
     124
     125            TravelPackage::create($validatedData);
     126        });
     127}}}
     128
     129
     1303.
     131{{{
     132DB::transaction(function () use ($request) {
     133            $validatedData = $request->validate([
     134                'naziv' => 'required|string|max:255',
     135                'vidovi' => 'required|string|max:255',
     136                'detali' => 'nullable|string',
     137                'pochetendatum' => 'required|date',
     138                'kraendatum' => 'required|date',
     139            ]);
     140
     141            TravelEvent::create($validatedData);
     142        });
     143}}}
     144
     145
     1464.
     147{{{
     148DB::transaction(function () use ($request) {
     149            $validatedData = $request->validate([
     150                'imeaktivnost' => 'required|string|max:255',
     151                'informacii' => 'nullable|string|max:255',
     152                'kategorija' => 'required|string|max:255',
     153                'iznos' => 'nullable|numeric',
     154            ]);
     155
     156            TravelActivity::create($validatedData);
     157        });
     158}}}
     159
     160=== Складирани функции и процедури
     1611. Просечна оцена за локација (функција)
     162{{{
     163CREATE OR REPLACE FUNCTION avg_rating_for_location(dest_id INT)
     164RETURNS FLOAT AS $$
     165DECLARE
     166    result FLOAT;
     167BEGIN
     168    SELECT AVG(ocenka)
     169    INTO result
     170    FROM recenzii
     171    WHERE iddest = dest_id;
     172    RETURN result;
     173END;
     174$$ LANGUAGE plpgsql;
     175}}}
     176
     1772. Додади препорака (процедура)
     178{{{
     179CREATE OR REPLACE PROCEDURE dodadi_preporaka(p_korisnik INT, p_dest INT)
     180LANGUAGE plpgsql
     181AS $$
     182BEGIN
     183    INSERT INTO preporaki(idkorisnik, iddestinacija, datum)
     184    VALUES (p_korisnik, p_dest, NOW());
     185END;
     186$$;
     187}}}
     188Овие складирани елементи се користат за централизирана логика и можат да се повикаат од Laravel или други процедури.
     189