feat: add HostedImage relation in Project table + data migration to HostedImage

This commit is contained in:
Dolu
2022-09-06 10:54:03 +02:00
parent 83713d9d62
commit 5e688466c0
9 changed files with 313 additions and 259 deletions

View File

@@ -200,13 +200,10 @@ export interface NexusGenObjects {
votes_count: number; // Int!
}
Project: { // root type
cover_image: string; // String!
description: string; // String!
id: number; // Int!
lightning_address?: string | null; // String
lnurl_callback_url?: string | null; // String
screenshots: string[]; // [String!]!
thumbnail_image: string; // String!
title: string; // String!
votes_count: number; // Int!
website: string; // String!

View File

@@ -6,6 +6,7 @@ const {
nonNull,
} = require('nexus')
const { prisma } = require('../../../prisma');
const resolveImgObjectToUrl = require('../../../utils/resolveImageUrl');
const { paginationArgs, getLnurlDetails, lightningAddressToLnurl } = require('./helpers');
const { MakerRole } = require('./users');
@@ -17,9 +18,41 @@ const Project = objectType({
t.nonNull.int('id');
t.nonNull.string('title');
t.nonNull.string('description');
t.nonNull.string('cover_image');
t.nonNull.string('thumbnail_image');
t.nonNull.list.nonNull.string('screenshots');
t.nonNull.string('cover_image', {
async resolve(parent) {
const imgObject = await prisma.hostedImage.findUnique({
where: {
id: parent.cover_image_id
}
});
return resolveImgObjectToUrl(imgObject);
}
});
t.nonNull.string('thumbnail_image', {
async resolve(parent) {
const imgObject = await prisma.hostedImage.findUnique({
where: {
id: parent.thumbnail_image_id
}
});
return resolveImgObjectToUrl(imgObject);
}
});
t.nonNull.list.nonNull.string('screenshots', {
async resolve(parent) {
const imgObject = await prisma.hostedImage.findMany({
where: {
id: { in: parent.screenshots_ids }
}
});
return imgObject.map(img => {
return resolveImgObjectToUrl(img);
});
}
});
t.nonNull.string('website');
t.string('lightning_address');
t.string('lnurl_callback_url');

View File

@@ -22,11 +22,11 @@ const postUploadImageUrl = async (req, res) => {
try {
const uploadUrl = await getDirectUploadUrl()
await prisma.hostedImage.create({
data: { id: uploadUrl.id, filename },
const hostedImage = await prisma.hostedImage.create({
data: { filename },
})
return res.status(200).json(uploadUrl)
return res.status(200).json({ id: hostedImage.id, uploadUrl: uploadUrl.uploadUrl })
} catch (error) {
res.status(500).send('Unexpected error happened, please try again')
}

View File

@@ -0,0 +1,10 @@
function resolveImgObjectToUrl(imgObject) {
if(imgObject && imgObject.provider === 'external'){
return imgObject.url;
}
else {
return "TODO";
}
}
module.exports = resolveImgObjectToUrl;

365
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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';

View File

@@ -0,0 +1,10 @@
-- AlterTable
ALTER TABLE "Project" ADD COLUMN "cover_image_id" INTEGER,
ADD COLUMN "screenshots_ids" INTEGER[],
ADD COLUMN "thumbnail_image_id" INTEGER;
-- 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;

View File

@@ -121,15 +121,20 @@ model Category {
}
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?
thumbnail_image_rel HostedImage? @relation("ProjectThumbnail", fields: [thumbnail_image_id], references: [id])
cover_image String?
cover_image_id Int?
cover_image_rel HostedImage? @relation("ProjectCoverImage", fields: [cover_image_id], references: [id])
lightning_address String?
lnurl_callback_url String?
category Category @relation(fields: [category_id], references: [id])
category_id Int
@@ -272,10 +277,16 @@ 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("ProjectThumbnail")
ProjectCoverImage Project[] @relation("ProjectCoverImage")
}
// -----------------

View File

@@ -64,6 +64,79 @@ async function main() {
// await createSkills();
// 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,
})
}
}
}
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() {