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
|
||||
initially forked from [JugglingDB](https://github.com/1602/jugglingdb).
|
||||
|
||||
## Overview
|
||||
|
||||
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
|
||||
|
||||
For full documentation, see [StrongLoop Suite Documentation](http://docs.strongloop.com/display/DOC/Data+Source+Juggler).
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -131,6 +14,6 @@ Also install the appropriated connector, for example for 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.ModelBaseClass = require('./lib/model.js');
|
||||
exports.Connector = require('./lib/connector.js');
|
||||
exports.ValidationError = require('./lib/validations.js').ValidationError;
|
||||
|
||||
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',
|
||||
accepts: {arg: 'id', type: 'any', description: 'Model id', required: 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.
|
||||
DataAccessObject.all = function () {
|
||||
|
|
|
@ -599,12 +599,16 @@ function ValidationError(obj) {
|
|||
if (!(this instanceof ValidationError)) return new ValidationError(obj);
|
||||
|
||||
this.name = 'ValidationError';
|
||||
this.message = 'Validation error';
|
||||
this.statusCode = 400;
|
||||
this.codes = obj.errors && obj.errors.codes;
|
||||
this.context = obj && obj.constructor && obj.constructor.modelName;
|
||||
this.message = 'The Model instance is not valid. ' +
|
||||
'See `details` property of the error object for more info.';
|
||||
this.statusCode = 422;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "loopback-datasource-juggler",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.5",
|
||||
"description": "LoopBack DataSoure Juggler",
|
||||
"keywords": [
|
||||
"StrongLoop",
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
var should = require('./init.js');
|
||||
|
||||
var db, Person;
|
||||
var ValidationError = require('..').ValidationError;
|
||||
|
||||
describe('manipulation', function() {
|
||||
|
||||
|
@ -173,7 +174,7 @@ describe('manipulation', function() {
|
|||
p.save({
|
||||
'throws': true
|
||||
});
|
||||
}).should.throw('Validation error');
|
||||
}).should.throw(ValidationError);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
var should = require('./init.js');
|
||||
|
||||
var j = require('../'), db, User;
|
||||
var ValidationError = require('../lib/validations.js').ValidationError;
|
||||
var ValidationError = j.ValidationError;
|
||||
|
||||
function getValidAttributes() {
|
||||
return {
|
||||
|
@ -98,7 +98,7 @@ describe('validations', function() {
|
|||
User.validatesPresenceOf('name');
|
||||
User.create(function(e, u) {
|
||||
should.exist(e);
|
||||
e.codes.name.should.eql(['presence']);
|
||||
e.details.codes.name.should.eql(['presence']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue