From 5798e8a46b44f1a9e494203e2c3d94ead7d4d283 Mon Sep 17 00:00:00 2001
From: Paolo Brasolin <paolo.brasolin@gmail.com>
Date: Tue, 19 Apr 2022 16:32:56 +0200
Subject: [PATCH] feat: #be triggers on db timestamps

---
 .../migrations/20220404144303_timestamps.ts   | 17 ------
 .../20220404144345_create_devices.ts          |  1 -
 .../migrations/20220419151400_timestamps.ts   | 53 +++++++++++++++++++
 3 files changed, 53 insertions(+), 18 deletions(-)
 delete mode 100644 backend/migrations/20220404144303_timestamps.ts
 create mode 100644 backend/migrations/20220419151400_timestamps.ts

diff --git a/backend/migrations/20220404144303_timestamps.ts b/backend/migrations/20220404144303_timestamps.ts
deleted file mode 100644
index 52a5c1b..0000000
--- a/backend/migrations/20220404144303_timestamps.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Knex } from "knex";
-
-export async function up(knex: Knex): Promise<void> {
-  return knex.schema
-    .alterTable("words", (table) => table.timestamps())
-    .alterTable("games", (table) => table.timestamps())
-    .alterTable("clues", (table) => table.timestamps())
-    .alterTable("shots", (table) => table.timestamps());
-}
-
-export async function down(knex: Knex): Promise<void> {
-  return knex.schema
-    .alterTable("words", (table) => table.dropTimestamps())
-    .alterTable("games", (table) => table.dropTimestamps())
-    .alterTable("clues", (table) => table.dropTimestamps())
-    .alterTable("shots", (table) => table.dropTimestamps());
-}
diff --git a/backend/migrations/20220404144345_create_devices.ts b/backend/migrations/20220404144345_create_devices.ts
index 6ca2a65..476fc36 100644
--- a/backend/migrations/20220404144345_create_devices.ts
+++ b/backend/migrations/20220404144345_create_devices.ts
@@ -4,7 +4,6 @@ export async function up(knex: Knex): Promise<void> {
   return knex.schema
     .createTable("devices", function (table) {
       table.uuid("id").primary().defaultTo(knex.raw("gen_random_uuid()"));
-      table.timestamps();
     })
     .alterTable("games", (table) => {
       table.uuid("device_id").references("devices.id"); // TODO: .notNullable();
diff --git a/backend/migrations/20220419151400_timestamps.ts b/backend/migrations/20220419151400_timestamps.ts
new file mode 100644
index 0000000..e7eede5
--- /dev/null
+++ b/backend/migrations/20220419151400_timestamps.ts
@@ -0,0 +1,53 @@
+import { Knex } from "knex";
+
+const CREATE_ON_UPDATE_TIMESTAMP_FUNCTION = `
+  CREATE OR REPLACE FUNCTION on_update_timestamp()
+  RETURNS trigger AS $$
+    BEGIN
+      NEW.updated_at = now();
+      RETURN NEW;
+    END;
+  $$ language 'plpgsql';
+`;
+
+const DROP_ON_UPDATE_TIMESTAMP_FUNCTION = `DROP FUNCTION on_update_timestamp`;
+
+const createUpdatedAtTrigger = (table: string) => `
+CREATE TRIGGER ${table}_updated_at
+BEFORE UPDATE ON ${table}
+FOR EACH ROW
+EXECUTE PROCEDURE on_update_timestamp();
+`;
+
+const dropUpdatedAtTrigger = (table: string) =>
+  `DROP TRIGGER ${table}_updated_at`;
+
+export async function up(knex: Knex): Promise<void> {
+  return knex.schema
+    .raw(CREATE_ON_UPDATE_TIMESTAMP_FUNCTION)
+    .alterTable("words", (table) => table.timestamps(true, true))
+    .alterTable("games", (table) => table.timestamps(true, true))
+    .alterTable("clues", (table) => table.timestamps(true, true))
+    .alterTable("shots", (table) => table.timestamps(true, true))
+    .alterTable("devices", (table) => table.timestamps(true, true))
+    .raw(createUpdatedAtTrigger("words"))
+    .raw(createUpdatedAtTrigger("games"))
+    .raw(createUpdatedAtTrigger("clues"))
+    .raw(createUpdatedAtTrigger("shots"))
+    .raw(createUpdatedAtTrigger("devices"));
+}
+
+export async function down(knex: Knex): Promise<void> {
+  return knex.schema
+    .raw(dropUpdatedAtTrigger("words"))
+    .raw(dropUpdatedAtTrigger("games"))
+    .raw(dropUpdatedAtTrigger("clues"))
+    .raw(dropUpdatedAtTrigger("shots"))
+    .raw(dropUpdatedAtTrigger("devices"))
+    .alterTable("words", (table) => table.dropTimestamps())
+    .alterTable("games", (table) => table.dropTimestamps())
+    .alterTable("clues", (table) => table.dropTimestamps())
+    .alterTable("shots", (table) => table.dropTimestamps())
+    .alterTable("devices", (table) => table.dropTimestamps())
+    .raw(DROP_ON_UPDATE_TIMESTAMP_FUNCTION);
+}
-- 
GitLab