LoopBack DataSource API

Model builder

modelBuilder.define(className, properties, settings)

Define a model class

Arguments
Name Type Description
className String
properties Object

hash of class properties in format {property: Type, property2: Type2, ...} or {property: {type: Type}, property2: {type: Type2}, ...}

settings Object

other configuration of class

Example

more advanced case var User = modelBuilder.define('User', { email: { type: String, limit: 150, index: true }, password: { type: String, limit: 50 }, birthDate: Date, registrationDate: {type: Date, default: function () { return new Date }}, activated: { type: Boolean, default: false } });

ModelClass.registerProperty(propertyName)

Register a property for the model class

Arguments
Name Type Description
propertyName

modelBuilder.defineProperty(model, propertyName, propertyDefinition)

Define single property named propertyName on model

Arguments
Name Type Description
model String

name of model

propertyName String

name of property

propertyDefinition Object

property settings

modelBuilder.extendModel(model, props)

Extend existing model with bunch of properties

Arguments
Name Type Description
model String

name of model

props Object

hash of properties Example:

// Instead of doing this:

// amend the content model with competition attributes
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
db.extendModel('Content', {
  competitionType: String,
  expiryDate: { type: Date, index: true },
  isExpired: { type: Boolean, index: true }
});

modelBuilder.getSchemaName()

Get the schema name

modelBuilder.resolveType(type)

Resolve the type string to be a function, for example, 'String' to String

Arguments
Name Type Description
type String

The type string, such as 'number', 'Number', 'boolean', or 'String'. It's case insensitive

Returns
Name Type Description
result Function

if the type is resolved

modelBuilder.buildModels(schemas)

Build models from schema definitions

schemas can be one of the following:

  1. An array of named schema definition JSON objects
  2. A schema definition JSON object
  3. A list of property definitions (anonymous)
Arguments
Name Type Description
schemas

The schemas

Returns
Name Type Description
result Object

A map of model constructors keyed by model name

modelBuilder.buildModelFromInstance(name, json, [Object} options The options)

Introspect the json document to build a corresponding model

Arguments
Name Type Description
name String

The model name

json Object

The json object

[Object} options The options
Returns
Name Type Description
result

{}

exports.ModelBuilder

Export public API

this.models

Class Properties
Name Type Description
models Object

Model constructors

this.definitions

Class Properties
Name Type Description
definitions Object

Definitions of the models

Types

Types.Text()

Schema types

GeoPoint

GeoPoint.distanceBetween()

Determine the spherical distance between two geo points.

geoPoint.distanceTo()

Determine the spherical distance to the given point.

geoPoint.toString()

Simple serialization.

exports.GeoPoint

Export the GeoPoint class.

Model

ModelBaseClass(data)

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

ModelBaseClass mixes Validatable and Hookable classes methods

Arguments
Name Type Description
data Object

initial object data

ModelBaseClass.defineProperty(prop, params)

Arguments
Name Type Description
prop String

property name

params Object

various property configuration

ModelBaseClass.toString()

Return string representation of class

modelBaseClass.toObject(onlySchema)

Convert instance to Object

Arguments
Name Type Description
onlySchema Boolean

restrict properties to dataSource only, default false when onlySchema == true, only properties defined in dataSource returned, otherwise all enumerable properties returned

Returns
Name Type Description
result Object
  • canonical object representation (no getters and setters)

modelBaseClass.propertyChanged(propertyName)

Checks is property changed based on current property and initial value

Arguments
Name Type Description
propertyName String

property name

modelBaseClass.reset()

Reset dirty attributes

this method does not perform any database operation it just reset object to it's initial state

module.exports

Module exports class Model

DataSource

DataSource(name, settings)

DataSource - connector-specific classes factory.

All classes in single dataSource shares same connector type and one database connection

Arguments
Name Type Description
name String

type of dataSource connector (mysql, mongoose, oracle, redis)

settings Object

any database-specific settings which we need to establish connection (of course it depends on specific connector)

  • host
  • port
  • username
  • password
  • database
  • debug {Boolean} = false
Example

