Skip to content

Commit 39f2b10

Browse files
authored
Merge pull request #1012 from constructive-io/devin/1776593883-fix-plugin-column-names
fix: align plugin SQL with actual DB schema (mime_type, no content_hash on files)
2 parents 28734dd + 7c1abf9 commit 39f2b10

3 files changed

Lines changed: 14 additions & 17 deletions

File tree

graphile/graphile-presigned-url-plugin/src/plugin.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -300,15 +300,15 @@ export function createPresignedUrlPlugin(
300300

301301
const s3Key = buildS3Key(contentHash);
302302

303-
// --- Dedup check: look for existing file with same content_hash in this bucket ---
303+
// --- Dedup check: look for existing file with same key (content hash) in this bucket ---
304304
const dedupResult = await txClient.query({
305305
text: `SELECT id, status
306306
FROM ${storageConfig.filesQualifiedName}
307-
WHERE content_hash = $1
307+
WHERE key = $1
308308
AND bucket_id = $2
309309
AND status IN ('ready', 'processed')
310310
LIMIT 1`,
311-
values: [contentHash, bucket.id],
311+
values: [s3Key, bucket.id],
312312
});
313313

314314
if (dedupResult.rows.length > 0) {
@@ -338,19 +338,18 @@ export function createPresignedUrlPlugin(
338338
const fileResult = await txClient.query({
339339
text: hasOwnerColumn
340340
? `INSERT INTO ${storageConfig.filesQualifiedName}
341-
(bucket_id, key, content_type, content_hash, size, filename, owner_id, is_public, status)
342-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'pending')
341+
(bucket_id, key, mime_type, size, filename, owner_id, is_public, status)
342+
VALUES ($1, $2, $3, $4, $5, $6, $7, 'pending')
343343
RETURNING id`
344344
: `INSERT INTO ${storageConfig.filesQualifiedName}
345-
(bucket_id, key, content_type, content_hash, size, filename, is_public, status)
346-
VALUES ($1, $2, $3, $4, $5, $6, $7, 'pending')
345+
(bucket_id, key, mime_type, size, filename, is_public, status)
346+
VALUES ($1, $2, $3, $4, $5, $6, 'pending')
347347
RETURNING id`,
348348
values: hasOwnerColumn
349349
? [
350350
bucket.id,
351351
s3Key,
352352
contentType,
353-
contentHash,
354353
size,
355354
filename || null,
356355
bucket.owner_id,
@@ -360,7 +359,6 @@ export function createPresignedUrlPlugin(
360359
bucket.id,
361360
s3Key,
362361
contentType,
363-
contentHash,
364362
size,
365363
filename || null,
366364
bucket.is_public,
@@ -447,14 +445,14 @@ export function createPresignedUrlPlugin(
447445

448446
// --- Verify file exists in S3 (per-database bucket) ---
449447
const s3ForDb = resolveS3ForDatabase(options, storageConfig, databaseId);
450-
const s3Head = await headObject(s3ForDb, file.key, file.content_type as string);
448+
const s3Head = await headObject(s3ForDb, file.key, file.mime_type as string);
451449

452450
if (!s3Head) {
453451
throw new Error('FILE_NOT_IN_S3: the file has not been uploaded yet');
454452
}
455453

456454
// --- Content-type verification ---
457-
if (s3Head.contentType && s3Head.contentType !== file.content_type) {
455+
if (s3Head.contentType && s3Head.contentType !== file.mime_type) {
458456
// Mark upload_request as rejected
459457
await txClient.query({
460458
text: `UPDATE ${storageConfig.uploadRequestsQualifiedName}
@@ -464,7 +462,7 @@ export function createPresignedUrlPlugin(
464462
});
465463

466464
throw new Error(
467-
`CONTENT_TYPE_MISMATCH: expected ${file.content_type}, got ${s3Head.contentType}`,
465+
`CONTENT_TYPE_MISMATCH: expected ${file.mime_type}, got ${s3Head.contentType}`,
468466
);
469467
}
470468

graphile/graphile-presigned-url-plugin/src/storage-module-cache.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export async function resolveStorageModuleByFileId(
294294
pgClient: { query: (opts: { text: string; values?: unknown[] }) => Promise<{ rows: unknown[] }> },
295295
databaseId: string,
296296
fileId: string,
297-
): Promise<{ storageConfig: StorageModuleConfig; file: { id: string; key: string; content_type: string; status: string; bucket_id: string } } | null> {
297+
): Promise<{ storageConfig: StorageModuleConfig; file: { id: string; key: string; mime_type: string; status: string; bucket_id: string } } | null> {
298298
// Load all storage modules for this database
299299
log.debug(`Resolving file ${fileId} across all storage modules for database ${databaseId}`);
300300

@@ -305,14 +305,14 @@ export async function resolveStorageModuleByFileId(
305305
// Probe each module's files table for the fileId
306306
for (const config of allConfigs) {
307307
const fileResult = await pgClient.query({
308-
text: `SELECT id, key, content_type, status, bucket_id
308+
text: `SELECT id, key, mime_type, status, bucket_id
309309
FROM ${config.filesQualifiedName}
310310
WHERE id = $1
311311
LIMIT 1`,
312312
values: [fileId],
313313
});
314314
if (fileResult.rows.length > 0) {
315-
const file = fileResult.rows[0] as { id: string; key: string; content_type: string; status: string; bucket_id: string };
315+
const file = fileResult.rows[0] as { id: string; key: string; mime_type: string; status: string; bucket_id: string };
316316
return { storageConfig: config, file };
317317
}
318318
}

graphql/server-test/__fixtures__/seed/simple-seed-storage/schema.sql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ CREATE TABLE IF NOT EXISTS "simple-storage-public".files (
4040
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
4141
bucket_id uuid NOT NULL REFERENCES "simple-storage-public".buckets(id),
4242
key text NOT NULL,
43-
content_type text NOT NULL,
44-
content_hash text,
43+
mime_type text NOT NULL,
4544
size bigint,
4645
filename text,
4746
owner_id uuid,

0 commit comments

Comments
 (0)