Skip to content

Commit

Permalink
add drizzle migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
mpfeil committed Sep 25, 2024
1 parent 0de74b2 commit f90bec2
Show file tree
Hide file tree
Showing 5 changed files with 1,284 additions and 0 deletions.
112 changes: 112 additions & 0 deletions packages/models/migrations/0000_init_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
DO $$ BEGIN
CREATE TYPE "public"."model" AS ENUM('HOME_V2_LORA');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."exposure" AS ENUM('indoor', 'outdoor', 'mobile', 'unknown');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."status" AS ENUM('active', 'inactive', 'old');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "device" (
"id" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"image" text,
"description" text,
"link" text,
"use_auth" boolean,
"exposure" "exposure",
"status" "status" DEFAULT 'inactive',
"model" "model",
"public" boolean DEFAULT false,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"latitude" double precision NOT NULL,
"longitude" double precision NOT NULL,
"user_id" text NOT NULL,
"sensor_wiki_model" text
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "measurement" (
"sensor_id" text NOT NULL,
"time" timestamp (3) with time zone DEFAULT now() NOT NULL,
"value" double precision,
CONSTRAINT "measurement_sensor_id_time_unique" UNIQUE("sensor_id","time")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "password" (
"hash" text NOT NULL,
"user_id" text NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "profile_image" (
"id" text PRIMARY KEY NOT NULL,
"alt_text" text,
"content_type" text NOT NULL,
"blob" "bytea" NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"profile_id" text
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "profile" (
"id" text PRIMARY KEY NOT NULL,
"username" text NOT NULL,
"public" boolean DEFAULT false,
"user_id" text,
CONSTRAINT "profile_username_unique" UNIQUE("username")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "sensor" (
"id" text PRIMARY KEY NOT NULL,
"title" text,
"unit" text,
"sensor_type" text,
"status" "status" DEFAULT 'inactive',
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"device_id" text NOT NULL,
"sensor_wiki_type" text,
"sensor_wiki_phenomenon" text,
"sensor_wiki_unit" text,
"lastMeasurement" json,
"data" json
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "user" (
"id" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"email" text NOT NULL,
"role" text DEFAULT 'user',
"language" text DEFAULT 'en_US',
"email_is_confirmed" boolean DEFAULT false,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
CONSTRAINT "user_email_unique" UNIQUE("email")
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "password" ADD CONSTRAINT "password_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE cascade;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "profile_image" ADD CONSTRAINT "profile_image_profile_id_profile_id_fk" FOREIGN KEY ("profile_id") REFERENCES "public"."profile"("id") ON DELETE cascade ON UPDATE cascade;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "profile" ADD CONSTRAINT "profile_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE cascade;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
116 changes: 116 additions & 0 deletions packages/models/migrations/0001_init_tsdb.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
-- This is a custom SQL migration file! --

-- CreateExtension
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;

-- Turn the measurement table into a hypertable
SELECT create_hypertable('measurement', 'time');

-- Drop raw data older than 1 year
SELECT add_retention_policy('measurement', INTERVAL '1 year');

-- Continuous aggregate (CAGG) of the hypertable
-- https://docs.timescale.com/use-timescale/latest/continuous-aggregates/real-time-aggregates/
CREATE MATERIALIZED VIEW measurement_10min WITH (timescaledb.continuous) AS
SELECT measurement.sensor_id,
time_bucket('10 minutes', measurement.time) AS time,
COUNT(*) total_values,
AVG(measurement.value) AS avg_value,
percentile_agg(measurement.value) as percentile_10min,
MAX(measurement.value) AS max_value,
MIN(measurement.value) AS min_value
FROM measurement
GROUP BY 1, 2
WITH NO DATA;

-- Add a CAGG policy in order to refresh it automatically
-- Automatically keep downsampled data up to date with new data from 20 minutes to 2 days ago.
-- https://docs.timescale.com/use-timescale/latest/continuous-aggregates/drop-data/
SELECT add_continuous_aggregate_policy('measurement_10min',
start_offset => INTERVAL '2 days',
end_offset => INTERVAL '10 minutes',
schedule_interval => INTERVAL '10 minutes'
);

-- Continuous aggregate (CAGG) of the hypertable
-- https://docs.timescale.com/use-timescale/latest/continuous-aggregates/real-time-aggregates/
CREATE MATERIALIZED VIEW measurement_1hour WITH (timescaledb.continuous) AS
SELECT sensor_id,
time_bucket('1 hour', time) AS time,
COUNT(*) total_values,
mean(rollup(percentile_10min)) AS avg_value,
rollup(percentile_10min) as percentile_1hour,
MAX(max_value) AS max_value,
MIN(min_value) AS min_value
FROM measurement_10min
GROUP BY 1, 2
WITH NO DATA;

SELECT add_continuous_aggregate_policy('measurement_1hour',
start_offset => INTERVAL '2 days',
end_offset => INTERVAL '3 minutes',
schedule_interval => INTERVAL '1 hour',
initial_start => date_trunc('hours', now() + INTERVAL '1 hour') + INTERVAL '5 minutes'
);

-- Continuous aggregate (CAGG) on top of another CAGG / Hierarchical Continuous Aggregates , new in Timescale 2.9, issue with TZ as of https://github.com/timescale/timescaledb/pull/5195
-- https://docs.timescale.com/use-timescale/latest/continuous-aggregates/real-time-aggregates/
CREATE MATERIALIZED VIEW measurement_1day WITH (timescaledb.continuous) AS
SELECT sensor_id,
time_bucket('1 day', time) AS time,
COUNT(*) total_values,
mean(rollup(percentile_1hour)) AS avg_value,
rollup(percentile_1hour) as percentile_1day,
MAX(max_value) AS max_value,
MIN(min_value) AS min_value
FROM measurement_1hour
GROUP BY 1, 2
WITH NO DATA;

-- Add a CAGG policy in order to refresh it automatically
-- Automatically keep downsampled data up to date with new data from 2 days to 4 days ago.
-- https://docs.timescale.com/use-timescale/latest/continuous-aggregates/drop-data/
SELECT add_continuous_aggregate_policy('measurement_1day',
start_offset => INTERVAL '3 days',
end_offset => INTERVAL '3 minutes',
schedule_interval => INTERVAL '1 day',
initial_start => date_trunc('day', now() + INTERVAL '1 day') + INTERVAL '5 minutes'
);

CREATE MATERIALIZED VIEW measurement_1month WITH (timescaledb.continuous) AS
SELECT sensor_id,
time_bucket('1 month', time) AS time,
COUNT(*) total_values,
mean(rollup(percentile_1day)) AS avg_value,
rollup(percentile_1day) as percentile_1month,
MAX(max_value) AS max_value,
MIN(min_value) AS min_value
FROM measurement_1day
GROUP BY 1, 2
WITH NO DATA;

SELECT add_continuous_aggregate_policy('measurement_1month',
start_offset => INTERVAL '3 months',
end_offset => INTERVAL '3 minutes',
schedule_interval => INTERVAL '1 month',
initial_start => date_trunc('month', now() + INTERVAL '1 month') + INTERVAL '5 minutes'
);

CREATE MATERIALIZED VIEW measurement_1year WITH (timescaledb.continuous) AS
SELECT sensor_id,
time_bucket('1 year', time) AS time,
COUNT(*) total_values,
mean(rollup(percentile_1day)) AS avg_value,
rollup(percentile_1day) as percentile_1year,
MAX(max_value) AS max_value,
MIN(min_value) AS min_value
FROM measurement_1day
GROUP BY 1, 2
WITH NO DATA;

SELECT add_continuous_aggregate_policy('measurement_1year',
start_offset => INTERVAL '3 years',
end_offset => INTERVAL '1 hour',
schedule_interval => INTERVAL '1 year',
initial_start => date_trunc('year', now() + INTERVAL '1 year') + INTERVAL '2 hours'
);
Loading

0 comments on commit f90bec2

Please sign in to comment.