UNPKG

feathers-express-cassandra

Version:

A Feathers service adapter for the Cassandra ORM (express-cassandra)

187 lines (152 loc) 5.06 kB
import omit from 'lodash.omit'; import Proto from 'uberproto'; import filter from 'feathers-query-filters'; import errors from 'feathers-errors'; import { select } from 'feathers-commons'; import * as utils from './utils'; class Service { constructor (options) { if (!options) { throw new Error('Cassandra options have to be provided'); } if (!options.Model) { throw new Error('You must provide a Cassandra Model'); } this.paginate = options.paginate || {}; this.Model = options.Model; this.id = options.id || 'id'; this.events = options.events; this.materialized_views = options.materialized_views || []; this.if_not_exist = false; this.if_not_exist = (typeof options.if_not_exist !== 'undefined' ? options.if_not_exist : this.if_not_exist); } extend (obj) { return Proto.extend(obj, this); } _find (params, getFilter = filter) { const { filters, query } = getFilter(params.query || params); const where = utils.getWhere(query); const order = utils.getOrder(filters.$sort); const options = utils.getMaterializedOptions({}, where, this.materialized_views); const rows = []; options.fetchSize = filters.$limit; if (filters.$limit && filters.$limit.length > 1) { options.raw = true; } return this.Model.eachRowAsync(where, options, function(n, row){ if (row) { rows.push(row); } }).then(function(result) { return rows || []; }).catch(utils.errorHandler); } find (params) { const paginate = (params && typeof params.paginate !== 'undefined') ? params.paginate : this.paginate; const result = this._find(params, where => filter(where, paginate)); if (!paginate.default) { return result.then(page => page.data); } return result; } findOne (params) { return this.find(params).then((results) => { return (results && results.length > 0) ? results[0] : null; }).catch(utils.errorHandler) } _get (id, params) { const {query, options} = utils.getQueryAndOptions(this.id, id, params, this.materialized_views); return this.Model.findOneAsync(query, options).then(instance => { if (!instance) { throw new errors.NotFound(`No record found for id '${id}'`); } return instance; }) .then(select(params, this.id)) .catch(utils.errorHandler); } // returns either the model intance for an id or all unpaginated // items for `params` if id is null _getOrFind (id, params) { if (id === null) { return this._find(params).then(page => page.data); } return this._get(id, params); } get (id, params) { return this._get(id, params).then(select(params, this.id)); } create (data, params) { var options = params.cassandra || {}; /* if (Array.isArray(data)) { return this.Model.bulkCreate(data, options).catch(utils.errorHandler); } */ let if_not_exist = (typeof options.if_not_exist !== 'undefined' ? options.if_not_exist : this.if_not_exist); const model = new this.Model(data); return model.saveAsync({if_not_exist: if_not_exist}) .then(()=> { return model; }) .then(select(params, this.id)) .catch(utils.errorHandler); } patch (id, data, params) { const query = {}; query[this.id] = id; return this.Model.findOneAsync(query).then((instance) => { if (!instance) { throw new errors.NotFound(`No record found for id '${id}'`); } Object.keys(data).forEach(function(key) { if (typeof instance[key] !== 'undefined') { instance[key] == data[key]; } }); return instance.saveAsync(); }) .then(select(params, this.id)) .catch(utils.errorHandler); } update (id, data, params) { const query = {}; query[this.id] = id; if (Array.isArray(data)) { return Promise.reject('Not replacing multiple records. Did you mean `patch`?'); } return this.Model.findOneAsync(query).then(function (instance) { if (!instance) { throw new errors.NotFound(`No record found for id '${id}'`); } var copy = {}; Object.keys(instance.toJSON()).forEach(function (key) { if (typeof data[key] === 'undefined') { copy[key] = null; } else { copy[key] = data[key]; } }); return instance.saveAsync(); }) .then(select(params, this.id)) .catch(utils.errorHandler); } remove (id, params) { const {query, options} = utils.getQueryAndOptions(this.id, id, params, this.materialized_views); return this.Model.findOneAsync(query, options).then(function (instance) { if (!instance) { throw new errors.NotFound(`No record found for id '${id}'`); } return instance.deleteAsync().then(function () { return {}; }); }) .then(select(params, this.id)) .catch(utils.errorHandler); } } export default function init (options) { return new Service(options); } init.Service = Service;