mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
fix(database): insertKeys filtering (#194)
* fix(database): insertKeys filtering * fix: tests
This commit is contained in:
parent
f85b922836
commit
67843f45db
2 changed files with 19 additions and 13 deletions
|
@ -6,22 +6,25 @@ import RequestError from '@/errors/RequestError';
|
||||||
import { createTestPool } from '@/utils/test-utils';
|
import { createTestPool } from '@/utils/test-utils';
|
||||||
|
|
||||||
import { buildInsertInto } from './insert-into';
|
import { buildInsertInto } from './insert-into';
|
||||||
import { convertToIdentifiers, excludeAutoSetFields } from './utils';
|
import { convertToIdentifiers } from './utils';
|
||||||
|
|
||||||
describe('buildInsertInto()', () => {
|
const buildExpectedInsertIntoSql = (keys: string[]) => [
|
||||||
const keys = excludeAutoSetFields(Users.fieldKeys);
|
|
||||||
const expectInsertIntoSql = [
|
|
||||||
`insert into "users" (${keys.map((key) => `"${decamelize(key)}"`).join(', ')})`,
|
`insert into "users" (${keys.map((key) => `"${decamelize(key)}"`).join(', ')})`,
|
||||||
`values (${keys.map((_, index) => `$${index + 1}`).join(', ')})`,
|
`values (${keys.map((_, index) => `$${index + 1}`).join(', ')})`,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
describe('buildInsertInto()', () => {
|
||||||
it('resolves a promise with `undefined` when `returning` is false', async () => {
|
it('resolves a promise with `undefined` when `returning` is false', async () => {
|
||||||
|
const user: CreateUser = { id: 'foo', username: '456' };
|
||||||
|
const expectInsertIntoSql = buildExpectedInsertIntoSql(Object.keys(user));
|
||||||
const pool = createTestPool(expectInsertIntoSql.join('\n'));
|
const pool = createTestPool(expectInsertIntoSql.join('\n'));
|
||||||
const insertInto = buildInsertInto(pool, Users);
|
const insertInto = buildInsertInto(pool, Users);
|
||||||
await expect(insertInto({ id: 'foo', username: '456' })).resolves.toBe(undefined);
|
await expect(insertInto(user)).resolves.toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves a promise with `undefined` when `returning` is false and `onConflict` is enabled', async () => {
|
it('resolves a promise with `undefined` when `returning` is false and `onConflict` is enabled', async () => {
|
||||||
|
const user: CreateUser = { id: 'foo', username: '456', primaryEmail: 'foo@bar.com' };
|
||||||
|
const expectInsertIntoSql = buildExpectedInsertIntoSql(Object.keys(user));
|
||||||
const pool = createTestPool(
|
const pool = createTestPool(
|
||||||
[
|
[
|
||||||
...expectInsertIntoSql,
|
...expectInsertIntoSql,
|
||||||
|
@ -36,13 +39,12 @@ describe('buildInsertInto()', () => {
|
||||||
setExcludedFields: [fields.primaryEmail],
|
setExcludedFields: [fields.primaryEmail],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await expect(
|
await expect(insertInto(user)).resolves.toBe(undefined);
|
||||||
insertInto({ id: 'foo', username: '456', primaryEmail: 'foo@bar.com' })
|
|
||||||
).resolves.toBe(undefined);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves a promise with single entity when `returning` is true', async () => {
|
it('resolves a promise with single entity when `returning` is true', async () => {
|
||||||
const user: CreateUser = { id: 'foo', username: '123', primaryEmail: 'foo@bar.com' };
|
const user: CreateUser = { id: 'foo', username: '123', primaryEmail: 'foo@bar.com' };
|
||||||
|
const expectInsertIntoSql = buildExpectedInsertIntoSql(Object.keys(user));
|
||||||
const pool = createTestPool(
|
const pool = createTestPool(
|
||||||
[...expectInsertIntoSql, 'returning *'].join('\n'),
|
[...expectInsertIntoSql, 'returning *'].join('\n'),
|
||||||
(_, [id, username, primaryEmail]) => ({
|
(_, [id, username, primaryEmail]) => ({
|
||||||
|
@ -58,6 +60,8 @@ describe('buildInsertInto()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws `entity.create_failed` error with `undefined` when `returning` is true', async () => {
|
it('throws `entity.create_failed` error with `undefined` when `returning` is true', async () => {
|
||||||
|
const user: CreateUser = { id: 'foo', username: '123', primaryEmail: 'foo@bar.com' };
|
||||||
|
const expectInsertIntoSql = buildExpectedInsertIntoSql(Object.keys(user));
|
||||||
const pool = createTestPool([...expectInsertIntoSql, 'returning *'].join('\n'));
|
const pool = createTestPool([...expectInsertIntoSql, 'returning *'].join('\n'));
|
||||||
const insertInto = buildInsertInto(pool, Users, { returning: true });
|
const insertInto = buildInsertInto(pool, Users, { returning: true });
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { SchemaLike, GeneratedSchema } from '@logto/schemas';
|
import { SchemaLike, GeneratedSchema } from '@logto/schemas';
|
||||||
|
import { has } from '@silverhand/essentials';
|
||||||
import { DatabasePoolType, IdentifierSqlTokenType, sql } from 'slonik';
|
import { DatabasePoolType, IdentifierSqlTokenType, sql } from 'slonik';
|
||||||
|
|
||||||
import assertThat from '@/utils/assert-that';
|
import assertThat from '@/utils/assert-that';
|
||||||
|
@ -59,15 +60,16 @@ export const buildInsertInto: BuildInsertInto = <
|
||||||
const onConflict = config?.onConflict;
|
const onConflict = config?.onConflict;
|
||||||
|
|
||||||
return async (data: OmitAutoSetFields<Schema>): Promise<ReturnType | void> => {
|
return async (data: OmitAutoSetFields<Schema>): Promise<ReturnType | void> => {
|
||||||
|
const insertingKeys = keys.filter((key) => has(data, key));
|
||||||
const {
|
const {
|
||||||
rows: [entry],
|
rows: [entry],
|
||||||
} = await pool.query<ReturnType>(sql`
|
} = await pool.query<ReturnType>(sql`
|
||||||
insert into ${table} (${sql.join(
|
insert into ${table} (${sql.join(
|
||||||
keys.map((key) => fields[key]),
|
insertingKeys.map((key) => fields[key]),
|
||||||
sql`, `
|
sql`, `
|
||||||
)})
|
)})
|
||||||
values (${sql.join(
|
values (${sql.join(
|
||||||
keys.map((key) => convertToPrimitiveOrSql(key, data[key] ?? null)),
|
insertingKeys.map((key) => convertToPrimitiveOrSql(key, data[key] ?? null)),
|
||||||
sql`, `
|
sql`, `
|
||||||
)})
|
)})
|
||||||
${conditionalSql(returning, () => sql`returning *`)}
|
${conditionalSql(returning, () => sql`returning *`)}
|
||||||
|
|
Loading…
Add table
Reference in a new issue