UNPKG

electrodb-temp

Version:

A library to more easily create and interact with multiple entities and heretical relationships in dynamodb

113 lines (102 loc) 2.83 kB
const { UpdateOperations } = require("./updateOperations"); const { AttributeOperationProxy, ExpressionState } = require("./operations"); const { ItemOperations, BuilderTypes } = require("./types"); class UpdateExpression extends ExpressionState { constructor(props = {}) { super({ ...props }); this.operations = { set: new Set(), remove: new Set(), add: new Set(), subtract: new Set(), delete: new Set(), }; this.composites = {}; this.seen = new Map(); this.type = BuilderTypes.update; } addComposite(attrName, value) { if (value !== undefined) { if ( this.composites[attrName] === undefined || this.composites[attrName] === value ) { this.composites[attrName] = value; return true; } } return false; } add(type, expression) { this.operations[type].add(expression); } unadd(type, expression) { this.operations[type].delete(expression); } set(name, value, operation = ItemOperations.set, attribute) { let operationToApply = operation; if (operation === ItemOperations.ifNotExists) { operationToApply = ItemOperations.set; } const seen = this.seen.get(name); let n; let v; if (seen) { n = seen.name; v = seen.value; this.unadd(operationToApply, seen.expression); } else { n = this.setName({}, name, name); v = this.setValue(name, value); } let expression = `${n.prop} = ${v}`; if (operation === ItemOperations.ifNotExists) { expression = `${n.prop} = if_not_exists(${n.prop}, ${v})`; } this.seen.set(name, { name: n, value: v, expression, }); this.add(operationToApply, expression); } remove(name) { const n = this.setName({}, name, name); this.add(ItemOperations.remove, `${n.prop}`); } build() { let expressions = []; for (const type of Object.keys(this.operations)) { const operations = this.operations[type]; if (operations.size > 0) { expressions.push( `${type.toUpperCase()} ${Array.from(operations).join(", ")}`, ); } } return expressions.join(" "); } } class UpdateEntity { constructor(attributes = {}, operations = {}) { this.attributes = { ...attributes }; this.operations = { ...operations }; } buildCallbackHandler(entity, state) { const proxy = new AttributeOperationProxy({ builder: state.query.update, attributes: this.attributes, operations: this.operations, }); return (cb, ...params) => { if (typeof cb !== "function") { throw new Error('Update Callback must be of type "function"'); } proxy.invokeCallback(cb, ...params); }; } } module.exports = { UpdateEntity, UpdateExpression, };