From 5f330ea3555094e26b7ccbd5b760214ce6f03f55 Mon Sep 17 00:00:00 2001 From: RhizoNymph Date: Wed, 8 Oct 2025 12:53:08 -0700 Subject: [PATCH 1/3] add metrics files --- metrics/1_create_mat_view.sql | 59 ++++++++++++++++++++++++++ metrics/2_create_mat_view_indicies.sql | 4 ++ metrics/3_refresh_mat_view.js | 21 +++++++++ metrics/refresh_mat_view_cron.sh | 2 + 4 files changed, 86 insertions(+) create mode 100644 metrics/1_create_mat_view.sql create mode 100644 metrics/2_create_mat_view_indicies.sql create mode 100644 metrics/3_refresh_mat_view.js create mode 100755 metrics/refresh_mat_view_cron.sh diff --git a/metrics/1_create_mat_view.sql b/metrics/1_create_mat_view.sql new file mode 100644 index 0000000..2066121 --- /dev/null +++ b/metrics/1_create_mat_view.sql @@ -0,0 +1,59 @@ +CREATE MATERIALIZED VIEW ${schema_name}.mv_pool_day_agg_2 +TABLESPACE pg_default +AS WITH bounds AS ( + SELECT EXTRACT(epoch FROM now() - '24:00:00'::interval)::bigint AS start_epoch, + EXTRACT(epoch FROM now())::bigint AS end_epoch + ), recent AS ( + SELECT f.pool, + f.minute_id, + f.volume_usd, + f.open, + f.close, + f.high, + f.low + FROM ${schema_name}.fifteen_minute_bucket_usd f + CROSS JOIN bounds b + WHERE f.minute_id >= b.start_epoch AND f.minute_id < b.end_epoch + ), per_pool AS ( + SELECT r.pool, + sum(r.volume_usd) AS volume, + max(r.high) AS high, + min(r.low) AS low + FROM recent r + GROUP BY r.pool + ), fo AS ( + SELECT DISTINCT ON (r.pool) r.pool, + r.open AS first_open + FROM recent r + ORDER BY r.pool, r.minute_id + ), lc AS ( + SELECT DISTINCT ON (r.pool) r.pool, + r.close AS last_close + FROM recent r + ORDER BY r.pool, r.minute_id DESC + ), combined AS ( + SELECT p.pool, + COALESCE(per_pool.volume, 0::numeric) AS volume, + fo.first_open, + lc.last_close, + per_pool.high, + per_pool.low + FROM ( SELECT pool.address AS pool + FROM ${schema_name}.pool) p + LEFT JOIN per_pool ON p.pool = per_pool.pool + LEFT JOIN fo ON p.pool = fo.pool + LEFT JOIN lc ON p.pool = lc.pool + ) + SELECT pool, + volume, + first_open AS open, + last_close AS close, + high, + low, + CASE + WHEN first_open IS NOT NULL AND last_close IS NOT NULL THEN (last_close - first_open) / NULLIF(first_open, 0::numeric)::numeric * 100.0 + ELSE NULL::numeric + END AS percent_day_change + FROM combined c + ORDER BY pool +WITH DATA; diff --git a/metrics/2_create_mat_view_indicies.sql b/metrics/2_create_mat_view_indicies.sql new file mode 100644 index 0000000..e06fc8a --- /dev/null +++ b/metrics/2_create_mat_view_indicies.sql @@ -0,0 +1,4 @@ +CREATE INDEX pdc_idx ON ${schema_name}.mv_pool_day_agg_2 (percent_day_change); +CREATE UNIQUE INDEX u_pool_idx ON ${schema_name}.mv_pool_day_agg_2 (pool); +CREATE INDEX volume ON ${schema_name}.mv_pool_day_agg_2 (volume); +CREATE INDEX symbol_idx ON ${schema_name}.token (symbol); diff --git a/metrics/3_refresh_mat_view.js b/metrics/3_refresh_mat_view.js new file mode 100644 index 0000000..7bafb55 --- /dev/null +++ b/metrics/3_refresh_mat_view.js @@ -0,0 +1,21 @@ +import 'dotenv/config'; +import * as pg from 'pg'; + + +const client = new pg.Client({ + connectionString: `postgres://${process.env.POSTGRES_USERNAME}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}?sslmode=require`, +}) + +// Schema needs to be set to the schema targeting the correct deployment +export async function refreshViews() { + try { + await client.connect(); + await client.query(`REFRESH MATERIALIZED VIEW CONCURRENTLY "${process.env.POSTGRES_SCHEMA}".mv_pool_day_agg_2;`); + } catch (error) { + await client.end(); + console.error("Error refreshing views:", error); + return + } finally { + await client.end(); + } +} diff --git a/metrics/refresh_mat_view_cron.sh b/metrics/refresh_mat_view_cron.sh new file mode 100755 index 0000000..129511c --- /dev/null +++ b/metrics/refresh_mat_view_cron.sh @@ -0,0 +1,2 @@ +# Run this from inside metrics directory +(crontab -l 2>/dev/null; echo "*/15 * * * * node 3_refresh_mat_view.js") | crontab - From 502bc402a16bf191d7655e5a82d8b65172fed70b Mon Sep 17 00:00:00 2001 From: RhizoNymph Date: Wed, 8 Oct 2025 12:53:12 -0700 Subject: [PATCH 2/3] Update refresh_mat_view_cron.sh --- metrics/refresh_mat_view_cron.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/metrics/refresh_mat_view_cron.sh b/metrics/refresh_mat_view_cron.sh index 129511c..a658c38 100755 --- a/metrics/refresh_mat_view_cron.sh +++ b/metrics/refresh_mat_view_cron.sh @@ -1,2 +1,4 @@ # Run this from inside metrics directory +# Make sure postgres connection envs are set +# Make sure POSTGRES_SCHEMA is set to current deployment (crontab -l 2>/dev/null; echo "*/15 * * * * node 3_refresh_mat_view.js") | crontab - From 604f29aef22166b15067f54b2e8c51001eeabd9a Mon Sep 17 00:00:00 2001 From: RhizoNymph Date: Wed, 8 Oct 2025 12:55:18 -0700 Subject: [PATCH 3/3] Update refresh_mat_view_cron.sh --- metrics/refresh_mat_view_cron.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/metrics/refresh_mat_view_cron.sh b/metrics/refresh_mat_view_cron.sh index a658c38..1f4f6b6 100755 --- a/metrics/refresh_mat_view_cron.sh +++ b/metrics/refresh_mat_view_cron.sh @@ -1,4 +1,5 @@ # Run this from inside metrics directory # Make sure postgres connection envs are set # Make sure POSTGRES_SCHEMA is set to current deployment +# Change 15 to how many minutes you want to have between refreshes (crontab -l 2>/dev/null; echo "*/15 * * * * node 3_refresh_mat_view.js") | crontab -