UNPKG

diffusion

Version:

Diffusion JavaScript client

166 lines (127 loc) 4.83 kB
var requireNonNull = require('util/require-non-null'); var SchemaImpl = require('data/record/schema/schema-impl'); var RecordImpl = require('data/record/schema/record-impl'); var FieldImpl = require('data/record/schema/field-impl'); function checkMultiplicity(name, min, max) { if (min < 0) { throw new Error("'" + name + "' has invalid 'min' value '" + min + "'"); } if (max !== -1 && (max < 1 || max < min)) { throw new Error("'" + name + "' has invalid 'max' value '" + max + "'"); } } function checkScale(name, scale) { if (scale < 1) { throw new Error("'" + name + "' has invalid 'scale' value '" + scale + "'"); } } module.exports = function SchemaBuilderImpl(constructor) { var records = []; // Track current record context var currentName, currentFields, currentMin, currentMax; this.record = function(name, min, max) { min = typeof min === "number" ? min : 1; max = typeof max === "number" ? max : min; checkMultiplicity(name, min, max); checkRecord(name); if (currentFields !== undefined) { addRecord(); } currentName = name; currentMin = min; currentMax = max; currentFields = []; return this; }; this.string = function(name, min, max) { min = typeof min === "number" ? min : 1; max = typeof max === "number" ? max : min; checkMultiplicity(name, min, max); checkField(name); currentFields.push(new FieldImpl(name, FieldImpl.Type.STRING, min, max, fieldIndex())); return this; }; this.integer = function(name, min, max) { min = typeof min === "number" ? min : 1; max = typeof max === "number" ? max : min; checkMultiplicity(name, min, max); checkField(name); currentFields.push(new FieldImpl(name, FieldImpl.Type.INTEGER, min, max, fieldIndex())); return this; }; this.decimal = function(name, scale, min, max) { min = typeof min === "number" ? min : 1; max = typeof max === "number" ? max : min; checkMultiplicity(name, min, max); checkScale(name, scale); checkField(name); currentFields.push(new FieldImpl(name, FieldImpl.Type.DECIMAL, min, max, fieldIndex(), scale)); return this; }; this.build = function() { if (currentFields !== undefined) { addRecord(); } if (records.length === 0) { throw new Error("Schema has no records"); } return new SchemaImpl(constructor, records); }; function fieldIndex() { if (currentFields.length === 0) { return 0; } var lastField = currentFields[currentFields.length - 1]; return lastField.index + lastField.max; } function addRecord() { if (currentFields.length === 0) { throw new Error("No fields specified for record: '" + currentName + "'"); } var index; if (records.length === 0) { index = 0; } else { var lastRecord = records[records.length - 1]; index = lastRecord.index + lastRecord.max; } records.push(new RecordImpl(currentName, currentMin, currentMax, index, currentFields)); } function checkRecord(name) { requireNonNull(name, "name"); if (name === currentName) { throw new Error("Duplicate record name: '" + name + "'"); } if (records.length) { for (var i = 0; i < records.length; ++i) { if (name === records[i].name) { throw new Error("Duplicate record name: '" + name + "'"); } } } if (currentFields !== undefined && currentMin !== currentMax) { throw new Error( "Record '" + name + "' not allowed after variable multiplicity record: '" + currentName + "'"); } } function checkField(name) { requireNonNull(name, "name"); if (currentFields === undefined) { throw new Error("Cannot add field '" + name + "' as there is no current record"); } if (currentFields.length) { for (var i = 0; i < currentFields.length; ++i) { if (name === currentFields[i].name) { throw new Error("Duplicate field name: '" + name + "'"); } } var lastField = currentFields[currentFields.length - 1]; if (lastField.isVariable) { throw new Error( "Field '" + name + "' is not allowed after variable multiplicity field '" + lastField.name + "'"); } } } };