Replace type TIMESTAMP WITHOUT TIME ZONE by TIMESTAMPZ with timezone forcing UTC as per best practice.

This commit is contained in:
xbgmsharp
2023-11-19 21:10:28 +01:00
parent 472131efbd
commit fddd3df05e
8 changed files with 70 additions and 69 deletions

View File

@@ -20,10 +20,10 @@ CREATE TABLE IF NOT EXISTS api.metadata(
ship_type NUMERIC NULL, ship_type NUMERIC NULL,
plugin_version TEXT NOT NULL, plugin_version TEXT NOT NULL,
signalk_version TEXT NOT NULL, signalk_version TEXT NOT NULL,
time TIMESTAMP WITHOUT TIME ZONE NOT NULL, -- should be rename to last_update !? time TIMESTAMPTZ NOT NULL, -- should be rename to last_update !?
active BOOLEAN DEFAULT True, -- trigger monitor online/offline active BOOLEAN DEFAULT True, -- trigger monitor online/offline
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW() updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
-- Description -- Description
COMMENT ON TABLE COMMENT ON TABLE
@@ -42,7 +42,7 @@ CREATE INDEX metadata_name_idx ON api.metadata (name);
CREATE TYPE status AS ENUM ('sailing', 'motoring', 'moored', 'anchored'); CREATE TYPE status AS ENUM ('sailing', 'motoring', 'moored', 'anchored');
-- Table api.metrics -- Table api.metrics
CREATE TABLE IF NOT EXISTS api.metrics ( CREATE TABLE IF NOT EXISTS api.metrics (
time TIMESTAMP WITHOUT TIME ZONE NOT NULL, time TIMESTAMPTZ NOT NULL,
client_id TEXT NULL, client_id TEXT NULL,
vessel_id TEXT NOT NULL REFERENCES api.metadata(vessel_id) ON DELETE RESTRICT, vessel_id TEXT NOT NULL REFERENCES api.metadata(vessel_id) ON DELETE RESTRICT,
latitude DOUBLE PRECISION NULL, latitude DOUBLE PRECISION NULL,
@@ -111,8 +111,8 @@ CREATE TABLE IF NOT EXISTS api.logbook(
track_geom geometry(LINESTRING,4326) NULL, track_geom geometry(LINESTRING,4326) NULL,
track_geog geography(LINESTRING) NULL, track_geog geography(LINESTRING) NULL,
track_geojson JSONB NULL, track_geojson JSONB NULL,
_from_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, _from_time TIMESTAMPTZ NOT NULL,
_to_time TIMESTAMP WITHOUT TIME ZONE NULL, _to_time TIMESTAMPTZ NULL,
distance NUMERIC, -- meters? distance NUMERIC, -- meters?
duration INTERVAL, -- duration in days and hours? duration INTERVAL, -- duration in days and hours?
avg_speed DOUBLE PRECISION NULL, avg_speed DOUBLE PRECISION NULL,
@@ -151,8 +151,8 @@ CREATE TABLE IF NOT EXISTS api.stays(
latitude DOUBLE PRECISION NULL, latitude DOUBLE PRECISION NULL,
longitude DOUBLE PRECISION NULL, longitude DOUBLE PRECISION NULL,
geog GEOGRAPHY(POINT) NULL, geog GEOGRAPHY(POINT) NULL,
arrived TIMESTAMP WITHOUT TIME ZONE NOT NULL, arrived TIMESTAMPTZ NOT NULL,
departed TIMESTAMP WITHOUT TIME ZONE, departed TIMESTAMPTZ,
duration INTERVAL, -- duration in days and hours? duration INTERVAL, -- duration in days and hours?
stay_code INT DEFAULT 1, -- REFERENCES api.stays_at(stay_code), stay_code INT DEFAULT 1, -- REFERENCES api.stays_at(stay_code),
notes TEXT NULL notes TEXT NULL

View File

@@ -41,8 +41,8 @@ CREATE OR REPLACE FUNCTION api.timelapse_fn(
WITH logbook as ( WITH logbook as (
SELECT track_geom SELECT track_geom
FROM api.logbook FROM api.logbook
WHERE _from_time >= start_log::TIMESTAMP WITHOUT TIME ZONE WHERE _from_time >= start_log::TIMESTAMPTZ
AND _to_time <= end_date::TIMESTAMP WITHOUT TIME ZONE + interval '23 hours 59 minutes' AND _to_time <= end_date::TIMESTAMPTZ + interval '23 hours 59 minutes'
AND track_geom IS NOT NULL AND track_geom IS NOT NULL
ORDER BY _from_time ASC ORDER BY _from_time ASC
) )
@@ -554,6 +554,7 @@ COMMENT ON FUNCTION
DROP FUNCTION IF EXISTS api.export_moorages_gpx_fn; DROP FUNCTION IF EXISTS api.export_moorages_gpx_fn;
CREATE FUNCTION api.export_moorages_gpx_fn() RETURNS pg_catalog.xml AS $export_moorages_gpx$ CREATE FUNCTION api.export_moorages_gpx_fn() RETURNS pg_catalog.xml AS $export_moorages_gpx$
DECLARE DECLARE
app_settings jsonb;
BEGIN BEGIN
-- Gather url from app settings -- Gather url from app settings
app_settings := get_app_url_fn(); app_settings := get_app_url_fn();
@@ -605,13 +606,13 @@ CREATE OR REPLACE FUNCTION api.stats_logs_fn(
IN end_date TEXT DEFAULT NULL, IN end_date TEXT DEFAULT NULL,
OUT stats JSON) RETURNS JSON AS $stats_logs$ OUT stats JSON) RETURNS JSON AS $stats_logs$
DECLARE DECLARE
_start_date TIMESTAMP WITHOUT TIME ZONE DEFAULT '1970-01-01'; _start_date TIMESTAMPTZ DEFAULT '1970-01-01';
_end_date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(); _end_date TIMESTAMPTZ DEFAULT NOW();
BEGIN BEGIN
IF start_date IS NOT NULL AND public.isdate(start_date::text) AND public.isdate(end_date::text) THEN IF start_date IS NOT NULL AND public.isdate(start_date::text) AND public.isdate(end_date::text) THEN
RAISE WARNING '--> stats_fn, filter result stats by date [%]', start_date; RAISE WARNING '--> stats_fn, filter result stats by date [%]', start_date;
_start_date := start_date::TIMESTAMP WITHOUT TIME ZONE; _start_date := start_date::TIMESTAMPTZ;
_end_date := end_date::TIMESTAMP WITHOUT TIME ZONE; _end_date := end_date::TIMESTAMPTZ;
END IF; END IF;
RAISE NOTICE '--> stats_fn, _start_date [%], _end_date [%]', _start_date, _end_date; RAISE NOTICE '--> stats_fn, _start_date [%], _end_date [%]', _start_date, _end_date;
WITH WITH
@@ -620,8 +621,8 @@ CREATE OR REPLACE FUNCTION api.stats_logs_fn(
logs_view AS ( logs_view AS (
SELECT * SELECT *
FROM api.logbook l FROM api.logbook l
WHERE _from_time >= _start_date::TIMESTAMP WITHOUT TIME ZONE WHERE _from_time >= _start_date::TIMESTAMPTZ
AND _to_time <= _end_date::TIMESTAMP WITHOUT TIME ZONE + interval '23 hours 59 minutes' AND _to_time <= _end_date::TIMESTAMPTZ + interval '23 hours 59 minutes'
), ),
first_date AS ( first_date AS (
SELECT _from_time as first_date from logs_view ORDER BY first_date ASC LIMIT 1 SELECT _from_time as first_date from logs_view ORDER BY first_date ASC LIMIT 1
@@ -673,21 +674,21 @@ CREATE OR REPLACE FUNCTION api.stats_stays_fn(
IN end_date TEXT DEFAULT NULL, IN end_date TEXT DEFAULT NULL,
OUT stats JSON) RETURNS JSON AS $stats_stays$ OUT stats JSON) RETURNS JSON AS $stats_stays$
DECLARE DECLARE
_start_date TIMESTAMP WITHOUT TIME ZONE DEFAULT '1970-01-01'; _start_date TIMESTAMPTZ DEFAULT '1970-01-01';
_end_date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(); _end_date TIMESTAMPTZ DEFAULT NOW();
BEGIN BEGIN
IF start_date IS NOT NULL AND public.isdate(start_date::text) AND public.isdate(end_date::text) THEN IF start_date IS NOT NULL AND public.isdate(start_date::text) AND public.isdate(end_date::text) THEN
RAISE NOTICE '--> stats_stays_fn, custom filter result stats by date [%]', start_date; RAISE NOTICE '--> stats_stays_fn, custom filter result stats by date [%]', start_date;
_start_date := start_date::TIMESTAMP WITHOUT TIME ZONE; _start_date := start_date::TIMESTAMPTZ;
_end_date := end_date::TIMESTAMP WITHOUT TIME ZONE; _end_date := end_date::TIMESTAMPTZ;
END IF; END IF;
RAISE NOTICE '--> stats_stays_fn, _start_date [%], _end_date [%]', _start_date, _end_date; RAISE NOTICE '--> stats_stays_fn, _start_date [%], _end_date [%]', _start_date, _end_date;
WITH WITH
moorages_log AS ( moorages_log AS (
SELECT s.id as stays_id, m.id as moorages_id, * SELECT s.id as stays_id, m.id as moorages_id, *
FROM api.stays s, api.moorages m FROM api.stays s, api.moorages m
WHERE arrived >= _start_date::TIMESTAMP WITHOUT TIME ZONE WHERE arrived >= _start_date::TIMESTAMPTZ
AND departed <= _end_date::TIMESTAMP WITHOUT TIME ZONE + interval '23 hours 59 minutes' AND departed <= _end_date::TIMESTAMPTZ + interval '23 hours 59 minutes'
AND s.id = m.stay_id AND s.id = m.stay_id
), ),
home_ports AS ( home_ports AS (
@@ -766,7 +767,7 @@ CREATE OR REPLACE FUNCTION api.delete_logbook_fn(IN _id integer) RETURNS BOOLEAN
-- Update previous stays with the departed time from current stays -- Update previous stays with the departed time from current stays
-- and set the active state from current stays -- and set the active state from current stays
UPDATE api.stays UPDATE api.stays
SET departed = current_stays_departed::timestamp without time zone, SET departed = current_stays_departed::TIMESTAMPTZ,
active = current_stays_active active = current_stays_active
WHERE vessel_id = current_setting('vessel.id', false) WHERE vessel_id = current_setting('vessel.id', false)
AND id = previous_stays_id; AND id = previous_stays_id;

View File

@@ -90,7 +90,7 @@ INSERT INTO public.email_templates VALUES
E'Congratulations!\nYou have just connect your account to Pushover.\n'), E'Congratulations!\nYou have just connect your account to Pushover.\n'),
('email_otp', ('email_otp',
'Email verification', 'Email verification',
E'Hello,\nPlease active your account using the following code: __OTP_CODE__.\nThe code is valid 15 minutes.\nSee more details at __APP_URL__/activate\nThe PostgSail Team', E'Hello,\nPlease active your account using the following code: __OTP_CODE__.\nThe code is valid 15 minutes.\nThe PostgSail Team',
'Email verification', 'Email verification',
E'Congratulations!\nPlease validate your account. Check your email!'), E'Congratulations!\nPlease validate your account. Check your email!'),
('email_valid', ('email_valid',
@@ -154,8 +154,8 @@ CREATE TABLE IF NOT EXISTS public.process_queue (
channel TEXT NOT NULL, channel TEXT NOT NULL,
payload TEXT NOT NULL, payload TEXT NOT NULL,
ref_id TEXT NOT NULL, ref_id TEXT NOT NULL,
stored TIMESTAMP WITHOUT TIME ZONE NOT NULL, stored TIMESTAMPTZ NOT NULL,
processed TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL processed TIMESTAMPTZ DEFAULT NULL
); );
-- Description -- Description
COMMENT ON TABLE COMMENT ON TABLE

View File

@@ -27,8 +27,8 @@ CREATE OR REPLACE FUNCTION public.logbook_metrics_dwithin_fn(
WHERE WHERE
m.latitude IS NOT NULL m.latitude IS NOT NULL
AND m.longitude IS NOT NULL AND m.longitude IS NOT NULL
AND m.time >= _start::TIMESTAMP WITHOUT TIME ZONE AND m.time >= _start::TIMESTAMPTZ
AND m.time <= _end::TIMESTAMP WITHOUT TIME ZONE AND m.time <= _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
AND ST_DWithin( AND ST_DWithin(
Geography(ST_MakePoint(m.longitude, m.latitude)), Geography(ST_MakePoint(m.longitude, m.latitude)),
@@ -60,8 +60,8 @@ CREATE OR REPLACE FUNCTION public.logbook_update_avg_fn(
FROM api.metrics m FROM api.metrics m
WHERE m.latitude IS NOT NULL WHERE m.latitude IS NOT NULL
AND m.longitude IS NOT NULL AND m.longitude IS NOT NULL
AND m.time >= _start::TIMESTAMP WITHOUT TIME ZONE AND m.time >= _start::TIMESTAMPTZ
AND m.time <= _end::TIMESTAMP WITHOUT TIME ZONE AND m.time <= _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false); AND vessel_id = current_setting('vessel.id', false);
RAISE NOTICE '-> logbook_update_avg_fn avg for logbook id=%, avg_speed:%, max_speed:%, max_wind_speed:%, count:%', _id, avg_speed, max_speed, max_wind_speed, count_metric; RAISE NOTICE '-> logbook_update_avg_fn avg for logbook id=%, avg_speed:%, max_speed:%, max_wind_speed:%, count:%', _id, avg_speed, max_speed, max_wind_speed, count_metric;
END; END;
@@ -87,8 +87,8 @@ CREATE FUNCTION public.logbook_update_geom_distance_fn(IN _id integer, IN _start
FROM api.metrics m FROM api.metrics m
WHERE m.latitude IS NOT NULL WHERE m.latitude IS NOT NULL
AND m.longitude IS NOT NULL AND m.longitude IS NOT NULL
AND m.time >= _start::TIMESTAMP WITHOUT TIME ZONE AND m.time >= _start::TIMESTAMPTZ
AND m.time <= _end::TIMESTAMP WITHOUT TIME ZONE AND m.time <= _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
ORDER BY m.time ASC ORDER BY m.time ASC
) )
@@ -151,8 +151,8 @@ CREATE FUNCTION public.logbook_update_geojson_fn(IN _id integer, IN _start text,
FROM api.metrics m FROM api.metrics m
WHERE m.latitude IS NOT NULL WHERE m.latitude IS NOT NULL
AND m.longitude IS NOT NULL AND m.longitude IS NOT NULL
AND time >= _start::TIMESTAMP WITHOUT TIME ZONE AND time >= _start::TIMESTAMPTZ
AND time <= _end::TIMESTAMP WITHOUT TIME ZONE AND time <= _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
ORDER BY m.time ASC ORDER BY m.time ASC
) )
@@ -231,8 +231,8 @@ AS $logbook_update_gpx$
FROM api.metrics m FROM api.metrics m
WHERE m.latitude IS NOT NULL WHERE m.latitude IS NOT NULL
AND m.longitude IS NOT NULL AND m.longitude IS NOT NULL
AND m.time >= log_rec._from_time::TIMESTAMP WITHOUT TIME ZONE AND m.time >= log_rec._from_time::TIMESTAMPTZ
AND m.time <= log_rec._to_time::TIMESTAMP WITHOUT TIME ZONE AND m.time <= log_rec._to_time::TIMESTAMPTZ
AND vessel_id = log_rec.vessel_id AND vessel_id = log_rec.vessel_id
GROUP BY m.time GROUP BY m.time
ORDER BY m.time ASC; ORDER BY m.time ASC;
@@ -256,7 +256,7 @@ AS $logbook_get_extra_json$
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE search WHERE key ILIKE search
AND time = _start::timestamp without time zone AND time = _start::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
LOOP LOOP
-- Engine Hours in seconds -- Engine Hours in seconds
@@ -268,7 +268,7 @@ AS $logbook_get_extra_json$
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE metric_rec.key WHERE key ILIKE metric_rec.key
AND time = _end::timestamp without time zone AND time = _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
), ),
metric AS ( metric AS (
@@ -304,7 +304,7 @@ CREATE FUNCTION logbook_update_extra_json_fn(IN _id integer, IN _start text, IN
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE 'navigation.log' WHERE key ILIKE 'navigation.log'
AND time = _start::timestamp without time zone AND time = _start::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
), ),
end_trip as ( end_trip as (
@@ -313,7 +313,7 @@ CREATE FUNCTION logbook_update_extra_json_fn(IN _id integer, IN _start text, IN
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE 'navigation.log' WHERE key ILIKE 'navigation.log'
AND time = _end::timestamp without time zone AND time = _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
), ),
nm as ( nm as (
@@ -330,7 +330,7 @@ CREATE FUNCTION logbook_update_extra_json_fn(IN _id integer, IN _start text, IN
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE 'propulsion.%.runTime' WHERE key ILIKE 'propulsion.%.runTime'
AND time = _start::timestamp without time zone AND time = _start::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
LOOP LOOP
-- Engine Hours in seconds -- Engine Hours in seconds
@@ -342,7 +342,7 @@ CREATE FUNCTION logbook_update_extra_json_fn(IN _id integer, IN _start text, IN
FROM api.metrics m, FROM api.metrics m,
jsonb_each_text(m.metrics) jsonb_each_text(m.metrics)
WHERE key ILIKE metric_rec.key WHERE key ILIKE metric_rec.key
AND time = _end::timestamp without time zone AND time = _end::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false) AND vessel_id = current_setting('vessel.id', false)
), ),
runtime AS ( runtime AS (
@@ -425,11 +425,11 @@ CREATE OR REPLACE FUNCTION process_logbook_queue_fn(IN _id integer) RETURNS void
-- Avoid/ignore/delete logbook stationary movement or time sync issue -- Avoid/ignore/delete logbook stationary movement or time sync issue
-- Check time start vs end -- Check time start vs end
SELECT logbook_rec._to_time::timestamp without time zone < logbook_rec._from_time::timestamp without time zone INTO _invalid_time; SELECT logbook_rec._to_time::TIMESTAMPTZ < logbook_rec._from_time::TIMESTAMPTZ INTO _invalid_time;
-- Is distance is less than 0.010 -- Is distance is less than 0.010
SELECT geo_rec._track_distance < 0.010 INTO _invalid_distance; SELECT geo_rec._track_distance < 0.010 INTO _invalid_distance;
-- Is duration is less than 100sec -- Is duration is less than 100sec
SELECT (logbook_rec._to_time::timestamp without time zone - logbook_rec._from_time::timestamp without time zone) < (100::text||' secs')::interval INTO _invalid_interval; SELECT (logbook_rec._to_time::TIMESTAMPTZ - logbook_rec._from_time::TIMESTAMPTZ) < (100::text||' secs')::interval INTO _invalid_interval;
-- if stationary fix data metrics,logbook,stays,moorage -- if stationary fix data metrics,logbook,stays,moorage
IF _invalid_time IS True OR _invalid_distance IS True IF _invalid_time IS True OR _invalid_distance IS True
OR _invalid_interval IS True OR count_metric = avg_rec.count_metric THEN OR _invalid_interval IS True OR count_metric = avg_rec.count_metric THEN
@@ -438,8 +438,8 @@ CREATE OR REPLACE FUNCTION process_logbook_queue_fn(IN _id integer) RETURNS void
-- Update metrics status to moored -- Update metrics status to moored
UPDATE api.metrics UPDATE api.metrics
SET status = 'moored' SET status = 'moored'
WHERE time >= logbook_rec._from_time::TIMESTAMP WITHOUT TIME ZONE WHERE time >= logbook_rec._from_time::TIMESTAMPTZ
AND time <= logbook_rec._to_time::TIMESTAMP WITHOUT TIME ZONE AND time <= logbook_rec._to_time::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false); AND vessel_id = current_setting('vessel.id', false);
-- Update logbook -- Update logbook
UPDATE api.logbook UPDATE api.logbook
@@ -464,7 +464,7 @@ CREATE OR REPLACE FUNCTION process_logbook_queue_fn(IN _id integer) RETURNS void
-- Update previous stays with the departed time from current stays -- Update previous stays with the departed time from current stays
-- and set the active state from current stays -- and set the active state from current stays
UPDATE api.stays UPDATE api.stays
SET departed = current_stays_departed::timestamp without time zone, SET departed = current_stays_departed::TIMESTAMPTZ,
active = current_stays_active active = current_stays_active
WHERE vessel_id = current_setting('vessel.id', false) WHERE vessel_id = current_setting('vessel.id', false)
AND id = previous_stays_id; AND id = previous_stays_id;
@@ -498,7 +498,7 @@ CREATE OR REPLACE FUNCTION process_logbook_queue_fn(IN _id integer) RETURNS void
RAISE NOTICE 'Updating valid logbook entry [%] [%] [%]', logbook_rec.id, logbook_rec._from_time, logbook_rec._to_time; RAISE NOTICE 'Updating valid logbook entry [%] [%] [%]', logbook_rec.id, logbook_rec._from_time, logbook_rec._to_time;
UPDATE api.logbook UPDATE api.logbook
SET SET
duration = (logbook_rec._to_time::timestamp without time zone - logbook_rec._from_time::timestamp without time zone), duration = (logbook_rec._to_time::TIMESTAMPTZ - logbook_rec._from_time::TIMESTAMPTZ),
avg_speed = avg_rec.avg_speed, avg_speed = avg_rec.avg_speed,
max_speed = avg_rec.max_speed, max_speed = avg_rec.max_speed,
max_wind_speed = avg_rec.max_wind_speed, max_wind_speed = avg_rec.max_wind_speed,
@@ -576,7 +576,7 @@ CREATE OR REPLACE FUNCTION process_stay_queue_fn(IN _id integer) RETURNS void AS
UPDATE api.stays UPDATE api.stays
SET SET
name = concat( name = concat(
ROUND( EXTRACT(epoch from (stay_rec.departed::timestamp without time zone - stay_rec.arrived::timestamp without time zone)::INTERVAL / 86400) ), ROUND( EXTRACT(epoch from (stay_rec.departed::TIMESTAMPTZ - stay_rec.arrived::TIMESTAMPTZ)::INTERVAL / 86400) ),
' days stay at ', ' days stay at ',
moorage.moorage_name, moorage.moorage_name,
' in ', ' in ',
@@ -585,7 +585,7 @@ CREATE OR REPLACE FUNCTION process_stay_queue_fn(IN _id integer) RETURNS void AS
TO_CHAR(stay_rec.departed, 'YYYY') TO_CHAR(stay_rec.departed, 'YYYY')
), ),
moorage_id = moorage.moorage_id, moorage_id = moorage.moorage_id,
duration = (stay_rec.departed::timestamp without time zone - stay_rec.arrived::timestamp without time zone)::INTERVAL, duration = (stay_rec.departed::TIMESTAMPTZ - stay_rec.arrived::TIMESTAMPTZ)::INTERVAL,
stay_code = moorage.moorage_type, stay_code = moorage.moorage_type,
geog = Geography(ST_MakePoint(stay_rec.longitude, stay_rec.latitude)) geog = Geography(ST_MakePoint(stay_rec.longitude, stay_rec.latitude))
WHERE id = stay_rec.id; WHERE id = stay_rec.id;
@@ -677,7 +677,7 @@ CREATE OR REPLACE FUNCTION process_moorage_queue_fn(IN _id integer) RETURNS void
reference_count = moorage_rec.reference_count + 1, reference_count = moorage_rec.reference_count + 1,
stay_duration = stay_duration =
moorage_rec.stay_duration + moorage_rec.stay_duration +
(stay_rec.departed::timestamp without time zone - stay_rec.arrived::timestamp without time zone) (stay_rec.departed::TIMESTAMPTZ - stay_rec.arrived::TIMESTAMPTZ)
WHERE id = moorage_rec.id; WHERE id = moorage_rec.id;
ELSE ELSE
RAISE NOTICE 'Insert new moorage entry from stay %', stay_rec; RAISE NOTICE 'Insert new moorage entry from stay %', stay_rec;
@@ -696,7 +696,7 @@ CREATE OR REPLACE FUNCTION process_moorage_queue_fn(IN _id integer) RETURNS void
coalesce(moorage_rec.country, null), coalesce(moorage_rec.country, null),
stay_rec.id, stay_rec.id,
stay_rec.stay_code, stay_rec.stay_code,
(stay_rec.departed::timestamp without time zone - stay_rec.arrived::timestamp without time zone), (stay_rec.departed::TIMESTAMPTZ - stay_rec.arrived::TIMESTAMPTZ),
1, -- default reference_count 1, -- default reference_count
stay_rec.latitude, stay_rec.latitude,
stay_rec.longitude, stay_rec.longitude,
@@ -1381,11 +1381,11 @@ CREATE OR REPLACE FUNCTION public.process_logbook_valid_fn(IN _id integer) RETUR
-- Avoid/ignore/delete logbook stationary movement or time sync issue -- Avoid/ignore/delete logbook stationary movement or time sync issue
-- Check time start vs end -- Check time start vs end
SELECT logbook_rec._to_time::timestamp without time zone < logbook_rec._from_time::timestamp without time zone INTO _invalid_time; SELECT logbook_rec._to_time::TIMESTAMPTZ < logbook_rec._from_time::TIMESTAMPTZ INTO _invalid_time;
-- Is distance is less than 0.010 -- Is distance is less than 0.010
SELECT geo_rec._track_distance < 0.010 INTO _invalid_distance; SELECT geo_rec._track_distance < 0.010 INTO _invalid_distance;
-- Is duration is less than 100sec -- Is duration is less than 100sec
SELECT (logbook_rec._to_time::timestamp without time zone - logbook_rec._from_time::timestamp without time zone) < (100::text||' secs')::interval INTO _invalid_interval; SELECT (logbook_rec._to_time::TIMESTAMPTZ - logbook_rec._from_time::TIMESTAMPTZ) < (100::text||' secs')::interval INTO _invalid_interval;
-- if stationary fix data metrics,logbook,stays,moorage -- if stationary fix data metrics,logbook,stays,moorage
IF _invalid_time IS True OR _invalid_distance IS True IF _invalid_time IS True OR _invalid_distance IS True
OR _invalid_interval IS True OR count_metric = avg_rec.count_metric THEN OR _invalid_interval IS True OR count_metric = avg_rec.count_metric THEN
@@ -1394,8 +1394,8 @@ CREATE OR REPLACE FUNCTION public.process_logbook_valid_fn(IN _id integer) RETUR
-- Update metrics status to moored -- Update metrics status to moored
UPDATE api.metrics UPDATE api.metrics
SET status = 'moored' SET status = 'moored'
WHERE time >= logbook_rec._from_time::TIMESTAMP WITHOUT TIME ZONE WHERE time >= logbook_rec._from_time::TIMESTAMPTZ
AND time <= logbook_rec._to_time::TIMESTAMP WITHOUT TIME ZONE AND time <= logbook_rec._to_time::TIMESTAMPTZ
AND vessel_id = current_setting('vessel.id', false); AND vessel_id = current_setting('vessel.id', false);
-- Update logbook -- Update logbook
UPDATE api.logbook UPDATE api.logbook
@@ -1421,7 +1421,7 @@ CREATE OR REPLACE FUNCTION public.process_logbook_valid_fn(IN _id integer) RETUR
-- Update previous stays with the departed time from current stays -- Update previous stays with the departed time from current stays
-- and set the active state from current stays -- and set the active state from current stays
UPDATE api.stays UPDATE api.stays
SET departed = current_stays_departed::timestamp without time zone, SET departed = current_stays_departed::TIMESTAMPTZ,
active = current_stays_active active = current_stays_active
WHERE vessel_id = current_setting('vessel.id', false) WHERE vessel_id = current_setting('vessel.id', false)
AND id = previous_stays_id; AND id = previous_stays_id;

View File

@@ -79,9 +79,9 @@ COMMENT ON FUNCTION
CREATE OR REPLACE FUNCTION public.istimestamptz(text) RETURNS BOOLEAN AS CREATE OR REPLACE FUNCTION public.istimestamptz(text) RETURNS BOOLEAN AS
$isdate$ $isdate$
DECLARE x TIMESTAMP WITHOUT TIME ZONE; DECLARE x TIMESTAMPTZ;
BEGIN BEGIN
x = $1::TIMESTAMP WITHOUT TIME ZONE; x = $1::TIMESTAMPTZ;
RETURN TRUE; RETURN TRUE;
EXCEPTION WHEN others THEN EXCEPTION WHEN others THEN
RETURN FALSE; RETURN FALSE;
@@ -92,7 +92,7 @@ LANGUAGE plpgsql IMMUTABLE;
-- Description -- Description
COMMENT ON FUNCTION COMMENT ON FUNCTION
public.istimestamptz public.istimestamptz
IS 'Check typeof value is TIMESTAMP WITHOUT TIME ZONE'; IS 'Check typeof value is TIMESTAMPTZ';
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- JSON helpers -- JSON helpers

View File

@@ -28,9 +28,9 @@ CREATE TABLE IF NOT EXISTS auth.accounts (
pass TEXT NOT NULL CHECK (length(pass) < 512), pass TEXT NOT NULL CHECK (length(pass) < 512),
role name NOT NULL CHECK (length(role) < 512), role name NOT NULL CHECK (length(role) < 512),
preferences JSONB NULL DEFAULT '{"email_notifications":true}', preferences JSONB NULL DEFAULT '{"email_notifications":true}',
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
connected_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), connected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT valid_email CHECK (length(email) > 5), -- Enforce at least 5 char, eg: a@b.io CONSTRAINT valid_email CHECK (length(email) > 5), -- Enforce at least 5 char, eg: a@b.io
CONSTRAINT valid_first CHECK (length(first) > 1), CONSTRAINT valid_first CHECK (length(first) > 1),
CONSTRAINT valid_last CHECK (length(last) > 1), CONSTRAINT valid_last CHECK (length(last) > 1),
@@ -64,8 +64,8 @@ CREATE TABLE IF NOT EXISTS auth.vessels (
name TEXT NOT NULL CHECK (length(name) >= 3 AND length(name) < 512), name TEXT NOT NULL CHECK (length(name) >= 3 AND length(name) < 512),
-- pass text not null check (length(pass) < 512), -- unused -- pass text not null check (length(pass) < 512), -- unused
role name not null check (length(role) < 512), role name not null check (length(role) < 512),
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW() updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
-- CONSTRAINT valid_length_mmsi CHECK (length(mmsi) < 10 OR length(mmsi) = 0) -- CONSTRAINT valid_length_mmsi CHECK (length(mmsi) < 10 OR length(mmsi) = 0)
CONSTRAINT valid_range_mmsi CHECK (mmsi > 100000000 AND mmsi < 800000000) CONSTRAINT valid_range_mmsi CHECK (mmsi > 100000000 AND mmsi < 800000000)
); );

View File

@@ -48,8 +48,8 @@ CREATE OR REPLACE VIEW api.vessels_view WITH (security_invoker=true,security_bar
v.mmsi as mmsi, v.mmsi as mmsi,
v.created_at::timestamp(0) as created_at, v.created_at::timestamp(0) as created_at,
m.last_contact as last_contact, m.last_contact as last_contact,
((NOW() AT TIME ZONE 'UTC' - m.last_contact::timestamp without time zone) > INTERVAL '70 MINUTES') as offline, ((NOW() AT TIME ZONE 'UTC' - m.last_contact::TIMESTAMPTZ) > INTERVAL '70 MINUTES') as offline,
(NOW() AT TIME ZONE 'UTC' - m.last_contact::timestamp without time zone) as duration (NOW() AT TIME ZONE 'UTC' - m.last_contact::TIMESTAMPTZ) as duration
FROM auth.vessels v, metadata m FROM auth.vessels v, metadata m
WHERE v.owner_email = current_setting('user.email'); WHERE v.owner_email = current_setting('user.email');
-- Description -- Description

View File

@@ -12,8 +12,8 @@ DROP TABLE IF EXISTS auth.otp;
CREATE TABLE IF NOT EXISTS auth.otp ( CREATE TABLE IF NOT EXISTS auth.otp (
-- update email type to CITEXT, https://www.postgresql.org/docs/current/citext.html -- update email type to CITEXT, https://www.postgresql.org/docs/current/citext.html
user_email CITEXT NOT NULL PRIMARY KEY REFERENCES auth.accounts(email) ON DELETE RESTRICT, user_email CITEXT NOT NULL PRIMARY KEY REFERENCES auth.accounts(email) ON DELETE RESTRICT,
otp_pass VARCHAR(10) NOT NULL, otp_pass TEXT NOT NULL,
otp_timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(), otp_timestamp TIMESTAMPTZ DEFAULT NOW(),
otp_tries SMALLINT NOT NULL DEFAULT '0' otp_tries SMALLINT NOT NULL DEFAULT '0'
); );
-- Description -- Description