mirror of
https://github.com/directus/directus.git
synced 2026-01-23 17:38:25 -05:00
enforce uppercase UUIDs for MS SQL (#16691)
* add forced uppercase for UUIDs in MS SQL * test whether mssql returned uuid is uppercase * use once just for slight better correctness * once is actually not enough Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> Co-authored-by: ian <licitdev@gmail.com>
This commit is contained in:
7
api/src/database/helpers/schema/dialects/mssql.ts
Normal file
7
api/src/database/helpers/schema/dialects/mssql.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { SchemaHelper } from '../types';
|
||||
|
||||
export class SchemaHelperMSSQL extends SchemaHelper {
|
||||
formatUUID(uuid: string): string {
|
||||
return uuid.toUpperCase();
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,4 @@ export { SchemaHelperDefault as redshift } from './dialects/default';
|
||||
export { SchemaHelperOracle as oracle } from './dialects/oracle';
|
||||
export { SchemaHelperSQLite as sqlite } from './dialects/sqlite';
|
||||
export { SchemaHelperDefault as mysql } from './dialects/default';
|
||||
export { SchemaHelperDefault as mssql } from './dialects/default';
|
||||
export { SchemaHelperMSSQL as mssql } from './dialects/mssql';
|
||||
|
||||
@@ -96,4 +96,8 @@ export abstract class SchemaHelper extends DatabaseHelper {
|
||||
// reference issue #14873
|
||||
return existingName;
|
||||
}
|
||||
|
||||
formatUUID(uuid: string): string {
|
||||
return uuid; // no-op by defaut
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ import { NestedDeepQuery } from '@directus/shared/types';
|
||||
import knex, { Knex } from 'knex';
|
||||
import { getTracker, MockClient, Tracker } from 'knex-mock-client';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { afterEach, beforeAll, describe, expect, it, vi, MockedFunction } from 'vitest';
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi, MockedFunction } from 'vitest';
|
||||
import { ItemsService } from '../../src/services';
|
||||
import { InvalidPayloadException } from '../exceptions';
|
||||
import { sqlFieldFormatter, sqlFieldList } from '../__utils__/items-utils';
|
||||
import { systemSchema, userSchema } from '../__utils__/schemas';
|
||||
import { getDatabaseClient } from '../../src/database/index';
|
||||
|
||||
vi.mock('../env', async () => {
|
||||
const actual = (await vi.importActual('../env')) as { default: Record<string, any> };
|
||||
@@ -21,7 +22,7 @@ vi.mock('../env', async () => {
|
||||
|
||||
vi.mock('../../src/database/index', () => ({
|
||||
default: vi.fn(),
|
||||
getDatabaseClient: vi.fn().mockReturnValue('postgres'),
|
||||
getDatabaseClient: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../cache', () => ({
|
||||
@@ -49,6 +50,10 @@ describe('Integration Tests', () => {
|
||||
tracker = getTracker();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(getDatabaseClient).mockReturnValue('postgres');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
tracker.reset();
|
||||
});
|
||||
@@ -80,6 +85,24 @@ describe('Integration Tests', () => {
|
||||
expect(response).toBe(item.id);
|
||||
}
|
||||
);
|
||||
|
||||
it(`the returned UUID primary key for MS SQL should be uppercase`, async () => {
|
||||
vi.mocked(getDatabaseClient).mockReturnValue('mssql');
|
||||
|
||||
const table = schemas.system.tables[0];
|
||||
|
||||
const itemsService = new ItemsService(table, {
|
||||
knex: db,
|
||||
accountability: { role: 'admin', admin: true },
|
||||
schema: schemas.system.schema,
|
||||
});
|
||||
|
||||
tracker.on.insert(table).responseOnce(item);
|
||||
|
||||
const response = await itemsService.createOne(item, { emitEvents: false });
|
||||
|
||||
expect(response).toBe(item.id.toUpperCase());
|
||||
});
|
||||
});
|
||||
|
||||
describe('readOne', () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Knex } from 'knex';
|
||||
import { assign, clone, cloneDeep, omit, pick, without } from 'lodash';
|
||||
import { getCache } from '../cache';
|
||||
import getDatabase from '../database';
|
||||
import { getHelpers } from '../database/helpers';
|
||||
import runAST from '../database/run-ast';
|
||||
import emitter from '../emitter';
|
||||
import env from '../env';
|
||||
@@ -145,7 +146,12 @@ export class ItemsService<Item extends AnyItem = AnyItem> implements AbstractSer
|
||||
.then((result) => result[0]);
|
||||
|
||||
const returnedKey = typeof result === 'object' ? result[primaryKeyField] : result;
|
||||
primaryKey = primaryKey ?? returnedKey;
|
||||
|
||||
if (this.schema.collections[this.collection].fields[primaryKeyField].type === 'uuid') {
|
||||
primaryKey = getHelpers(trx).schema.formatUUID(primaryKey ?? returnedKey);
|
||||
} else {
|
||||
primaryKey = primaryKey ?? returnedKey;
|
||||
}
|
||||
} catch (err: any) {
|
||||
throw await translateDatabaseError(err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user