Fix updating in SQLite

Fixes #141, ref #283
This commit is contained in:
rijkvanzanten
2020-09-18 12:06:46 -04:00
parent 197134d859
commit 52540e60a3
3 changed files with 44 additions and 15 deletions

View File

@@ -1,11 +1,23 @@
import { AST, NestedCollectionAST } from '../types/ast';
import { clone, uniq, pick } from 'lodash';
import database, { schemaInspector } from './index';
import database from './index';
import SchemaInspector from 'knex-schema-inspector';
import { Query, Item } from '../types';
import PayloadService from '../services/payload';
import applyQuery from '../utils/apply-query';
import Knex from 'knex';
type RunASTOptions = {
query?: AST['query'],
knex?: Knex
}
export default async function runAST(ast: AST, options?: RunASTOptions) {
const query = options?.query || ast.query;
const knex = options?.knex || database;
const schemaInspector = SchemaInspector(knex);
export default async function runAST(ast: AST, query = ast.query) {
const toplevelFields: string[] = [];
const tempFields: string[] = [];
const nestedCollections: NestedCollectionAST[] = [];
@@ -14,7 +26,7 @@ export default async function runAST(ast: AST, query = ast.query) {
({ column }) => column
);
const payloadService = new PayloadService(ast.name);
const payloadService = new PayloadService(ast.name, { knex });
for (const child of ast.children) {
if (child.type === 'field') {
@@ -40,7 +52,7 @@ export default async function runAST(ast: AST, query = ast.query) {
tempFields.push(primaryKeyField);
}
let dbQuery = database.select([...toplevelFields, ...tempFields]).from(ast.name);
let dbQuery = knex.select([...toplevelFields, ...tempFields]).from(ast.name);
// Query defaults
query.limit = typeof query.limit === 'number' ? query.limit : 100;
@@ -125,7 +137,7 @@ export default async function runAST(ast: AST, query = ast.query) {
}
}
const nestedResults = await runAST(batch, batchQuery);
const nestedResults = await runAST(batch, { query: batchQuery, knex });
results = results.map((record) => {
if (m2o) {

View File

@@ -168,7 +168,7 @@ export default class ItemsService implements AbstractService {
const authorizationService = new AuthorizationService({
accountability: this.accountability,
});
let ast = await getASTFromQuery(this.collection, query, this.accountability);
let ast = await getASTFromQuery(this.collection, query, { accountability: this.accountability, knex: this.knex });
if (this.accountability && this.accountability.admin === false) {
ast = await authorizationService.processAST(ast);
@@ -204,19 +204,24 @@ export default class ItemsService implements AbstractService {
let ast = await getASTFromQuery(
this.collection,
queryWithFilter,
this.accountability,
action
{
accountability: this.accountability,
action,
knex: this.knex,
}
);
if (this.accountability && this.accountability.admin !== true) {
const authorizationService = new AuthorizationService({
accountability: this.accountability,
knex: this.knex,
});
ast = await authorizationService.processAST(ast, action);
}
const records = await runAST(ast);
const records = await runAST(ast, { knex: this.knex });
return Array.isArray(key) ? records : records[0];
return [] as Item;
}
update(data: Partial<Item>, keys: PrimaryKey[]): Promise<PrimaryKey[]>;
@@ -301,7 +306,6 @@ export default class ItemsService implements AbstractService {
}
const itemsService = new ItemsService(this.collection, { knex: trx });
const snapshots = await itemsService.readByKey(keys);
const revisionRecords = activityPrimaryKeys.map((key, index) => ({

View File

@@ -13,26 +13,39 @@ import {
} from '../types';
import database from '../database';
import { clone } from 'lodash';
import Knex from 'knex';
type GetASTOptions = {
accountability?: Accountability | null;
action?: PermissionsAction;
knex?: Knex;
}
export default async function getASTFromQuery(
collection: string,
query: Query,
accountability?: Accountability | null,
action?: PermissionsAction
options?: GetASTOptions
// accountability?: Accountability | null,
// action?: PermissionsAction
): Promise<AST> {
query = clone(query);
const accountability = options?.accountability;
const action = options?.action || 'read';
const knex = options?.knex || database;
/**
* we might not need al this info at all times, but it's easier to fetch it all once, than trying to fetch it for every
* requested field. @todo look into utilizing graphql/dataloader for this purpose
*/
const relations = await database.select<Relation[]>('*').from('directus_relations');
const relations = await knex.select<Relation[]>('*').from('directus_relations');
const permissions =
accountability && accountability.admin !== true
? await database
? await knex
.select<{ collection: string; fields: string }[]>('collection', 'fields')
.from('directus_permissions')
.where({ role: accountability.role, action: action || 'read' })
.where({ role: accountability.role, action: action })
: null;
const ast: AST = {