Skip to content

Commit

Permalink
Merge 97ce9a2 into bd11229
Browse files Browse the repository at this point in the history
  • Loading branch information
okv committed Jan 23, 2020
2 parents bd11229 + 97ce9a2 commit 40c42ad
Show file tree
Hide file tree
Showing 30 changed files with 1,572 additions and 142 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
lib/migrationTemplates/
35 changes: 35 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"extends": "airbnb-base",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "script"
},
"rules": {
"comma-dangle": ["error", "never"],
"object-curly-spacing": ["error", "never"],
"indent": ["error", "tab"],
"no-tabs": 0,
"arrow-body-style": ["off"],
"arrow-parens": ["error", "always"],
"no-underscore-dangle": ["off"],
"camelcase": ["error", {
"properties": "never"
}],
"max-len": ["error", {
"code": 80,
"tabWidth": 1,
"ignoreTemplateLiterals": true
}],
"function-paren-newline": ["error", "consistent"],
"class-methods-use-this": [0],
"global-require": ["off"],
"prefer-destructuring": ["off"],
"strict": ["error", "global"],
"no-plusplus": ["error", {"allowForLoopAfterthoughts": true}],
"no-else-return": ["off"],
"no-lonely-if": ["off"],
"no-param-reassign": ["off"],
"consistent-return": ["off"],
"prefer-rest-params": ["off"]
}
}
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ coverage/
.npmrc
.travis.yml
.nycrc
.eslintignore
.eslintrc.json
5 changes: 2 additions & 3 deletions .nycrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"testUtils/**",
"tap-snapshots/**",
"coverage/**",
"migrations/**",
"lib/migrationTemplate.js"
"migrations/**"
]
}
}
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ before_script:
- npm install mongodb@${MONGODB_DRIVER_VERSION}

script:
- >
nodeVersionMajor=`node --version | grep -Eo 'v[0-9]+' | sed 's/v//'`;
if [ $nodeVersionMajor -ge 10 ]; then
npm run lint
else
echo "*** Do not lint for node.js < 10 builds ($nodeVersionMajor)";
fi;
- >
nodeVersionMajor=`node --version | grep -Eo 'v[0-9]+' | sed 's/v//'`;
Expand Down
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,52 @@ All executed migrations names will be stored at `_migrations` collection in the
current database. Object with following properties will be passed to `migrate`
and `rollback` functions:

