diffusion
Version:
Diffusion JavaScript client
166 lines (127 loc) • 4.83 kB
JavaScript
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 + "'");
}
}
}
};