2020-01-21 18:12:14 +00:00
|
|
|
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
|
2016-04-01 22:25:16 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2016-08-22 19:55:22 +00:00
|
|
|
'use strict';
|
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const g = require('strong-globalize')();
|
|
|
|
const util = require('util');
|
|
|
|
const Connector = require('loopback-connector').Connector;
|
|
|
|
const utils = require('../utils');
|
|
|
|
const crypto = require('crypto');
|
2014-08-30 08:53:10 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the Transient connector against the given data source
|
|
|
|
*
|
|
|
|
* @param {DataSource} dataSource The loopback-datasource-juggler dataSource
|
|
|
|
* @param {Function} [callback] The callback function
|
|
|
|
*/
|
|
|
|
exports.initialize = function initializeDataSource(dataSource, callback) {
|
|
|
|
dataSource.connector = new Transient(null, dataSource.settings);
|
|
|
|
dataSource.connector.connect(callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.Transient = Transient;
|
|
|
|
|
|
|
|
function Transient(m, settings) {
|
|
|
|
settings = settings || {};
|
|
|
|
if (typeof settings.generateId === 'function') {
|
|
|
|
this.generateId = settings.generateId.bind(this);
|
|
|
|
}
|
|
|
|
this.defaultIdType = settings.defaultIdType || String;
|
|
|
|
if (m instanceof Transient) {
|
|
|
|
this.isTransaction = true;
|
|
|
|
this.constructor.super_.call(this, 'transient', settings);
|
|
|
|
this._models = m._models;
|
|
|
|
} else {
|
|
|
|
this.isTransaction = false;
|
|
|
|
this.constructor.super_.call(this, 'transient', settings);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
util.inherits(Transient, Connector);
|
|
|
|
|
|
|
|
Transient.prototype.getDefaultIdType = function() {
|
|
|
|
return this.defaultIdType;
|
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.getTypes = function() {
|
|
|
|
return ['db', 'nosql', 'transient'];
|
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
Transient.prototype.connect = function(callback) {
|
2014-08-30 08:53:10 +00:00
|
|
|
if (this.isTransaction) {
|
|
|
|
this.onTransactionExec = callback;
|
|
|
|
} else {
|
|
|
|
process.nextTick(callback);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-08-30 09:43:36 +00:00
|
|
|
Transient.prototype.generateId = function(model, data, idName) {
|
2018-12-07 14:54:29 +00:00
|
|
|
let idType;
|
|
|
|
const props = this._models[model].properties;
|
2014-08-30 09:43:36 +00:00
|
|
|
if (idName) idType = props[idName] && props[idName].type;
|
2014-08-30 08:53:10 +00:00
|
|
|
idType = idType || this.getDefaultIdType();
|
2014-08-30 09:43:36 +00:00
|
|
|
if (idType === Number) {
|
2014-08-30 08:53:10 +00:00
|
|
|
return Math.floor(Math.random() * 10000); // max. 4 digits
|
|
|
|
} else {
|
2016-04-01 11:48:17 +00:00
|
|
|
return crypto.randomBytes(Math.ceil(24 / 2))
|
2018-06-12 07:13:32 +00:00
|
|
|
.toString('hex') // convert to hexadecimal format
|
|
|
|
.slice(0, 24); // return required number of characters
|
2014-08-30 08:53:10 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.exists = function exists(model, id, callback) {
|
2016-04-01 11:48:17 +00:00
|
|
|
process.nextTick(function() { callback(null, false); }.bind(this));
|
2014-08-30 08:53:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.find = function find(model, id, callback) {
|
2016-04-01 11:48:17 +00:00
|
|
|
process.nextTick(function() { callback(null, null); }.bind(this));
|
2014-08-30 08:53:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.all = function all(model, filter, callback) {
|
2016-04-01 11:48:17 +00:00
|
|
|
process.nextTick(function() { callback(null, []); });
|
2014-08-30 08:53:10 +00:00
|
|
|
};
|
|
|
|
|
2014-08-30 09:43:36 +00:00
|
|
|
Transient.prototype.count = function count(model, callback, where) {
|
2016-04-01 11:48:17 +00:00
|
|
|
process.nextTick(function() { callback(null, 0); });
|
2014-08-30 09:43:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.create = function create(model, data, callback) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const props = this._models[model].properties;
|
|
|
|
const idName = this.idName(model);
|
2018-12-07 15:22:36 +00:00
|
|
|
let id = undefined;
|
2014-08-30 09:43:36 +00:00
|
|
|
if (idName && props[idName]) {
|
2018-12-07 15:22:36 +00:00
|
|
|
id = this.getIdValue(model, data) || this.generateId(model, data, idName);
|
2014-08-30 09:43:36 +00:00
|
|
|
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
|
|
|
|
this.setIdValue(model, data, id);
|
2014-08-30 08:53:10 +00:00
|
|
|
}
|
2014-08-30 09:43:36 +00:00
|
|
|
this.flush('create', id, callback);
|
2014-08-30 08:53:10 +00:00
|
|
|
};
|
|
|
|
|
2014-08-30 09:43:36 +00:00
|
|
|
Transient.prototype.save = function save(model, data, callback) {
|
|
|
|
this.flush('save', data, callback);
|
2014-08-30 08:53:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.update =
|
|
|
|
Transient.prototype.updateAll = function updateAll(model, where, data, cb) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const count = 0;
|
2016-08-19 17:46:59 +00:00
|
|
|
this.flush('update', {count: count}, cb);
|
2016-04-01 11:48:17 +00:00
|
|
|
};
|
2014-08-30 08:53:10 +00:00
|
|
|
|
|
|
|
Transient.prototype.updateAttributes = function updateAttributes(model, id, data, cb) {
|
|
|
|
if (!id) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const err = new Error(g.f('You must provide an {{id}} when updating attributes!'));
|
2014-08-30 08:53:10 +00:00
|
|
|
if (cb) {
|
|
|
|
return cb(err);
|
|
|
|
} else {
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
}
|
2015-03-20 07:34:58 +00:00
|
|
|
|
2014-08-30 08:53:10 +00:00
|
|
|
this.setIdValue(model, data, id);
|
|
|
|
this.save(model, data, cb);
|
|
|
|
};
|
|
|
|
|
2014-08-30 09:43:36 +00:00
|
|
|
Transient.prototype.destroy = function destroy(model, id, callback) {
|
|
|
|
this.flush('destroy', null, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
Transient.prototype.destroyAll = function destroyAll(model, where, callback) {
|
|
|
|
if (!callback && 'function' === typeof where) {
|
|
|
|
callback = where;
|
|
|
|
where = undefined;
|
|
|
|
}
|
|
|
|
this.flush('destroyAll', null, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Flush the cache - noop.
|
|
|
|
* @param {Function} callback
|
|
|
|
*/
|
2016-04-01 11:48:17 +00:00
|
|
|
Transient.prototype.flush = function(action, result, callback) {
|
|
|
|
process.nextTick(function() { callback && callback(null, result); });
|
2014-08-30 09:43:36 +00:00
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
Transient.prototype.transaction = function() {
|
2014-08-30 08:53:10 +00:00
|
|
|
return new Transient(this);
|
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
Transient.prototype.exec = function(callback) {
|
2014-08-30 08:53:10 +00:00
|
|
|
this.onTransactionExec();
|
|
|
|
setTimeout(callback, 50);
|
|
|
|
};
|