UNPKG

blow-data-service

Version:

Observable data service for Blow.

164 lines (163 loc) 5.03 kB
'use strict'; const rxjs_1 = require('rxjs'); const mongodb = require('mongodb'); const DataConnector_1 = require('./DataConnector'); class MongoClient { static connect(url, options) { return rxjs_1.Observable.from(mongodb.MongoClient.connect(url, options)) .map(db => new Db(db)); } } exports.MongoClient = MongoClient; class Db { constructor(db) { this._db = db; } collection(name) { return new Collection(this._db.collection(name)); } delete() { return rxjs_1.Observable.from(this._db.dropDatabase()) .mergeMap(() => this.close()); } close() { return rxjs_1.Observable.from(this._db.close()); } } exports.Db = Db; class Collection { constructor(collection) { this._collection = collection; } find(query) { query = Object.assign({}, { where: {} }, query || {}); let cursor = this._collection.find(query.where); Object.keys(query).forEach(key => { if (key !== 'where') { cursor = cursor[key](query[key]); } }); return rxjs_1.Observable.create(subscriber => { cursor.forEach(document => { subscriber.next(document); }, error => { if (error) { subscriber.error(error); } subscriber.complete(); }); }); } count(query) { query = query || {}; return rxjs_1.Observable.from(this._collection.count(query)); } delete(query) { query = query || {}; return rxjs_1.Observable.from(this._collection.deleteMany(query)); } insert(doc) { return rxjs_1.Observable.from(this._collection.insertOne(doc)) .map(response => response['ops'][0]); } update(query, doc, options) { return rxjs_1.Observable.from(this._collection.updateOne(query, { $set: doc }, options)) .map(response => { if (response['modifiedCount']) { doc._id = query._id.toString(); return doc; } else { return null; } }); } } exports.Collection = Collection; class MongoDBConnector extends DataConnector_1.DataConnector { _buildQueryWhereForId(id) { return this._prepareQueryWhere({ _id: id }); } _normalizeId(value) { let id; try { id = new mongodb.ObjectID(value); } catch (e) { id = value; } return id; } _prepareQueryWhere(queryWhere) { const where = {}; Object.keys(queryWhere).forEach(key => { let value = queryWhere[key]; if (key === '_id') { value = this._normalizeId(value); } where[key] = value; }); return where; } _collection(collectionName) { return this._db.collection(collectionName); } connect() { this._state.connecting(); return rxjs_1.Observable.from(MongoClient.connect(this._settings['url'])) .do(db => { this._db = db; this._state.connected(); }) .mapTo(this); } disconnect() { this._state.disconnecting(); return rxjs_1.Observable.from(this._db.close()) .do(() => this._state.disconnected()) .mapTo(this); } destroyDb() { return this._db.delete(); } find(collectionName, query) { return this._collection(collectionName) .find(this._prepareQuery(query)); } count(collectionName, query) { return this._collection(collectionName) .count(this._prepareQuery(query).where); } delete(collectionName, query) { return this._collection(collectionName) .delete(this._prepareQuery(query).where) .map(response => response['result'].n); } deleteById(collectionName, id) { return this._collection(collectionName) .delete(this._buildQueryWhereForId(id)) .map(response => response['result'].n === 1); } get(collectionName, id) { return this._collection(collectionName) .find({ where: this._buildQueryWhereForId(id) }); } save(collectionName, doc) { const hasId = Object.keys(doc).indexOf('_id') > -1 && doc['_id']; if (!hasId) { return this._collection(collectionName).insert(doc); } else { return this._collection(collectionName).update(this._buildQueryWhereForId(doc['_id']), doc, { upsert: true }); } } updateAttributes(collectionName, id, attributes) { delete attributes['_id']; return this.get(collectionName, id) .map(result => Object.assign(result, attributes)) .mergeMap(doc => this.save(collectionName, doc)); } } exports.MongoDBConnector = MongoDBConnector;