* `db` - instance of [mongodb native db](http://mongodb.github.io/node-mongodb-native/api-generated/db.html)
* `dropIndexIfExists` function(collection, index, callback) - helper function
*Please note* that mainstream mongodb adapter version (>= 1.x) requires
east >= 1.x, for using adapter with older east versions (prior to 1.x) please
use mongodb adapter version < 1.x.

* `db` - instance of [mongodb native db](http://mongodb.github.io/node-mongodb-native/3.4/api/Db.html)
* `dropIndexIfExists` function(collection, index, [callback]) - helper function
which can be used for dropping index in safe way (contrasting to
`collection.dropIndex` which throws an error if index doesn't exist).
`collection.dropIndex` which throws an error if index doesn't exist). This
function returns promise and can be used that way instead of providing
callback.

east mongo package also provides following migration templates:

* [lib/migrationTemplates/promises.js](lib/migrationTemplates/promises.js) -
default migration template, uses built-in `Promise` in `migrate`,
`rollback` functions.
* [lib/migrationTemplates/async.js](lib/migrationTemplates/async.js) -
migration template that uses async functions to describe `migrate`,
`rollback` functions.

Default migration template will be used if `template` is not set. To get path
of another template `require.resolve` could be used, e.g. at `.eastrc`:

```js
module.exports = {
template: require.resolve('east-mongo/lib/migrationTemplates/async.js')
}
```

[![Npm version](https://img.shields.io/npm/v/east-mongo.svg)](https://www.npmjs.org/package/east-mongo)
[![Build Status](https://travis-ci.org/okv/east-mongo.svg?branch=master)](https://travis-ci.org/okv/east-mongo)
[![Coverage Status](https://coveralls.io/repos/github/okv/east-mongo/badge.svg?branch=master)](https://coveralls.io/github/okv/east-mongo?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/npm/east-mongo/badge.svg)](https://snyk.io/test/npm/east-mongo)


## Node.js compatibility

east mongo requires node.js >= 4 to work.

## Installation

mongodb adapter requires `mongodb` package as peer dependency (versions 2.x and
3.x are supported), so you should install it manually along side with east:

```sh
npm install east east-mongo
npm install east east-mongo mongodb
```

alternatively you could install it globally
Expand Down
103 changes: 47 additions & 56 deletions lib/adapter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use strict';

var MongoClient = require('mongodb').MongoClient,
path = require('path'),
mongodbUri = require('mongodb-uri'),
helpers = require('./helpers');
const MongoClient = require('mongodb').MongoClient;
const mongodbPackageJson = require('mongodb/package.json');
const path = require('path');
const helpers = require('./helpers');

const mongodbMajor = Number(mongodbPackageJson.version.split('.')[0]);

function Adapter(params) {
this.params = params || {};
Expand All @@ -15,77 +17,66 @@ function Adapter(params) {
this.helpers = helpers;
}

Adapter.prototype.getTemplatePath = function() {
return path.join(__dirname, 'migrationTemplate.js');
Adapter.prototype.getTemplatePath = function getTemplatePath() {
return path.join(__dirname, 'migrationTemplates', 'promises.js');
};

// mongodb driver 2.x passes `db`, 3.x passes `client` to the
// `MongoClient.connect` callback this method sets clitnt and db
// parsed from this polymorphic parameter
Adapter.prototype._setDbAndClient = function(dbOrClient) {
if (dbOrClient.collection) {
this.client = null;
// mongodb driver 2.x returns `db`, 3.x returns `client` as a result of
// `MongoClient.connect`, this method sets client and db parsed from that
// polymorphic result
Adapter.prototype._setDbAndClient = function _setDbAndClient(connectResult) {
if (mongodbMajor > 2) {
this.client = connectResult;

this.db = dbOrClient;
// `db` without args gets db from uri ("test" if no db at uri)
this.db = this.client.db();
} else {
this.client = dbOrClient;

var parsedUrl = mongodbUri.parse(this.params.url);
var dbName = parsedUrl.database || 'admin';
this.client = null;

this.db = this.client.db(dbName);
// there db name from uri ("admin" if no db at uri)
this.db = connectResult;
}
};

Adapter.prototype.connect = function(callback) {
var self = this;

MongoClient.connect(
self.params.url,
self.params.options || {},
function(err, dbOrClient) {
if (err) {
return callback(err);
}

self._setDbAndClient(dbOrClient);

self.collection = self.db.collection('_migrations');

callback(null, {
db: self.db,
dropIndexIfExists: self.helpers.dropIndexIfExists
});
}
);
Adapter.prototype.connect = function connect() {
return Promise.resolve()
.then(() => MongoClient.connect(this.params.url, this.params.options))
.then((connectResult) => {
this._setDbAndClient(connectResult);
this.collection = this.db.collection('_migrations');

return {
db: this.db,
dropIndexIfExists: this.helpers.dropIndexIfExists
};
});
};

Adapter.prototype.disconnect = function(callback) {
Adapter.prototype.disconnect = function disconnect() {
if (this.client) {
this.client.close(callback);
return this.client.close();
} else if (this.db) {
this.db.close(callback);
return this.db.close();
} else {
callback();
return Promise.resolve();
}
};

Adapter.prototype.getExecutedMigrationNames = function(callback) {
this.collection.find({}).toArray(function(err, docs) {
if (err) {
return callback(err);
}

callback(null, docs.map(function(doc) { return doc._id; }));
});
};
Adapter.prototype.getExecutedMigrationNames =
function getExecutedMigrationNames() {
return Promise.resolve()
.then(() => this.collection.find({}).toArray())
.then((docs) => {
return docs.map((doc) => doc._id);
});
};

Adapter.prototype.markExecuted = function(name, callback) {
this.collection.replaceOne({_id: name}, {_id: name}, {upsert: true}, callback);
Adapter.prototype.markExecuted = function markExecuted(name) {
return this.collection.replaceOne({_id: name}, {_id: name}, {upsert: true});
};

Adapter.prototype.unmarkExecuted = function(name, callback) {
this.collection.deleteOne({_id: name}, callback);
Adapter.prototype.unmarkExecuted = function unmarkExecuted(name) {
return this.collection.deleteOne({_id: name});
};

module.exports = Adapter;
51 changes: 31 additions & 20 deletions lib/helpers.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
'use strict';

exports.dropIndexIfExists = function(collection, index, callback) {
var indexName = '';
// convert object to string coz `indexExists` don't recognize objects
if (typeof index === 'object') {
for (var key in index) {
indexName += '_' + key + '_' + index[key];
}
indexName = indexName.replace(/^_/, '');
} else {
indexName = index;
}
collection.indexExists(indexName, function(err, exist) {
if (err) {callback(err); return;}
if (exist) {
collection.dropIndex(indexName, callback);
} else {
callback();
}
});
};
exports.dropIndexIfExists =
function dropIndexIfExists(collection, index, callback) {
let indexName = '';

return Promise.resolve()
.then(() => {
// convert object to string coz `indexExists` doesn't`
// recognize objects
if (typeof index === 'object') {
Object.keys(index).forEach((key) => {
indexName += `_${key}_${index[key]}`;
});

indexName = indexName.replace(/^_/, '');
} else {
indexName = index;
}

return collection.indexExists(indexName);
})
.then((indexExist) => {
if (indexExist) {
return collection.dropIndex(indexName);
}
})
.then(() => {
if (typeof callback === 'function') {
callback();
}
});
};
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
'use strict';

module.exports = require('./adapter');
10 changes: 0 additions & 10 deletions lib/migrationTemplate.js

This file was deleted.

7 changes: 7 additions & 0 deletions lib/migrationTemplates/async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
exports.tags = [];

exports.migrate = async ({db}) => {
};

exports.rollback = async ({db}) => {
};
13 changes: 13 additions & 0 deletions lib/migrationTemplates/promises.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
exports.tags = [];

exports.migrate = function(params) {
const db = params.db;

return Promise.resolve();
};

exports.rollback = function(params) {
const db = params.db;

return Promise.resolve();
};

0 comments on commit 40c42ad

Please sign in to comment.