Merge branch 'release/1.2.5' into production
This commit is contained in:
commit
e2cd20d73f
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
support/nodeunit
|
121
README.md
121
README.md
|
@ -4,124 +4,7 @@ LoopBack DataSource Juggler is an ORM that provides a common set of interfaces
|
||||||
for interacting with databases, REST APIs, and other data sources. It was
|
for interacting with databases, REST APIs, and other data sources. It was
|
||||||
initially forked from [JugglingDB](https://github.com/1602/jugglingdb).
|
initially forked from [JugglingDB](https://github.com/1602/jugglingdb).
|
||||||
|
|
||||||
## Overview
|
For full documentation, see [StrongLoop Suite Documentation](http://docs.strongloop.com/display/DOC/Data+Source+Juggler).
|
||||||
|
|
||||||
LoopBack DataSource Juggler consists of the following components:
|
|
||||||
|
|
||||||
* LoopBack Definition Language
|
|
||||||
* DataSource
|
|
||||||
* Connector
|
|
||||||
|
|
||||||
![loopback-datasource-juggler-overview](docs/overview.png "LoopBack Diagram")
|
|
||||||
|
|
||||||
## LoopBack Definition Language
|
|
||||||
|
|
||||||
To define model dataSource have single method `dataSource.define`. It accepts
|
|
||||||
three arguments:
|
|
||||||
|
|
||||||
* **model name**:
|
|
||||||
String name in camel-case with first upper-case letter. This name will be
|
|
||||||
used later to access model.
|
|
||||||
* **properties**:
|
|
||||||
Object with property type definitions. Key is property name, value is type
|
|
||||||
definition. Type definition can be function representing type of property
|
|
||||||
(String, Number, Date, Boolean), or object with {type: String|Number|...,
|
|
||||||
index: true|false} format.
|
|
||||||
* **settings**:
|
|
||||||
Object with model-wide settings such as `tableName` or so.
|
|
||||||
|
|
||||||
Examples of model definition:
|
|
||||||
|
|
||||||
var User = dataSource.define('User', {
|
|
||||||
email: String,
|
|
||||||
password: String,
|
|
||||||
birthDate: Date,
|
|
||||||
activated: Boolean
|
|
||||||
});
|
|
||||||
|
|
||||||
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 }
|
|
||||||
}, {
|
|
||||||
tableName: 'users'
|
|
||||||
});
|
|
||||||
|
|
||||||
## DataSource
|
|
||||||
|
|
||||||
DataSource is a factory for model classes. DataSource connected with specific
|
|
||||||
database or other backend system using connector.
|
|
||||||
|
|
||||||
All model classes within single datasource shares same connector type and one
|
|
||||||
database connection. But it's possible to use more than one datasource to
|
|
||||||
connect with different databases.
|
|
||||||
|
|
||||||
### Creating dataSource
|
|
||||||
|
|
||||||
`DataSource` constructor available on `loopback-datasource-juggler` module:
|
|
||||||
|
|
||||||
var DataSource = require('loopback-datasource-juggler').DataSource;
|
|
||||||
|
|
||||||
DataSource constructor accepts two arguments. First argument is connector. It
|
|
||||||
could be a connector name or connector package:
|
|
||||||
|
|
||||||
var dataSourceByConnectorName = new DataSource('memory');
|
|
||||||
var dataSourceByConnectorModule = new DataSource(require('redis'));
|
|
||||||
|
|
||||||
### Settings
|
|
||||||
|
|
||||||
Second argument is optional settings. Settings object format and defaults
|
|
||||||
depends on specific connector, but common fields are:
|
|
||||||
|
|
||||||
* `host`: Database host
|
|
||||||
* `port`: Database port
|
|
||||||
* `username`: Username to connect to database
|
|
||||||
* `password`: Password to connect to database
|
|
||||||
* `database`: Database name
|
|
||||||
* `debug`: Turn on verbose mode to debug db queries and lifecycle
|
|
||||||
|
|
||||||
For connector-specific settings refer to connector's readme file.
|
|
||||||
|
|
||||||
## LoopBack Connectors
|
|
||||||
|
|
||||||
| Type | Package Name |
|
|
||||||
| --------- |:--------------------------------------------------------------------------------------:|
|
|
||||||
| MongoDB | [loopback-connector-mongodb](https://github.com/strongloop/loopback-connector-mongodb) |
|
|
||||||
| Oracle | [loopback-connector-oracle](https://github.com/strongloop/loopback-connector-oracle) |
|
|
||||||
| MySQL | [loopback-connector-mysql](https://github.com/strongloop/loopback-connector-mysql) |
|
|
||||||
|
|
||||||
|
|
||||||
LoopBack connectors provide access to backend systems including databases,
|
|
||||||
REST APIs and other services. Connectors are not used directly by application
|
|
||||||
code. We create a DataSource to interact with the connector.
|
|
||||||
|
|
||||||
For example,
|
|
||||||
|
|
||||||
var DataSource = require('loopback-datasource-juggler').DataSource;
|
|
||||||
var oracleConnector = require('loopback-connector-oracle');
|
|
||||||
|
|
||||||
var ds = new DataSource(oracleConnector, {
|
|
||||||
host : '127.0.0.1',
|
|
||||||
database : 'XE',
|
|
||||||
username : 'strongloop',
|
|
||||||
password : 'password',
|
|
||||||
debug : true
|
|
||||||
});
|
|
||||||
|
|
||||||
The connector argument passed the DataSource constructor can be one of the
|
|
||||||
following:
|
|
||||||
|
|
||||||
* The connector module from `require(connectorName)`
|
|
||||||
* The full name of the connector module, such as 'loopback-connector-oracle'
|
|
||||||
* The short name of the connector module, such as 'oracle', which will be
|
|
||||||
converted to 'loopback-connector-<shortName>'
|
|
||||||
* A local module under ./connectors/<connectorName> folder
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
@ -131,6 +14,6 @@ Also install the appropriated connector, for example for mongodb:
|
||||||
|
|
||||||
npm install loopback-connector-mongodb
|
npm install loopback-connector-mongodb
|
||||||
|
|
||||||
check following list of available connectors
|
See [StrongLoop Suite Documentation](http://docs.strongloop.com/) for up-to-date list of connectors supported.
|
||||||
|
|
||||||
|
|
||||||
|
|
1
index.js
1
index.js
|
@ -4,6 +4,7 @@ exports.ModelBuilder = exports.LDL = require('./lib/model-builder.js').ModelBuil
|
||||||
exports.DataSource = exports.Schema = require('./lib/datasource.js').DataSource;
|
exports.DataSource = exports.Schema = require('./lib/datasource.js').DataSource;
|
||||||
exports.ModelBaseClass = require('./lib/model.js');
|
exports.ModelBaseClass = require('./lib/model.js');
|
||||||
exports.Connector = require('./lib/connector.js');
|
exports.Connector = require('./lib/connector.js');
|
||||||
|
exports.ValidationError = require('./lib/validations.js').ValidationError;
|
||||||
|
|
||||||
var baseSQL = './lib/sql';
|
var baseSQL = './lib/sql';
|
||||||
|
|
||||||
|
|
13
lib/dao.js
13
lib/dao.js
|
@ -331,9 +331,20 @@ setRemoting(DataAccessObject.findById, {
|
||||||
description: 'Find a model instance by id from the data source',
|
description: 'Find a model instance by id from the data source',
|
||||||
accepts: {arg: 'id', type: 'any', description: 'Model id', required: true},
|
accepts: {arg: 'id', type: 'any', description: 'Model id', required: true},
|
||||||
returns: {arg: 'data', type: 'any', root: true},
|
returns: {arg: 'data', type: 'any', root: true},
|
||||||
http: {verb: 'get', path: '/:id'}
|
http: {verb: 'get', path: '/:id'},
|
||||||
|
rest: {after: convertNullToNotFoundError}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function convertNullToNotFoundError(ctx, cb) {
|
||||||
|
if (ctx.result !== null) return cb();
|
||||||
|
|
||||||
|
var modelName = ctx.method.sharedClass.name;
|
||||||
|
var id = ctx.getArgByName('id');
|
||||||
|
var msg = 'Unkown "' + modelName + '" id "' + id + '".';
|
||||||
|
var error = new Error(msg);
|
||||||
|
error.statusCode = error.status = 404;
|
||||||
|
cb(error);
|
||||||
|
}
|
||||||
|
|
||||||
// alias function for backwards compat.
|
// alias function for backwards compat.
|
||||||
DataAccessObject.all = function () {
|
DataAccessObject.all = function () {
|
||||||
|
|
|
@ -599,12 +599,16 @@ function ValidationError(obj) {
|
||||||
if (!(this instanceof ValidationError)) return new ValidationError(obj);
|
if (!(this instanceof ValidationError)) return new ValidationError(obj);
|
||||||
|
|
||||||
this.name = 'ValidationError';
|
this.name = 'ValidationError';
|
||||||
this.message = 'Validation error';
|
this.message = 'The Model instance is not valid. ' +
|
||||||
this.statusCode = 400;
|
'See `details` property of the error object for more info.';
|
||||||
this.codes = obj.errors && obj.errors.codes;
|
this.statusCode = 422;
|
||||||
this.context = obj && obj.constructor && obj.constructor.modelName;
|
|
||||||
|
this.details = {
|
||||||
|
context: obj && obj.constructor && obj.constructor.modelName,
|
||||||
|
codes: obj.errors && obj.errors.codes,
|
||||||
|
messages: obj.errors
|
||||||
|
};
|
||||||
|
|
||||||
Error.call(this);
|
|
||||||
Error.captureStackTrace(this, this.constructor);
|
Error.captureStackTrace(this, this.constructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-datasource-juggler",
|
"name": "loopback-datasource-juggler",
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"description": "LoopBack DataSoure Juggler",
|
"description": "LoopBack DataSoure Juggler",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"StrongLoop",
|
"StrongLoop",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
var should = require('./init.js');
|
var should = require('./init.js');
|
||||||
|
|
||||||
var db, Person;
|
var db, Person;
|
||||||
|
var ValidationError = require('..').ValidationError;
|
||||||
|
|
||||||
describe('manipulation', function() {
|
describe('manipulation', function() {
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ describe('manipulation', function() {
|
||||||
p.save({
|
p.save({
|
||||||
'throws': true
|
'throws': true
|
||||||
});
|
});
|
||||||
}).should.throw('Validation error');
|
}).should.throw(ValidationError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
var should = require('./init.js');
|
var should = require('./init.js');
|
||||||
|
|
||||||
var j = require('../'), db, User;
|
var j = require('../'), db, User;
|
||||||
var ValidationError = require('../lib/validations.js').ValidationError;
|
var ValidationError = j.ValidationError;
|
||||||
|
|
||||||
function getValidAttributes() {
|
function getValidAttributes() {
|
||||||
return {
|
return {
|
||||||
|
@ -98,7 +98,7 @@ describe('validations', function() {
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function(e, u) {
|
User.create(function(e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
e.codes.name.should.eql(['presence']);
|
e.details.codes.name.should.eql(['presence']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue