diff --git a/Iridium.njsproj b/Iridium.njsproj index 7a73e52..b2a5ce5 100644 --- a/Iridium.njsproj +++ b/Iridium.njsproj @@ -1,134 +1,136 @@  - - Debug - 2.0 - {a2511e8c-33be-4b8d-8203-70d403aa446a} - - ShowAllFiles - index.js - . - . - {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} - 11.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - True - 0 - / - http://localhost:48022/ - False - True - http://localhost:1337 - False - - - - - - - CurrentPage - True - False - False - False - - - - - - - - - False - False - - - - + + Debug + 2.0 + {a2511e8c-33be-4b8d-8203-70d403aa446a} + + ShowAllFiles + index.js + . + . + {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} + 11.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + 0 + / + http://localhost:48022/ + False + True + http://localhost:1337 + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + \ No newline at end of file diff --git a/example/IntelliSense.js b/example/IntelliSense.js new file mode 100644 index 0000000..4bd967d --- /dev/null +++ b/example/IntelliSense.js @@ -0,0 +1,31 @@ +var Iridium = require('../index'); + +var db = new Iridium({ + database: 'iridium_test' +}); + +db.register('Test', new Iridium.Model(db, 'test', { + name: String, + birthday: Date +}, { + virtuals: { + age: function() { + /// + } + }, + methods: { + greet: function() { + console.log('Hello!'); + } + } +})); + +var x = new db.Test.Instance({ name: 'test', birthday: new Date() }); +x.name.toUpperCase(); +x.birthday.toDateString(); + +db.Test.insert({}, function(err, instance) { + /// + instance.name = "Demo"; + instance.greet(); +}); \ No newline at end of file diff --git a/lib/Instance.js b/lib/Instance.js index da78de2..b69f384 100644 --- a/lib/Instance.js +++ b/lib/Instance.js @@ -5,6 +5,7 @@ var ObjectID = require('mongodb').ObjectID, EventEmitter = require('events').EventEmitter, debug = require('debug')('iridium:Instance'), + inherit = require('./utils/Inherit'), validate = require('./utils/validation'), diff = require('./utils/diff'); @@ -67,12 +68,12 @@ Instance.prototype.save = function(conditions, changes, callback) { /// /// /// Saves changes made to the current instance to the database - /// A function which is called when the save has been completed + /// A function which is called when the save has been completed /// /// /// Saves changes made to the current instance to the database /// MongoDB changes query to be used instead of differential patching - /// A function which is called when the save has been completed + /// A function which is called when the save has been completed /// /// /// Saves changes made to the current instance to the database @@ -83,7 +84,7 @@ Instance.prototype.save = function(conditions, changes, callback) { /// Saves changes made to the current instance to the database /// A set of conditions used to determine aspects of the document to update, merged with _id: ... /// MongoDB changes query to be used instead of differential patching - /// A function which is called when the save has been completed + /// A function which is called when the save has been completed /// var args = Array.prototype.splice.call(arguments, 0); @@ -180,7 +181,7 @@ Instance.prototype.refresh = Instance.prototype.update = function(callback) { /// /// /// Updates this object from the database, bringing it up to date - /// A function to be called once the update is complete + /// A function to be called once the update is complete /// var onError = (function (err) { @@ -206,7 +207,7 @@ Instance.prototype.refresh = Instance.prototype.update = function(callback) { Instance.prototype.remove = Instance.prototype.delete = function(callback) { /// Removes this object from the database collection - /// A function to be called when the object has been removed + /// A function to be called when the object has been removed if(this.__state.isNew) return (callback || function() { })(null, 0); @@ -307,26 +308,19 @@ Instance.prototype.__extendSchema = function() { Instance.forModel = function(model) { /// Creates an instance wrapper for the specified model /// The model which the instance wraps - /// function ModelInstance(doc, isNew) { - /// /// Creates a new model instance for the specified document /// The document which the instance should wrap - /// - /// - /// Creates a new model instance for the specified document - /// The document which the instance should wrap - /// Whether or not the document was sourced from the database - /// - + /// Whether or not the document was sourced from the database + Instance.call(this, model, doc, isNew); } - - var proto = {}; + + inherit(ModelInstance, Instance); _.each(model.schema, function(validator, name) { - Object.defineProperty(proto, name, { + Object.defineProperty(ModelInstance.prototype, name, { get: function() { return this.__state.modified[name] === undefined ? null : this.__state.modified[name]; }, @@ -336,29 +330,28 @@ Instance.forModel = function(model) { enumerable: true }); }); - + _.each(model.options.virtuals, function(property, name) { if('function' == typeof property) - Object.defineProperty(proto, name, { + Object.defineProperty(ModelInstance.prototype, name, { get: property, enumerable: true }); else - Object.defineProperty(proto, name, { + Object.defineProperty(ModelInstance.prototype, name, { get: property.get, set: property.set, enumerable: true }); }); - proto.__proto__ = Instance.prototype; - _.each(model.options.methods, function(method, name) { - proto[name] = method; + Object.defineProperty(ModelInstance.prototype, name, { + value: method, + enumerable: false + }); }); - ModelInstance.prototype = proto; - return ModelInstance; }; diff --git a/lib/Model.js b/lib/Model.js index a73f864..a669bcb 100644 --- a/lib/Model.js +++ b/lib/Model.js @@ -9,12 +9,12 @@ var _ = require('lodash'), EventEmitter = require('events').EventEmitter, Concoction = require('concoction'), + inherit = require('./utils/Inherit'), Database = require('./Database'), Instance = require('./Instance'), validate = require('./utils/validation'), NoOpCache = require('./caches/NoOpCache'); - (require.modules || {}).Model = module.exports = Model; function Model(database, collection, schema, options) { @@ -107,7 +107,7 @@ function Model(database, collection, schema, options) { } } -Model.prototype.__proto__ = EventEmitter.prototype; +inherit(Model, EventEmitter); Model.prototype.fromSource = function(document) { /// Applies the model's preprocessors to convert the document from the source @@ -172,52 +172,34 @@ Model.prototype.wrap = function (document, isNew) { /// /// Wraps the given database object in this model's Instance wrapper /// The database object to be wrapped by this model - /// + /// /// /// /// Wraps the given database object in this model's Instance wrapper /// The database object to be wrapped by this model /// Whether or not this instance is new (not in the database) - /// + /// /// return new this.Instance(document, isNew); }; Model.prototype.onRetrieved = function(conditions, results, callback, wrapper, options) { - /// - ///Handles any post-receive hooks and the wrapping of objects from the database - ///The conditions which resulted in the object being retrieved - ///The object retrieved from the database - ///The function to be called once the objects have been wrapped - /// /// ///Handles any post-receive hooks and the wrapping of objects from the database ///The conditions which resulted in the object being retrieved ///The objects retrieved from the database - ///The function to be called once the objects have been wrapped - /// - /// - ///Handles any post-receive hooks and the wrapping of objects from the database - ///The conditions which resulted in the object being retrieved - ///The object retrieved from the database - ///The function to be called once the objects have been wrapped - ///A function which converts the retrieved objects prior to submission + ///The function to be called once the objects have been wrapped + ///A function which converts the retrieved objects prior to submission + ///A set of options determining how to handle the retrieved object /// /// ///Handles any post-receive hooks and the wrapping of objects from the database ///The conditions which resulted in the object being retrieved ///The objects retrieved from the database - ///The function to be called once the objects have been wrapped - ///A function which converts the retrieved objects prior to submission - /// - /// - ///Handles any post-receive hooks and the wrapping of objects from the database - ///The conditions which resulted in the object being retrieved - ///The objects retrieved from the database - ///The function to be called once the objects have been wrapped - ///A function which converts the retrieved objects prior to submission - ///A set of options determining how to handle the retrieved object + ///The function to be called once the objects have been wrapped + ///A function which converts the retrieved objects prior to submission + ///A set of options determining how to handle the retrieved object /// var $ = this; @@ -285,6 +267,12 @@ Model.prototype.onRetrieved = function(conditions, results, callback, wrapper, o }; Model.prototype.onCreating = function(document, callback) { + /// + ///Handles any pre-creation hooks for the model + ///The document being created - prior to any transformations being applied + ///The function to be called once the hooks have completed + /// + function doHook(hook, target, args, next) { if(!hook) return next(); if(hook.length === 0) { @@ -308,6 +296,12 @@ Model.prototype.onCreating = function(document, callback) { }; Model.prototype.onSaving = function(instance, changes, callback) { + /// + /// Handles any pre-save hooks for the model + /// The instance being saved to the database + /// The MongoDB changes object being applied to the database document + /// The function to be called once the hooks have completed + /// function doHook(hook, target, args, next) { if(!hook) return next(); @@ -332,43 +326,24 @@ Model.prototype.onSaving = function(instance, changes, callback) { }; Model.prototype.find = function (conditions, options, callback) { - /// - /// Gets all objects in the collection. - /// A function to be called with the results once they have been retrieved. - /// /// /// Finds all occurences in the collection with an _id field matching the given conditions. - /// The _id field of the object to locate - /// A function to be called with the results once they have been retrieved. + /// The _id field of the object to locate + /// Options dictating how Iridium handles this request + /// A function to be called with the results once they have been retrieved. /// /// /// Finds all occurences in the collection which match the given conditions. - /// The conditions which will be used to select matches - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Gets all objects in the collection. - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Finds all occurences in the collection with an _id field matching the given conditions. - /// The _id field of the object to locate - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Finds all occurences in the collection which match the given conditions. - /// The conditions which will be used to select matches - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. + /// The conditions which will be used to select matches + /// Options dictating how Iridium handles this request + /// A function to be called with the results once they have been retrieved. /// var args = Array.prototype.splice.call(arguments, 0); conditions = null; options = null; - + for(var i = 0; i < args.length; i++) { if('function' == typeof args[i]) callback = args[i]; @@ -398,40 +373,21 @@ Model.prototype.find = function (conditions, options, callback) { }; Model.prototype.findOne = Model.prototype.get = function (conditions, options, callback) { - /// - /// Gets a single object from the collection. - /// A function to be called with the results once they have been retrieved. - /// /// /// Finds the first occurence in the collection with an _id field matching the given conditions. - /// The _id field of the object to locate - /// A function to be called with the results once they have been retrieved. + /// The _id field of the object to locate + /// Options dictating how Iridium handles this request + /// A function to be called with the results once they have been retrieved. /// /// /// Finds the first occurence in the collection which matches the given conditions. - /// The conditions which will be used to select matches - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Gets a single object from the collection. - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Finds the first occurence in the collection with an _id field matching the given conditions. - /// The _id field of the object to locate - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. - /// - /// - /// Finds the first occurence in the collection which matches the given conditions. - /// The conditions which will be used to select matches - /// Options dictating how Iridium handles this request - /// A function to be called with the results once they have been retrieved. + /// The conditions which will be used to select matches + /// Options dictating how Iridium handles this request + /// A function to be called with the results once they have been retrieved. /// var args = Array.prototype.splice.call(arguments, 0); - + conditions = null; options = null; @@ -480,42 +436,25 @@ Model.prototype.insert = Model.prototype.create = function (object, options, cal /// /// Inserts the given object into the database /// The properties to set on the newly created object + /// Options dictating how Iridium handles this request + /// A function to be called once the object has been created /// /// - /// Inserts the given object into the database - /// An array of objects representing the properties to set on the newly created objects - /// - /// - /// Inserts the given object into the database - /// The properties to set on the newly created object - /// A function to be called once the object has been created - /// - /// - /// Inserts the given object into the database - /// An array of objects representing the properties to set on the newly created objects - /// A function to be called once the objects have been created - /// - /// Inserts the given object into the database - /// The properties to set on the newly created object - /// Options dictating how Iridium handles this request - /// A function to be called once the object has been created - /// - /// - /// Inserts the given object into the database + /// Inserts the given objects into the database /// An array of objects representing the properties to set on the newly created objects - /// Options dictating how Iridium handles this request - /// A function to be called once the objects have been created + /// Options dictating how Iridium handles this request + /// A function to be called once the objects have been created /// var $ = this; - + var returnArray = true; if(!callback) { callback = options; options = options || {}; } - + _.defaults(options, { wrap: true }); @@ -571,16 +510,11 @@ Model.prototype.update = function (conditions, changes, callback) { /// Updates all documents in the collection which match the specified conditions - making the requested changes /// The conditions used to select objects to be updated /// The changes to be made to objects in the collection - /// - /// - /// Updates all documents in the collection which match the specified conditions - making the requested changes - /// The conditions used to select objects to be updated - /// The changes to be made to objects in the collection - /// A function to be called once the update has completed + /// A function to be called once the update has completed /// this.toSource(conditions); - + this.collection.update(conditions, changes, { w: callback ? 1 : 0, multi: true }, (function(err, modified) { if (err) this.emit('error', err); return callback(err, modified); @@ -590,14 +524,10 @@ Model.prototype.update = function (conditions, changes, callback) { Model.prototype.count = function (conditions, callback) { /// /// Counts the number of documents in the collection - /// A function to be called once the documents have been counted. + /// The conditions on which to match documents for counting + /// A function to be called once the documents have been counted. /// - /// - /// Counts the number of documents in the collection which match the given conditions - /// The conditions on which to match documents for counting - /// A function to be called once the documents have been counted. - /// - + if (!callback) { callback = conditions; conditions = {}; @@ -614,24 +544,24 @@ Model.prototype.count = function (conditions, callback) { Model.prototype.remove = function (conditions, callback) { /// /// Removes all objects in the collection. - /// A function to be called once all objects have been removed. + /// A function to be called once all objects have been removed. /// /// /// Removes all occurences in the collection with an _id field matching the given condition value. /// The _id field of the object to locate - /// A function to be called once all objects have been removed. + /// A function to be called once all objects have been removed. /// /// /// Removes all occurences in the collection which match the given conditions. /// The conditions which will be used to select matches - /// A function to be called once all objects have been removed. + /// A function to be called once all objects have been removed. /// if (!callback) { callback = conditions; conditions = {}; } - + if (!_.isPlainObject(conditions)) conditions = this.downstreamID(conditions); this.toSource(conditions); @@ -712,3 +642,20 @@ Model.prototype.setupIndexes = function (callback) { $.ensureIndex($.options.indexes[i][0], $.options.indexes[i][1], next); }; + + +/** + * INTELLISENSE STUFF + */ + +function Model_InstanceCallback_Single(err, instance) { + /// A function that is executed upon insertion of a single document + /// An error object representing a problem inserting the document + /// The document which was inserted into the database +} + +function Model_InstanceCallback_Multiple(err, instances) { + /// A function that is executed upon insertion of multiple documents + /// An error object representing a problem inserting the documents + /// The documents which were inserted into the database +} diff --git a/lib/utils/Inherit.js b/lib/utils/Inherit.js new file mode 100644 index 0000000..728fa16 --- /dev/null +++ b/lib/utils/Inherit.js @@ -0,0 +1,13 @@ +module.exports = function(target, inherits) { + /// Inherits properties from one class into a child + /// The target class which should inherit properties of its parent + /// The parent class from which to inherit + + var targetProto = function() {}; + targetProto.prototype = inherits.prototype; + targetProto.constructor = targetProto; + + target.prototype = new targetProto(); + target.prototype.constructor = target; + inherits.prototype.constructor = inherits; +}; \ No newline at end of file