/* Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
License: GPL-3.0 or later. */
+CREATE TABLE IF NOT EXISTS time_zones (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(128) NOT NULL UNIQUE
+);
+
CREATE TABLE IF NOT EXISTS sleep (
id SERIAL PRIMARY KEY,
date DATE DEFAULT CURRENT_DATE,
start TIME(0) WITH TIME ZONE,
- finish TIME(0) WITH TIME ZONE
+ start_time_zone_id INTEGER REFERENCES time_zones (id),
+ finish TIME(0) WITH TIME ZONE,
+ finish_time_zone_id INTEGER REFERENCES time_zones (id)
);
DO $$
CREATE ROLE metrics_tracker LOGIN;
GRANT SELECT
- ON TABLE sleep
+ ON TABLE sleep, time_zones
TO metrics_tracker;
GRANT INSERT
- ON TABLE sleep
+ ON TABLE sleep, time_zones
TO metrics_tracker;
GRANT USAGE, SELECT
- ON SEQUENCE sleep_id_seq
+ ON SEQUENCE sleep_id_seq, time_zones_id_seq
TO metrics_tracker;
/* Execute for the current database. */
IF EXISTS (SELECT * FROM pg_user WHERE usename = 'metrics_tracker')
THEN
REVOKE SELECT
- ON TABLE sleep
+ ON TABLE sleep, time_zones
FROM metrics_tracker;
REVOKE INSERT
- ON TABLE sleep
+ ON TABLE sleep, time_zones
FROM metrics_tracker;
REVOKE USAGE, SELECT
- ON SEQUENCE sleep_id_seq
+ ON SEQUENCE sleep_id_seq, time_zones_id_seq
FROM metrics_tracker;
EXECUTE
END$$;
DROP TABLE IF EXISTS sleep;
+DROP TABLE IF EXISTS time_zones;
. /etc/environment
+query_db() {
+ /usr/bin/psql --user=payments_tracker --dbname="${PAYMENTS_DB}" \
+ --tuples-only --no-align --command="${1}"
+}
+
+as_options() {
+ xargs --replace={} echo "<option value='{}'>{}</option>"
+}
+
+time_zones=$(query_db "SELECT name FROM time_zones")
+
PAGE="
<!DOCTYPE html>
<html>
column-gap: 5px;
display: flex;
}
- input[type=date] {
+ input {
width: 100%;
}
+ input[list] {
+ width: 30%;
+ }
</style>
</head>
<body>
📅<input type='date' id='date' name='date' required />
</label>
- <input type='time' id='start' name='start' required />
- <input type='time' id='end' name='end' required />
+ <label>
+ <input type='time' id='start' name='start' required />
+ <input list='time_zones' id='start_time_zone' name='start_time_zone'
+ placeholder='Timezone' required />
+ <datalist id='time_zones'>
+ $(echo ${time_zones} | as_options)
+ </datalist>
+ </label>
+
+ <label>
+ <input type='time' id='finish' name='finish' required />
+ <input list='time_zones' id='finish_time_zone' name='finish_time_zone'
+ placeholder='Timezone' required />
+ <datalist id='time_zones'>
+ $(echo ${time_zones} | as_options)
+ </datalist>
+ </label>
<button type='submit'>Record</>
</fieldset>
--tuples-only --no-align --command="${1}"
}
+insert_into() {
+ query_db "\
+ WITH new_id AS (
+ INSERT INTO ${1} (name)
+ VALUES ('${2}')
+ ON CONFLICT DO NOTHING
+ RETURNING id
+ )
+ SELECT *
+ FROM new_id
+ UNION
+ SELECT id
+ FROM ${1}
+ WHERE name='${2}'"
+}
+
sleep_date=$(get_query_param "date")
+
start=$(get_query_param "start")
+start_time_zone=$(get_query_param "start_time_zone")
+start_time_zone_id=$(insert_into "time_zones" "${start_time_zone}")
+
finish=$(get_query_param "finish")
+finish_time_zone=$(get_query_param "finish_time_zone")
+finish_time_zone_id=$(insert_into "time_zones" "${finish_time_zone}")
+
sleep_id=$(query_db "\
WITH new_sleep_id AS (
INSERT INTO sleep (
date,
start,
- finish
+ start_time_zone_id,
+ finish,
+ finish_time_zone_id
)
VALUES (
'${sleep_date}',
'${start}',
- '${finish}'
+ ${start_time_zone_id},
+ '${finish}',
+ ${finish_time_zone_id}
)
RETURNING id
)
</style>
</head>
<body>
-Recorded new sleep (id=${sleep_id}) from ${start} to ${finish}.
+Recorded new sleep (id=${sleep_id}) from ${start} ${start_time_zone} \
+(id=${start_time_zone_id}) to ${finish} ${finish_time_zone} \
+(id=${finish_time_zone_id}).
</body>
</html>"