fql-toolkit
Version:
163 lines • 5.84 kB
JavaScript
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
function buildStringFromCondition(condition) {
if (Array.isArray(condition)) {
const [operator, ...operands] = condition;
if (operator === 'symb') {
return operands.join('.');
}
return operands.map(buildStringFromCondition).join(` ${operator} `);
}
if (typeof condition === 'string') {
return `'${escapeFQLLiteral(condition)}'`;
}
return String(condition);
}
export function escapeFQLLiteral(s) {
return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'"); // backslash FIRST, then quote
}
function formatValue(value) {
if (typeof value === 'string') {
return `'${escapeFQLLiteral(value)}'`;
}
if (Array.isArray(value)) {
return `(${value.map(formatValue).join(', ')})`;
}
return String(value);
}
function getPathString(path) {
if (typeof path === 'string') {
return path;
}
return path
.map((element) => {
if (typeof element === 'string') {
return element;
}
return `(${element.map(getPathString).join(', ')})`;
})
.join('.');
}
// ---------------------------------------------------------------------------
// FQLQueryBuilder
// ---------------------------------------------------------------------------
export default class FQLQueryBuilder {
static buildCreateFormQuery({ name, specs }) {
const specsString = specs
.map((spec) => {
if (spec.type === 'reference') {
const ref = spec;
let s = `${ref.name} references ${ref.cardinality[0]}..${ref.cardinality[1]} ${getPathString(ref.path)}`;
if (ref.unique) {
s += ' unique';
}
if (ref.totally) {
s += ' totally unique';
}
return s;
}
const def = spec;
let s = `${def.name} ${def.type}`;
if (def.notNull) {
s += ' not null';
}
if (def.unique) {
s += ' unique';
}
return s;
})
.join(', ');
return `create form ${name}(${specsString})`;
}
static buildShowFormsQuery(forms) {
return forms.length !== 0 ? `show forms ${forms.join(' ')}` : 'show forms';
}
static buildRemoveFormsQuery(forms) {
return forms.length !== 0 ? `remove forms ${forms.join(' ')}` : 'remove forms';
}
static buildCreateNewQuery(formName, values) {
return `create ${formName}(${values.map(formatValue).join(', ')})`;
}
static buildGetCaseQuery(formName, fields = [], condition = null) {
let result = `get ${formName}`;
if (fields.length !== 0) {
result += `(${fields.join(', ')})`;
}
if (condition) {
result += ` with ${buildStringFromCondition(condition)}`;
}
return result;
}
static buildRemoveCaseQuery(formName, condition = null) {
let result = `remove ${formName}`;
if (condition) {
result += ` with ${buildStringFromCondition(condition)}`;
}
return result;
}
static buildModifyCaseQuery(formName, values, condition = null) {
let result = `modify ${formName}(${values.map(formatValue).join(', ')})`;
if (condition) {
result += ` with ${buildStringFromCondition(condition)}`;
}
return result;
}
static buildDefineRuleQuery(ruleName, formName, fields, during, condition, action, dict) {
let result = `define rule ${ruleName}: on ${formName}`;
if (fields.length !== 0) {
result += `(${fields.join(', ')})`;
}
if (during.length !== 0) {
result += ` during (${during.join(' ')})`;
}
if (action !== 'is unique') {
result += ` when ${buildStringFromCondition(condition)}`;
}
if (action === 'set') {
result += ` set ${dict.map(({ key, value }) => `${key} = ${typeof value === 'string' ? `'${escapeFQLLiteral(value)}'` : value}`).join(', ')}`;
}
else {
result += ` ${action}`;
}
return result;
}
static buildDefineConceptQuery(conceptName, entityName, condition) {
return `define concept ${conceptName} is ${entityName} with ${buildStringFromCondition(condition)}`;
}
static buildModifyFormQuery(formName, { add = [], remove = [] }) {
let result = `modify form ${formName}`;
if (add.length > 0) {
const addSpecs = add
.map((spec) => {
if (spec.type === 'reference') {
const ref = spec;
let s = `${ref.name} references ${ref.cardinality[0]}..${ref.cardinality[1]} ${getPathString(ref.path)}`;
if (ref.unique) {
s += ' unique';
}
if (ref.totally) {
s += ' totally unique';
}
return s;
}
const def = spec;
let s = `${def.name} ${def.type}`;
if (def.notNull) {
s += ' not null';
}
if (def.unique) {
s += ' unique';
}
return s;
})
.join(', ');
result += ` add (${addSpecs})`;
}
if (remove.length > 0) {
result += ` remove (${remove.join(', ')})`;
}
return result;
}
}
//# sourceMappingURL=builders.js.map