diff --git a/lib/datasource.js b/lib/datasource.js index 62505c132..2f7c6d931 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -264,8 +264,12 @@ DataSource._resolveConnector = function(name, loader) { }; /** - * Connect to the data source + * Connect to the data source. + * If no callback is provided, it will return a Promise. + * Emits the 'connect' event. * @param callback + * @returns {Promise} + * @emits connected */ DataSource.prototype.connect = function(callback) { callback = callback || utils.createPromiseCallback(); @@ -439,9 +443,14 @@ function isModelDataSourceAttached(model) { } /*! - * Define scopes for the model class from the scopes object - * @param modelClass - * @param scopes + * Define scopes for the model class from the scopes object. See + * [scopes](./Model-definition-JSON-file.html#scopes) for more information on + * scopes and valid options objects. + * @param {Object} modelClass - The model class that corresponds to the model + * definition that will be enhanced by the provided scopes. + * @param {Object} scopes A key-value collection of names and their object + * definitions + * @property options The options defined on the scope object. */ DataSource.prototype.defineScopes = function(modelClass, scopes) { if (scopes) { @@ -452,9 +461,12 @@ DataSource.prototype.defineScopes = function(modelClass, scopes) { }; /*! - * Define relations for the model class from the relations object - * @param modelClass - * @param relations + * Define relations for the model class from the relations object. See + * [relations](./Model-definition-JSON-file.html#relations) for more information. + * @param {Object} modelClass - The model class that corresponds to the model + * definition that will be enhanced by the provided relations. + * @param {Object} relations A key-value collection of relation names and their + * object definitions. */ DataSource.prototype.defineRelations = function(modelClass, relations) { var self = this; @@ -548,9 +560,11 @@ function isValidRelationName(relationName) { } /*! - * Set up the data access functions from the data source - * @param {Model} modelClass The model class - * @param {Object} settings The settings object + * Set up the data access functions from the data source. Each data source will + * expose a data access object (DAO), which will be mixed into the modelClass. + * @param {Model} modelClass The model class that will receive DAO mixins. + * @param {Object} settings The settings object; typically allows any settings + * that would be valid for a typical Model object. */ DataSource.prototype.setupDataAccess = function(modelClass, settings) { if (this.connector) { @@ -643,7 +657,7 @@ DataSource.prototype.setupDataAccess = function(modelClass, settings) { * @param {String} className Name of the model to create. * @param {Object} properties Hash of model properties in format `{property: Type, property2: Type2, ...}` or `{property: {type: Type}, property2: {type: Type2}, ...}` * @options {Object} properties Other configuration options. This corresponds to the options key in the config object. - * + * @param {Object} settings A settings object that would typically be used for Model objects. */ DataSource.prototype.createModel = @@ -731,23 +745,35 @@ DataSource.prototype.mixin = function(ModelCtor) { }; /** - * See ModelBuilder.getModel + * + * FIXME: Deprecation notice for 4.x? + * See [ModelBuilder.getModel](http://apidocs.strongloop.com/loopback-datasource-juggler/#modelbuilder-prototype-getmodel) + * for details. */ DataSource.prototype.getModel = function(name, forceCreate) { return this.modelBuilder.getModel(name, forceCreate); }; /** + * // FIXME: Make this a link to ModelBuilder.getModelDefinition's docs! + * // FIXME: Deprecation notice for 4.x? * See ModelBuilder.getModelDefinition + * See [ModelBuilder.getModelDefinition](http://apidocs.strongloop.com/loopback-datasource-juggler/#modelbuilder-prototype-getmodeldefinition) + * for details. */ DataSource.prototype.getModelDefinition = function(name) { return this.modelBuilder.getModelDefinition(name); }; /** - * Get the data source types - * @returns {String[]} The data source type, such as ['db', 'nosql', 'mongodb'], - * ['rest'], or ['db', 'rdbms', 'mysql'] + * Get the data source types collection. + * @returns {String[]} The data source type array. + * For example, ['db', 'nosql', 'mongodb'] would be represent a datasource of + * type 'db', with a subtype of 'nosql', and would use the 'mongodb' connector. + * + * Alternatively, ['rest'] would be a different type altogether, and would have + * no subtype. + * FIXME: Deprecation notice for 4.x? */ DataSource.prototype.getTypes = function() { var getTypes = this.connector && this.connector.getTypes; @@ -760,7 +786,7 @@ DataSource.prototype.getTypes = function() { /** * 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. + * @param {String|String[]} types Type name or an array of type names. * @returns {Boolean} true if all types are supported by the data source */ DataSource.prototype.supportTypes = function(types) { @@ -782,8 +808,12 @@ DataSource.prototype.supportTypes = function(types) { /** * Attach an existing model to a data source. - * - * @param {Function} modelClass The model constructor + * This will mixin all of the data access object functions (DAO) into your + * modelClass definition. + * @param {Function} modelClass The model constructor that will be enhanced by + * DAO mixins. + * FIXME: In future versions, this will not maintain a strict 1:1 relationship + * between datasources and model classes. */ DataSource.prototype.attach = function(modelClass) { @@ -808,11 +838,13 @@ DataSource.prototype.attach = function(modelClass) { }; /** - * Define single property named `prop` on `model` - * + * Define a property with name `prop` on a target `model`. See + * [Properties](./Model-definition-JSON-file.html#properties) for more information + * regarding valid options for `params`. + * FIXME: Deprecate for 4.0? * @param {String} model Name of model * @param {String} prop Name of property - * @param {Object} params Property settings + * @param {Property} params Property settings */ DataSource.prototype.defineProperty = function(model, prop, params) { this.modelBuilder.defineProperty(model, prop, params); @@ -824,15 +856,18 @@ DataSource.prototype.defineProperty = function(model, prop, params) { }; /** - * Drop each model table and re-create. - * This method applies only to database connectors. For MongoDB, it drops and creates indexes. + * Drop schema objects such as tables, indexes, views, triggers, etc that correspond + * to model definitions attached to this DataSource instance, specified by the `models` parameter. + * + * **WARNING**: In many situations, this will destroy data! `autoupdate()` will attempt to preserve + * data while updating the schema on your target DataSource, but this is not guaranteed to be safe. * - * **WARNING**: Calling this function deletes all data! Use `autoupdate()` to preserve data. + * Please check the documentation for your specific connector(s) for a detailed breakdown of + * behaviors for automigrate! * - * @param {String} model Model to migrate. If not present, apply to all models. Can also be an array of Strings. + * @param {String|String[]} [models] Model(s) to migrate. If not present, apply to all models. * @param {Function} [callback] Callback function. Optional. * - */ DataSource.prototype.automigrate = function(models, cb) { this.freeze(); @@ -886,7 +921,13 @@ DataSource.prototype.automigrate = function(models, cb) { * Update existing database tables. * This method applies only to database connectors. * - * @param {String} model Model to migrate. If not present, apply to all models. Can also be an array of Strings. + * **WARNING**: `autoupdate()` will attempt to preserve data while updating the + * schema on your target DataSource, but this is not guaranteed to be safe. + * + * Please check the documentation for your specific connector(s) for a detailed breakdown of + * behaviors for automigrate!* + * + * @param {String|String[]} [models] Model(s) to migrate. If not present, apply to all models. * @param {Function} [cb] The callback function */ DataSource.prototype.autoupdate = function(models, cb) { @@ -949,7 +990,7 @@ DataSource.prototype.autoupdate = function(models, cb) { * @property {Boolean} views If true, include views; if false, only tables. * @property {Number} limit Page size * @property {Number} offset Starting index - * + * @returns {ModelDefinition[]} */ DataSource.prototype.discoverModelDefinitions = function(options, cb) { this.freeze(); @@ -970,13 +1011,14 @@ DataSource.prototype.discoverModelDefinitions = function(options, cb) { }; /** + * FIXME Deprecate/remove this for LB 4.0? * The synchronous version of discoverModelDefinitions. * @options {Object} options The options * @property {Boolean} all If true, discover all models; if false, discover only models owned by the current user. * @property {Boolean} views If true, nclude views; if false, only tables. * @property {Number} limit Page size * @property {Number} offset Starting index - * @returns {*} + * @returns {ModelDefinition[]} */ DataSource.prototype.discoverModelDefinitionsSync = function(options) { this.freeze(); @@ -1001,11 +1043,14 @@ DataSource.prototype.discoverModelDefinitionsSync = function(options) { *|dataPrecision | Number | Numeric data precision| *|dataScale |Number | Numeric data scale| *|nullable |Boolean | If true, then the data can be null| - * + * See [Properties](./Model-definition-JSON-file.html#properties) for more + * details on the Property return type. * @param {String} modelName The table/view name * @options {Object} options The options * @property {String} owner|schema The database owner or schema * @param {Function} cb Callback function. Optional + * @callback cb + * @returns {Promise} A promise that returns an array of Properties (Property[]) * */ DataSource.prototype.discoverModelProperties = function(modelName, options, cb) { @@ -1027,6 +1072,7 @@ DataSource.prototype.discoverModelProperties = function(modelName, options, cb) }; /** + * FIXME: Deprecate this for LB 4.x? * The synchronous version of discoverModelProperties * @param {String} modelName The table/view name * @param {Object} options The options @@ -1051,11 +1097,13 @@ DataSource.prototype.discoverModelPropertiesSync = function(modelName, options) *| columnName |String| Column name *| keySeq |Number| Sequence number within primary key (1 indicates the first column in the primary key; 2 indicates the second column in the primary key). *| pkName |String| Primary key name (may be null) - * + * See [ID Properties](./Model-definition-JSON-file.html#id-properties) for more + * information. * @param {String} modelName The model name * @options {Object} options The options * @property {String} owner|schema The database owner or schema * @param {Function} [cb] The callback function + * @returns {Promise} A promise with an array of Primary Keys (Property[]) */ DataSource.prototype.discoverPrimaryKeys = function(modelName, options, cb) { this.freeze(); @@ -1076,10 +1124,11 @@ DataSource.prototype.discoverPrimaryKeys = function(modelName, options, cb) { }; /** + * FIXME: Obsolete? * The synchronous version of discoverPrimaryKeys * @param {String} modelName The model name * @options {Object} options The options - * @property {String} owner|schema The database owner orschema + * @property {String} owner|schema The database owner or schema * @returns {*} */ DataSource.prototype.discoverPrimaryKeysSync = function(modelName, options) { @@ -1106,11 +1155,13 @@ DataSource.prototype.discoverPrimaryKeysSync = function(modelName, options) { *|pkName |String | Primary key name (may be null) *|pkTableName |String | Primary key table name being imported *|pkColumnName |String | Primary key column name being imported - * + * See [Relations](/Model-definition-JSON-file.html#relations) for more + * information. * @param {String} modelName The model name * @options {Object} options The options * @property {String} owner|schema The database owner or schema * @param {Function} [cb] The callback function + * @returns {Promise} A Promise with an array of foreign key relations. * */ DataSource.prototype.discoverForeignKeys = function(modelName, options, cb) { @@ -1132,6 +1183,7 @@ DataSource.prototype.discoverForeignKeys = function(modelName, options, cb) { }; /** + * FIXME: Obsolete? * The synchronous version of discoverForeignKeys * * @param {String} modelName The model name @@ -1163,11 +1215,14 @@ DataSource.prototype.discoverForeignKeysSync = function(modelName, options) { *|pkName |String | Primary key name (may be null) *|pkTableName |String | Primary key table name being imported *|pkColumnName |String | Primary key column name being imported + * See [Relations](/Model-definition-JSON-file.html#relations) for more + * information. * * @param {String} modelName The model name * @options {Object} options The options * @property {String} owner|schema The database owner or schema * @param {Function} [cb] The callback function + * @returns {Promise} A Promise with an array of exported foreign key relations. */ DataSource.prototype.discoverExportedForeignKeys = function(modelName, options, cb) { this.freeze(); @@ -1188,6 +1243,7 @@ DataSource.prototype.discoverExportedForeignKeys = function(modelName, options, }; /** + * FIXME: Obsolete? * The synchronous version of discoverExportedForeignKeys * @param {String} modelName The model name * @param {Object} options The options @@ -1275,11 +1331,13 @@ function fromDBName(dbName, camelCase) { * } * ``` * - * @param {String} modelName The model name - * @param {Object} [options] The options + * @param {String} tableName The name of the table to discover. + * @options {Object} [options] An options object typically used for Relations. + * See [Relations](./Model-definition-JSON-file.html#relations) for more information. * @param {Function} [cb] The callback function + * @returns {Promise} A promise object that resolves to a single schema. */ -DataSource.prototype.discoverSchema = function(modelName, options, cb) { +DataSource.prototype.discoverSchema = function(tableName, options, cb) { options = options || {}; if (!cb && 'function' === typeof options) { @@ -1291,7 +1349,7 @@ DataSource.prototype.discoverSchema = function(modelName, options, cb) { cb = cb || utils.createPromiseCallback(); - this.discoverSchemas(modelName, options, function(err, schemas) { + this.discoverSchemas(tableName, options, function(err, schemas) { if (err || !schemas) { cb && cb(err, schemas); return; @@ -1305,17 +1363,18 @@ DataSource.prototype.discoverSchema = function(modelName, options, cb) { }; /** - * Discover schema from a given modelName/view. + * Discover schema from a given tableName/viewName. * - * @param {String} modelName The model name. + * @param {String} tableName The table name. * @options {Object} [options] Options; see below. * @property {String} owner|schema Database owner or schema name. * @property {Boolean} relations True if relations (primary key/foreign key) are navigated; false otherwise. * @property {Boolean} all True if all owners are included; false otherwise. * @property {Boolean} views True if views are included; false otherwise. * @param {Function} [cb] The callback function + * @returns {Promise} A promise object that resolves to an array of schemas. */ -DataSource.prototype.discoverSchemas = function(modelName, options, cb) { +DataSource.prototype.discoverSchemas = function(tableName, options, cb) { options = options || {}; if (!cb && 'function' === typeof options) { @@ -1352,17 +1411,17 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { if (this.connector.discoverSchemas) { // Delegate to the connector implementation - this.connector.discoverSchemas(modelName, options, cb); + this.connector.discoverSchemas(tableName, options, cb); return cb.promise; } var tasks = [ - this.discoverModelProperties.bind(this, modelName, options), - this.discoverPrimaryKeys.bind(this, modelName, options)]; + this.discoverModelProperties.bind(this, tableName, options), + this.discoverPrimaryKeys.bind(this, tableName, options)]; var followingRelations = options.associations || options.relations; if (followingRelations) { - tasks.push(this.discoverForeignKeys.bind(this, modelName, options)); + tasks.push(this.discoverForeignKeys.bind(this, tableName, options)); } async.parallel(tasks, function(err, results) { @@ -1373,7 +1432,7 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { var columns = results[0]; if (!columns || columns.length === 0) { - cb(new Error(g.f('Table \'%s\' does not exist.', modelName))); + cb(new Error(g.f('Table \'%s\' does not exist.', tableName))); return cb.promise; } @@ -1389,7 +1448,7 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { } var schema = { - name: nameMapper('table', modelName), + name: nameMapper('table', tableName), options: { idInjection: false, // DO NOT add id property }, @@ -1398,7 +1457,7 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { schema.options[dbType] = { schema: columns[0].owner, - table: modelName, + table: tableName, }; columns.forEach(function(item) { @@ -1433,7 +1492,7 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { // Add current modelName to the visited tables options.visited = options.visited || {}; - var schemaKey = columns[0].owner + '.' + modelName; + var schemaKey = columns[0].owner + '.' + tableName; if (!options.visited.hasOwnProperty(schemaKey)) { if (self.settings.debug) { debug('Adding schema for ' + schemaKey); @@ -1507,13 +1566,14 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) { /** * Discover schema from a given table/view synchronously - * + * FIXME Obsolete? * @param {String} modelName The model name * @options {Object} [options] Options; see below. * @property {String} owner|schema Database owner or schema name. * @property {Boolean} relations True if relations (primary key/foreign key) are navigated; false otherwise. * @property {Boolean} all True if all owners are included; false otherwise. * @property {Boolean} views True if views are included; false otherwise. + * @returns {Array} An array of schema definition objects. */ DataSource.prototype.discoverSchemasSync = function(modelName, options) { var self = this; @@ -1660,6 +1720,8 @@ DataSource.prototype.discoverSchemasSync = function(modelName, options) { * @property {Boolean} all True if all owners are included; false otherwise. * @property {Boolean} views True if views are included; false otherwise. * @param {Function} [cb] The callback function + * @returns {Promise} A Promise object that resolves with a map of model + * constructors, keyed by model name */ DataSource.prototype.discoverAndBuildModels = function(modelName, options, cb) { var self = this; @@ -1689,7 +1751,7 @@ DataSource.prototype.discoverAndBuildModels = function(modelName, options, cb) { /** * Discover and build models from the given owner/modelName synchronously. - * + * FIXME: Obsolete? * @param {String} modelName The model name. * @options {Object} [options] Options; see below. * @property {String} owner|schema Database owner or schema name. @@ -1699,6 +1761,7 @@ DataSource.prototype.discoverAndBuildModels = function(modelName, options, cb) { * @param {String} modelName The model name * @param {Object} [options] The options + * @returns {Object} A map of model constructors, keyed by model name */ DataSource.prototype.discoverAndBuildModelsSync = function(modelName, options) { options = options || {}; @@ -1725,7 +1788,7 @@ DataSource.prototype.discoverAndBuildModelsSync = function(modelName, options) { * @param {String} name Name of the model * @param {Object} json The json object representing a model instance * @param {Object} options Options - * @returns {*} + * @returns {Model} A Model class */ DataSource.prototype.buildModelFromInstance = function(name, json, options) { // Introspect the JSON document to generate a schema @@ -1736,9 +1799,11 @@ DataSource.prototype.buildModelFromInstance = function(name, json, options) { }; /** - * Check whether migrations needed - * This method applies only to SQL connectors. + * Check whether or not migrations are required for the database schema to match + * the Model definitions attached to the DataSource. + * Note: This method applies only to SQL connectors. * @param {String|String[]} [models] A model name or an array of model names. If not present, apply to all models. + * @returns {Boolean} Whether or not migrations are required. */ DataSource.prototype.isActual = function(models, cb) { this.freeze(); @@ -1759,7 +1824,7 @@ DataSource.prototype.isActual = function(models, cb) { /** * Log benchmarked message. Do not redefine this method, if you need to grab - * chema logs, use `dataSource.on('log', ...)` emitter event + * schema logs, use `dataSource.on('log', ...)` emitter event * * @private used by connectors */ @@ -1770,6 +1835,9 @@ DataSource.prototype.log = function(sql, t) { /** * Freeze dataSource. Behavior depends on connector + * REVIEW: Raymond, can you give example of what behavior(s) are typically + * expected here? I understand that it's connector-specific, but surely there's + * a common goal here. */ DataSource.prototype.freeze = function freeze() { if (!this.connector) { @@ -1784,8 +1852,9 @@ DataSource.prototype.freeze = function freeze() { }; /** - * Return table name for specified `modelName` - * @param {String} modelName The model name + * Return table name for specified `modelName`. + * @param {String} modelName The model name. + * @returns {String} The table name. */ DataSource.prototype.tableName = function(modelName) { return this.getModelDefinition(modelName).tableName(this.connector.name); @@ -1918,7 +1987,8 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key }; /** - * Close database connection + * Close connection to the DataSource. + * REVIEW: Why is this not Promisified like the connect function? * @param {Function} [cb] The callback function. Optional. */ DataSource.prototype.disconnect = function disconnect(cb) { @@ -1939,7 +2009,7 @@ DataSource.prototype.disconnect = function disconnect(cb) { /** * Copy the model from Master. * @param {Function} Master The model constructor - * @returns {Function} The copy of the model constructor + * @returns {Model} A copy of the Model object constructor * * @private */ @@ -1979,7 +2049,7 @@ DataSource.prototype.copyModel = function copyModel(Master) { }; /** - * + * Run a transaction against the DataSource. * @returns {EventEmitter} * @private */ @@ -2124,9 +2194,10 @@ DataSource.prototype.isRelational = function() { return this.connector && this.connector.relational; }; -/*! +/** * Check if the data source is ready. * Returns a Boolean value. + * REVIEW: What is "obj" supposed to represent? * @param {Object} obj ? * @param {Object} args ? */ @@ -2217,6 +2288,8 @@ DataSource.prototype.ping = function(cb) { /** * Define a hidden property + * REVIEW: Why is a hidden property not writable or enumerable? What + * purpose does it serve? * @param {Object} obj The property owner * @param {String} key The property name * @param {Mixed} value The default value