diffusion
Version:
Diffusion JavaScript client
145 lines (114 loc) • 4.19 kB
JavaScript
var RecordV2Writer = require('data/record/recordv2-writer');
function resolveRecordIndex(record, records, index) {
var actualIndex = record.getAbsoluteIndex(index);
if (actualIndex > records.length - 1) {
throw new Error(
"Index '" + index +
"' does not have a matching entry for variable occurence record: '" + record.name + "'");
}
return actualIndex;
}
function resolveFieldIndex(field, fields, index) {
var actualIndex = field.getAbsoluteIndex(index);
if (actualIndex > fields.length - 1) {
throw new Error(
"Index '" + index +
"' does not have a matching entry for variable occurence field: '" + field.name + "'");
}
return actualIndex;
}
module.exports = function AbstractRecordModel(constructor, schema) {
var self = this;
this.schema = function() {
return schema;
};
this.asValue = function() {
return new constructor(RecordV2Writer.toBuffer(self.model()));
};
this.get = function(recordName, recordIndex, fieldName, fieldIndex) {
// Account for optional indices
if (arguments.length < 4) {
fieldIndex = 0;
}
if (arguments.length === 2) {
fieldName = recordIndex;
recordIndex = 0;
}
if (arguments.length === 1) {
var key = parseKey(recordName);
recordName = key.recordName;
recordIndex = key.recordIndex;
fieldName = key.fieldName;
fieldIndex = key.fieldIndex;
}
var schemaRecord = schema.getRecord(recordName);
var schemaField = schemaRecord.getField(fieldName);
var record = getRecord(schemaRecord, recordIndex);
return record[resolveFieldIndex(schemaField, record, fieldIndex)];
};
this.recordCount = function(recordName) {
var schemaRecord = schema.getRecord(recordName);
if (schemaRecord.isVariable) {
return self.model().length - schemaRecord.getIndex();
} else {
return schemaRecord.min;
}
};
this.fieldCount = function(recordName, recordIndex, fieldName) {
var schemaRecord = schema.getRecord(recordName);
var schemaField = schemaRecord.getField(fieldName);
if (schemaField.isVariable) {
var record = getRecord(schemaRecord, recordIndex);
return record.length - schemaField.getIndex();
} else {
return schemaField.min;
}
};
function getRecord(schemaRecord, index) {
var model = self.model();
return model[resolveRecordIndex(schemaRecord, model, index)];
}
function parseKey(key) {
var parts = key.split(".", 2);
var recordName;
var recordIndex;
var fieldKey;
if (parts.length === 1) {
recordName = schema.firstRecord().name;
recordIndex = 0;
fieldKey = parts[0];
} else {
var recordKeyParts = parseKeyPart(parts[0].trim());
recordName = recordKeyParts[0];
recordIndex = recordKeyParts[1];
fieldKey = parts[1];
}
var keyParts = parseKeyPart(fieldKey);
return {
recordName: recordName,
recordIndex: recordIndex,
fieldName: keyParts[0],
fieldIndex: keyParts[1]
};
}
function parseKeyPart(keyPart) {
if (keyPart.length === 0) {
throw new Error("No name specified");
}
var openIndex = keyPart.indexOf("(");
if (openIndex === -1) {
return [keyPart, 0];
}
if (openIndex === 0) {
throw new Error("No name specified");
}
var closeIndex = keyPart.indexOf(")");
if (closeIndex === -1 || closeIndex < openIndex) {
throw new Error("'(' found without closing ')");
}
if (closeIndex < keyPart.length - 1) {
throw new Error("Characters found after closing ')");
}
return [keyPart.substring(0, openIndex), parseInt(keyPart.substring(openIndex + 1, closeIndex), 10)];
}
};