Various relational updates

This commit is contained in:
rijkvanzanten
2020-08-31 19:22:25 -04:00
parent 3cd22d416c
commit 56ba0eec64
10 changed files with 93 additions and 45 deletions

View File

@@ -105,7 +105,7 @@ router.patch(
let results: any = [];
for (const field of req.body) {
await service.updateField(req.params.collection, field, req.accountability);
await service.updateField(req.params.collection, field);
const updatedField = await service.readOne(req.params.collection, field.field);
@@ -120,17 +120,13 @@ router.patch(
'/:collection/:field',
validateCollection,
useCollection('directus_fields'),
// @todo: validate field
asyncHandler(async (req, res) => {
const exists = await schemaInspector.hasColumn(req.collection, req.params.field);
if (exists === false) throw new ForbiddenException();
const service = new FieldsService({ accountability: req.accountability });
const fieldData: Partial<Field> & { field: string; type: typeof types[number] } = req.body;
if (!fieldData.field) fieldData.field = req.params.field;
await service.updateField(req.params.collection, fieldData, req.accountability);
await service.updateField(req.params.collection, fieldData);
const updatedField = await service.readOne(req.params.collection, req.params.field);
@@ -143,11 +139,7 @@ router.delete(
validateCollection,
useCollection('directus_fields'),
asyncHandler(async (req, res) => {
const exists = await schemaInspector.hasColumn(req.collection, req.params.field);
if (exists === false) throw new ForbiddenException();
const service = new FieldsService({ accountability: req.accountability });
await service.deleteField(req.params.collection, req.params.field, req.accountability);
res.status(200).end();

View File

@@ -1,7 +1,6 @@
import database, { schemaInspector } from '../database';
import { Field } from '../types/field';
import { uniq } from 'lodash';
import { Accountability, AbstractServiceOptions, FieldMeta } from '../types';
import { Accountability, AbstractServiceOptions, FieldMeta, Relation } from '../types';
import ItemsService from '../services/items';
import { ColumnBuilder } from 'knex';
import getLocalType from '../utils/get-local-type';
@@ -172,6 +171,10 @@ export default class FieldsService {
field: Partial<Field> & { field: string; type: typeof types[number] },
table?: CreateTableBuilder // allows collection creation to
) {
if (this.accountability && this.accountability.admin !== true) {
throw new ForbiddenException('Only admins can perform this action.');
}
/**
* @todo
* Check if table / directus_fields row already exists
@@ -198,7 +201,11 @@ export default class FieldsService {
/** @todo research how to make this happen in SQLite / Redshift */
async updateField(collection: string, field: RawField, accountability?: Accountability) {
async updateField(collection: string, field: RawField) {
if (this.accountability && this.accountability.admin !== true) {
throw new ForbiddenException('Only admins can perform this action.');
}
if (field.schema) {
await this.knex.schema.alterTable(collection, (table) => {
let column: ColumnBuilder;
@@ -251,12 +258,35 @@ export default class FieldsService {
}
/** @todo save accountability */
async deleteField(collection: string, field: string, accountability?: Accountability) {
await database('directus_fields').delete().where({ collection, field });
async deleteField(collection: string, field: string) {
if (this.accountability && this.accountability.admin !== true) {
throw new ForbiddenException('Only admins can perform this action.');
}
await database.schema.table(collection, (table) => {
table.dropColumn(field);
});
await this.knex('directus_fields').delete().where({ collection, field });
if (await schemaInspector.hasColumn(collection, field)) {
await this.knex.schema.table(collection, (table) => {
table.dropColumn(field);
});
}
const relations = await this.knex
.select<Relation[]>('*')
.from('directus_relations')
.where({ many_collection: collection, many_field: field })
.orWhere({ one_collection: collection, one_field: field });
for (const relation of relations) {
const isM2O = relation.many_collection === collection && relation.many_field === field;
if (isM2O) {
await this.knex('directus_relations').delete().where({ many_collection: collection, many_field: field });
await this.deleteField(relation.one_collection, relation.one_field);
} else {
await this.knex('directus_relations').update({ one_field: null }).where({ one_collection: collection, one_field: field });
}
}
}
public addColumnToTable(table: CreateTableBuilder, field: Field) {