2013-04-09 16:02:36 +00:00
# asteroid
2013-06-17 15:04:37 +00:00
2013-06-25 20:52:14 +00:00
v0.9.0
2013-04-09 16:02:36 +00:00
## Install
2013-04-09 18:33:29 +00:00
slnode install asteroid -g
2013-04-26 18:44:19 +00:00
2013-06-06 20:50:46 +00:00
## Server API
2013-04-26 18:44:19 +00:00
2013-06-05 14:38:04 +00:00
- [App ](#app )
2013-06-06 20:50:46 +00:00
- [Model ](#model )
- [DataSource ](#data-source )
2013-06-06 20:12:03 +00:00
- [Connectors ](#connectors )
2013-06-06 20:50:46 +00:00
- [GeoPoint ](#geo-point )
2013-06-05 19:13:55 +00:00
- [Asteroid Types ](#asteroid-types )
2013-06-06 20:50:46 +00:00
- [REST Router ](#rest-router )
2013-04-26 18:44:19 +00:00
2013-06-06 20:50:46 +00:00
## Client API
2013-04-26 18:44:19 +00:00
2013-06-05 14:38:04 +00:00
_TODO_
### App
2013-06-06 00:11:21 +00:00
Create an asteroid application.
2013-06-05 14:38:04 +00:00
var asteroid = require('asteroid');
var app = asteroid();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
**Notes:**
- extends [express ](http://expressjs.com/api.html#express )
- see [express docs ](http://expressjs.com/api.html ) for details
- supports [express / connect middleware ](http://expressjs.com/api.html#middleware )
#### app.model(Model)
Expose a `Model` to remote clients.
2013-06-11 16:01:44 +00:00
var memory = asteroid.createDataSource({connector: asteroid.Memory});
var Color = memory.createModel('color', {name: String});
2013-06-05 14:38:04 +00:00
app.model(Color);
app.use(asteroid.rest());
**Note:** this will expose all [shared methods ](#shared-methods ) on the model.
#### app.models()
Get the app's exposed models.
var models = app.models();
models.forEach(function (Model) {
2013-06-11 16:01:44 +00:00
console.log(Model.modelName); // color
2013-06-05 14:38:04 +00:00
});
### Model
2013-06-11 16:01:44 +00:00
An Asteroid `Model` is a vanilla JavaScript class constructor with an attached set of properties and options. A `Model` instance is created by passing a data object containing properties to the `Model` constructor. A `Model` constructor will clean the object passed to it and only set the values matching the properties you define.
2013-06-06 20:30:52 +00:00
2013-06-11 16:01:44 +00:00
// valid color
var Color = asteroid.createModel('color', {name: String});
2013-06-06 20:30:52 +00:00
var red = new Color({name: 'red'});
2013-06-11 16:01:44 +00:00
console.log(red.name); // red
// invalid color
var foo = new Color({bar: 'bat baz'});
console.log(foo.bar); // undefined
2013-06-05 14:38:04 +00:00
**Properties**
A model defines a list of property names, types and other validation metadata. A [DataSource ](#data-source ) uses this definition to validate a `Model` during operations such as `save()` .
2013-06-11 16:01:44 +00:00
**Options**
2013-06-05 14:38:04 +00:00
2013-06-11 16:01:44 +00:00
Some [DataSources ](#data-source ) may support additional `Model` options.
2013-06-05 14:38:04 +00:00
Define an asteroid model.
var User = asteroid.createModel('user', {
first: String,
last: String,
age: Number
});
2013-06-06 20:30:52 +00:00
2013-06-18 18:44:47 +00:00
### Validation (expiremental)
2013-06-06 20:30:52 +00:00
#### Model.validatesPresenceOf(properties...)
Require a model to include a property to be considered valid.
User.validatesPresenceOf('first', 'last', 'age');
#### Model.validatesLengthOf(property, options)
Require a property length to be within a specified range.
User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}});
#### Model.validatesInclusionOf(property, options)
Require a value for `property` to be in the specified array.
User.validatesInclusionOf('gender', {in: ['male', 'female']});
#### Model.validatesExclusionOf(property, options)
Require a value for `property` to not exist in the specified array.
User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']});
#### Model.validatesNumericalityOf(property, options)
Require a value for `property` to be a specific type of `Number` .
User.validatesNumericalityOf('age', {int: true});
#### Model.validatesUniquenessOf(property, options)
Ensure the value for `property` is unique.
User.validatesUniquenessOf('email', {message: 'email is not unique'});
**Note:** not available for all [connectors ](#connectors ).
#### myModel.isValid()
Validate the model instance.
user.isValid(function (valid) {
if (!valid) {
user.errors // hash of errors {attr: [errmessage, errmessage, ...], attr: ...}
}
});
2013-06-28 01:26:44 +00:00
#### Model.properties
2013-06-28 01:28:21 +00:00
An object containing a normalized set of properties supplied to `asteroid.createModel(name, properties)` .
2013-06-28 01:26:44 +00:00
Example:
var props = {
a: String,
b: {type: 'Number'},
c: {type: 'String', min: 10, max: 100},
d: Date,
e: asteroid.GeoPoint
};
var MyModel = asteroid.createModel('foo', props);
console.log(MyModel.properties);
Outputs:
{
"a": {type: String},
"b": {type: Number},
"c": {
"type": String,
"min": 10,
"max": 100
},
"d": {type: Date},
"e": {type: GeoPoint},
"id": {
"id": 1
}
}
2013-06-05 14:38:04 +00:00
#### Model.attachTo(dataSource)
Attach a model to a [DataSource ](#data-source ). Attaching a [DataSource ](#data-source ) updates the model with additional methods and behaviors.
var oracle = asteroid.createDataSource({
2013-06-20 21:17:38 +00:00
connector: require('asteroid-connector-oracle'),
2013-06-05 14:38:04 +00:00
host: '111.22.333.44',
database: 'MYDB',
username: 'username',
password: 'password'
});
User.attachTo(oracle);
2013-06-06 20:50:46 +00:00
**Note:** until a model is attached to a data source it will **not** have any **attached methods** .
2013-06-05 14:38:04 +00:00
2013-06-18 18:44:47 +00:00
#### CRUD and Query Mixins
Mixins are added by attaching a vanilla model to a data source with a connector. Each [connector ](#connectors ) enables its own set of operations that are attached to a `Model` as methods. To see available methods for a data source with a connector call `dataSource.operations()` .
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
#### Static Methods
2013-06-06 00:44:46 +00:00
2013-06-21 21:59:30 +00:00
##### Model.create(data, [callback])
2013-06-06 00:44:46 +00:00
2013-06-21 21:59:30 +00:00
Create an instance of Model with given data and save to the attached data source. Callback is optional.
2013-06-06 00:44:46 +00:00
User.create({first: 'Joe', last: 'Bob'}, function(err, user) {
console.log(user instanceof User); // true
});
2013-06-21 21:59:30 +00:00
**Note:** You must include a callback and use the created model provided in the callback if your code depends on your model being saved or having an `id` .
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
##### Model.count([query], callback)
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
Query count of Model instances in data source. Optional query param allows to count filtered set of Model instances.
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
User.count({approved: true}, function(err, count) {
console.log(count); // 2081
2013-06-06 00:44:46 +00:00
});
2013-06-24 19:26:46 +00:00
##### Model.find(filter, callback)
2013-06-06 00:44:46 +00:00
Find all instances of Model, matched by query. Fields used for filter and sort should be declared with `{index: true}` in model definition.
**filter**
2013-06-06 20:12:03 +00:00
- **where** `Object` { key: val, key2: {gt: 'val2'}}
- **include** `String` , `Object` or `Array` .
- **order** `String`
- **limit** `Number`
- **skip** `Number`
2013-06-06 00:44:46 +00:00
2013-06-06 20:50:46 +00:00
Find the second page of 10 users over age 21 in descending order.
2013-06-24 19:26:46 +00:00
User.find({where: {age: {gt: 21}}, order: 'age DESC', limit: 10, skip: 10})
2013-06-06 20:50:46 +00:00
**Note:** See the specific connector's [docs ](#connectors ) for more info.
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
##### Model.destroyAll(callback)
2013-06-06 00:44:46 +00:00
2013-06-18 18:44:47 +00:00
Delete all Model instances from data source. **Note:** destroyAll method does not perform destroy hooks.
2013-06-06 00:44:46 +00:00
2013-06-24 19:26:46 +00:00
##### Model.findById(id, callback)
2013-06-18 18:44:47 +00:00
Find instance by id.
2013-06-24 19:26:46 +00:00
User.findById(23, function(err, user) {
2013-06-18 18:44:47 +00:00
console.info(user.id); // 23
2013-06-06 00:44:46 +00:00
});
2013-06-21 00:31:23 +00:00
##### Model.findOne(where, callback)
2013-06-18 18:44:47 +00:00
2013-06-21 00:31:23 +00:00
Find a single instance that matches the given where expression.
2013-06-18 18:44:47 +00:00
2013-06-21 00:31:23 +00:00
User.findOne({id: 23}, function(err, user) {
2013-06-18 18:44:47 +00:00
console.info(user.id); // 23
});
##### Model.upsert(data, callback)
Update when record with id=data.id found, insert otherwise. **Note:** no setters, validations or hooks applied when using upsert.
##### Custom Static Methods
2013-06-05 14:38:04 +00:00
Define a static model method.
2013-06-20 21:17:38 +00:00
2013-06-05 14:38:04 +00:00
User.login = function (username, password, fn) {
var passwordHash = hashPassword(password);
this.findOne({username: username}, function (err, user) {
var failErr = new Error('login failed');
if(err) {
fn(err);
} else if(!user) {
fn(failErr);
} else if(user.password === passwordHash) {
MySessionModel.create({userId: user.id}, function (err, session) {
fn(null, session.id);
});
} else {
fn(failErr);
}
});
}
2013-06-20 21:17:38 +00:00
Setup the static model method to be exposed to clients as a [remote method ](#remote-method ).
2013-06-05 19:13:55 +00:00
2013-06-06 00:11:21 +00:00
asteroid.remoteMethod(
User.login,
{
accepts: [
{arg: 'username', type: 'string', required: true},
{arg: 'password', type: 'string', required: true}
],
returns: {arg: 'sessionId', type: 'any'},
http: {path: '/sign-in'}
}
);
2013-06-05 14:38:04 +00:00
#### Instance Methods
2013-06-18 18:44:47 +00:00
##### model.save([options], [callback])
Save an instance of a Model to the attached data source.
var joe = new User({first: 'Joe', last: 'Bob'});
joe.save(function(err, user) {
if(user.errors) {
console.log(user.errors);
} else {
console.log(user.id);
}
});
##### model.updateAttributes(data, [callback])
Save specified attributes to the attached data source.
user.updateAttributes({
first: 'updatedFirst',
name: 'updatedLast'
}, fn);
##### model.destroy([callback])
Remove a model from the attached data source.
model.destroy(function(err) {
// model instance destroyed
});
##### Custom Instance Methods
2013-06-06 00:11:21 +00:00
Define an instance method.
2013-06-05 14:38:04 +00:00
User.prototype.logout = function (fn) {
MySessionModel.destroyAll({userId: this.id}, fn);
}
2013-06-06 00:11:21 +00:00
Define a remote model instance method.
2013-06-05 14:38:04 +00:00
2013-06-11 16:01:44 +00:00
asteroid.remoteMethod(User.prototype.logout);
2013-06-05 19:13:55 +00:00
2013-06-05 19:17:29 +00:00
#### Remote Methods
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
Both instance and static methods can be exposed to clients. A remote method must accept a callback with the conventional `fn(err, result, ...)` signature.
2013-06-05 19:13:55 +00:00
2013-06-11 16:01:44 +00:00
##### asteroid.remoteMethod(fn, [options]);
2013-06-05 19:13:55 +00:00
2013-06-05 19:17:29 +00:00
Expose a remote method.
2013-06-05 19:13:55 +00:00
Product.stats = function(fn) {
myApi.getStats('products', fn);
}
2013-06-06 00:16:00 +00:00
asteroid.remoteMethod(
Product.stats,
{
returns: {arg: 'stats', type: 'array'},
http: {path: '/info', verb: 'get'}
}
);
2013-06-05 19:13:55 +00:00
**Options**
2013-06-05 19:17:29 +00:00
- **accepts** - (optional) an arguments description specifying the remote method's arguments. A
- **returns** - (optional) an arguments description specifying the remote methods callback arguments.
2013-06-05 19:13:55 +00:00
- **http** - (advanced / optional, object) http routing info
2013-06-18 18:44:47 +00:00
- **http.path** - the path relative to the model the method will be exposed at. May be a path fragment (eg. '/:myArg') which will be populated by an arg of the same name in the accepts description. For example the stats method above will be at the whole path `/products/stats` .
2013-06-05 19:13:55 +00:00
- **http.verb** - (get, post, put, del, all) - the route verb the method will be available from.
**Argument Description**
An arguments description defines either a single argument as an object or an ordered set of arguments as an array.
2013-06-06 00:11:21 +00:00
// examples
{arg: 'myArg', type: 'number'}
[
{arg: 'arg1', type: 'number', required: true},
{arg: 'arg2', type: 'array'}
]
2013-06-05 19:13:55 +00:00
**Types**
Each argument may define any of the [asteroid types ](#asteroid-types ).
**Notes:**
- The callback is an assumed argument and does not need to be specified in the accepts array.
- The err argument is also assumed and does not need to be specified in the returns array.
2013-06-05 14:38:04 +00:00
#### Remote Hooks
2013-06-05 19:13:55 +00:00
Run a function before or after a remote method is called by a client.
2013-06-05 14:38:04 +00:00
2013-06-12 22:44:38 +00:00
// *.save === prototype.save
User.beforeRemote('*.save', function(ctx, user, next) {
if(ctx.user) {
2013-06-05 14:38:04 +00:00
next();
} else {
next(new Error('must be logged in to update'))
}
});
2013-06-12 22:44:38 +00:00
User.afterRemote('*.save', function(ctx, user, next) {
2013-06-11 16:01:44 +00:00
console.log('user has been saved', user);
next();
});
2013-06-12 22:44:38 +00:00
Remote hooks also support wildcards. Run a function before any remote method is called.
// ** will match both prototype.* and *.*
User.beforeRemote('**', function(ctx, user, next) {
console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely
next();
});
Other wildcard examples
2013-06-24 19:26:46 +00:00
// run before any static method eg. User.find
2013-06-12 22:44:38 +00:00
User.beforeRemote('*', ...);
// run before any instance method eg. User.prototype.save
User.beforeRemote('prototype.*', ...);
2013-06-13 04:30:20 +00:00
// prevent password hashes from being sent to clients
User.afterRemote('**', function (ctx, user, next) {
if(ctx.result) {
if(Array.isArray(ctx.result)) {
ctx.result.forEach(function (result) {
result.password = undefined;
});
} else {
ctx.result.password = undefined;
}
}
next();
});
2013-06-05 19:13:55 +00:00
#### Context
2013-06-12 22:44:38 +00:00
Remote hooks are provided with a Context `ctx` object which contains transport specific data (eg. for http: `req` and `res` ). The `ctx` object also has a set of consistent apis across transports.
2013-06-05 19:13:55 +00:00
2013-06-12 22:44:38 +00:00
##### ctx.user
2013-06-05 19:13:55 +00:00
2013-06-12 22:44:38 +00:00
A `Model` representing the user calling the method remotely. **Note:** this is undefined if the remote method is not invoked by a logged in user.
2013-06-05 19:13:55 +00:00
2013-06-13 04:30:20 +00:00
##### ctx.result
During `afterRemote` hooks, `ctx.result` will contain the data about to be sent to a client. Modify this object to transform data before it is sent.
2013-06-05 19:13:55 +00:00
##### Rest
When [asteroid.rest ](#asteroidrest ) is used the following `ctx` properties are available.
###### ctx.req
The express ServerRequest object. [See full documentation ](http://expressjs.com/api.html#req ).
###### ctx.res
The express ServerResponse object. [See full documentation ](http://expressjs.com/api.html#res ).
Access the raw `req` object for the remote method call.
#### Relationships
##### Model.hasMany(Model)
Define a "one to many" relationship.
// by referencing model
Book.hasMany(Chapter);
// specify the name
Book.hasMany('chapters', {model: Chapter});
Query and create the related models.
Book.create(function(err, book) {
2013-06-20 21:17:38 +00:00
// create a chapter instance
// ready to be saved in the data source
var chapter = book.chapters.build({name: 'Chapter 1'});
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
// save the new chapter
chapter.save();
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
// you can also call the Chapter.create method with
// the `chapters` property which will build a chapter
// instance and save the it in the data source
book.chapters.create({name: 'Chapter 2'}, function(err, savedChapter) {
// this callback is optional
});
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
// query chapters for the book using the
2013-06-05 19:13:55 +00:00
book.chapters(function(err, chapters) {
2013-06-20 21:17:38 +00:00
// all chapters with bookId = book.id
console.log(chapters);
2013-06-05 19:13:55 +00:00
});
book.chapters({where: {name: 'test'}, function(err, chapters) {
// all chapters with bookId = book.id and name = 'test'
2013-06-20 21:17:38 +00:00
console.log(chapters);
2013-06-05 19:13:55 +00:00
});
});
##### Model.hasAndBelongsToMany()
TODO: implement / document
2013-06-05 14:38:04 +00:00
#### Shared Methods
Any static or instance method can be decorated as `shared` . These methods are exposed over the provided transport (eg. [asteroid.rest ](#rest )).
### Data Source
2013-06-05 19:17:29 +00:00
An Asteroid `DataSource` provides [Models ](#model ) with the ability to manipulate data. Attaching a `DataSource` to a `Model` adds [instance methods ](#instance-methods ) and [static methods ](#static-methods ) to the `Model` . The added methods may be [remote methods ](#remote-methods ).
2013-06-05 14:38:04 +00:00
Define a data source for persisting models.
var oracle = asteroid.createDataSource({
2013-06-06 20:12:03 +00:00
connector: 'oracle',
2013-06-05 14:38:04 +00:00
host: '111.22.333.44',
database: 'MYDB',
username: 'username',
password: 'password'
2013-04-26 18:44:19 +00:00
});
2013-06-11 16:01:44 +00:00
#### dataSource.createModel(name, properties, options)
2013-04-26 18:44:19 +00:00
2013-06-05 14:38:04 +00:00
Define a model and attach it to a `DataSource` .
2013-04-26 18:44:19 +00:00
2013-06-05 14:38:04 +00:00
var Color = oracle.createModel('color', {name: String});
2013-04-26 18:44:19 +00:00
2013-06-20 21:17:38 +00:00
#### dataSource.discoverModelDefinitions([username], fn)
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
Discover a set of model definitions (table or collection names) based on tables or collections in a data source.
2013-06-20 17:17:55 +00:00
2013-06-20 21:17:38 +00:00
oracle.discoverModelDefinitions(function (err, models) {
2013-06-20 17:17:55 +00:00
models.forEach(function (def) {
// def.name ~ the model name
oracle.discoverSchema(null, def.name, function (err, schema) {
console.log(schema);
});
});
2013-06-05 19:13:55 +00:00
});
2013-06-05 14:38:04 +00:00
2013-06-20 17:17:55 +00:00
#### dataSource.discoverSchema([owner], name, fn)
2013-06-05 19:13:55 +00:00
2013-06-20 21:17:38 +00:00
Discover the schema of a specific table or collection.
2013-06-11 16:01:44 +00:00
2013-06-20 21:17:38 +00:00
**Example schema from oracle connector:**
2013-06-11 16:01:44 +00:00
2013-06-20 21:17:38 +00:00
{
"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"
}
},
"audibleRange": {
"type": "Number",
"required": false,
"length": 22,
"oracle": {
"columnName": "AUDIBLE_RANGE",
"dataType": "NUMBER",
"dataLength": 22,
"nullable": "Y"
}
},
"effectiveRange": {
"type": "Number",
"required": false,
"length": 22,
"oracle": {
"columnName": "EFFECTIVE_RANGE",
"dataType": "NUMBER",
"dataLength": 22,
"nullable": "Y"
}
},
"rounds": {
"type": "Number",
"required": false,
"length": 22,
"oracle": {
"columnName": "ROUNDS",
"dataType": "NUMBER",
"dataLength": 22,
"nullable": "Y"
}
},
"extras": {
"type": "String",
"required": false,
"length": 64,
"oracle": {
"columnName": "EXTRAS",
"dataType": "VARCHAR2",
"dataLength": 64,
"nullable": "Y"
}
},
"fireModes": {
"type": "String",
"required": false,
"length": 64,
"oracle": {
"columnName": "FIRE_MODES",
"dataType": "VARCHAR2",
"dataLength": 64,
"nullable": "Y"
}
}
}
2013-06-11 16:01:44 +00:00
}
2013-06-12 22:44:38 +00:00
#### dataSource.enableRemote(operation)
2013-06-06 20:12:03 +00:00
2013-06-12 22:44:38 +00:00
Enable remote access to a data source operation. Each [connector ](#connector ) has its own set of set remotely enabled and disabled operations. You can always list these by calling `dataSource.operations()` .
2013-06-06 20:12:03 +00:00
2013-06-12 22:44:38 +00:00
#### dataSource.disableRemote(operation)
2013-06-06 20:12:03 +00:00
2013-06-12 22:44:38 +00:00
Disable remote access to a data source operation. Each [connector ](#connector ) has its own set of set enabled and disabled operations. You can always list these by calling `dataSource.operations()` .
2013-06-06 20:12:03 +00:00
// all rest data source operations are
// disabled by default
var oracle = asteroid.createDataSource({
2013-06-20 21:17:38 +00:00
connector: require('asteroid-connector-oracle'),
2013-06-06 20:12:03 +00:00
host: '...',
...
});
// or only disable it as a remote method
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
#### dataSource.operations()
List the enabled and disabled operations.
console.log(oracle.operations());
Output:
{
find: {
2013-06-11 16:01:44 +00:00
remoteEnabled: true,
2013-06-06 20:12:03 +00:00
accepts: [...],
returns: [...]
enabled: true
},
2013-06-11 16:01:44 +00:00
save: {
remoteEnabled: true,
prototype: true,
accepts: [...],
returns: [...],
enabled: true
},
2013-06-06 20:12:03 +00:00
...
}
2013-06-06 20:30:52 +00:00
#### Connectors
2013-06-06 20:12:03 +00:00
Create a data source with a specific connector. See **available connectors** for specific connector documentation.
2013-06-06 00:11:21 +00:00
var memory = asteroid.createDataSource({
2013-06-11 16:01:44 +00:00
connector: asteroid.Memory
2013-06-06 00:11:21 +00:00
});
2013-06-06 20:12:03 +00:00
**Available Connectors**
2013-06-06 00:11:21 +00:00
2013-06-06 20:12:03 +00:00
- [Oracle ](http://github.com/strongloop/asteroid-connectors/oracle )
- [In Memory ](http://github.com/strongloop/asteroid-connectors/memory )
- TODO - [REST ](http://github.com/strongloop/asteroid-connectors/rest )
- TODO - [MySQL ](http://github.com/strongloop/asteroid-connectors/mysql )
- TODO - [SQLite3 ](http://github.com/strongloop/asteroid-connectors/sqlite )
- TODO - [Postgres ](http://github.com/strongloop/asteroid-connectors/postgres )
- TODO - [Redis ](http://github.com/strongloop/asteroid-connectors/redis )
- TODO - [MongoDB ](http://github.com/strongloop/asteroid-connectors/mongo )
- TODO - [CouchDB ](http://github.com/strongloop/asteroid-connectors/couch )
- TODO - [Firebird ](http://github.com/strongloop/asteroid-connectors/firebird )
**Installing Connectors**
Include the connector in your package.json dependencies and run `npm install` .
{
"dependencies": {
2013-06-20 21:17:38 +00:00
"asteroid-connector-oracle": "latest"
2013-06-06 20:12:03 +00:00
}
}
2013-06-06 00:11:21 +00:00
2013-06-24 23:30:09 +00:00
### GeoPoint
Use the `GeoPoint` class.
var GeoPoint = require('asteroid').GeoPoint;
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
Embed a latitude / longitude point in a [Model ](#model ).
var CoffeeShop = asteroid.createModel('coffee-shop', {
location: 'GeoPoint'
});
Asteroid Model's with a GeoPoint property and an attached DataSource may be queried using geo spatial filters and sorting.
Find the 3 nearest coffee shops.
2013-06-24 22:22:25 +00:00
CoffeeShop.attachTo(oracle);
2013-06-24 22:32:22 +00:00
var here = new GeoPoint({lat: 10.32424, lng: 5.84978});
2013-06-28 21:01:49 +00:00
CoffeeShop.find({where: {location: {near: here}}, limit:3}, function(err, nearbyShops) {
2013-06-05 19:13:55 +00:00
console.info(nearbyShops); // [CoffeeShop, ...]
});
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
#### geoPoint.distanceTo(geoPoint, options)
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
Get the distance to another `GeoPoint` .
2013-06-05 14:38:04 +00:00
2013-06-24 22:32:22 +00:00
var here = new GeoPoint({lat: 10, lng: 10});
var there = new GeoPoint({lat: 5, lng: 5});
2013-06-05 19:13:55 +00:00
console.log(here.distanceTo(there, {type: 'miles'})); // 438
#### GeoPoint.distanceBetween(a, b, options)
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
Get the distance between two points.
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
#### Distance Types
2013-06-05 14:38:04 +00:00
2013-06-24 23:30:09 +00:00
**Note:** all distance methods use `miles` by default.
2013-06-07 16:49:33 +00:00
- `miles`
- `radians`
- `kilometers`
2013-06-24 23:30:09 +00:00
- `meters`
- `miles`
- `feet`
- `degrees`
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
#### geoPoint.lat
2013-06-05 14:38:04 +00:00
2013-06-05 19:13:55 +00:00
The latitude point in degrees. Range: -90 to 90.
2013-04-09 16:02:36 +00:00
2013-06-24 22:32:22 +00:00
#### geoPoint.lng
2013-04-09 16:02:36 +00:00
2013-06-05 19:13:55 +00:00
The longitude point in degrees. Range: -180 to 180.
2013-05-20 21:31:04 +00:00
2013-06-05 19:13:55 +00:00
### Asteroid Types
2013-05-20 21:31:04 +00:00
2013-06-06 00:11:21 +00:00
Various APIs in Asteroid accept type descriptions (eg. [remote methods ](#remote-methods ), [asteroid.createModel() ](#model )). The following is a list of supported types.
2013-05-20 21:31:04 +00:00
2013-06-05 19:13:55 +00:00
- `null` - JSON null
- `Boolean` - JSON boolean
- `Number` - JSON number
- `String` - JSON string
- `Object` - JSON object
- `Array` - JSON array
- `Date` - a JavaScript date object
- `Buffer` - a node.js Buffer object
2013-06-20 21:17:38 +00:00
- [GeoPoint ](#geopoint ) - an asteroid GeoPoint object. TODO
2013-06-26 03:29:58 +00:00
### User Model
Allow users of your asteroid app to register and authenticate.
// define a User model
var User = asteroid.createModel(
'user',
{
email: 'EmailAddress',
password: {
type: 'Password',
min: 4,
max: 26
}
},
{
username: 'email',
extend: 'User'
}
);
// attach to the memory connector
User.attachTo(memory);
// create a user
User.create({
email: 'foo@bar.com',
password: '123456'
});
### Email Model
Send emails from your asteroid app.
2013-06-06 20:50:46 +00:00
### REST Router
2013-06-06 00:11:21 +00:00
2013-06-06 20:50:46 +00:00
Expose models over rest using the `asteroid.rest` router.
2013-06-06 00:11:21 +00:00
app.use(asteroid.rest());
2013-06-06 20:50:46 +00:00
**REST Documentation**
View generated REST documentation by visiting: [http://localhost:3000/_docs ](http://localhost:3000/_docs ).
2013-06-06 00:11:21 +00:00
### SocketIO Middleware **Not Available**
**Coming Soon** - Expose models over socket.io using the `asteroid.sio()` middleware.
app.use(asteroid.sio);