mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 16:38:19 +01:00
refactor(database): ♻️ Move Note <-> Media relations to a many-to-many model instead of one-to-many
This commit is contained in:
parent
9c30dacda7
commit
3216fc339a
|
|
@ -17,7 +17,7 @@ import type {
|
||||||
import { Instance, db } from "@versia/kit/db";
|
import { Instance, db } from "@versia/kit/db";
|
||||||
import {
|
import {
|
||||||
EmojiToNote,
|
EmojiToNote,
|
||||||
Medias,
|
MediasToNotes,
|
||||||
NoteToMentions,
|
NoteToMentions,
|
||||||
Notes,
|
Notes,
|
||||||
Users,
|
Users,
|
||||||
|
|
@ -630,22 +630,15 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
||||||
|
|
||||||
// Remove old attachments
|
// Remove old attachments
|
||||||
await db
|
await db
|
||||||
.update(Medias)
|
.delete(MediasToNotes)
|
||||||
.set({
|
.where(eq(MediasToNotes.noteId, this.data.id));
|
||||||
noteId: null,
|
|
||||||
})
|
await db.insert(MediasToNotes).values(
|
||||||
.where(eq(Medias.noteId, this.data.id));
|
mediaAttachments.map((media) => ({
|
||||||
await db
|
|
||||||
.update(Medias)
|
|
||||||
.set({
|
|
||||||
noteId: this.data.id,
|
noteId: this.data.id,
|
||||||
})
|
mediaId: media.id,
|
||||||
.where(
|
})),
|
||||||
inArray(
|
);
|
||||||
Medias.id,
|
|
||||||
mediaAttachments.map((i) => i.id),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,11 @@ export const findManyNotes = async (
|
||||||
...query,
|
...query,
|
||||||
with: {
|
with: {
|
||||||
...query?.with,
|
...query?.with,
|
||||||
attachments: true,
|
attachments: {
|
||||||
|
with: {
|
||||||
|
media: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
emojis: {
|
emojis: {
|
||||||
with: {
|
with: {
|
||||||
emoji: {
|
emoji: {
|
||||||
|
|
@ -65,7 +69,11 @@ export const findManyNotes = async (
|
||||||
},
|
},
|
||||||
reblog: {
|
reblog: {
|
||||||
with: {
|
with: {
|
||||||
attachments: true,
|
attachments: {
|
||||||
|
with: {
|
||||||
|
media: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
emojis: {
|
emojis: {
|
||||||
with: {
|
with: {
|
||||||
emoji: {
|
emoji: {
|
||||||
|
|
@ -176,6 +184,7 @@ export const findManyNotes = async (
|
||||||
...mention.user,
|
...mention.user,
|
||||||
endpoints: mention.user.endpoints,
|
endpoints: mention.user.endpoints,
|
||||||
})),
|
})),
|
||||||
|
attachments: post.attachments.map((attachment) => attachment.media),
|
||||||
emojis: (post.emojis ?? []).map((emoji) => emoji.emoji),
|
emojis: (post.emojis ?? []).map((emoji) => emoji.emoji),
|
||||||
reblog: post.reblog && {
|
reblog: post.reblog && {
|
||||||
...post.reblog,
|
...post.reblog,
|
||||||
|
|
@ -184,6 +193,9 @@ export const findManyNotes = async (
|
||||||
...mention.user,
|
...mention.user,
|
||||||
endpoints: mention.user.endpoints,
|
endpoints: mention.user.endpoints,
|
||||||
})),
|
})),
|
||||||
|
attachments: post.reblog.attachments.map(
|
||||||
|
(attachment) => attachment.media,
|
||||||
|
),
|
||||||
emojis: (post.reblog.emojis ?? []).map((emoji) => emoji.emoji),
|
emojis: (post.reblog.emojis ?? []).map((emoji) => emoji.emoji),
|
||||||
reblogCount: Number(post.reblog.reblogCount),
|
reblogCount: Number(post.reblog.reblogCount),
|
||||||
likeCount: Number(post.reblog.likeCount),
|
likeCount: Number(post.reblog.likeCount),
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
import type { Config } from "drizzle-kit";
|
import type { Config } from "drizzle-kit";
|
||||||
import { config } from "~/packages/config-manager/index.ts";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
dialect: "postgresql",
|
dialect: "postgresql",
|
||||||
out: "./drizzle/migrations",
|
out: "./drizzle/migrations",
|
||||||
schema: "./drizzle/schema.ts",
|
schema: "./drizzle/schema.ts",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
/* host: "localhost",
|
host: "localhost",
|
||||||
port: 40000,
|
port: 40000,
|
||||||
user: "lysand",
|
user: "lysand",
|
||||||
password: "lysand",
|
password: "lysand",
|
||||||
database: "lysand", */
|
database: "lysand",
|
||||||
host: config.database.host,
|
/* host: config.database.host,
|
||||||
port: Number(config.database.port),
|
port: Number(config.database.port),
|
||||||
user: config.database.username,
|
user: config.database.username,
|
||||||
password: config.database.password,
|
password: config.database.password,
|
||||||
database: config.database.database,
|
database: config.database.database, */
|
||||||
},
|
},
|
||||||
// Print all statements
|
// Print all statements
|
||||||
verbose: true,
|
verbose: true,
|
||||||
|
|
|
||||||
26
drizzle/migrations/0042_swift_the_phantom.sql
Normal file
26
drizzle/migrations/0042_swift_the_phantom.sql
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
CREATE TABLE "MediasToNote" (
|
||||||
|
"mediaId" uuid NOT NULL,
|
||||||
|
"noteId" uuid NOT NULL
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP CONSTRAINT "Medias_noteId_Notes_id_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" ADD COLUMN "content" jsonb NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" ADD COLUMN "original_content" jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" ADD COLUMN "thumbnail" jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "MediasToNote" ADD CONSTRAINT "MediasToNote_mediaId_Medias_id_fk" FOREIGN KEY ("mediaId") REFERENCES "public"."Medias"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
|
||||||
|
ALTER TABLE "MediasToNote" ADD CONSTRAINT "MediasToNote_noteId_Notes_id_fk" FOREIGN KEY ("noteId") REFERENCES "public"."Notes"("id") ON DELETE cascade ON UPDATE cascade;--> statement-breakpoint
|
||||||
|
CREATE INDEX "MediasToNote_mediaId_index" ON "MediasToNote" USING btree ("mediaId");--> statement-breakpoint
|
||||||
|
CREATE INDEX "MediasToNote_noteId_index" ON "MediasToNote" USING btree ("noteId");--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "url";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "remote_url";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "thumbnail_url";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "mime_type";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "description";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "sha256";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "fps";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "duration";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "width";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "height";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "size";--> statement-breakpoint
|
||||||
|
ALTER TABLE "Medias" DROP COLUMN "noteId";
|
||||||
2334
drizzle/migrations/meta/0042_snapshot.json
Normal file
2334
drizzle/migrations/meta/0042_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -295,6 +295,13 @@
|
||||||
"when": 1737644734501,
|
"when": 1737644734501,
|
||||||
"tag": "0041_bright_doctor_spectrum",
|
"tag": "0041_bright_doctor_spectrum",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 42,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1737660317024,
|
||||||
|
"tag": "0042_swift_the_phantom",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,10 +309,6 @@ export const Medias = pgTable("Medias", {
|
||||||
originalContent: jsonb("original_content").$type<ContentFormat>(),
|
originalContent: jsonb("original_content").$type<ContentFormat>(),
|
||||||
thumbnail: jsonb("thumbnail").$type<ContentFormat>(),
|
thumbnail: jsonb("thumbnail").$type<ContentFormat>(),
|
||||||
blurhash: text("blurhash"),
|
blurhash: text("blurhash"),
|
||||||
noteId: uuid("noteId").references(() => Notes.id, {
|
|
||||||
onDelete: "cascade",
|
|
||||||
onUpdate: "cascade",
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Notifications = pgTable("Notifications", {
|
export const Notifications = pgTable("Notifications", {
|
||||||
|
|
@ -791,10 +787,38 @@ export const UserToPinnedNotes = pgTable(
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
export const AttachmentsRelations = relations(Medias, ({ one }) => ({
|
export const MediasRelations = relations(Medias, ({ many }) => ({
|
||||||
notes: one(Notes, {
|
notes: many(Notes),
|
||||||
fields: [Medias.noteId],
|
}));
|
||||||
|
|
||||||
|
export const MediasToNotes = pgTable(
|
||||||
|
"MediasToNote",
|
||||||
|
{
|
||||||
|
mediaId: uuid("mediaId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => Medias.id, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
onUpdate: "cascade",
|
||||||
|
}),
|
||||||
|
noteId: uuid("noteId")
|
||||||
|
.notNull()
|
||||||
|
.references(() => Notes.id, {
|
||||||
|
onDelete: "cascade",
|
||||||
|
onUpdate: "cascade",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
(table) => [index().on(table.mediaId), index().on(table.noteId)],
|
||||||
|
);
|
||||||
|
|
||||||
|
export const MediasToNotesRelations = relations(MediasToNotes, ({ one }) => ({
|
||||||
|
media: one(Medias, {
|
||||||
|
fields: [MediasToNotes.mediaId],
|
||||||
|
references: [Medias.id],
|
||||||
|
}),
|
||||||
|
note: one(Notes, {
|
||||||
|
fields: [MediasToNotes.noteId],
|
||||||
references: [Notes.id],
|
references: [Notes.id],
|
||||||
|
relationName: "AttachmentToNote",
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -886,7 +910,9 @@ export const NotesRelations = relations(Notes, ({ many, one }) => ({
|
||||||
references: [Users.id],
|
references: [Users.id],
|
||||||
relationName: "NoteToAuthor",
|
relationName: "NoteToAuthor",
|
||||||
}),
|
}),
|
||||||
attachments: many(Medias),
|
attachments: many(MediasToNotes, {
|
||||||
|
relationName: "AttachmentToNote",
|
||||||
|
}),
|
||||||
mentions: many(NoteToMentions),
|
mentions: many(NoteToMentions),
|
||||||
reblog: one(Notes, {
|
reblog: one(Notes, {
|
||||||
fields: [Notes.reblogId],
|
fields: [Notes.reblogId],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue