address comments

This commit is contained in:
Fredrik Adelöw
2020-06-18 11:54:12 +02:00
parent 8d961027a9
commit 3bff1d6a68
9 changed files with 83 additions and 79 deletions
@@ -49,7 +49,7 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
const response = await this.database.transaction(tx =>
this.entityByNameInternal(tx, kind, name, namespace),
);
return response ? response.entity : undefined;
return response?.entity;
}
async addOrUpdateEntity(
@@ -22,6 +22,7 @@ import {
import {
Entity,
EntityMeta,
entityMetaGeneratedFields,
generateEntityEtag,
generateEntityUid,
Location,
@@ -44,63 +45,9 @@ import type {
EntityFilters,
} from './types';
function serializeMetadata(metadata: EntityMeta): string {
const withoutGeneratedFields = lodash.cloneDeep(metadata);
delete withoutGeneratedFields.uid;
delete withoutGeneratedFields.etag;
delete withoutGeneratedFields.generation;
return JSON.stringify(withoutGeneratedFields);
}
function serializeSpec(spec: Entity['spec']): DbEntitiesRow['spec'] {
if (!spec) {
return null;
}
return JSON.stringify(spec);
}
function toEntityRow(
locationId: string | undefined,
entity: Entity,
): DbEntitiesRow {
return {
id: entity.metadata.uid!,
location_id: locationId || null,
etag: entity.metadata.etag!,
generation: entity.metadata.generation!,
api_version: entity.apiVersion,
kind: entity.kind,
name: entity.metadata.name,
namespace: entity.metadata.namespace || null,
metadata: serializeMetadata(entity.metadata),
spec: serializeSpec(entity.spec),
};
}
function toEntityResponse(row: DbEntitiesRow): DbEntityResponse {
const entity: Entity = {
apiVersion: row.api_version,
kind: row.kind,
metadata: {
...(JSON.parse(row.metadata) as Entity['metadata']),
uid: row.id,
etag: row.etag,
generation: Number(row.generation), // cast because of sqlite
},
};
if (row.spec) {
const spec = JSON.parse(row.spec);
entity.spec = spec;
}
return {
locationId: row.location_id || undefined,
entity,
};
}
/**
* The core database implementation.
*/
export class CommonDatabase implements Database {
constructor(
private readonly database: Knex,
@@ -149,7 +96,7 @@ export class CommonDatabase implements Database {
generation: 1,
};
const newRow = toEntityRow(request.locationId, newEntity);
const newRow = this.toEntityRow(request.locationId, newEntity);
await tx<DbEntitiesRow>('entities').insert(newRow);
await this.updateEntitiesSearch(tx, newRow.id, newEntity);
@@ -202,7 +149,7 @@ export class CommonDatabase implements Database {
// Store the updated entity; select on the old etag to ensure that we do
// not lose to another writer
const newRow = toEntityRow(request.locationId, request.entity);
const newRow = this.toEntityRow(request.locationId, request.entity);
const updatedRows = await tx<DbEntitiesRow>('entities')
.where({ id: oldRow.id, etag: oldRow.etag })
.update(newRow);
@@ -270,7 +217,7 @@ export class CommonDatabase implements Database {
.orderBy('name', 'asc')
.groupBy('id');
return rows.map(row => toEntityResponse(row));
return rows.map(row => this.toEntityResponse(row));
}
async entity(
@@ -289,7 +236,7 @@ export class CommonDatabase implements Database {
return undefined;
}
return toEntityResponse(rows[0]);
return this.toEntityResponse(rows[0]);
}
async entityByUid(
@@ -304,7 +251,7 @@ export class CommonDatabase implements Database {
return undefined;
}
return toEntityResponse(rows[0]);
return this.toEntityResponse(rows[0]);
}
async removeEntity(txOpaque: unknown, uid: string): Promise<void> {
@@ -466,4 +413,47 @@ export class CommonDatabase implements Database {
}
}
}
private toEntityRow(
locationId: string | undefined,
entity: Entity,
): DbEntitiesRow {
return {
id: entity.metadata.uid!,
location_id: locationId || null,
etag: entity.metadata.etag!,
generation: entity.metadata.generation!,
api_version: entity.apiVersion,
kind: entity.kind,
name: entity.metadata.name,
namespace: entity.metadata.namespace || null,
metadata: JSON.stringify(
lodash.omit(entity.metadata, ...entityMetaGeneratedFields),
),
spec: entity.spec ? JSON.stringify(entity.spec) : null,
};
}
private toEntityResponse(row: DbEntitiesRow): DbEntityResponse {
const entity: Entity = {
apiVersion: row.api_version,
kind: row.kind,
metadata: {
...(JSON.parse(row.metadata) as EntityMeta),
uid: row.id,
etag: row.etag,
generation: Number(row.generation), // cast because of sqlite
},
};
if (row.spec) {
const spec = JSON.parse(row.spec);
entity.spec = spec;
}
return {
locationId: row.location_id || undefined,
entity,
};
}
}
@@ -14,13 +14,12 @@
* limitations under the License.
*/
import React, { ComponentProps } from 'react';
import { render, cleanup } from '@testing-library/react';
import { RegisterComponentResultDialog } from './RegisterComponentResultDialog';
import { ThemeProvider } from '@material-ui/core';
import { lightTheme } from '@backstage/theme';
import { ThemeProvider } from '@material-ui/core';
import { cleanup, render } from '@testing-library/react';
import React, { ComponentProps } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Entity } from '@backstage/catalog-model';
import { RegisterComponentResultDialog } from './RegisterComponentResultDialog';
const setup = (
props?: Partial<ComponentProps<typeof RegisterComponentResultDialog>>,
@@ -52,6 +51,7 @@ it('should show a list of components if success', async () => {
const { rendered } = setup({
entities: [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'Component1',
@@ -61,6 +61,7 @@ it('should show a list of components if success', async () => {
},
},
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'Component2',
@@ -69,7 +70,7 @@ it('should show a list of components if success', async () => {
type: 'service',
},
},
] as Entity[],
],
});
expect(