* refactor(logger): improve logger format * chore: improve log format * feat(logger): plugin-logger * feat: allow to download log files, close T-1917 * chore: update yarn.lock * chore: improve log format * fix: add maxsize params * chore: add userId field to request * chore: remove userId from request * chore: change userId in response * chore: change action in response * chore: add database logger * fix: build * fix: test * chore: solve conflicts * fix: escape delimiter in message * refactor: improve create logger api * chore: update app logger options * chore: remove colorize for json * fix: bug of data2tree * fix: test * chore: log * chore: remove GITHUB_ACTION check * fix: bug * chore: change version * fix: transports * fix: mockServer * chore: use new plugin settings api * fix: version * fix: build * feat: support logfmt * fix: build * fix: build * fix: test * chore: update config * fix: test * fix: bug * fix: test * fix: format * chore: update path * fix: build * fix: bug * chore: update comment * fix: allow to custom format * fix: package.json * fix: version * fix: bug
97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
import { Context, Next } from '@nocobase/actions';
|
|
import { SQLModel, SqlCollection } from '@nocobase/database';
|
|
import { CollectionModel } from '../models';
|
|
|
|
const updateCollection = async (ctx: Context, transaction: any) => {
|
|
const { filterByTk, values } = ctx.action.params;
|
|
const repo = ctx.db.getRepository('collections');
|
|
const collection: CollectionModel = await repo.findOne({
|
|
filter: {
|
|
name: filterByTk,
|
|
},
|
|
transaction,
|
|
});
|
|
const existFields = await collection.getFields({ transaction });
|
|
const deletedFields = existFields.filter((field: any) => !values.fields?.find((f: any) => f.name === field.name));
|
|
for (const field of deletedFields) {
|
|
await field.destroy({ transaction });
|
|
}
|
|
const upRes = await repo.update({
|
|
filterByTk,
|
|
values,
|
|
updateAssociationValues: ['fields'],
|
|
transaction,
|
|
});
|
|
|
|
return { collection, upRes };
|
|
};
|
|
|
|
export default {
|
|
name: 'sqlCollection',
|
|
actions: {
|
|
execute: async (ctx: Context, next: Next) => {
|
|
let {
|
|
values: { sql },
|
|
} = ctx.action.params;
|
|
sql = sql.trim().split(';').shift();
|
|
if (!sql) {
|
|
ctx.throw(400, ctx.t('SQL is empty'));
|
|
}
|
|
if (!/^select/i.test(sql) && !/^with([\s\S]+)select([\s\S]+)/i.test(sql)) {
|
|
ctx.throw(400, ctx.t('Only select query allowed'));
|
|
}
|
|
const tmpCollection = new SqlCollection({ name: 'tmp', sql }, { database: ctx.db });
|
|
const model = tmpCollection.model as typeof SQLModel;
|
|
// The result is for preview only, add limit clause to avoid too many results
|
|
const data = await model.findAll({ attributes: ['*'], limit: 5, raw: true });
|
|
let fields: {
|
|
[field: string]: {
|
|
type: string;
|
|
source: string;
|
|
collection: string;
|
|
interface: string;
|
|
};
|
|
} = {};
|
|
try {
|
|
fields = model.inferFields();
|
|
} catch (err) {
|
|
ctx.logger.warn(`resource: sql-collection, action: execute, error: ${err}`);
|
|
fields = {};
|
|
}
|
|
const sources = Array.from(new Set(Object.values(fields).map((field) => field.collection)));
|
|
ctx.body = { data, fields, sources };
|
|
await next();
|
|
},
|
|
setFields: async (ctx: Context, next: Next) => {
|
|
const transaction = await ctx.app.db.sequelize.transaction();
|
|
try {
|
|
const {
|
|
upRes: [collection],
|
|
} = await updateCollection(ctx, transaction);
|
|
await collection.loadFields({
|
|
transaction,
|
|
});
|
|
await transaction.commit();
|
|
} catch (e) {
|
|
await transaction.rollback();
|
|
throw e;
|
|
}
|
|
await next();
|
|
},
|
|
update: async (ctx: Context, next: Next) => {
|
|
const transaction = await ctx.app.db.sequelize.transaction();
|
|
try {
|
|
const { upRes } = await updateCollection(ctx, transaction);
|
|
const [collection] = upRes;
|
|
await (collection as CollectionModel).load({ transaction, resetFields: true });
|
|
await transaction.commit();
|
|
ctx.body = upRes;
|
|
} catch (e) {
|
|
await transaction.rollback();
|
|
throw e;
|
|
}
|
|
await next();
|
|
},
|
|
},
|
|
};
|