mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-02-01 04:34:38 +01:00
update: db schema to include imgs-uploading feature
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- The primary key for the `HostedImage` table will be changed. If it partially fails, the table could be left without primary key constraint.
|
||||
- The `id` column on the `HostedImage` table would be dropped and recreated. This will lead to data loss if there is data in the column.
|
||||
- Added the required column `provider` to the `HostedImage` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `provider_image_id` to the `HostedImage` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `url` to the `HostedImage` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
|
||||
-- START Custom SQL
|
||||
-- Because of the breaking changes, we have to apply some custom SQL.
|
||||
-- By chance, the previous HostedImage migration is not used it production, so we can remove all data from this table
|
||||
DELETE FROM "HostedImage";
|
||||
-- END Custom SQL
|
||||
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "HostedImage" DROP CONSTRAINT "HostedImage_pkey",
|
||||
ADD COLUMN "provider" TEXT NOT NULL,
|
||||
ADD COLUMN "provider_image_id" TEXT NOT NULL,
|
||||
ADD COLUMN "url" TEXT NOT NULL,
|
||||
DROP COLUMN "id",
|
||||
ADD COLUMN "id" SERIAL NOT NULL,
|
||||
ADD CONSTRAINT "HostedImage_pkey" PRIMARY KEY ("id");
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "UserKey" ALTER COLUMN "name" SET DEFAULT E'My new wallet key';
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[image_id]` on the table `Award` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[cover_image_id]` on the table `Category` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[cover_image_id]` on the table `Hackathon` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[thumbnail_image_id]` on the table `Project` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[cover_image_id]` on the table `Project` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[cover_image_id]` on the table `Story` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[avatar_id]` on the table `User` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Award" ADD COLUMN "image_id" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Category" ADD COLUMN "cover_image_id" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Hackathon" ADD COLUMN "cover_image_id" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Project" ADD COLUMN "cover_image_id" INTEGER,
|
||||
ADD COLUMN "screenshots_ids" INTEGER[],
|
||||
ADD COLUMN "thumbnail_image_id" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Story" ADD COLUMN "body_image_ids" INTEGER[],
|
||||
ADD COLUMN "cover_image_id" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "avatar_id" INTEGER;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Award_image_id_key" ON "Award"("image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Category_cover_image_id_key" ON "Category"("cover_image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Hackathon_cover_image_id_key" ON "Hackathon"("cover_image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Project_thumbnail_image_id_key" ON "Project"("thumbnail_image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Project_cover_image_id_key" ON "Project"("cover_image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Story_cover_image_id_key" ON "Story"("cover_image_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_avatar_id_key" ON "User"("avatar_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "User" ADD CONSTRAINT "User_avatar_id_fkey" FOREIGN KEY ("avatar_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Category" ADD CONSTRAINT "Category_cover_image_id_fkey" FOREIGN KEY ("cover_image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Project" ADD CONSTRAINT "Project_thumbnail_image_id_fkey" FOREIGN KEY ("thumbnail_image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Project" ADD CONSTRAINT "Project_cover_image_id_fkey" FOREIGN KEY ("cover_image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Award" ADD CONSTRAINT "Award_image_id_fkey" FOREIGN KEY ("image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Story" ADD CONSTRAINT "Story_cover_image_id_fkey" FOREIGN KEY ("cover_image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Hackathon" ADD CONSTRAINT "Hackathon_cover_image_id_fkey" FOREIGN KEY ("cover_image_id") REFERENCES "HostedImage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -40,11 +40,13 @@ model Vote {
|
||||
// -----------------
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
pubKey String? @unique
|
||||
name String?
|
||||
avatar String?
|
||||
role String @default("user")
|
||||
id Int @id @default(autoincrement())
|
||||
pubKey String? @unique
|
||||
name String?
|
||||
avatar String?
|
||||
avatar_id Int? @unique
|
||||
avatar_rel HostedImage? @relation("User_Avatar", fields: [avatar_id], references: [id])
|
||||
role String @default("user")
|
||||
|
||||
email String?
|
||||
jobTitle String?
|
||||
@@ -112,24 +114,31 @@ model Skill {
|
||||
// -----------------
|
||||
|
||||
model Category {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
cover_image String?
|
||||
icon String?
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
cover_image String?
|
||||
cover_image_id Int? @unique
|
||||
cover_image_rel HostedImage? @relation("Category_CoverImage", fields: [cover_image_id], references: [id])
|
||||
icon String?
|
||||
|
||||
project Project[]
|
||||
}
|
||||
|
||||
model Project {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String
|
||||
screenshots String[]
|
||||
website String
|
||||
thumbnail_image String?
|
||||
cover_image String?
|
||||
lightning_address String?
|
||||
lnurl_callback_url String?
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String
|
||||
screenshots String[]
|
||||
screenshots_ids Int[]
|
||||
website String
|
||||
thumbnail_image String?
|
||||
thumbnail_image_id Int? @unique
|
||||
thumbnail_image_rel HostedImage? @relation("Project_Thumbnail", fields: [thumbnail_image_id], references: [id])
|
||||
cover_image String?
|
||||
cover_image_id Int? @unique
|
||||
cover_image_rel HostedImage? @relation("Project_CoverImage", fields: [cover_image_id], references: [id])
|
||||
lightning_address String?
|
||||
lnurl_callback_url String?
|
||||
|
||||
category Category @relation(fields: [category_id], references: [id])
|
||||
category_id Int
|
||||
@@ -155,10 +164,12 @@ model ProjectRecruitRoles {
|
||||
}
|
||||
|
||||
model Award {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
image String
|
||||
url String
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
image String
|
||||
image_id Int? @unique
|
||||
image_rel HostedImage? @relation("Award_Image", fields: [image_id], references: [id])
|
||||
url String
|
||||
|
||||
project Project @relation(fields: [project_id], references: [id])
|
||||
project_id Int
|
||||
@@ -169,15 +180,18 @@ model Award {
|
||||
// -----------------
|
||||
|
||||
model Story {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
body String
|
||||
excerpt String
|
||||
cover_image String?
|
||||
votes_count Int @default(0)
|
||||
is_published Boolean @default(true)
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
body String
|
||||
body_image_ids Int[]
|
||||
excerpt String
|
||||
cover_image String?
|
||||
cover_image_id Int? @unique
|
||||
cover_image_rel HostedImage? @relation("Story_CoverImage", fields: [cover_image_id], references: [id])
|
||||
votes_count Int @default(0)
|
||||
is_published Boolean @default(true)
|
||||
|
||||
tags Tag[]
|
||||
|
||||
@@ -230,15 +244,17 @@ model PostComment {
|
||||
// Hackathons
|
||||
// -----------------
|
||||
model Hackathon {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
start_date DateTime @db.Date
|
||||
end_date DateTime @db.Date
|
||||
cover_image String
|
||||
description String
|
||||
location String
|
||||
website String
|
||||
votes_count Int @default(0)
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
start_date DateTime @db.Date
|
||||
end_date DateTime @db.Date
|
||||
cover_image String
|
||||
cover_image_id Int? @unique
|
||||
cover_image_rel HostedImage? @relation("Hackathon_CoverImage", fields: [cover_image_id], references: [id])
|
||||
description String
|
||||
location String
|
||||
website String
|
||||
votes_count Int @default(0)
|
||||
|
||||
tags Tag[]
|
||||
}
|
||||
@@ -272,10 +288,21 @@ model GeneratedK1 {
|
||||
// Hosted Image
|
||||
// -----------------
|
||||
model HostedImage {
|
||||
id String @id
|
||||
filename String
|
||||
createdAt DateTime @default(now())
|
||||
is_used Boolean @default(false)
|
||||
id Int @id @default(autoincrement())
|
||||
filename String
|
||||
provider_image_id String
|
||||
provider String
|
||||
url String
|
||||
createdAt DateTime @default(now())
|
||||
is_used Boolean @default(false)
|
||||
|
||||
ProjectThumbnail Project? @relation("Project_Thumbnail")
|
||||
ProjectCoverImage Project? @relation("Project_CoverImage")
|
||||
CategoryCoverImage Category? @relation("Category_CoverImage")
|
||||
AwardImage Award? @relation("Award_Image")
|
||||
HackathonCoverImage Hackathon? @relation("Hackathon_CoverImage")
|
||||
StoryCoverImage Story? @relation("Story_CoverImage")
|
||||
User User? @relation("User_Avatar")
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
||||
@@ -65,8 +65,192 @@ async function main() {
|
||||
|
||||
// await createSkills();
|
||||
|
||||
await createTournament();
|
||||
// await createTournament();
|
||||
|
||||
await migrateOldImages();
|
||||
}
|
||||
|
||||
async function migrateOldImages() {
|
||||
console.log('Migrating old images data to HostedImage');
|
||||
|
||||
// Can't use prisma method createMany() for columns like Project.screenshots, because this method doesn't return created IDs.
|
||||
|
||||
/**
|
||||
* Project
|
||||
**/
|
||||
const projects = await prisma.project.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
screenshots: true,
|
||||
cover_image: true,
|
||||
thumbnail_image: true
|
||||
}
|
||||
})
|
||||
for (const project of projects) {
|
||||
/**
|
||||
* Project.screenshots to Project.screenshots_ids
|
||||
**/
|
||||
let projectScreenshotIds = [];
|
||||
for (const screenshot of project.screenshots) {
|
||||
let hostedImageId = await _insertInHostedImage(screenshot)
|
||||
projectScreenshotIds.push(hostedImageId);
|
||||
}
|
||||
if (projectScreenshotIds.length > 0) {
|
||||
await _updateObjectWithHostedImageId(prisma.project, project.id, {
|
||||
screenshots_ids: projectScreenshotIds,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Project.cover_image to Project.cover_image_id
|
||||
**/
|
||||
if (project.cover_image) {
|
||||
let hostedImageId = await _insertInHostedImage(project.cover_image)
|
||||
await _updateObjectWithHostedImageId(prisma.project, project.id, {
|
||||
cover_image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Project.thumbnail_image to Project.thumbnail_image_id
|
||||
**/
|
||||
if (project.cover_image) {
|
||||
let hostedImageId = await _insertInHostedImage(project.thumbnail_image)
|
||||
await _updateObjectWithHostedImageId(prisma.project, project.id, {
|
||||
thumbnail_image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Category
|
||||
**/
|
||||
const categories = await prisma.category.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
cover_image: true,
|
||||
}
|
||||
})
|
||||
for (const category of categories) {
|
||||
if (category.cover_image) {
|
||||
let hostedImageId = await _insertInHostedImage(category.cover_image)
|
||||
await _updateObjectWithHostedImageId(prisma.category, category.id, {
|
||||
cover_image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Award
|
||||
**/
|
||||
const awards = await prisma.award.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
image: true,
|
||||
}
|
||||
})
|
||||
for (const award of awards) {
|
||||
if (award.image) {
|
||||
let hostedImageId = await _insertInHostedImage(award.image)
|
||||
await _updateObjectWithHostedImageId(prisma.award, award.id, {
|
||||
image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hackaton
|
||||
**/
|
||||
const hackatons = await prisma.hackathon.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
cover_image: true,
|
||||
}
|
||||
})
|
||||
for (const hackaton of hackatons) {
|
||||
if (hackaton.cover_image) {
|
||||
let hostedImageId = await _insertInHostedImage(hackaton.cover_image)
|
||||
await _updateObjectWithHostedImageId(prisma.hackathon, hackaton.id, {
|
||||
cover_image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Story
|
||||
**/
|
||||
const stories = await prisma.story.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
cover_image: true,
|
||||
body: true,
|
||||
}
|
||||
})
|
||||
for (const story of stories) {
|
||||
/**
|
||||
* Story.body to Story.body_image_ids
|
||||
**/
|
||||
let bodyImageIds = [];
|
||||
const regex = /(?:!\[(.*?)\]\((.*?)\))/g
|
||||
let match;
|
||||
while ((match = regex.exec(story.body))) {
|
||||
const [, , value] = match
|
||||
let hostedImageId = await _insertInHostedImage(value)
|
||||
bodyImageIds.push(hostedImageId)
|
||||
}
|
||||
if (bodyImageIds.length > 0) {
|
||||
await _updateObjectWithHostedImageId(prisma.story, story.id, {
|
||||
body_image_ids: bodyImageIds,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Story.cover_image to Story.cover_image_id
|
||||
**/
|
||||
if (story.cover_image) {
|
||||
let hostedImageId = await _insertInHostedImage(story.cover_image)
|
||||
await _updateObjectWithHostedImageId(prisma.story, story.id, {
|
||||
cover_image_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User
|
||||
**/
|
||||
const users = await prisma.user.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
avatar: true,
|
||||
}
|
||||
})
|
||||
for (const user of users) {
|
||||
if (user.avatar) {
|
||||
let hostedImageId = await _insertInHostedImage(user.avatar)
|
||||
await _updateObjectWithHostedImageId(prisma.user, user.id, {
|
||||
avatar_id: hostedImageId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function _insertInHostedImage(url) {
|
||||
const newHostedImage = await prisma.hostedImage.create({
|
||||
data: {
|
||||
filename: "default.png",
|
||||
provider: "external",
|
||||
provider_image_id: "",
|
||||
url,
|
||||
is_used: true
|
||||
}
|
||||
});
|
||||
return newHostedImage.id;
|
||||
}
|
||||
async function _updateObjectWithHostedImageId(prismaObject, objectId, data) {
|
||||
await prismaObject.update({
|
||||
where: { id: objectId },
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async function createCategories() {
|
||||
|
||||
Reference in New Issue
Block a user