Pārlūkot izejas kodu

add user_id to visits

Pouria Ezzati 1 gadu atpakaļ
vecāks
revīzija
bb36712c13

+ 58 - 0
server/migrations/20241223103044_visits_user_id.js

@@ -0,0 +1,58 @@
+/**
+ * @param { import("knex").Knex } knex
+ * @returns { Promise<void> }
+ */
+async function up(knex) {
+  const hasUserIDColumn = await knex.schema.hasColumn("visits", "user_id");
+
+  if (hasUserIDColumn) return;
+
+  await knex.schema.alterTable("visits", function(table) {
+    table
+      .integer("user_id")
+      .unsigned();
+    table
+      .foreign("user_id")
+      .references("id")
+      .inTable("users")
+      .onDelete("CASCADE")
+      .withKeyName("visits_user_id_foreign");
+  });
+
+  const [{ count }] = await knex("visits").count('*');
+  
+  if (count < 1_000_000) {
+    const last_visit = await knex("visits").orderBy("id", "desc").first();
+
+    const size = 100_000;
+    const loops = Math.floor(last_visit.id / size) + 1;
+    
+    await Promise.all(
+      new Array(loops).fill(null).map((_, i) => {
+        return knex("visits")
+          .fromRaw(knex.raw("visits v"))
+          .update({ user_id: knex.ref("links.user_id") })
+          .updateFrom("links")
+          .where("links.id", knex.ref("link_id"))
+          .andWhereBetween("v.id", [i * size, (i * size) + size]);
+      })
+    );
+  } else {
+    console.warn(
+      "MIGRATION WARN:" +
+      "Skipped adding user_id to visits due to high volume of visits and the potential risk of locking the database.\n" + 
+      "Please refer to Kutt's migration guide for more information."
+    );
+  } 
+};
+
+/**
+ * @param { import("knex").Knex } knex
+ * @returns { Promise<void> }
+ */
+async function down(knex) {};
+
+module.exports = {
+  up, 
+  down,
+}

+ 9 - 0
server/models/visit.model.js

@@ -18,6 +18,15 @@ async function createVisitTable(knex) {
         .inTable("links")
         .onDelete("CASCADE")
         .withKeyName("visits_link_id_foreign");
+      table
+        .integer("user_id")
+        .unsigned();
+      table
+        .foreign("user_id")
+        .references("id")
+        .inTable("users")
+        .onDelete("CASCADE")
+        .withKeyName("visits_user_id_foreign");
       table.jsonb("referrers").defaultTo("{}");
       table
         .integer("total")

+ 3 - 2
server/queries/visit.queries.js

@@ -22,7 +22,7 @@ async function add(params) {
       .select({
         created_at_hours: utils.knexUtils(trx).truncatedTimestamp("created_at", "hour")
       })
-      .where({ link_id: params.id })
+      .where({ link_id: data.link_id })
       .as("subquery");
 
     const visit = await trx
@@ -59,7 +59,8 @@ async function add(params) {
         referrers: { [data.referrer]: 1 },
         [`os_${data.os}`]: 1,
         total: 1,
-        link_id: data.id
+        link_id: data.link_id,
+        user_id: data.user_id,
       });
     }
 

+ 2 - 1
server/queues/visit.js

@@ -40,7 +40,8 @@ module.exports = function({ data }) {
     query.visit.add({
       browser: browser.toLowerCase(),
       country: country || "Unknown",
-      id: data.link.id,
+      link_id: data.link.id,
+      user_id: data.link.user_id,
       os: os.toLowerCase().replace(/\s/gi, ""),
       referrer: (referrer && referrer.replace(/\./gi, "[dot]")) || "Direct"
     })