Updates to JSDoc comments for API doc

This commit is contained in:
crandmck 2014-03-12 16:28:46 -07:00
parent ac8887835f
commit 9c2098cd35
9 changed files with 426 additions and 254 deletions

View File

@ -1,9 +1,9 @@
/**
/*!
* Module exports class Model
*/
module.exports = DataAccessObject;
/**
/*!
* Module dependencies
*/
var jutil = require('./jutil');
@ -19,15 +19,14 @@ var fieldsToArray = utils.fieldsToArray;
var removeUndefined = utils.removeUndefined;
/**
* DAO class - base class for all persist objects
* provides **common API** to access any database connector.
* This class describes only abstract behavior layer, refer to `lib/connectors/*.js`
* to learn more about specific connector implementations
* Base class for all persistent objects.
* Provides a common API to access any database connector.
* This class describes only abstract behavior. Refer to the specific connector (`lib/connectors/*.js`) for details.
*
* `DataAccessObject` mixes `Inclusion` classes methods
* `DataAccessObject` mixes `Inclusion` classes methods.
*
* @constructor
* @param {Object} data - initial object data
* @class DataAccessObject
* @param {Object} data Initial object data
*/
function DataAccessObject() {
if (DataAccessObject._mixins) {
@ -71,14 +70,15 @@ DataAccessObject._forDB = function (data) {
};
/**
* Create new instance of Model class, saved in database
*
* @param data [optional]
* @param callback(err, obj)
* callback called with arguments:
* Create new instance of Model class, saved in database.
* The callback function is called with arguments:
*
* - err (null or Error)
* - instance (null or Model)
*
* @param data {Object} Optional data object
* @param callback {Function} Callback function
*/
DataAccessObject.create = function (data, callback) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -208,9 +208,9 @@ function stillConnecting(dataSource, obj, args) {
}
/**
* Update or insert a model instance
* Update or insert a model instance.
* @param {Object} data The model instance data
* @param {Function} [callback] The callback function
* @param {Function} callback The callback function (optional).
*/
DataAccessObject.upsert = DataAccessObject.updateOrCreate = function upsert(data, callback) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -254,9 +254,9 @@ setRemoting(DataAccessObject.upsert, {
* Find one record, same as `all`, limited by 1 and return object, not collection,
* if not found, create using data provided as second argument
*
* @param {Object} query - search conditions: {where: {test: 'me'}}.
* @param {Object} data - object to create.
* @param {Function} cb - callback called with (err, instance)
* @param {Object} query Search conditions: {where: {test: 'me'}}.
* @param {Object} data Object to create.
* @param {Function} cb Callback called with (err, instance)
*/
DataAccessObject.findOrCreate = function findOrCreate(query, data, callback) {
if (query === undefined) {
@ -282,8 +282,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, callback) {
/**
* Check whether a model instance exists in database
*
* @param {id} id - identifier of object (primary key value)
* @param {Function} cb - callbacl called with (err, exists: Bool)
* @param {id} id Identifier of object (primary key value)
* @param {Function} cb Callback function called with (err, exists: Bool)
*/
DataAccessObject.exists = function exists(id, cb) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -306,8 +306,8 @@ setRemoting(DataAccessObject.exists, {
/**
* Find object by id
*
* @param {*} id - primary key value
* @param {Function} cb - callback called with (err, instance)
* @param {*} id Primary key value
* @param {Function} cb Callback called with (err, instance)
*/
DataAccessObject.findById = function find(id, cb) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -458,20 +458,16 @@ DataAccessObject._coerce = function (where) {
/**
* Find all instances of Model, matched by query
* make sure you have marked as `index: true` fields for filter or sort
*
* @param {Object} params (optional)
*
* make sure you have marked as `index: true` fields for filter or sort.
* The params object:
* - where: Object `{ key: val, key2: {gt: 'val2'}}`
* - include: String, Object or Array. See DataAccessObject.include documentation.
* - include: String, Object or Array. See `DataAccessObject.include()`.
* - order: String
* - limit: Number
* - skip: Number
*
* @param {Function} callback (required) called with arguments:
*
* - err (null or Error)
* - Array of instances
*
* @param {Object} params (optional)
* @param {Function} callback (required) called with two arguments: err (null or Error), array of instances
*/
DataAccessObject.find = function find(params, cb) {
@ -598,8 +594,8 @@ setRemoting(DataAccessObject.find, {
/**
* Find one record, same as `all`, limited by 1 and return object, not collection
*
* @param {Object} params - search conditions: {where: {test: 'me'}}
* @param {Function} cb - callback called with (err, instance)
* @param {Object} params Search conditions: {where: {test: 'me'}}
* @param {Function} cb Callback called with (err, instance)
*/
DataAccessObject.findOne = function findOne(params, cb) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -626,7 +622,7 @@ setRemoting(DataAccessObject.findOne, {
/**
* Destroy all matching records
* @param {Object} [where] An object that defines the criteria
* @param {Function} [cb] - callback called with (err)
* @param {Function} [cb] Callback called with (err)
*/
DataAccessObject.remove =
DataAccessObject.deleteAll =
@ -657,7 +653,7 @@ DataAccessObject.remove =
/**
* Destroy a record by id
* @param {*} id The id value
* @param {Function} cb - callback called with (err)
* @param {Function} cb Callback called with (err)
*/
DataAccessObject.removeById =
DataAccessObject.deleteById =
@ -683,8 +679,8 @@ setRemoting(DataAccessObject.deleteById, {
/**
* Return count of matched records
*
* @param {Object} where - search conditions (optional)
* @param {Function} cb - callback, called with (err, count)
* @param {Object} where Search conditions (optional)
* @param {Function} cb Callback, called with (err, count)
*/
DataAccessObject.count = function (where, cb) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -797,7 +793,7 @@ DataAccessObject.prototype._adapter = function () {
/**
* Delete object from persistence
*
* @triggers `destroy` hook (async) before and after destroying object
* Triggers `destroy` hook (async) before and after destroying object
*/
DataAccessObject.prototype.remove =
DataAccessObject.prototype.delete =
@ -825,9 +821,9 @@ DataAccessObject.prototype.remove =
*
* equals to `updateAttributes({name: value}, cb)
*
* @param {String} name - name of property
* @param {Mixed} value - value of property
* @param {Function} callback - callback called with (err, instance)
* @param {String} name Name of property
* @param {Mixed} value Value of property
* @param {Function} callback Callback function called with (err, instance)
*/
DataAccessObject.prototype.updateAttribute = function updateAttribute(name, value, callback) {
var data = {};
@ -841,8 +837,8 @@ DataAccessObject.prototype.updateAttribute = function updateAttribute(name, valu
* this method performs validation before updating
*
* @trigger `validation`, `save` and `update` hooks
* @param {Object} data - data to update
* @param {Function} callback - callback called with (err, instance)
* @param {Object} data Data to update
* @param {Function} callback Callback function called with (err, instance)
*/
DataAccessObject.prototype.updateAttributes = function updateAttributes(data, cb) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -911,9 +907,8 @@ setRemoting(DataAccessObject.prototype.updateAttributes, {
/**
* Reload object from persistence
*
* @requires `id` member of `object` to be able to call `find`
* @param {Function} callback - called with (err, instance) arguments
* Requires `id` member of `object` to be able to call `find`
* @param {Function} callback Called with (err, instance) arguments
*/
DataAccessObject.prototype.reload = function reload(callback) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
@ -946,8 +941,8 @@ function defineReadonlyProp(obj, key, value) {
var defineScope = require('./scope.js').defineScope;
/**
* Define scope
/*!
* Define scope. N.B. Not clear if this needs to be exposed in API doc.
*/
DataAccessObject.scope = function (name, filter, targetClass) {
defineScope(this, targetClass || this, name, filter);

View File

@ -19,7 +19,7 @@ if (process.env.DEBUG === 'loopback') {
}
var debug = require('debug')('loopback:datasource');
/**
/*!
* Export public API
*/
exports.DataSource = DataSource;
@ -30,23 +30,32 @@ exports.DataSource = DataSource;
var slice = Array.prototype.slice;
/**
* DataSource - connector-specific classes factory.
* LoopBack models can manipulate data via the DataSource object.
* Attaching a `DataSource` to a `Model` adds instance methods and static methods to the `Model`;
* some of the added methods may be remote methods.
*
* All classes in single dataSource shares same connector type and
* one database connection
*
* @param {String} name - type of dataSource connector (mysql, mongoose, oracle, redis)
* @param {Object} settings - any database-specific settings which we need to
* establish connection (of course it depends on specific connector)
* Define a data source for persisting models.
* Typically, you create a DataSource by calling createDataSource() on the LoopBack object; for example:
* ```js
* var oracle = loopback.createDataSource({
* connector: 'oracle',
* host: '111.22.333.44',
* database: 'MYDB',
* username: 'username',
* password: 'password'
* });
* ```
*
* All classes in single dataSource share same the connector type and
* one database connection. The `settings` argument is an object that can have the following properties:
* - host
* - port
* - username
* - password
* - database
* - debug {Boolean} = false
* - debug (Boolean, default is false)
*
* @example DataSource creation, waiting for connection callback
* @desc For example, the following creates a DataSource, and waits for a connection callback.
* ```
* var dataSource = new DataSource('mysql', { database: 'myapp_test' });
* dataSource.define(...);
@ -54,6 +63,9 @@ var slice = Array.prototype.slice;
* // work with database
* });
* ```
* @class Define new DataSource
* @param {String} name Type of dataSource connector (mysql, mongoose, oracle, redis)
* @param {Object} settings Database-specific settings to establish connection (settings depend on specific connector). See above.
*/
function DataSource(name, settings, modelBuilder) {
if (!(this instanceof DataSource)) {
@ -477,28 +489,19 @@ DataSource.prototype.setupDataAccess = function (modelClass, settings) {
};
/**
* Define a model class
*
* @param {String} className
* @param {Object} properties - hash of class properties in format
* `{property: Type, property2: Type2, ...}`
* or
* `{property: {type: Type}, property2: {type: Type2}, ...}`
* @param {Object} settings - other configuration of class
* @return newly created class
*
* @example simple case
* Define a model class.
* Simple example:
* ```
* var User = dataSource.define('User', {
* var User = dataSource.createModel('User', {
* email: String,
* password: String,
* birthDate: Date,
* activated: Boolean
* });
* ```
* @example more advanced case
* More advanced example
* ```
* var User = dataSource.define('User', {
* var User = dataSource.createModel('User', {
* email: { type: String, limit: 150, index: true },
* password: { type: String, limit: 50 },
* birthDate: Date,
@ -506,6 +509,29 @@ DataSource.prototype.setupDataAccess = function (modelClass, settings) {
* activated: { type: Boolean, default: false }
* });
* ```
* You can also define an ACL when you create a new data source with the `DataSource.create()` method. For example:
*
* ```js
* var Customer = ds.createModel('Customer', {
* name: {
* type: String,
* acls: [
* {principalType: ACL.USER, principalId: 'u001', accessType: ACL.WRITE, permission: ACL.DENY},
* {principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
* ]
* }
* }, {
* acls: [
* {principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
* ]
* });
* ```
*
* @param {String} className Name of the model to create.
* @param {Object} properties Hash of class properties in format `{property: Type, property2: Type2, ...}` or `{property: {type: Type}, property2: {type: Type2}, ...}`
* @param {Object} settings Other configuration settings.
* @returns newly created class
*
*/
DataSource.prototype.createModel = DataSource.prototype.define = function defineClass(className, properties, settings) {
@ -591,14 +617,14 @@ DataSource.prototype.mixin = function (ModelCtor) {
};
/**
* @see ModelBuilder.prototype.getModel
* See ModelBuilder.getModel
*/
DataSource.prototype.getModel = function (name, forceCreate) {
return this.modelBuilder.getModel(name, forceCreate);
};
/**
* @see ModelBuilder.prototype.getModelDefinition
* See ModelBuilder.getModelDefinition
*/
DataSource.prototype.getModelDefinition = function (name) {
return this.modelBuilder.getModelDefinition(name);
@ -618,9 +644,9 @@ DataSource.prototype.getTypes = function () {
};
/**
* Check the data source supports the given types
* @param String|String[]) types A type name or an array of type names
* @return {Boolean} true if all types are supported by the data source
* Check the data source supports the specified types.
* @param {String} types Type name or an array of type names. Can also be array of Strings.
* @returns {Boolean} true if all types are supported by the data source
*/
DataSource.prototype.supportTypes = function (types) {
var supportedTypes = this.getTypes();
@ -670,9 +696,9 @@ DataSource.prototype.attach = function (modelClass) {
/**
* Define single property named `prop` on `model`
*
* @param {String} model - name of model
* @param {String} prop - name of property
* @param {Object} params - property settings
* @param {String} model Name of model
* @param {String} prop Name of property
* @param {Object} params Property settings
*/
DataSource.prototype.defineProperty = function (model, prop, params) {
this.modelBuilder.defineProperty(model, prop, params);
@ -685,12 +711,12 @@ DataSource.prototype.defineProperty = function (model, prop, params) {
/**
* Drop each model table and re-create.
* This method make sense only for sql connectors.
* This method applies only to SQL connectors.
*
* @param {String} or {[String]} Models to be migrated, if not present, apply to all models
* @param {Function} [cb] The callback function
* @param {String} Models to be migrated, if not present, apply to all models. This can also be an array of Strings.
* @param {Function} cb Callback function. Optional.
*
* @warning All data will be lost! Use autoupdate if you need your data.
* WARNING: Calling this function will cause all data to be lost! Use autoupdate if you need to preserve data.
*/
DataSource.prototype.automigrate = function (models, cb) {
this.freeze();
@ -709,7 +735,7 @@ DataSource.prototype.automigrate = function (models, cb) {
* Update existing database tables.
* This method make sense only for sql connectors.
*
* @param {String} or {[String]} Models to be migrated, if not present, apply to all models
* @param {String} Models to be migrated, if not present, apply to all models. This can also be an array of Strings.
* @param {Function} [cb] The callback function
*/
DataSource.prototype.autoupdate = function (models, cb) {
@ -729,15 +755,15 @@ DataSource.prototype.autoupdate = function (models, cb) {
* Discover existing database tables.
* This method returns an array of model objects, including {type, name, onwer}
*
* `options`
* Kyes in options object:
*
* all: true - Discovering all models, false - Discovering the models owned by the current user
* views: true - Including views, false - only tables
* limit: The page size
* offset: The starting index
* - all: true - Discovering all models, false - Discovering the models owned by the current user
* - views: true - Including views, false - only tables
* - limit: The page size
* - offset: The starting index
*
* @param {Object} options The options
* @param {Function} [cb] The callback function
* @param {Function} Callback function. Optional.
*
*/
DataSource.prototype.discoverModelDefinitions = function (options, cb) {
@ -765,24 +791,25 @@ DataSource.prototype.discoverModelDefinitionsSync = function (options) {
/**
* Discover properties for a given model.
*
* `property description`
* property description:
*
* owner {String} The database owner or schema
* tableName {String} The table/view name
* columnName {String} The column name
* dataType {String} The data type
* dataLength {Number} The data length
* dataPrecision {Number} The numeric data precision
* dataScale {Number} The numeric data scale
* nullable {Boolean} If the data can be null
*| Key | Type | Description |
*|-----|------|-------------|
*|owner | String | Database owner or schema|
*|tableName | String | Table/view name|
*|columnName | String | Column name|
*|dataType | String | Data type|
*|dataLength | Number | Data length|
*|dataPrecision | Number | Numeric data precision|
*|dataScale |Number | Numeric data scale|
*|nullable |Boolean | If true, then the data can be null|
*
* `options`
*
* owner/schema The database owner/schema
* Options:
* - owner/schema The database owner/schema
*
* @param {String} modelName The table/view name
* @param {Object} options The options
* @param {Function} [cb] The callback function
* @param {Function} cb Callback function. Optional
*
*/
DataSource.prototype.discoverModelProperties = function (modelName, options, cb) {
@ -809,21 +836,20 @@ DataSource.prototype.discoverModelPropertiesSync = function (modelName, options)
};
/**
* Discover primary keys for a given owner/modelName
* Discover primary keys for a given owner/modelName.
*
* Each primary key column description has the following columns:
*
* owner {String} => table schema (may be null)
* tableName {String} => table name
* columnName {String} => column name
* keySeq {Number} => sequence number within primary key( a value of 1 represents the first column of the primary key, a value of 2 would represent the second column within the primary key).
* pkName {String} => primary key name (may be null)
* - owner {String} => table schema (may be null)
* - tableName {String} => table name
* - columnName {String} => column name
* - keySeq {Number} => sequence number within primary key( a value of 1 represents the first column of the primary key, a value of 2 would represent the second column within the primary key).
* - pkName {String} => primary key name (may be null)
*
* The owner, default to current user
* The owner defaults to current user.
*
* `options`
*
* owner/schema The database owner/schema
* Options:
* - owner/schema The database owner/schema
*
* @param {String} modelName The model name
* @param {Object} options The options
@ -968,7 +994,58 @@ function fromDBName(dbName, camelCase) {
}
/**
* Discover one schema from the given model without following the relations
* Discover one schema from the given model without following the relations.
**Example schema from oracle connector:**
*
* ```js
* {
* "name": "Product",
* "options": {
* "idInjection": false,
* "oracle": {
* "schema": "BLACKPOOL",
* "table": "PRODUCT"
* }
* },
* "properties": {
* "id": {
* "type": "String",
* "required": true,
* "length": 20,
* "id": 1,
* "oracle": {
* "columnName": "ID",
* "dataType": "VARCHAR2",
* "dataLength": 20,
* "nullable": "N"
* }
* },
* "name": {
* "type": "String",
* "required": false,
* "length": 64,
* "oracle": {
* "columnName": "NAME",
* "dataType": "VARCHAR2",
* "dataLength": 64,
* "nullable": "Y"
* }
* },
* ...
* "fireModes": {
* "type": "String",
* "required": false,
* "length": 64,
* "oracle": {
* "columnName": "FIRE_MODES",
* "dataType": "VARCHAR2",
* "dataLength": 64,
* "nullable": "Y"
* }
* }
* }
* }
* ```
*
* @param {String} modelName The model name
* @param {Object} [options] The options
@ -1489,7 +1566,7 @@ DataSource.prototype.idNames = function (modelName) {
/**
* Define foreign key to another model
* @param {String} className The model name that owns the key
* @param {String} key - name of key field
* @param {String} key Name of key field
* @param {String} foreignClassName The foreign model name
*/
DataSource.prototype.defineForeignKey = function defineForeignKey(className, key, foreignClassName) {
@ -1528,7 +1605,7 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
/**
* Close database connection
* @param {Fucntion} [cb] The callback function
* @param {Fucntion} cb The callback function. Optional.
*/
DataSource.prototype.disconnect = function disconnect(cb) {
var self = this;
@ -1545,7 +1622,7 @@ DataSource.prototype.disconnect = function disconnect(cb) {
};
/**
* Copy the model from Master
* Copy the model from Master.
* @param {Function} Master The model constructor
* @returns {Function} The copy of the model constructor
*
@ -1625,7 +1702,8 @@ DataSource.prototype.transaction = function () {
};
/**
* Enable a data source operation to be remote.
* Enable remote access to a data source operation. Each [connector](#connector) has its own set of set
* remotely enabled and disabled operations. To list the operations, call `dataSource.operations()`.
* @param {String} operation The operation name
*/
@ -1639,7 +1717,23 @@ DataSource.prototype.enableRemote = function (operation) {
}
/**
* Disable a data source operation to be remote.
* Disable remote access to a data source operation. Each [connector](#connector) has its own set of set enabled
* and disabled operations. To list the operations, call `dataSource.operations()`.
*
*```js
*
* var oracle = loopback.createDataSource({
* connector: require('loopback-connector-oracle'),
* host: '...',
* ...
* });
* oracle.disableRemote('destroyAll');
* ```
* **Notes:**
*
* - Disabled operations will not be added to attached models.
* - Disabling the remoting for a method only affects client access (it will still be available from server models).
* - Data sources must enable / disable operations before attaching or creating models.
* @param {String} operation The operation name
*/
@ -1671,7 +1765,27 @@ DataSource.prototype.getOperation = function (operation) {
}
/**
* Get all operations.
* Return JSON object describing all operations.
*
* Example return value:
* ```js
* {
* find: {
* remoteEnabled: true,
* accepts: [...],
* returns: [...]
* enabled: true
* },
* save: {
* remoteEnabled: true,
* prototype: true,
* accepts: [...],
* returns: [...],
* enabled: true
* },
* ...
* }
* ```
*/
DataSource.prototype.operations = function () {
return this._operations;
@ -1681,7 +1795,7 @@ DataSource.prototype.operations = function () {
* Define an operation to the data source
* @param {String} name The operation name
* @param {Object} options The options
* @param [Function} fn The function
* @param {Function} fn The function
*/
DataSource.prototype.defineOperation = function (name, options, fn) {
options.fn = fn;
@ -1698,10 +1812,10 @@ DataSource.prototype.isRelational = function () {
};
/**
* Check if the data source is ready
* @param obj
* @param args
* @returns {boolean}
* Check if the data source is ready.
* Returns a Boolean value.
* @param obj {Object} ?
* @param args {Object} ?
*/
DataSource.prototype.ready = function (obj, args) {
var self = this;

View File

@ -1,7 +1,3 @@
/**
* Dependencies.
*/
var assert = require('assert');
/*!
@ -80,12 +76,41 @@ exports.filter = function (arr, filter) {
});
}
/**
* Export the `GeoPoint` class.
*/
exports.GeoPoint = GeoPoint;
/**
* The GeoPoint object represents a physical location.
*
* For example:
*
* ```js
* var here = new GeoPoint({lat: 10.32424, lng: 5.84978});
* ```
*
* Embed a latitude / longitude point in a model.
*
* ```js
* var CoffeeShop = loopback.createModel('coffee-shop', {
* location: 'GeoPoint'
* });
* ```
*
* You can query LoopBack models with a GeoPoint property and an attached data source using geo-spatial filters and
* sorting. For example, the following code finds the three nearest coffee shops.
*
* ```js
* CoffeeShop.attachTo(oracle);
* var here = new GeoPoint({lat: 10.32424, lng: 5.84978});
* CoffeeShop.find( {where: {location: {near: here}}, limit:3}, function(err, nearbyShops) {
* console.info(nearbyShops); // [CoffeeShop, ...]
* });
* ```
* @class GeoPoint
* @param {Object} latlong Object with two Number properties: lat and long.
* @prop {Number} lat
* @prop {Number} lng
*/
function GeoPoint(data) {
if (!(this instanceof GeoPoint)) {
return new GeoPoint(data);
@ -118,7 +143,18 @@ function GeoPoint(data) {
}
/**
* Determine the spherical distance between two geo points.
* Determine the spherical distance between two GeoPoints.
* Specify units of measurement with the 'type' property in options object. Type can be:
* - `miles` (default)
* - `radians`
* - `kilometers`
* - `meters`
* - `miles`
* - `feet`
* - `degrees`
* @param {GeoPoint} pointA Point A
* @param {GeoPoint} pointB Point B
* @param {Object} options Options object; has one key, 'type', to specify the units of measurment (see above). Default is miles.
*/
GeoPoint.distanceBetween = function distanceBetween(a, b, options) {
@ -140,6 +176,14 @@ GeoPoint.distanceBetween = function distanceBetween(a, b, options) {
/**
* Determine the spherical distance to the given point.
* Example:
* ```js
* var here = new GeoPoint({lat: 10, lng: 10});
* var there = new GeoPoint({lat: 5, lng: 5});
* GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438
* ```
* @param {Object} point GeoPoint object to which to measure distance.
* @param {Object} options Use type key to specify units of measurment (default is miles).
*/
GeoPoint.prototype.distanceTo = function (point, options) {
@ -155,16 +199,19 @@ GeoPoint.prototype.toString = function () {
}
/**
* Si
*/
* @property {Number} PI - Ratio of a circle's circumference to its diameter.
* @property {Number} DEG2RAD - Factor to convert degrees to radians.
* @property {Number} RAD2DEG - Factor to convert radians to degrees.
* @property {Object} EARTH_RADIUS - Radius of the earth.
*/
// ratio of a circle's circumference to its diameter
var PI = 3.1415926535897932384626433832795;
// factor to convert decimal degrees to radians
// factor to convert degrees to radians
var DEG2RAD = 0.01745329252;
// factor to convert decimal degrees to radians
// factor to convert radians degrees to degrees
var RAD2DEG = 57.29577951308;
// radius of the earth

View File

@ -2,32 +2,42 @@ var utils = require('./utils');
var isPlainObject = utils.isPlainObject;
var defineCachedRelations = utils.defineCachedRelations;
/**
/*!
* Include mixin for ./model.js
*/
module.exports = Inclusion;
/**
* Inclusion - Model mixin.
*
* @class
*/
function Inclusion() {
}
/**
* Allows you to load relations of several objects and optimize numbers of requests.
*
* @param {Array} objects - array of instances
* @param {String}, {Object} or {Array} include - which relations you want to load.
* @param {Function} cb - Callback called when relations are loaded
* Enables you to load relations of several objects and optimize numbers of requests.
*
* Examples:
*
* - User.include(users, 'posts', function() {}); will load all users posts with only one additional request.
* - User.include(users, ['posts'], function() {}); // same
* - User.include(users, ['posts', 'passports'], function() {}); // will load all users posts and passports with two
* additional requests.
* - Passport.include(passports, {owner: 'posts'}, function() {}); // will load all passports owner (users), and all
* posts of each owner loaded
* - Passport.include(passports, {owner: ['posts', 'passports']}); // ...
* - Passport.include(passports, {owner: [{posts: 'images'}, 'passports']}); // ...
* Load all users' posts with only one additional request:
* `User.include(users, 'posts', function() {});`
* Or
* `User.include(users, ['posts'], function() {});`
*
* Load all users posts and passports with two additional requests:
* `User.include(users, ['posts', 'passports'], function() {});`
*
* Load all passports owner (users), and all posts of each owner loaded:
*```Passport.include(passports, {owner: 'posts'}, function() {});
*``` Passport.include(passports, {owner: ['posts', 'passports']});
*``` Passport.include(passports, {owner: [{posts: 'images'}, 'passports']});
*
* @param {Array} objects Array of instances
* @param {String}, {Object} or {Array} include Which relations to load.
* @param {Function} cb Callback called when relations are loaded
*
*/
Inclusion.include = function (objects, include, cb) {
var self = this;

View File

@ -16,7 +16,7 @@ require('./types')(ModelBuilder);
var introspect = require('./introspection')(ModelBuilder);
/**
/*!
* Export public API
*/
exports.ModelBuilder = exports.Schema = ModelBuilder;
@ -27,9 +27,9 @@ exports.ModelBuilder = exports.Schema = ModelBuilder;
var slice = Array.prototype.slice;
/**
* ModelBuilder - A builder to define data models
* ModelBuilder - A builder to define data models.
*
* @constructor
* @class
*/
function ModelBuilder() {
// create blank models pool
@ -57,11 +57,11 @@ function isModelClass(cls) {
}
/**
* Get a model by name
* Get a model by name.
*
* @param {String} name The model name
* @param {Boolean} forceCreate Indicate if a stub should be created for the
* given name if a model doesn't exist
* @returns {*} The model class
* @param {Boolean} forceCreate Whether the create a stub for the given name if a model doesn't exist.
* Returns {*} The model class
*/
ModelBuilder.prototype.getModel = function (name, forceCreate) {
var model = this.models[name];
@ -81,17 +81,8 @@ ModelBuilder.prototype.getModelDefinition = function (name) {
};
/**
* Define a model class
*
* @param {String} className
* @param {Object} properties - hash of class properties in format
* `{property: Type, property2: Type2, ...}`
* or
* `{property: {type: Type}, property2: {type: Type2}, ...}`
* @param {Object} settings - other configuration of class
* @return newly created class
*
* @example simple case
* Define a model class.
* Simple example:
* ```
* var User = modelBuilder.define('User', {
* email: String,
@ -100,7 +91,7 @@ ModelBuilder.prototype.getModelDefinition = function (name) {
* activated: Boolean
* });
* ```
* @example more advanced case
* More advanced example:
* ```
* var User = modelBuilder.define('User', {
* email: { type: String, limit: 150, index: true },
@ -110,6 +101,12 @@ ModelBuilder.prototype.getModelDefinition = function (name) {
* activated: { type: Boolean, default: false }
* });
* ```
*
* @param {String} className Name of class
* @param {Object} properties Hash of class properties in format `{property: Type, property2: Type2, ...}` or `{property: {type: Type}, property2: {type: Type2}, ...}`
* @param {Object} settings Other configuration of class
* @return newly created class
*
*/
ModelBuilder.prototype.define = function defineClass(className, properties, settings, parent) {
var modelBuilder = this;
@ -331,7 +328,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
/**
* Register a property for the model class
* @param propertyName
* @param {String} propertyName Name of the property.
*/
ModelClass.registerProperty = function (propertyName) {
var properties = modelDefinition.build();
@ -426,9 +423,9 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
/**
* Define single property named `propertyName` on `model`
*
* @param {String} model - name of model
* @param {String} propertyName - name of property
* @param {Object} propertyDefinition - property settings
* @param {String} model Name of model
* @param {String} propertyName Name of property
* @param {Object} propertyDefinition Property settings
*/
ModelBuilder.prototype.defineProperty = function (model, propertyName, propertyDefinition) {
this.definitions[model].defineProperty(propertyName, propertyDefinition);
@ -438,25 +435,25 @@ ModelBuilder.prototype.defineProperty = function (model, propertyName, propertyD
/**
* Extend existing model with bunch of properties
*
* @param {String} model - name of model
* @param {Object} props - hash of properties
*
* Example:
*
* // Instead of doing this:
*
* // amend the content model with competition attributes
* Instead of doing amending the content model with competition attributes like this:
*
* ```js
* db.defineProperty('Content', 'competitionType', { type: String });
* db.defineProperty('Content', 'expiryDate', { type: Date, index: true });
* db.defineProperty('Content', 'isExpired', { type: Boolean, index: true });
*
* // modelBuilder.extend allows to
* // extend the content model with competition attributes
*```
* The extendModel() method enables you to extend the content model with competition attributes.
* ```js
* db.extendModel('Content', {
* competitionType: String,
* expiryDate: { type: Date, index: true },
* isExpired: { type: Boolean, index: true }
* });
*```
*
* @param {String} model Name of model
* @param {Object} props Hash of properties
*/
ModelBuilder.prototype.extendModel = function (model, props) {
var t = this;
@ -523,9 +520,9 @@ ModelBuilder.prototype.getSchemaName = function (name) {
};
/**
* Resolve the type string to be a function, for example, 'String' to String
* Resolve the type string to be a function, for example, 'String' to String.
* Returns {Function} if the type is resolved
* @param {String} type The type string, such as 'number', 'Number', 'boolean', or 'String'. It's case insensitive
* @returns {Function} if the type is resolved
*/
ModelBuilder.prototype.resolveType = function (type) {
if (!type) {
@ -620,10 +617,10 @@ ModelBuilder.prototype.buildModels = function (schemas) {
};
/**
* Introspect the json document to build a corresponding model
* Introspect the JSON document to build a corresponding model.
* @param {String} name The model name
* @param {Object} json The json object
* @param [Object} options The options
* @param {Object} json The JSON object
* @param {Object} options The options
* @returns {}
*/
ModelBuilder.prototype.buildModelFromInstance = function (name, json, options) {

View File

@ -1,9 +1,9 @@
/**
/*!
* Module exports class Model
*/
module.exports = ModelBaseClass;
/**
/*!
* Module dependencies
*/
@ -17,15 +17,12 @@ var validations = require('./validations.js');
var BASE_TYPES = ['String', 'Boolean', 'Number', 'Date', 'Text'];
/**
* Model class - base class for all persist objects
* provides **common API** to access any database connector.
* This class describes only abstract behavior layer, refer to `lib/connectors/*.js`
* to learn more about specific connector implementations
* Model class: base class for all persistent objects.
*
* `ModelBaseClass` mixes `Validatable` and `Hookable` classes methods
*
* @constructor
* @param {Object} data - initial object data
* @class
* @param {Object} data Initial object data
*/
function ModelBaseClass(data, options) {
options = options || {};
@ -195,8 +192,9 @@ ModelBaseClass.prototype._initProperties = function (data, options) {
};
/**
* @param {String} prop - property name
* @param {Object} params - various property configuration
* Define a property on the model.
* @param {String} prop Property name
* @param {Object} params Various property configuration
*/
ModelBaseClass.defineProperty = function (prop, params) {
this.dataSource.defineProperty(this.modelName, prop, params);
@ -221,20 +219,17 @@ ModelBaseClass.prototype.getPropertyType = function (propName) {
/**
* Return string representation of class
*
* @override default toString method
* This overrides the default `toString()` method
*/
ModelBaseClass.toString = function () {
return '[Model ' + this.modelName + ']';
};
/**
* Convert model instance to a plain JSON object
* Convert model instance to a plain JSON object.
* Returns a canonical object representation (no getters and setters).
*
* @param {Boolean} onlySchema - restrict properties to dataSource only,
* default to false. When onlySchema is true, only properties defined in
* the schema are returned, otherwise all enumerable properties returned
* @returns {Object} - canonical object representation (no getters and setters)
* @param {Boolean} onlySchema Restrict properties to dataSource only. Default is false. If true, the function returns only properties defined in the schema; Otherwise it returns all enumerable properties.
*/
ModelBaseClass.prototype.toObject = function (onlySchema) {
if(onlySchema === undefined) {
@ -303,7 +298,7 @@ ModelBaseClass.prototype.fromObject = function (obj) {
/**
* Checks is property changed based on current property and initial value
*
* @param {String} propertyName - property name
* @param {String} propertyName Property name
* @return Boolean
*/
ModelBaseClass.prototype.propertyChanged = function propertyChanged(propertyName) {
@ -311,10 +306,9 @@ ModelBaseClass.prototype.propertyChanged = function propertyChanged(propertyName
};
/**
* Reset dirty attributes
*
* this method does not perform any database operation it just reset object to it's
* initial state
* Reset dirty attributes.
* This method does not perform any database operations; it just resets the object to its
* initial state.
*/
ModelBaseClass.prototype.reset = function () {
var obj = this;

View File

@ -1,4 +1,4 @@
/**
/*!
* Dependencies
*/
var i8n = require('inflection');
@ -7,6 +7,11 @@ var ModelBaseClass = require('./model.js');
module.exports = Relation;
/**
* Relations class
*
* @class Relation
*/
function Relation() {
}
@ -31,11 +36,12 @@ function lookupModel(models, modelName) {
}
/**
* Declare hasMany relation
*
* @param {Relation} anotherClass - class to has many
* @param {Object} params - configuration {as:, foreignKey:}
* @example `User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});`
* Declare "hasMany" relation.
* Example:
* ```User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});```
*
* @param {Relation} anotherClass Class to has many
* @param {Object} params Configuration {as:, foreignKey:}
*/
Relation.hasMany = function hasMany(anotherClass, params) {
var thisClassName = this.modelName;
@ -172,27 +178,34 @@ Relation.hasMany = function hasMany(anotherClass, params) {
};
/**
* Declare belongsTo relation
* Declare "belongsTo" relation.
*
* @param {Class} anotherClass - class to belong
* @param {Object} params - configuration {as: 'propertyName', foreignKey: 'keyName'}
*
* **Usage examples**
* Suppose model Post have a *belongsTo* relationship with User (the author of the post). You could declare it this way:
* **Examples**
*
* Suppose the model Post has a *belongsTo* relationship with User (the author of the post). You could declare it this way:
* ```js
* Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});
* ```
*
* When a post is loaded, you can load the related author with:
* ```js
* post.author(function(err, user) {
* // the user variable is your user object
* });
* ```
*
* The related object is cached, so if later you try to get again the author, no additional request will be made.
* But there is an optional boolean parameter in first position that set whether or not you want to reload the cache:
* ```js
* post.author(true, function(err, user) {
* // The user is reloaded, even if it was already cached.
* });
*
* ```
* This optional parameter default value is false, so the related object will be loaded from cache if available.
*
* @param {Class} anotherClass Class to belong
* @param {Object} params Configuration {as: 'propertyName', foreignKey: 'keyName'}
*
*/
Relation.belongsTo = function (anotherClass, params) {
params = params || {};
@ -291,7 +304,13 @@ Relation.belongsTo = function (anotherClass, params) {
/**
* Many-to-many relation
*
* Post.hasAndBelongsToMany('tags'); creates connection model 'PostTag'
* For example, this creates connection model 'PostTag':
* ```js
* Post.hasAndBelongsToMany('tags');
* ```
* @param {String} anotherClass
* @param {Object} params
*
*/
Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params) {
params = params || {};

View File

@ -5,7 +5,7 @@ module.exports = BaseSQL;
/**
* Base class for connectors that are backed by relational databases/SQL
* @constructor
* @class
*/
function BaseSQL() {
Connector.apply(this, [].slice.call(arguments));
@ -21,7 +21,7 @@ BaseSQL.prototype.relational = true;
/**
* Get types associated with the connector
* @returns {String[]} The types for the connector
* Returns {String[]} The types for the connector
*/
BaseSQL.prototype.getTypes = function() {
return ['db', 'rdbms', 'sql'];
@ -29,7 +29,7 @@ BaseSQL.prototype.relational = true;
/*!
* Get the default data type for ID
* @returns {Function}
* Returns {Function}
*/
BaseSQL.prototype.getDefaultIdType = function() {
return Number;
@ -51,9 +51,9 @@ BaseSQL.prototype.queryOne = function (sql, callback) {
};
/**
* Get the table name for a given model
* Get the table name for a given model.
* Returns the table name (String).
* @param {String} model The model name
* @returns {String} The table name
*/
BaseSQL.prototype.table = function (model) {
var name = this.getDataSource(model).tableName(model);

View File

@ -1,15 +1,15 @@
var util = require('util');
/**
/*!
* Module exports
*/
exports.ValidationError = ValidationError;
exports.Validatable = Validatable;
/**
* Validation mixins for model.js
* Validation mixins for LoopBack models.
*
* Basically validation configurators is just class methods, which adds validations
* configs to AbstractClass._validations. Each of this validations run when
* `obj.isValid()` method called.
* This class provides methods that add validation cababilities to models.
* Each of this validations run when `obj.isValid()` method called.
*
* Each configurator can accept n params (n-1 field names and one config). Config
* is {Object} depends on specific validation, but all of them has one common part:
@ -18,9 +18,8 @@ exports.ValidationError = ValidationError;
*
* In more complicated cases it can be {Hash} of messages (for each case):
* `User.validatesLengthOf('password', { min: 6, max: 20, message: {min: 'too short', max: 'too long'}});`
* @class Validatable
*/
exports.Validatable = Validatable;
function Validatable() {
}
@ -29,19 +28,16 @@ function Validatable() {
*
* Default error message "can't be blank"
*
* @example presence of title
* For example, validate presence of title
* ```
* Post.validatesPresenceOf('title');
* ```
* @example with custom message
*Example with custom message
* ```
* Post.validatesPresenceOf('title', {message: 'Can not be blank'});
* Post.validatesPresenceOf('title', {message: 'Cannot be blank'});
* ```
*
* @sync
*
* @nocode
* @see helper/validatePresence
* @param
*/
Validatable.validatesPresenceOf = getConfigurator('presence');
@ -54,14 +50,14 @@ Validatable.validatesPresenceOf = getConfigurator('presence');
* - max: too long
* - is: length is wrong
*
* @example length validations
* Example: length validations
* ```
* User.validatesLengthOf('password', {min: 7});
* User.validatesLengthOf('email', {max: 100});
* User.validatesLengthOf('state', {is: 2});
* User.validatesLengthOf('nick', {min: 3, max: 15});
* ```
* @example length validations with custom error messages
* Example: length validations with custom error messages
* ```
* User.validatesLengthOf('password', {min: 7, message: {min: 'too weak'}});
* User.validatesLengthOf('state', {is: 2, message: {is: 'is not valid state name'}});
@ -76,7 +72,7 @@ Validatable.validatesLengthOf = getConfigurator('length');
/**
* Validate numericality.
*
* @example
* Example
* ```
* User.validatesNumericalityOf('age', { message: { number: '...' }});
* User.validatesNumericalityOf('age', {int: true, message: { int: '...' }});
@ -96,7 +92,7 @@ Validatable.validatesNumericalityOf = getConfigurator('numericality');
/**
* Validate inclusion in set
*
* @example
* Example:
* ```
* User.validatesInclusionOf('gender', {in: ['male', 'female']});
* User.validatesInclusionOf('role', {
@ -115,7 +111,7 @@ Validatable.validatesInclusionOf = getConfigurator('inclusion');
/**
* Validate exclusion
*
* @example `Company.validatesExclusionOf('domain', {in: ['www', 'admin']});`
* Example: `Company.validatesExclusionOf('domain', {in: ['www', 'admin']});`
*
* Default error message: is reserved
*
@ -332,7 +328,7 @@ function getConfigurator(name, opts) {
* @param {Function} callback called with (valid)
* @return {Boolean} true if no async validation configured and all passed
*
* @example ExpressJS controller: render user if valid, show flash otherwise
* Example: ExpressJS controller: render user if valid, show flash otherwise
* ```
* user.isValid(function (valid) {
* if (valid) res.render({user: user});