Skip to content

Commit 2ed02fa

Browse files
committed
improve db migration
1 parent dc0f07c commit 2ed02fa

File tree

1 file changed

+31
-35
lines changed

1 file changed

+31
-35
lines changed

backend/src/db/migrations/20250502230521-migrate-to-s3.ts

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-argument */
22

3-
import { existsSync, createReadStream } from 'node:fs'
3+
import { open } from 'node:fs/promises'
44
import path from 'node:path'
55

66
import { S3Client, ObjectCannedACL } from '@aws-sdk/client-s3'
@@ -13,10 +13,11 @@ import { getDriver } from '@db/neo4j'
1313
export const description =
1414
'Upload all image files to a S3 compatible object storage in order to reduce load on our backend.'
1515

16-
export async function up() {
16+
export async function up(_next) {
1717
if (CONFIG.NODE_ENV === 'test') {
1818
// Let's skip this migration for simplicity.
1919
// There is nothing to migrate in test environment and setting up the S3 services seems overkill.
20+
return
2021
}
2122
const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ENDPOINT, AWS_BUCKET } = CONFIG
2223
if (!(AWS_ACCESS_KEY_ID && AWS_SECRET_ACCESS_KEY && AWS_ENDPOINT && AWS_BUCKET)) {
@@ -39,44 +40,39 @@ export async function up() {
3940
const { records } = await transaction.run('MATCH (image:Image) RETURN image.url as url')
4041
let urls: string[] = records.map((r) => r.get('url') as string)
4142
urls = urls.filter((url) => url.startsWith('/uploads'))
42-
const locations = await Promise.all(
43+
await Promise.all(
4344
urls
44-
.map((url) => {
45-
return async () => {
46-
const { pathname } = new URL(url, 'http://example.org')
47-
const fileLocation = path.join(__dirname, `../../../public/${pathname}`)
48-
const s3Location = `original${pathname}`
49-
// eslint-disable-next-line n/no-sync, security/detect-non-literal-fs-filename
50-
if (existsSync(fileLocation)) {
51-
const mimeType = lookup(fileLocation)
52-
const params = {
53-
Bucket: AWS_BUCKET,
54-
Key: s3Location,
55-
ACL: ObjectCannedACL.public_read,
56-
ContentType: mimeType || 'image/jpeg',
57-
// eslint-disable-next-line security/detect-non-literal-fs-filename
58-
Body: createReadStream(fileLocation),
59-
}
45+
.map((url) => async () => {
46+
const { pathname } = new URL(url, 'http://example.org')
47+
const fileLocation = path.join(__dirname, `../../../public/${pathname}`)
48+
const s3Location = `original${pathname}`
49+
const mimeType = lookup(fileLocation)
50+
console.log('fileLocation', fileLocation)
51+
// eslint-disable-next-line security/detect-non-literal-fs-filename
52+
const fileHandle = await open(fileLocation)
53+
const params = {
54+
Bucket: AWS_BUCKET,
55+
Key: s3Location,
56+
ACL: ObjectCannedACL.public_read,
57+
ContentType: mimeType || 'image/jpeg',
58+
Body: fileHandle.createReadStream(),
59+
}
6060

61-
const command = new Upload({ client: s3, params })
62-
const data = await command.done()
63-
const { Location: spacesUrl } = data
61+
const command = new Upload({ client: s3, params })
62+
const data = await command.done()
63+
const { Location: spacesUrl } = data
6464

65-
const updatedRecord = await transaction.run(
66-
'MATCH (image:Image {url: $url}) SET image.url = $spacesUrl RETURN image.url as url',
67-
{ url, spacesUrl },
68-
)
69-
const [updatedUrl] = updatedRecord.records.map(
70-
(record) => record.get('url') as string,
71-
)
72-
return updatedUrl
73-
}
74-
}
65+
const updatedRecord = await transaction.run(
66+
'MATCH (image:Image {url: $url}) SET image.url = $spacesUrl RETURN image.url as url',
67+
{ url, spacesUrl },
68+
)
69+
const [updatedUrl] = updatedRecord.records.map((record) => record.get('url') as string)
70+
// eslint-disable-next-line no-console
71+
console.log('Migrated:', updatedUrl)
72+
return updatedUrl
7573
})
7674
.map((p) => p()),
7775
)
78-
// eslint-disable-next-line no-console
79-
console.log('these are the locations', locations)
8076
await transaction.commit()
8177
} catch (error) {
8278
// eslint-disable-next-line no-console
@@ -90,7 +86,7 @@ export async function up() {
9086
}
9187
}
9288

93-
export async function down() {
89+
export async function down(_next) {
9490
const driver = getDriver()
9591
const session = driver.session()
9692
const transaction = session.beginTransaction()

0 commit comments

Comments
 (0)