Browse Source

Merge branch homework/3

Vsevolod Levitan 1 month ago
parent
commit
fb6ceaeef6
4 changed files with 96 additions and 0 deletions
  1. 0 0
      homework/0.sql
  2. 5 0
      homework/3.class.sql
  3. 35 0
      homework/3.data.sql
  4. 56 0
      homework/3.sql

+ 0 - 0
homework/init.sql → homework/0.sql


+ 5 - 0
homework/3.class.sql

@@ -1,3 +1,5 @@
+create table if not exists numeric_constants(key varchar primary key, value numeric);
+
 -- Функция формата даты
 create or replace function approx_report_date(t_date timestamptz)
 	returns varchar(5)
@@ -60,3 +62,6 @@ begin
 	return (approx_report_date(date)::varchar(5), approx_report_height(height)::varchar(4), approx_report_deviation(pressure, temperature)::varchar(5)) as approx_report;
 end;
 $$;
+
+insert into numeric_constants(key, value) values ('rel_pressure', 750);
+insert into numeric_constants(key, value) values ('rel_temperature', 15.9);

+ 35 - 0
homework/3.data.sql

@@ -0,0 +1,35 @@
+DO $$
+DECLARE
+    user_count INT := 5; -- Количество пользователей
+    measurements_per_user INT := 100; -- Количество измерений на пользователя
+    user_id INT;
+    batch_id INT;
+BEGIN
+    -- Добавление пользователей
+    FOR i IN 1..user_count LOOP
+        INSERT INTO users (name, rank_id) VALUES ('User' || i, i);
+        user_id := currval(pg_get_serial_sequence('users', 'id'));
+
+        -- Добавление пакетов измерений для каждого пользователя
+        FOR j IN 1..(measurements_per_user / 10) LOOP
+            INSERT INTO measurement_batch (start_period, user_id, pos_x, pos_y)
+            VALUES (NOW() - (j || ' days')::interval, user_id, random() * 100, random() * 100);
+            batch_id := currval(pg_get_serial_sequence('measurement_batch', 'id'));
+
+            -- Добавление измерений в пакет
+            FOR k IN 1..10 LOOP
+                INSERT INTO measurement_params (measurement_type_id, measurement_batch_id, height, temperature, pressure, wind_speed, wind_direction, bullet_speed)
+                VALUES (
+                    1, -- Тип измерения
+                    batch_id,
+                    random() * 1000, -- Высота
+                    (random() * 116 - 58)::NUMERIC, -- Температура (-58..58)
+                    (random() * 400 + 500)::NUMERIC, -- Давление (500..900)
+                    random() * 20, -- Скорость ветра
+                    (random() * 60)::INT, -- Направление ветра (0..59)
+                    random() * 1000 -- Скорость пули
+                );
+            END LOOP;
+        END LOOP;
+    END LOOP;
+END $$;

+ 56 - 0
homework/3.sql

@@ -0,0 +1,56 @@
+CREATE TABLE IF NOT EXISTS measure_settings (
+    id SERIAL PRIMARY KEY,
+    parameter_name VARCHAR(50) NOT NULL UNIQUE,
+    min_value NUMERIC NOT NULL,
+    max_value NUMERIC NOT NULL,
+    unit VARCHAR(20)
+);
+
+INSERT INTO measure_settings (parameter_name, min_value, max_value, unit)
+VALUES 
+('temperature', -58, 58, '°C'),
+('pressure', 500, 900, 'mmHg'),
+('wind_direction', 0, 59, 'degrees');
+
+CREATE TYPE measurement_data AS (
+    temperature NUMERIC,
+    pressure NUMERIC,
+    wind_direction NUMERIC
+);
+
+CREATE OR REPLACE FUNCTION validate_measurement(
+    input_temperature NUMERIC,
+    input_pressure NUMERIC,
+    input_wind_direction NUMERIC
+) RETURNS measurement_data AS $$
+DECLARE
+    validated_data measurement_data;
+BEGIN
+    IF input_temperature < (SELECT min_value FROM measure_settings WHERE parameter_name = 'temperature') OR
+       input_temperature > (SELECT max_value FROM measure_settings WHERE parameter_name = 'temperature') THEN
+        RAISE EXCEPTION 'Temperature out of range. Allowed range: % to % °C',
+            (SELECT min_value FROM measure_settings WHERE parameter_name = 'temperature'),
+            (SELECT max_value FROM measure_settings WHERE parameter_name = 'temperature');
+    END IF;
+
+    IF input_pressure < (SELECT min_value FROM measure_settings WHERE parameter_name = 'pressure') OR
+       input_pressure > (SELECT max_value FROM measure_settings WHERE parameter_name = 'pressure') THEN
+        RAISE EXCEPTION 'Pressure out of range. Allowed range: % to % mmHg',
+            (SELECT min_value FROM measure_settings WHERE parameter_name = 'pressure'),
+            (SELECT max_value FROM measure_settings WHERE parameter_name = 'pressure');
+    END IF;
+
+    IF input_wind_direction < (SELECT min_value FROM measure_settings WHERE parameter_name = 'wind_direction') OR
+       input_wind_direction > (SELECT max_value FROM measure_settings WHERE parameter_name = 'wind_direction') THEN
+        RAISE EXCEPTION 'Wind direction out of range. Allowed range: % to % degrees',
+            (SELECT min_value FROM measure_settings WHERE parameter_name = 'wind_direction'),
+            (SELECT max_value FROM measure_settings WHERE parameter_name = 'wind_direction');
+    END IF;
+
+    validated_data.temperature := input_temperature;
+    validated_data.pressure := input_pressure;
+    validated_data.wind_direction := input_wind_direction;
+
+    RETURN validated_data;
+END;
+$$ LANGUAGE plpgsql;