@decaf-ts/core
Version:
Core persistence module for the decaf framework
87 lines • 4.09 kB
JavaScript
import { MethodQueryBuilder } from "./MethodQueryBuilder.js";
import { QueryError } from "./errors.js";
import { apply, Decoration, Metadata, methodMetadata, } from "@decaf-ts/decoration";
import { PersistenceKeys } from "./../persistence/constants.js";
export function prepared() {
function prepared() {
return function prepared(obj, prop, descriptor) {
return apply(methodMetadata(Metadata.key(PersistenceKeys.STATEMENT, prop), true))(obj, prop, descriptor);
};
}
return Decoration.for(PersistenceKeys.STATEMENT)
.define({
decorator: prepared,
args: [],
})
.apply();
}
export function query(options = {}) {
function query(options) {
return function query(obj, prop, descriptor) {
function innerQuery(options) {
return function innerQuery(obj, propertyKey, descriptor) {
descriptor.value = new Proxy(descriptor.value, {
apply(target, thisArg, args) {
const { select, where, groupBy, orderBy, limit, offset } = MethodQueryBuilder.build(target.name, ...args);
let stmt = thisArg.select(select);
if (where)
stmt = stmt.where(where);
// if (orderBy) stmt = stmt.orderBy(orderBy[0]);
if (groupBy) {
// group by not implemented yet
/* stmt = stmt.groupBy(groupBy); */
}
// allow limit and offset by default
const { allowLimit, allowOffset, allowOrderBy, throws } = {
allowLimit: true,
allowOrderBy: true,
allowOffset: true,
throws: true,
...options,
};
const params = [
// keep the order to ensure the expected behavior
{
key: "orderBy",
value: (orderBy || [])[0], // orderBy only supports one sentence
allowed: allowOrderBy,
},
{ key: "limit", value: limit, allowed: allowLimit },
{ key: "offset", value: offset, allowed: allowOffset },
];
for (const param of params) {
if (param.value !== undefined) {
if (!param.allowed && throws) {
throw new QueryError(`${param.key[0].toUpperCase() + param.key.slice(1)} is not allowed for this query`);
}
else if (param.allowed) {
stmt = stmt[param.key](param.value);
}
}
}
return stmt.execute();
},
});
};
}
const fields = MethodQueryBuilder.getFieldsFromMethodName(prop);
// const paramNames = descriptor.value
// .toString()
// .match(/\(([^)]*)\)/)?.[1]
// .split(",")
// .map((x) => x.trim())
// .filter(Boolean);
return apply(methodMetadata(Metadata.key(PersistenceKeys.QUERY, prop), {
...options,
fields,
}), prepared(), innerQuery(options))(obj, prop, descriptor);
};
}
return Decoration.for(PersistenceKeys.QUERY)
.define({
decorator: query,
args: [options],
})
.apply();
}
//# sourceMappingURL=decorators.js.map