Beyo Model Mapper
Data mappers for beyo models
Preamble
This module is not an ORM. It is a DI abstraction layer for models, but still allowing projects to manually access the persistence layer and optimize data access.
Install
npm install beyo-model-mapper
Usage
// declarevar mapper = Mapper
// fetching the mappervar fooMapper = Mapper; // fetching the model mappervar FooModel = Model;var foo = ; // new instance // foo._mapper === FooModel.mapper === fooMapper foo;
Mapper
A mapper's purpose is to bind a model to a persistence storage.
NOTE : A model bound to a mapper cannot be bound again with another mapper.
Mapper Public API
- define (mapperName:String, options:Object):{Mapper} - define a new mapper and return it
- get (mapperName:String):{Mapper} - return a defined mapper, or throw an exception is the mapper does not exist
- isDefined (mapperName:String):{Boolean} - check if a mapper is defined
Mapper Options
- model:{Object} - the mapped model options. The model class (model type) will
be extended with a static property
mapper, and the prototype with a property
_mapper`, which returns the defining mapper instance for the model.- type:{String} - the model type (must be already defined, see Model.define.
- methods:{Object} - (optional) the methods to add to the model's prototype.
This option behaves like the mapper's
methods
options, but methods are added to the model's prototype.
- options:{mixed} - any value that will be mixed with the mapper's prototype.
- connection:{String} - the defined connection name. Defining this option
will add
_connectionName
, the connection name as string, andgetAdapter()
, a yieldable function returning the define connection adapter's client (see Connections.define), to the mapper's prototype - methods:{Object} - an object mapping the methods to add to the mapper's
prototype. Typically, all the basic CRUD methods should be defined here. These
methods should be,
create
,find
,findAll
,update
,delete
, anddeleteAll
. - events:{Object} - an object to enable the mapper's methods to emit events.
- emitter (optional) - the event emitter to use. The value may be any object
exposing an
emit
method. The value may also be a getter (i.e.get emitter() { ... }
) for lazy emitter loading, where the getter will be called every time a method event is emitted. (Defaults to the Mapper's built-in event emitter. See Mapper Events.) - pattern (optional) - a string representing the event name pattern to emit.
The default pattern, if none specified is
"mapper.{mapper}.{event}"
. The pattern may include the tokens{mapper}
, the mapper'stypeName
;{event}
, the events being fired, according to the eventmapping
; and{model}
the model (if any) provided. Any token may include a cannonical path, for example :{model.id}
. - mapping (optional) - an object consisting of method names (keys) with their
associated event--action--names. The default mapping defines the method/action as
create
/create
,update
/update
,delete
/delete
, anddeleteAll
/delete
. Specifying a mapping will not extend the default mapping, but override it.
- emitter (optional) - the event emitter to use. The value may be any object
exposing an
NOTE: all basic CRUD methods must be define, or the application may throw
an AbstractMapperMethodException
error. More methods may also be defined.
CRUD methods
All CRUD methods must be yieldable. The following methods are defined abstract and
must be defined to be used. Calling any of these methods without defining them
using the mapper options will throw a "Method ... not implemented"
error.
- Create - create a new model.
create(model)
- receive a model as argument, and should return it
- Read - find one or more models given a filter and sorter arguments
find(filter, sorter)
- receive a filter and sorter and should return the first model found.findAll(filter, sorter)
- receive a filter and sorter and should return aCollection
of models found.
- Update - update the specified model
update(model)
- receive the model to update and return it
- Delete - delete the specified model(s)
delete(model)
- receive the model to delete and return a boolean statusdeleteAll(filter)
- receive a filter and delete all matching models, and return the number of models deleted.
Mapper Events
The module itself extends events.EventEmitter
and will emit two events; define
and create
.
define
handlers will receive an object as first argument, wheremapperName
is the actual mapper name (fully qualified),namespace
is the mapper's namespace,typeName
the relative name (used to create the mapper's constructor name),prototype
is the actual mapper's prototype before it get's frozen, andoptions
is the unmodified options object.create
handlers will receive an object as first argument, wheretypeName
is the mapper's relative name, andinstance
is the newly created mapper's instance. Note: the event is emitted before the constructor is returned! Any error thrown in a sync'ed emitter will fail at constructing the new mapper.
Along with global events, the module's event emitter may be used to send any method's events for the mappers not specifying their own event emitters. See Mapper Options's events configuration.
Connections
To facilitate connection pooling and management, the Connections
class act as a
connection registry for mappers. In such, mappers will make use of this registry
to return their persistence storage adapter.
For example, for PostgreSQL :
var suspend = ;var pg = ;var mapper; Connections; Connections mapper = Mapper; var client = mappergetAdapter;
Connections Public API
- registerAdapter (name:String, factory:Function) - register a new client
adapter factory. The
factory
should be a yieldable function and should return the client storage object that the mapper can use to perform basic CRUD operatons. - isAdapterRegistered (name:String):{Boolean} - return true if the adapter factory is defined.
- unregisterAdapter (name:String) - unregister an adapter factory. This method does not perform any check and this may break mappers using a connection for the specified adapter factory!
- define (name:String, conStr:String) - define a new named connection string
usable by mappers. The connection string should have the format 'adapter://user:pass@host/dbname',
where
adapter
is the registered adpater factory. All other values are optional, but should follow the format is specified. - isDefined (name:String):{Boolean} - returns true if the named connection exists.
- get (name:String):{mixed} - a yieldable function returning the adapter's factory client instance.
- undefine (name:String) - undefine a named connection.
- DEFAULT_EVENT_PATTERN {String} - the default event pattern string.
- DEFAULT_EVENT_MAPPING {Object} - the default event method mapping.
Contribution
All contributions welcome! Every PR must be accompanied by their associated unit tests!
License
The MIT License (MIT)
Copyright (c) 2014 Mind2Soft yanick.rochon@mind2soft.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.