Extensible Object-relational Mapper for Node.js
npm install nomatic-data










Extensible Object-relational Mapping Framework for Node.js
Adapters allow you to connect to a variety of data sources. You can use a pre-built Adapter (see table below),
or you can write your own by implementing either the Adapter or DatabaseAdapter abstract classes.
Each Adapter is operated by one or more Mapper instances. Each Mapper instance is managed by a Container
instance. A Mapper will generate Record instances, which store the state of each document in the collection.
npm i --save nomatic-data
`If you want to write your own adapter, you can stop there. Otherwise, you'll need to install an adapter:
| Adapter | Author | Links | Installation |
| :--- | :--- | :--- | :--- |
| ArangoDB | bdfoster | npm, GitHub |
npm i --save nomatic-arangodb-adapter |$3
This example uses the ArangoDB adapter.`javascript
import { Container } from 'nomatic-data';
import ArangoDBAdapter from 'nomatic-arangodb-adapter';const adapter = new ArangoDBAdapter({
name: 'my-database',
host: '127.0.0.1',
port: 8579,
password: 'somethingMoreSecureThanThis'
});
const store = new Container({
adapter: adapter,
/**
* A few hooks are provided for your convenience, including:
* - beforeGet
* - afterGet
* - beforeInsert
* - afterInsert
* - beforeUpdate
* - afterUpdate
* - beforeValidate
* - afterValidate
*/
beforeInsert(mapper, record) {
record.createdAt = new Date();
},
beforeUpdate(mapper, record) {
record.updatedAt = new Date();
},
/**
* Here, we define the schema of all of our mappers. Other options
* for each mapper can also be set here. Schema validation is provided
* by ajv.
*/
mappers: {
people: {
properties: {
/**
* Implicit properties, such as
id and rev, need not be
* defined here.
*/
firstName: {
type: 'string'
},
lastName: {
type: 'string'
},
emailAddress: {
type: 'string',
format: 'email'
}
},
required: ['firstName', 'lastName'],
/**
* By default, additional properties are allowed in the record.
*/
additionalProperties: false
},
accounts: {
properties: {
people: {
type: 'array',
items: {
type: 'string',
/**
* The 'mapper' keyword enforces relational integrity. Each item
* in this array matches an id of a record in the collection
* managed by the 'people' mapper.
*/
mapper: 'people'
},
default: []
}
}
}
}
});/**
* The
load() method will establish a connection with the database server,
* ensure that the database exists (or it will try and create it), and
* ensure all collection exists (or will create them).
*/
store.load().then(() => {
return store.insertAll('people', [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Doe' }
]);
}).then(() => {
/**
* This is one way you can query for documents.
*/
store.find('people')
.where('lastName')
.eq('Doe')
.sort('firstName', 1)
.limit(2)
.skip(1)
.run().then((results) => {
//...
});
/**
* You can also query much like how MongoDB query filters. The supported operators are:
* - $and
* Syntax: { $where: { $and: [ , ..., }, ... }
* - $or
* Syntax: { $where: { $or: [ , ..., }, ... }
* - $eq (expression)
* Syntax: { : { $eq: { } }
* - $ne (expression)
* Syntax: { : { $ne: { } }
* - $gt (expression)
* Syntax: { : { $gt: { } }
* - $gte (expression)
* Syntax: { : { $gte: { } }
* - $lt (expression)
* Syntax: { : { $lt: { } }
* - $lte (expression)
* Syntax: { : { $lte: { } }
* - $in (expression)
* Syntax: { : { $in: [ , ..., ] }
* - $nin (expression)
* Syntax: { : { $nin: [ , ..., ] }
* - $exists (expression)
* Syntax: { : { $exists: } }
*
* An expression always follows this form:
* { : { : | [ , ..., ] }
*
* All the operators above can only be used in a $where object.
*/
store.findAll('people', {
$where: {
firstName: 'Jane'
},
$sort: [
['firstName', 1]
],
$limit: 2,
$skip: 1
}).then((results) => {
//...
});
});
``More documentation will be added as moves forward, but if you have a question please feel free to
open an issue.