@sqb/connect
Version:
Multi-dialect database connection framework written with TypeScript
78 lines (77 loc) • 3 kB
JavaScript
import { And, Param, Update } from '@sqb/builder';
import { checkEnumValue, isColumnField, isEmbeddedField, resolveEntityForEmbeddedField, } from '../util/orm.helper.js';
import { prepareFilter } from './command.helper.js';
export class UpdateCommand {
// istanbul ignore next
constructor() {
throw new Error('This class is abstract');
}
static async execute(args) {
const { entity } = args;
const tableName = entity.tableName;
if (!tableName)
throw new Error(`${entity.ctor.name} is not decorated with @Entity decorator`);
// Create a context
const ctx = {
entity,
queryParams: {},
queryValues: {},
queryFilter: [],
colCount: 0,
};
// Prepare
await this._prepareParams(ctx, entity, args.values);
if (!ctx.colCount)
return 0;
if (args.filter)
await this._prepareFilter(ctx, args.filter);
const query = Update(tableName + ' as T', ctx.queryValues).where(...ctx.queryFilter);
const qr = await args.connection.execute(query, {
params: args.params ? [...args.params, ctx.queryParams] : ctx.queryParams,
objectRows: false,
cursor: false,
});
return qr.rowsAffected || 0;
}
static async _prepareFilter(ctx, filter) {
if (filter) {
const where = And();
await prepareFilter(ctx.entity, filter, where);
ctx.queryFilter.push(...where._items);
}
}
static async _prepareParams(ctx, entity, values, prefix, suffix) {
let v;
prefix = prefix || '';
suffix = suffix || '';
for (const col of Object.values(entity.fields)) {
v = values[col.name];
if (v === undefined)
continue;
if (isColumnField(col)) {
if (col.noUpdate)
continue;
if (typeof col.serialize === 'function')
v = col.serialize(v, col.name);
if (v === null && col.notNull)
throw new Error(`${entity.name}.${col.name} is required and can't be null`);
if (v === undefined)
continue;
checkEnumValue(col, v);
const fieldName = prefix + col.fieldName + suffix;
const k = ('I$_' + fieldName).substring(0, 30);
ctx.queryValues[fieldName] = Param({
name: k,
dataType: col.dataType,
isArray: col.isArray,
});
ctx.queryParams[k] = v;
ctx.colCount++;
}
else if (v != null && isEmbeddedField(col)) {
const type = await resolveEntityForEmbeddedField(col);
await this._prepareParams(ctx, type, v, col.fieldNamePrefix, col.fieldNameSuffix);
}
}
}
}