DataSource creation, waiting for connection callback var dataSource = new DataSource('mysql', { database: 'myapp_test' }); dataSource.define(...); dataSource.on('connected', function () { // work with database });

dataSource.createModel(className, properties, settings)

Define a model class

Arguments
Name Type Description
className String
properties Object

hash of class properties in format {property: Type, property2: Type2, ...} or {property: {type: Type}, property2: {type: Type2}, ...}

settings Object

other configuration of class

Example

more advanced case var User = dataSource.define('User', { email: { type: String, limit: 150, index: true }, password: { type: String, limit: 50 }, birthDate: Date, registrationDate: {type: Date, default: function () { return new Date }}, activated: { type: Boolean, default: false } });

dataSource.mixin(ModelCtor)

Mixin DataAccessObject methods.

Arguments
Name Type Description
ModelCtor Function

The model constructor

dataSource.attach(modelClass)

Attach an existing model to a data source.

Arguments
Name Type Description
modelClass Function

The model constructor

dataSource.defineProperty(model, prop, params)

Define single property named prop on model

Arguments
Name Type Description
model String

name of model

prop String

name of property

params Object

property settings

dataSource.automigrate(or, [cb])

Drop each model table and re-create. This method make sense only for sql connectors.

Arguments
Name Type Description
or String

{[String]} Models to be migrated, if not present, apply to all models

[cb] Function

The callback function

dataSource.autoupdate(or, [cb])

Update existing database tables. This method make sense only for sql connectors.

Arguments
Name Type Description
or String

{[String]} Models to be migrated, if not present, apply to all models

[cb] Function

The callback function

dataSource.discoverModelDefinitions(options, [cb])

Discover existing database tables. This method returns an array of model objects, including {type, name, onwer}

options

 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
Arguments
Name Type Description
options Object

The options

[cb] Function

The callback function

dataSource.discoverModelDefinitionsSync(options)

The synchronous version of discoverModelDefinitions

Arguments
Name Type Description
options Object

The options

Returns
Name Type Description
result

dataSource.discoverModelProperties(modelName, options, [cb])

Discover properties for a given model.

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

options

 owner/schema The database owner/schema
Arguments
Name Type Description
modelName String

The table/view name

options Object

The options

[cb] Function

The callback function

dataSource.discoverModelPropertiesSync(modelName, options)

The synchronous version of discoverModelProperties

Arguments
Name Type Description
modelName String

The table/view name

options Object

The options

Returns
Name Type Description
result

dataSource.discoverPrimaryKeys(modelName, options, [cb])

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)

 The owner, default to current user

options

 owner/schema The database owner/schema
Arguments
Name Type Description
modelName String

The model name

options Object

The options

[cb] Function

The callback function

dataSource.discoverPrimaryKeysSync(modelName, options)

The synchronous version of discoverPrimaryKeys

Arguments
Name Type Description
modelName String

The model name

options Object

The options

Returns
Name Type Description
result

dataSource.discoverForeignKeys(modelName, options, [cb])

Discover foreign keys for a given owner/modelName

foreign key description

 fkOwner String => foreign key table schema (may be null)
 fkName String => foreign key name (may be null)
 fkTableName String => foreign key table name
 fkColumnName String => foreign key column name
 keySeq Number => sequence number within a foreign key( a value of 1 represents the first column of the foreign key, a value of 2 would represent the second column within the foreign key).
 pkOwner String => primary key table schema being imported (may be null)
 pkName String => primary key name (may be null)
 pkTableName String => primary key table name being imported
 pkColumnName String => primary key column name being imported

options

 owner/schema The database owner/schema
Arguments
Name Type Description
modelName String

The model name

options Object

The options

[cb] Function

The callback function

dataSource.discoverForeignKeysSync(modelName, options)

The synchronous version of discoverForeignKeys

Arguments
Name Type Description
modelName String

The model name

options Object

The options

Returns
Name Type Description
result

dataSource.discoverExportedForeignKeys(modelName, options, [cb])

Retrieves a description of the foreign key columns that reference the given table's primary key columns (the foreign keys exported by a table). They are ordered by fkTableOwner, fkTableName, and keySeq.

foreign key description

 fkOwner {String} => foreign key table schema (may be null)
 fkName {String} => foreign key name (may be null)
 fkTableName {String} => foreign key table name
 fkColumnName {String} => foreign key column name
 keySeq {Number} => sequence number within a foreign key( a value of 1 represents the first column of the foreign key, a value of 2 would represent the second column within the foreign key).
 pkOwner {String} => primary key table schema being imported (may be null)
 pkName {String} => primary key name (may be null)
 pkTableName {String} => primary key table name being imported
 pkColumnName {String} => primary key column name being imported

options

 owner/schema The database owner/schema
Arguments
Name Type Description
modelName String

The model name

options Object

The options

[cb] Function

The callback function

dataSource.discoverExportedForeignKeysSync(modelName, options)

The synchronous version of discoverExportedForeignKeys

Arguments
Name Type Description
modelName String

The model name

options Object

The options

Returns
Name Type Description
result

dataSource.discoverSchema(modelName, [options], [cb])

Discover one schema from the given model without following the relations

Arguments
Name Type Description
modelName String

The model name

[options] Object

The options

[cb] Function

The callback function

dataSource.discoverSchemas(modelName, [options], [cb])

Discover schema from a given modelName/view

options

 {String} owner/schema - The database owner/schema name
 {Boolean} relations - If relations (primary key/foreign key) are navigated
 {Boolean} all - If all owners are included
 {Boolean} views - If views are included
Arguments
Name Type Description
modelName String

The model name

[options] Object

The options

[cb] Function

The callback function

dataSource.discoverSchemasSync(modelName, [options])

Discover schema from a given table/view synchronously

options

 {String} owner/schema - The database owner/schema name
 {Boolean} relations - If relations (primary key/foreign key) are navigated
 {Boolean} all - If all owners are included
 {Boolean} views - If views are included
Arguments
Name Type Description
modelName String

The model name

[options] Object

The options

dataSource.discoverAndBuildModels(modelName, [options], [cb])

Discover and build models from the given owner/modelName

options

 {String} owner/schema - The database owner/schema name
 {Boolean} relations - If relations (primary key/foreign key) are navigated
 {Boolean} all - If all owners are included
 {Boolean} views - If views are included
Arguments
Name Type Description
modelName String

The model name

[options] Object

The options

[cb] Function

The callback function

dataSource.discoverAndBuildModelsSync(modelName, [options])

Discover and build models from the given owner/modelName synchronously

options

 {String} owner/schema - The database owner/schema name
 {Boolean} relations - If relations (primary key/foreign key) are navigated
 {Boolean} all - If all owners are included
 {Boolean} views - If views are included
Arguments
Name Type Description
modelName String

The model name

[options] Object

The options

dataSource.isActual([models])

Check whether migrations needed This method make sense only for sql connectors.

Arguments
Name Type Description
[models] Array.<String>

A model name or an array of model names. If not present, apply to all models

dataSource.freeze()

Freeze dataSource. Behavior depends on connector

dataSource.tableName(modelName)

Return table name for specified modelName

Arguments
Name Type Description
modelName String

The model name

dataSource.columnName(modelName, propertyName)

Return column name for specified modelName and propertyName

Arguments
Name Type Description
modelName String

The model name

propertyName

The property name

Returns
Name Type Description
result String

columnName

dataSource.columnMetadata(modelName, propertyName)

Return column metadata for specified modelName and propertyName

Arguments
Name Type Description
modelName String

The model name

propertyName

The property name

Returns
Name Type Description
result Object

column metadata

dataSource.columnNames(modelName)

Return column names for specified modelName

Arguments
Name Type Description
modelName String

The model name

Returns
Name Type Description
result Array.<String>

column names

dataSource.idColumnName(modelName)

Find the ID column name

Arguments
Name Type Description
modelName String

The model name

Returns
Name Type Description
result String

columnName for ID

dataSource.idName(modelName)

Find the ID property name

Arguments
Name Type Description
modelName String

The model name

Returns
Name Type Description
result String

property name for ID

dataSource.idNames(modelName)

Find the ID property names sorted by the index

Arguments
Name Type Description
modelName String

The model name

Returns
Name Type Description
result Array.<String>

property names for IDs

dataSource.defineForeignKey(className, key, foreignClassName)

Define foreign key to another model

Arguments
Name Type Description
className String

The model name that owns the key

key String

name of key field

foreignClassName String

The foreign model name

dataSource.disconnect([cb])

Close database connection

Arguments
Name Type Description
[cb] Fucntion

The callback function

dataSource.enableRemote(operation)

Enable a data source operation to be remote.

Arguments
Name Type Description
operation String

The operation name

dataSource.disableRemote(operation)

Disable a data source operation to be remote.

Arguments
Name Type Description
operation String

The operation name

dataSource.getOperation(operation)

Get an operation's metadata.

Arguments
Name Type Description
operation String

The operation name

dataSource.operations()

Get all operations.

dataSource.defineOperation(name, options, [Function} fn The function)

Define an operation to the data source

Arguments
Name Type Description
name String

The operation name

options Object

The options

[Function} fn The function

dataSource.isRelational()

Check if the backend is a relational DB

Returns
Name Type Description
result Boolean

dataSource.ready(obj, args)

Check if the data source is ready

Arguments
Name Type Description
obj
args
Returns
Name Type Description
result boolean

hiddenProperty(obj, key, value)

Define a hidden property

Arguments
Name Type Description
obj Object

The property owner

key String

The property name

value Mixed

The default value

defineReadonlyProp(obj, key, value)

Define readonly property on object

Arguments
Name Type Description
obj Object

The property owner

key String

The property name

value Mixed

The default value

exports.DataSource

Export public API

Data access mixins

DataAccessObject(data)

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

DataAccessObject mixes Inclusion classes methods

Arguments
Name Type Description
data Object

initial object data

DataAccessObject.create(data, callback(err,)

Create new instance of Model class, saved in database

Arguments
Name Type Description
data

[optional]

callback(err,

obj) callback called with arguments:

  • err (null or Error)
  • instance (null or Model)

DataAccessObject.upsert(data, [callback])

Update or insert a model instance

Arguments
Name Type Description
data Object

The model instance data

[callback] Function

The callback function

DataAccessObject.findOrCreate(query, data, cb)

Find one record, same as all, limited by 1 and return object, not collection, if not found, create using data provided as second argument

Arguments
Name Type Description
query Object

search conditions: {where: {test: 'me'}}.

data Object

object to create.

cb Function

callback called with (err, instance)

DataAccessObject.exists(id, cb)

Check whether a model instance exists in database

Arguments
Name Type Description
id id

identifier of object (primary key value)

cb Function

callbacl called with (err, exists: Bool)

DataAccessObject.findById(id, cb)

Find object by id

Arguments
Name Type Description
id

primary key value

cb Function

callback called with (err, instance)

DataAccessObject.find(params, callback)

Find all instances of Model, matched by query make sure you have marked as index: true fields for filter or sort

Arguments
Name Type Description
params Object

(optional)

  • where: Object { key: val, key2: {gt: 'val2'}}
  • include: String, Object or Array. See DataAccessObject.include documentation.
  • order: String
  • limit: Number
  • skip: Number
callback Function

(required) called with arguments:

  • err (null or Error)
  • Array of instances

DataAccessObject.findOne(params, cb)

Find one record, same as all, limited by 1 and return object, not collection

Arguments
Name Type Description
params Object

search conditions: {where: {test: 'me'}}

cb Function

callback called with (err, instance)

DataAccessObject.remove([where], [cb])

Destroy all matching records

Arguments
Name Type Description
[where] Object

An object that defines the criteria

[cb] Function

callback called with (err)

DataAccessObject.removeById(id, cb)

Destroy a record by id

Arguments
Name Type Description
id

The id value

cb Function

callback called with (err)

DataAccessObject.count(where, cb)

Return count of matched records

Arguments
Name Type Description
where Object

search conditions (optional)

cb Function

callback, called with (err, count)

dataAccessObject.save(options, callback(err,)

Save instance. When instance haven't id, create method called instead. Triggers: validate, save, update | create

Arguments
Name Type Description
options

{validate: true, throws: false} [optional]

callback(err,

obj)

dataAccessObject.updateAttribute(name, value, callback)

Update single attribute

equals to `updateAttributes({name: value}, cb)

Arguments
Name Type Description
name String

name of property

value Mixed

value of property

callback Function

callback called with (err, instance)

dataAccessObject.updateAttributes(data, callback)

Update set of attributes

this method performs validation before updating

Arguments
Name Type Description
data Object

data to update

callback Function

callback called with (err, instance)

dataAccessObject.reload(callback)

Reload object from persistence

Arguments
Name Type Description
callback Function

called with (err, instance) arguments

defineReadonlyProp(obj, key, value)

Define readonly property on object

Arguments
Name Type Description
obj Object
key String
value Mixed

DataAccessObject.scope()

Define scope

module.exports

Module exports class Model

DataAccessObject.prototype.remove

Delete object from persistence

Hookable()

Hooks mixins

module.exports

Module exports

Hookable.afterInitialize

List of hooks available

Inclusion.include(objects, {String},, cb)

Allows you to load relations of several objects and optimize numbers of requests.

Arguments
Name Type Description
objects Array

array of instances

{String},

{Object} or {Array} include - which relations you want to load.

cb Function

Callback called when relations are loaded 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']}); // ...

module.exports

Include mixin for ./model.js

Relation.hasMany(anotherClass, params)

Declare hasMany relation

Arguments
Name Type Description
anotherClass Relation

class to has many

params Object

configuration {as:, foreignKey:}

Example

User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});

Relation.belongsTo(anotherClass, params)

Declare belongsTo relation

Arguments
Name Type Description
anotherClass Class

class to belong

params Object

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: Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});

When a post is loaded, you can load the related author with: 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: 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.

validatePresence()

Presence validator

validateLength()

Length validator

validateNumericality()

Numericality validator

validateInclusion()

Inclusion validator

validateExclusion()

Exclusion validator

validateFormat()

Format validator

validateCustom()

Custom validator

validateUniqueness()

Uniqueness validator

validatable.isValid(callback)

This method performs validation, triggers validation hooks. Before validation obj.errors collection cleaned. Each validation can add errors to obj.errors collection. If collection is not blank, validation failed.

Arguments
Name Type Description
callback Function

called with (valid)

Example

ExpressJS controller: render user if valid, show flash otherwise user.isValid(function (valid) { if (valid) res.render({user: user}); else res.flash('error', 'User is not valid'), console.log(user.errors), res.redirect('/users'); });

exports.ValidationError

Module exports

exports.Validatable

Validation mixins for model.js

Basically validation configurators is just class methods, which adds validations configs to AbstractClass._validations. 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: message member. It can be just string, when only one situation possible, e.g. Post.validatesPresenceOf('title', { message: 'can not be blank' });

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'}});

Validatable.validatesPresenceOf

Validate presence. This validation fails when validated field is blank.

Default error message "can't be blank"

Example

with custom message Post.validatesPresenceOf('title', {message: 'Can not be blank'});

Validatable.validatesLengthOf

Validate length. Three kinds of validations: min, max, is.

Default error messages:

  • min: too short
  • max: too long
  • is: length is wrong
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'}});

Validatable.validatesNumericalityOf

Validate numericality.

Example
User.validatesNumericalityOf('age', { message: { number: '...' }});
User.validatesNumericalityOf('age', {int: true, message: { int: '...' }});

Default error messages:

  • number: is not a number
  • int: is not an integer

Validatable.validatesInclusionOf

Validate inclusion in set

Example
User.validatesInclusionOf('gender', {in: ['male', 'female']});
User.validatesInclusionOf('role', {
    in: ['admin', 'moderator', 'user'], message: 'is not allowed'
});

Default error message: is not included in the list

Validatable.validatesExclusionOf

Validate exclusion

Example

Company.validatesExclusionOf('domain', {in: ['www', 'admin']}); Default error message: is reserved

Validatable.validatesFormatOf

Validate format

Default error message: is invalid

Validatable.validate

Validate using custom validator

Default error message: is invalid

Example:

User.validate('name', customValidator, {message: 'Bad name'});
function customValidator(err) {
    if (this.name === 'bad') err();
});
var user = new User({name: 'Peter'});
user.isValid(); // true
user.name = 'bad';
user.isValid(); // false

Validatable.validateAsync

Validate using custom async validator

Default error message: is invalid

Example:

User.validateAsync('name', customValidator, {message: 'Bad name'});
function customValidator(err, done) {
    process.nextTick(function () {
        if (this.name === 'bad') err();
        done();
    });
});
var user = new User({name: 'Peter'});
user.isValid(); // false (because async validation setup)
user.isValid(function (isValid) {
    isValid; // true
})
user.name = 'bad';
user.isValid(); // false
user.isValid(function (isValid) {
    isValid; // false
})

Validatable.validatesUniquenessOf

Validate uniqueness

Default error message: is not unique

Base class for SQL connectors