UNPKG

livia-orientdb

Version:

OrientDB adapter for universal database driver Livia

434 lines (345 loc) 13.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _livia = require('livia'); var _orientjsLibDbQuery = require('orientjs/lib/db/query'); var _orientjsLibDbQuery2 = _interopRequireDefault(_orientjsLibDbQuery); var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug); var _lodashIsPlainObject = require('lodash/isPlainObject'); var _lodashIsPlainObject2 = _interopRequireDefault(_lodashIsPlainObject); var _lodashIsObject = require('lodash/isObject'); var _lodashIsObject2 = _interopRequireDefault(_lodashIsObject); var log = (0, _debug2['default'])('livia-orientdb:query'); var Operation = _livia.Query.Operation; function stripslashes(str) { return (str + '').replace(/\\(.?)/g, function (s, n1) { switch (n1) { case '\\': return '\\'; case '0': return '\u0000'; case '': return ''; default: return n1; } }); } var OrientDBQuery = (function (_Query) { _inherits(OrientDBQuery, _Query); function OrientDBQuery(model) { _classCallCheck(this, OrientDBQuery); _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'constructor', this).call(this, model); this._increment = []; this._addToSet = []; } _createClass(OrientDBQuery, [{ key: 'prepareValue', value: function prepareValue(value) { if (value && value instanceof _livia.Document && value.get('@rid')) { return value.get('@rid'); } return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'prepareValue', this).call(this, value); } }, { key: 'scalar', value: function scalar(useScalar, castFn) { if (typeof castFn === 'undefined') { return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'scalar', this).call(this, useScalar, Number); } return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'scalar', this).call(this, useScalar, castFn); } }, { key: 'options', value: function options() { var _options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; if (_options['new']) { _options['return'] = 'AFTER @this'; delete _options['new']; if (_options.upsert) { _options.scalar = false; _options.first = true; } } return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'options', this).call(this, _options); } }, { key: 'increment', value: function increment(prop, value) { this._increment.push({ prop: prop, value: value }); } }, { key: 'addToSet', value: function addToSet(prop, value) { this._addToSet.push({ prop: prop, value: value }); } }, { key: 'set', value: function set(doc) { var _this = this; if (doc.$inc) { (function () { var inc = doc.$inc; delete doc.$inc; Object.keys(inc).forEach(function (propName) { _this.increment(propName, inc[propName]); }); })(); } if (doc.$addToSet) { (function () { var addToSet = doc.$addToSet; delete doc.$addToSet; Object.keys(addToSet).forEach(function (propName) { _this.addToSet(propName, addToSet[propName]); }); })(); } return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'set', this).call(this, doc); } // fix contains for collections }, { key: 'queryLanguage', value: function queryLanguage(conditions, parentPath) { var model = this.model; if (typeof!model === 'undefined') { return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'queryLanguage', this).call(this, conditions, parentPath); } var schema = model.schema; Object.keys(conditions).forEach(function (propertyName) { var pos = propertyName.indexOf('.'); if (pos === -1) { return; } var value = conditions[propertyName]; var parent = propertyName.substr(0, pos); var child = propertyName.substr(pos + 1); var currentPath = parentPath ? parentPath + '.' + parent : parent; var prop = schema.getPath(currentPath); if (!prop || !prop.SchemaType || !prop.SchemaType.isArray) { return; } // replace condition delete conditions[propertyName]; var subConditions = conditions[parent] || {}; if (!(0, _lodashIsPlainObject2['default'])(subConditions)) { subConditions = { $eq: subConditions }; } if (!subConditions.$contains) { subConditions.$contains = {}; } if (subConditions.$contains[child]) { throw new Error('Condition already exists for ' + child); } subConditions.$contains[child] = value; conditions[parent] = subConditions; }); return _get(Object.getPrototypeOf(OrientDBQuery.prototype), 'queryLanguage', this).call(this, conditions, parentPath); } }, { key: 'fixRecord', value: function fixRecord(record) { var options = this.model.connection.adapter.options; if (options.fixEmbeddedEscape) { return this.fixEmbeddedEscape(record); } return record; } }, { key: 'fixEmbeddedEscape', value: function fixEmbeddedEscape(record, isChild) { var _this2 = this; if (!(0, _lodashIsObject2['default'])(record)) { return record; } Object.keys(record).forEach(function (key) { var value = record[key]; if ((0, _lodashIsObject2['default'])(value)) { record[key] = _this2.fixEmbeddedEscape(value, true); return; } if (typeof value === 'string' && isChild) { record[key] = stripslashes(value); } }); return record; } }, { key: 'native', value: function native() { return new _orientjsLibDbQuery2['default'](this.model.native); } }, { key: 'exec', value: function exec() { var _this3 = this; var callback = arguments.length <= 0 || arguments[0] === undefined ? function () {} : arguments[0]; var model = this.model; var schema = model.schema; var operation = this._operation; if (!operation) { throw new Error('Operation is not defined'); } var query = this.native(); var q = query; var target = this._target; if (target instanceof _livia.Document) { target = target.get('@rid'); if (!target) { throw new Error('Target is document but his RID is not defined'); } } var select = this._select || '*'; var escapedTarget = typeof target === 'string' && target[0] !== '#' ? '`' + target + '`' : target; var isGraph = schema instanceof _livia.Schema.Graph; if (isGraph) { var graphType = schema instanceof _livia.Schema.Edge ? 'EDGE' : 'VERTEX'; if (operation === Operation.INSERT) { query = query.create(graphType, escapedTarget); } else if (operation === Operation.DELETE) { query = query['delete'](graphType, escapedTarget); } else if (operation === Operation.SELECT) { query = query.select(select).from(escapedTarget); } else { query = query.update(target); } } else { if (operation === Operation.INSERT) { query = query.insert().into(escapedTarget); } else if (operation === Operation.DELETE) { query = query['delete']().from(escapedTarget); } else if (operation === Operation.SELECT) { query = query.select(select).from(escapedTarget); } else { query = query.update(escapedTarget); } } if (this._from) { var from = this._from; if (from instanceof _livia.Document) { from = from.get('@rid'); if (!from) { throw new Error('From is document but his rid is not defined'); } } query.from(from); } if (this._to) { var to = this._to; if (to instanceof _livia.Document) { to = to.get('@rid'); if (!to) { throw new Error('To is document but his rid is not defined'); } } query.to(to); } if (this._set) { if (operation === Operation.INSERT) { if (this._set['@type']) { delete this._set['@type']; } if (this._set['@class']) { delete this._set['@class']; } } if (Object.keys(this._set).length) { query.set(this._set); } } if (this._increment.length) { this._increment.forEach(function (item) { query.increment(item.prop, item.value); }); } if (this._addToSet.length) { this._addToSet.forEach(function (item) { query.add(item.prop, item.value); }); } if (this._upsert) { query.upsert(); } this._operators.forEach(function (operator) { query = query[operator.type](operator.query); }); query.addParams(this._params); if (!this._scalar && (operation === Operation.SELECT || operation === Operation.INSERT || this._return)) { query = query.transform(function (record) { record = _this3.fixRecord(record); return model.createDocument(record); }); } if (this._limit) { query = query.limit(this._limit); } if (this._skip) { query = query.skip(this._skip); } if (this._group.length) { this._group.forEach(function (item) { query = query.group(item); }); } if (this._populate.length) { // transform to fetch var _fetch = this._populate.map(function (field) { return field + ':0'; }).join(' '); this._fetchPlan = this._fetchPlan ? _fetch + ' ' + this._fetchPlan : _fetch; } if (this._fetchPlan) { query = query.fetch(this._fetchPlan); } if (this._return) { query = query['return'](this._return); } if (this._sort) { (function () { var order = {}; Object.keys(_this3._sort).forEach(function (key) { var value = _this3._sort[key]; order[key] = value === 'asc' || value === 'ascending' || value === 1 ? 'ASC' : 'DESC'; }); query = query.order(order); })(); } log(q.buildStatement(), q.buildOptions()); return query.exec().then(function (results) { if (!results) { return callback(null, results); } if (_this3._first || _this3._scalar) { results = results[0]; } if (_this3._scalar && results) { var keys = Object.keys(results).filter(function (item) { return item[0] !== '@'; }); if (keys.length) { results = results[keys[0]]; if (_this3._scalarCast && results !== null && typeof results !== 'undefined') { results = _this3._scalarCast(results); } } } callback(null, results); }, function (err) { log('Error: ' + err.message); callback(err); }); } }]); return OrientDBQuery; })(_livia.Query); exports['default'] = OrientDBQuery; module.exports = exports['default'];