Permalink
Browse files

oopps missing lib!

  • Loading branch information...
1 parent 6907ea3 commit e10406fa0d2d4ef7640806c1dbfcb89a43af0e5f @masylum masylum committed Oct 6, 2010
Showing with 282 additions and 0 deletions.
  1. +191 −0 model.js
  2. +91 −0 validator.js
View
191 model.js
@@ -0,0 +1,191 @@
+var Class = require('class').Class;
+
+module.exports = new Class({
+ constructor: function (db, collection_name) {
+ this.db = db;
+ this.collection_name = collection_name;
+ },
+
+ getCollection: function (callback) {
+ this.db.collection(this.collection_name, function (error, collection) {
+ if (error) {
+ callback(error);
+ } else {
+ callback(null, collection);
+ }
+ });
+ },
+
+ mongoCall: function () {
+ var self = this,
+ args = Array.prototype.slice.call(arguments, 0),
+ funk = args.shift(),
+ callback = args.last;
+
+ this.getCollection(function (error, collection) {
+ if (error) {
+ callback(error);
+ } else {
+ switch (funk) {
+ case 'findArray':
+ args.last = function (error, cursor) {
+ cursor.toArray(callback);
+ };
+ funk = 'find';
+ break;
+ case 'insert':
+ if (Array.isArray(args[0])) {
+ args[0].forEach(function (element) {
+ self.onCreate(element);
+ });
+ } else {
+ self.onCreate(args[0]);
+ }
+
+ args.last = function (error, docs) {
+ docs.forEach(function (element) {
+ self.afterCreate(element);
+ });
+ callback(error, docs);
+ };
+ break;
+ case 'update':
+ case 'findAndModify':
+ self.onUpdate(args[1]);
+ break;
+ case 'mapReduceArray':
+ args.last = function (error, collection) {
+
+ collection.find(function (error, cursor) {
+ var results = [];
+
+ if (error) {
+ callback(error);
+ } else {
+ cursor.each(function (error, item) {
+ if (error) {
+ callback(error);
+ } else {
+ if (item) {
+ results.push(Object.merge(item._id, item.value));
+ } else {
+ callback(null, results);
+ }
+ }
+ });
+ }
+
+ });
+ };
+ funk = 'mapReduce';
+ break;
+ case 'mapReduceCursor':
+ args.last = function (error, collection) {
+ collection.find(callback);
+ };
+ funk = 'mapReduce';
+ break;
+ }
+ collection[funk].apply(collection, args);
+ }
+ });
+ },
+
+ createInstance: function (element, callback) {
+ var self = this;
+
+ self.validate({}, element, function (errors, validator) {
+ if (!validator.hasErrors()) {
+ self.onCreateInstance(element, function (errors, element) {
+ self.mongoCall('insert', element, function (errors, element) {
+ validator.updated_model = element[0];
+ callback(null, validator);
+ });
+ });
+ } else {
+ callback(null, validator);
+ }
+ });
+ },
+
+ onCreate: function (element) {
+ if (!element.created_at) {
+ element.created_at = new Date();
+ }
+ },
+
+ afterCreate: function (element) {
+ // to implement on your models
+ },
+
+ onCreateInstance: function (element, callback) {
+ // to implement on your models
+ callback(null, element);
+ },
+
+ updateInstance: function (model, update, callback) {
+ var self = this;
+
+ self.validate(model, update, function (errors, validator) {
+ if (!validator.hasErrors()) {
+ self.onUpdateInstance(model, update, function (errors, update) {
+ self.mongoCall('update', {'_id': model._id}, {'$set': update}, { upsert: true, multi: false}, function (error, element) {
+ callback(null, validator);
+ });
+ });
+ } else {
+ callback(null, validator);
+ }
+ });
+ },
+
+ onUpdate: function (update) {
+ if (!update.$set) {
+ update.$set = {};
+ }
+ update.$set.updated_at = new Date();
+ },
+
+ onUpdateInstance: function (model, update, callback) {
+ // to implement
+ callback(null, update);
+ },
+
+ setEmbedObject: function (name, object) {
+ var result = {};
+
+ this.skeletons[name].forEach(function (attr) {
+ result[attr] = object[attr];
+ });
+
+ return result;
+ },
+
+ updateEmbedObject: function (model, data, embed, options, callback) {
+ var new_data = {},
+ i = null,
+ query = {};
+
+ query[embed + '._id'] = model._id;
+
+ for (i in data) {
+ new_data[embed + '.' + i] = data[i];
+ }
+
+ this.mongoCall('update', query, {'$set': new_data}, options || {upsert: true, multi: true}, callback);
+ },
+
+ pushEmbedObject: function (model, data, embed, options, callback) {
+ var new_data = {},
+ i = null,
+ query = {};
+
+ query[embed + '._id'] = model._id;
+
+ for (i in data) {
+ new_data[embed + '.' + i] = data[i];
+ }
+
+ this.mongoCall('update', query, {'$push': new_data}, options || {upsert: true, multi: true}, callback);
+ }
+});
View
@@ -0,0 +1,91 @@
+module.exports = function (args) {
+ var validator = {},
+
+ // private methods
+ getKeys = function (object) {
+ return Object.keys(object).intersect(Object.keys(validator.data));
+ };
+
+ validator.model = args[0];
+ validator.data = args[1];
+ validator.updated_model = Object.merge(Object.clone(this.model), this.data);
+ validator.errors = {};
+
+ validator.regex = {
+ login: /^[A-Za-z](?=[A-Za-z0-9_.]{3,11}$)[a-zA-Z0-9_]*\.?[a-zA-Z0-9_]*$/,
+ username: /^[A-Za-z0-9][A-Za-z0-9_@&$. \-]{3,31}[a-zA-Z0-9_]$/,
+ title: /^[A-Za-z0-9].{3,50}/,
+ description: /.{10,300}/,
+ email: /^\S+@\S+\.\S+$/,
+ password: /.{6,20}/
+ };
+
+ validator.isUpdating = function () {
+ return Object.isEmpty(this.model);
+ };
+
+ validator.isInserting = function () {
+ return !Object.isEmpty(this.model);
+ };
+
+ validator.attrChanged = function (attr) {
+ return this.model[attr] !== this.data[attr];
+ };
+
+ validator.hasError = function (field) {
+ return this.hasErrors() && this.errors[field];
+ };
+
+ validator.hasErrors = function () {
+ return !Object.isEmpty(this.errors);
+ };
+
+ validator.validateExistence = function (validations) {
+ getKeys(validations).forEach(function (key, i) {
+ if (!this.data[key]) {
+ this.addError(key, validations[key]);
+ }
+ }, this);
+ };
+
+ validator.validateRegex = function (validations) {
+ getKeys(validations).forEach(function (key, i) {
+ if (!this.data[key].match(validations[key][0])) {
+ this.addError(key, validations[key][1]);
+ }
+ }, this);
+ };
+
+ validator.validateConfirmation = function (validations) {
+ getKeys(validations).forEach(function (key, i) {
+ if (this.data[key] !== this.data[validations[key][0]]) {
+ this.addError(key, validations[key][1]);
+ this.addError(validations[key][0], validations[key][1]);
+ }
+ }, this);
+ };
+
+ validator.validateQuery = function (validations, callback) {
+ var funk = $.funk();
+
+ getKeys(validations).forEach(function (key, i) {
+ validations[key][0].mongoCall('findOne', validations[key][1], funk.add(function (errors, doc) {
+ if ((validations[key][2] === true && !doc || validations[key][2] === false && doc)) {
+ this.addError(key, validations[key][3]);
+ }
+ }));
+ });
+
+ funk.parallel(callback);
+ };
+
+ validator.addError = function (name, value) {
+ if (!this.errors[name]) {
+ this.errors[name] = [];
+ }
+
+ this.errors[name].push(value);
+ };
+
+ return validator;
+}

0 comments on commit e10406f

Please sign in to comment.