Storage Module

Build Status

A storage framework for Nxus applications using waterline.

Configuration

"config": {
  "storage": {
    "adapters": {
      "default": "sails-mongo"
    },
    "connections": {
      "default": {
        "adapter": "default",
        "url": "mongodb://...."
      }
    },
  }
}

Defining models

You define models by extending a base model class: BaseModel is a general-purpose base class; GeoModel is a base class for models containing a GeoJSON attribute. You can also define your own base class by extending BaseModel or GeoModel.

(The PointModel base class, for models containing a GeoJSON coordinate point attribute, is deprecated; use GeoModel instead.)

Using models

HasModels is a base class for nxus modules that define or use models. It automatically registers all model definitions contained in the module ./models subdirectory. It makes model definitions available through its HasModels#models property, which you can configure to load models defined by your module or other modules.

The Storage model() and modelDir() methods let you explicitly register model definitions, and you can use getModel() to load definitions. However, these methods are rarely used, since using the HasModels base class is typically more concise and convenient.

Model events

The storage model emits events for create, update, and destroy. You can register a handler for all events:

  storage.on('model.create', (identity, record) => {})
  storage.on('model.update', (identity, record) => {})
  storage.on('model.destroy', (identity, record) => {})

Or just a specific model identity:

  storage.on('model.create.user', (identity, record) => {})
  storage.on('model.update.user', (identity, record) => {})
  storage.on('model.destroy.user', (identity, record) => {})

Lifecycle notes

  • load

    • Models should be registered during load, e.g. var User = BaseModel.extend({ identity: 'user', ... }); application.get('storage').model(User)
  • startup

    • The configured database is connected during load.after

    • You can query models from startup and beyond, retrieve the model by the 'identity':

      application.get('storage').getModel('user').then((User) => {
          User.create(...);
      });
      

API

Storage provides a common interface for defining models. Uses the Waterline ORM.

new Storage()

Extends NxusModule

Instance Members
model(model)
getModel(id)
modelDir(dir)

Base class for nxus modules that define or use models. It automatically registers all model definitions contained in the module ./models subdirectory. It makes model definitions available through its #HasModels#models property, which you can configure to load models defined by your module or other modules.

new HasModels(options: Object)

Extends NxusModule

Parameters
options (Object = {}) Configuration options.
Name Description
options.modelNames (Object | Array) (default null) Model definitions to load. If specified as an object, each object property specifies a model – its key is a model identity (the model's identity property), and its value is used as the model's name in HasModels#models . If specified as an array, each array element specifies a model – the element string serves as both model identity and name.
Instance Members
modelNames()
models

Base class for Waterline model definitions.

It extends the Waterline.Collection to make it less awkward to use and better adapted to the nxus environment.

It provides an extend() method that is better-behaved than the Waterline extend() method.

It emits create, update, and destroy events for model instances. The model identity and record are passed as parameters to the handler. You can register to be notified of all events of a specified type, or restrict notifications to a specific model by specifying its identity as a suffix to the event type:

  • model.create, model.create.identity - emitted after create
  • model.update, model.update.identity - emitted after update
  • model.destroy, model.destroy.identity - emitted after destroy

Use the extend() method to create a Waterline model based on BaseModel. For example:

  import {BaseModel} from 'nxus-storage'
  const MyModel = BaseModel.extend({
      identity: 'my-model',
      attributes: {
          name: 'string'
      }
  })
BaseModel

Extends Waterline.Collection

Static Members
connection
findOrCreate(criteria, values)
createOrUpdate(criteria, values)
extend(properties)
Instance Members
displayName()

Base class for Waterline models containing a GeoJSON geographic attribute.

It provides methods for performing geo queries on the GeoJSON attribute – findWithin() selects records that lie within specified coordinates, and findIntersects() selects records that intersect.

To implement the geo queries, the GeoJSON data must be indexed. And because the MongoDB 2dsphere index can handle only GeoJSON geometry features, the index is applied to a derived features attribute that contains just the geometry features from the primary GeoJSON attribute.

The GeoModel provides the machinery for keeping the features attribute synchronized with the primary GeoJSON attribute. It also attempts to ensure the features attribute is well-formed and has a consistent organization. For Polygon objects, it discards duplicate points, closes open paths and ensures clockwise winding order. It combines Geometry objects so there is at most one of each geometry type: Polygon/MultiPolygon, Point/MultiPoint and LineString/MultiLineString.

The createGeoIndex() method should be invoked to ensure the index is created. Typically, you do this after the startup lifecycle phase.

Configuration is through these model properties:

  • geometryField (string) - Name of the primary GeoJSON attribute (default is geo).
  • geometryFeatureField (string) - Name of the geometry features attribute (default is geoFeatures). Both of these attributes must also be defined as model attributes with type json.

Use the extend() method to create a Waterline model based on GeoModel. For example:

  import {GeoModel} from 'nxus-storage'
  const MyGeo = GeoModel.extend({
      identity: 'my-geo',
      attributes: {
          ...
          location: 'json',
          locationFeatures: 'json'
      },
      geometryField: 'location',
      geometryFeaturesField: 'locationFeatures'
  })
GeoModel

Extends BaseModel

Static Members
createGeoIndex()
findWithin(coordinates)
findIntersects(coordinates)
getGeometry(record, types)
getCentroid(record)

Base collection for Waterline models containing a GeoJSON coordinate point attribute.

PointModel

Extends BaseModel

Deprecated: Use GeoModel .