Skip to content

Commit

Permalink
fix(core): allow empty strings in postgres arrays (#2680)
Browse files Browse the repository at this point in the history
  • Loading branch information
evantrimboli authored Jan 28, 2022
1 parent c069960 commit 5a33722
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
5 changes: 3 additions & 2 deletions packages/postgresql/src/PostgreSqlPlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,16 @@ export class PostgreSqlPlatform extends AbstractSqlPlatform {
}

marshallArray(values: string[]): string {
return `{${values.join(',')}}`;
// Empty string needs to be explicitly represented
return `{${values.map(v => !v ? `""` : v).join(',')}}`;
}

unmarshallArray(value: string): string[] {
if (value === '{}') {
return [];
}

return value.substring(1, value.length - 1).split(',');
return value.substring(1, value.length - 1).split(',').map(v => v === `""` ? '' : v);
}

getBlobDeclarationSQL(): string {
Expand Down
93 changes: 93 additions & 0 deletions tests/issues/GH2679.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { ArrayType, Entity, LoadStrategy, ManyToOne, MikroORM, PrimaryKey, Property, wrap } from '@mikro-orm/core';
import type { PostgreSqlDriver } from '@mikro-orm/postgresql';

@Entity()
export class User {

@PrimaryKey()
id!: number;

@Property({ type: ArrayType })
groups!: readonly string[];

}

describe('GH issue 2679', () => {

let orm: MikroORM<PostgreSqlDriver>;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [User],
dbName: 'mikro_orm_test_gh_2679',
type: 'postgresql',
});

await orm.getSchemaGenerator().ensureDatabase();
await orm.getSchemaGenerator().dropSchema();
await orm.getSchemaGenerator().createSchema();
});

beforeEach(async () => {
await orm.em.createQueryBuilder(User).truncate().execute();
orm.em.clear();
});

afterAll(() => orm.close(true));

test('should be able to have an empty string alone', async () => {
const create = orm.em.create(User, {
groups: [''],
});
await orm.em.persistAndFlush(create);
orm.em.clear();

const loaded = (await orm.em.find(User, {}))[0];
expect(loaded.groups).toEqual(['']);
});

test('should be able to have an empty string at the start', async () => {
const create = orm.em.create(User, {
groups: ['', 'foo', 'bar'],
});
await orm.em.persistAndFlush(create);
orm.em.clear();

const loaded = (await orm.em.find(User, {}))[0];
expect(loaded.groups).toEqual(['', 'foo', 'bar']);
});

test('should be able to have an empty string at the end', async () => {
const create = orm.em.create(User, {
groups: ['foo', 'bar', ''],
});
await orm.em.persistAndFlush(create);
orm.em.clear();

const loaded = (await orm.em.find(User, {}))[0];
expect(loaded.groups).toEqual(['foo', 'bar', '']);
});

test('should be able to have an empty string in the middle', async () => {
const create = orm.em.create(User, {
groups: ['foo', '', 'bar'],
});
await orm.em.persistAndFlush(create);
orm.em.clear();

const f2 = orm.em.fork();
const loaded = (await f2.find(User, {}))[0];
expect(loaded.groups).toEqual(['foo', '', 'bar']);
});

test('should be able to have multiple empty strings', async () => {
const create = orm.em.create(User, {
groups: ['', 'foo', '', 'bar', ''],
});
await orm.em.persistAndFlush(create);
orm.em.clear();

const loaded = (await orm.em.find(User, {}))[0];
expect(loaded.groups).toEqual(['', 'foo', '', 'bar', '']);
});
});

0 comments on commit 5a33722

Please sign in to comment.