Skip to content

Instantly share code, notes, and snippets.

@shadeglare
Last active December 24, 2015 10:29
Show Gist options
  • Save shadeglare/6784274 to your computer and use it in GitHub Desktop.
Save shadeglare/6784274 to your computer and use it in GitHub Desktop.
Dynamically build models from descriptions.
//npm install uuid
var uuid = require("uuid");
// ContentDescription for DSL
var ContentDescription = function(name, defaultValue) {
this.name = name;
this.defaultValue = defaultValue || null;
};
// RelationDescription for DSL
var RelationDescription = function(relatedModelName) {
this.relatedModelName = relatedModelName;
};
var ModelDescription = function(name) {
this.name = name;
this.contentDescriptions = [];
this.relationDescriptions = [];
};
ModelDescription.prototype.addContentDescription = function(contentDescription) {
this.contentDescriptions.push(contentDescription);
};
ModelDescription.prototype.addRelationDescription = function(relationDescription) {
this.relationDescriptions.push(relationDescription);
};
// Model implementing
var Model = function() {
this.modelStorage = null;
this.id = uuid.v4();
this.contents = {};
this.relations = {};
};
Model.prototype.setId = function(value) {
this.id = value;
};
Model.prototype.getId = function() {
return this.id;
};
Model.prototype.getContentNames = function() {
return Object.getOwnPropertyNames(this.contents);
};
Model.prototype.setContent = function(name, value) {
this.contents[name] = value;
};
Model.prototype.getContent = function(name) {
return this.contents[name];
};
Model.prototype.setRelation = function(relatedModelName, value) {
this.relations[relatedModelName] = value;
};
Model.prototype.getRelation = function(relatedModelName) {
return this.relations[relatedModelName];
};
Model.prototype.fetchByRelation = function(relatedModelName) {
var key = this.relations[relatedModelName];
return this.modelStorage.models[relatedModelName][key];
};
Model.prototype.toJSON = function() {
return {
id: this.id,
contents: this.contents,
relations: this.relations
};
};
// Model Storage
var ModelStorage = function() {
this.modelDescriptions = {};
this.models = {};
};
ModelStorage.prototype.registerModel = function(modelDescription) {
this.modelDescriptions[modelDescription.name] = modelDescription;
};
ModelStorage.prototype.createModelInstance = function(name) {
var model = new Model();
model.modelStorage = this;
// Add content node
var modelDescription = this.modelDescriptions[name];
var contentDescriptions = modelDescription.contentDescriptions;
for (var i = 0; i < contentDescriptions.length; i++) {
var c = contentDescriptions[i];
model.setContent(c.name, c.defaultValue);
}
// Add relation node
var relationDescriptions = modelDescription.relationDescriptions;
for (var i = 0; i < relationDescriptions.length; i++) {
var r = relationDescriptions[i];
model.setRelation(r.relatedModelName, null);
}
this.models[name] = this.models[name] || {};
this.models[name][model.getId()] = model;
return model;
};
//Test cases
var modelStorage = new ModelStorage();
var ticketDescription = new ModelDescription("ticket");
ticketDescription.addContentDescription(new ContentDescription("from"));
ticketDescription.addContentDescription(new ContentDescription("to"));
ticketDescription.addContentDescription(new ContentDescription("price"));
ticketDescription.addRelationDescription(new RelationDescription("passenger"));
var passengerDescription = new ModelDescription("passenger");
passengerDescription.addContentDescription(new ContentDescription("firstName"));
passengerDescription.addContentDescription(new ContentDescription("lastName"));
passengerDescription.addContentDescription(new ContentDescription("birthDate"));
modelStorage.registerModel(ticketDescription);
modelStorage.registerModel(passengerDescription);
var ticket1 = modelStorage.createModelInstance("ticket");
var ticket2 = modelStorage.createModelInstance("ticket");
ticket1.setContent("from", "MOW");
ticket1.setContent("to", "LHR");
ticket1.setContent("price", 12000);
ticket2.setContent("from", "PAR");
ticket2.setContent("to", "NYC");
ticket2.setContent("price", 75000);
console.log("\nTickets");
console.log(ticket1.toJSON());
console.log(ticket2.toJSON());
var passenger = modelStorage.createModelInstance("passenger");
console.log("\nPassenger");
console.log(passenger.toJSON());
ticket1.setRelation("passenger", passenger.getId());
console.log("\nAdd passenger to ticket");
console.log(ticket1.toJSON());
var relatedPassenger = ticket1.fetchByRelation("passenger");
console.log("\nFetch passenger from ticket relation");
console.log(relatedPassenger.toJSON());
//Mongo collection entry example
//{ "_id" : ObjectId("50691737d386d8fadbd6b01d"), "firstName" : "first1", "lastName" : "last1", "birthDate": "Sun May 30 18:47:06 +0000 2010" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment