2016-04-01 22:25:16 +00:00
|
|
|
// Copyright IBM Corp. 2015,2016. All Rights Reserved.
|
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2015-10-10 14:21:06 +00:00
|
|
|
module.exports.buildOneToOneIdentityMapWithOrigKeys = buildOneToOneIdentityMapWithOrigKeys;
|
2015-10-30 15:15:48 +00:00
|
|
|
module.exports.buildOneToManyIdentityMapWithOrigKeys = buildOneToManyIdentityMapWithOrigKeys;
|
2015-08-24 12:41:04 +00:00
|
|
|
module.exports.join = join;
|
2015-10-30 15:15:48 +00:00
|
|
|
module.exports.KVMap = KVMap;
|
2015-08-24 12:41:04 +00:00
|
|
|
|
2015-10-10 14:21:06 +00:00
|
|
|
/**
|
|
|
|
* Effectively builds associative map on id -> object relation and stores original keys.
|
|
|
|
* Map returned in form of object with ids in keys and object as values.
|
|
|
|
* @param objs array of objects to build from
|
|
|
|
* @param idName name of property to be used as id. Such property considered to be unique across array.
|
|
|
|
* In case of collisions last wins. For non-unique ids use buildOneToManyIdentityMap()
|
2015-10-30 15:15:48 +00:00
|
|
|
* @returns {} object where keys are ids and values are objects itself
|
2015-10-10 14:21:06 +00:00
|
|
|
*/
|
|
|
|
function buildOneToOneIdentityMapWithOrigKeys(objs, idName) {
|
2015-10-30 15:15:48 +00:00
|
|
|
var kvMap = new KVMap();
|
2016-04-01 11:48:17 +00:00
|
|
|
for (var i = 0; i < objs.length; i++) {
|
2015-10-10 14:21:06 +00:00
|
|
|
var obj = objs[i];
|
|
|
|
var id = obj[idName];
|
2015-10-30 15:15:48 +00:00
|
|
|
kvMap.set(id, obj);
|
2015-10-10 14:21:06 +00:00
|
|
|
}
|
2015-10-30 15:15:48 +00:00
|
|
|
return kvMap;
|
2015-10-10 14:21:06 +00:00
|
|
|
}
|
|
|
|
|
2015-10-10 16:00:00 +00:00
|
|
|
function buildOneToManyIdentityMapWithOrigKeys(objs, idName) {
|
2015-10-30 15:15:48 +00:00
|
|
|
var kvMap = new KVMap();
|
2016-04-01 11:48:17 +00:00
|
|
|
for (var i = 0; i < objs.length; i++) {
|
2015-10-10 16:00:00 +00:00
|
|
|
var obj = objs[i];
|
|
|
|
var id = obj[idName];
|
2015-10-30 15:15:48 +00:00
|
|
|
var value = kvMap.get(id) || [];
|
|
|
|
value.push(obj);
|
|
|
|
kvMap.set(id, value);
|
2015-10-10 16:00:00 +00:00
|
|
|
}
|
2015-10-30 15:15:48 +00:00
|
|
|
return kvMap;
|
2015-10-10 16:00:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-24 12:41:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Yeah, it joins. You need three things id -> obj1 map, id -> [obj2] map and merge function.
|
|
|
|
* This functions will take each obj1, locate all data to join in map2 and call merge function.
|
|
|
|
* @param oneToOneIdMap
|
|
|
|
* @param oneToManyIdMap
|
|
|
|
* @param mergeF function(obj, objectsToMergeIn)
|
|
|
|
*/
|
|
|
|
function join(oneToOneIdMap, oneToManyIdMap, mergeF) {
|
2015-10-30 15:15:48 +00:00
|
|
|
var ids = oneToOneIdMap.getKeys();
|
2016-04-01 11:48:17 +00:00
|
|
|
for (var i = 0; i < ids.length; i++) {
|
2015-08-24 12:41:04 +00:00
|
|
|
var id = ids[i];
|
2015-10-30 15:15:48 +00:00
|
|
|
var obj = oneToOneIdMap.get(id);
|
|
|
|
var objectsToMergeIn = oneToManyIdMap.get(id) || [];
|
2015-08-24 12:41:04 +00:00
|
|
|
mergeF(obj, objectsToMergeIn);
|
|
|
|
}
|
|
|
|
}
|
2015-10-30 15:15:48 +00:00
|
|
|
|
|
|
|
|
2015-10-30 15:19:37 +00:00
|
|
|
/**
|
|
|
|
* Map with arbitrary keys and values. User .set() and .get() to work with values instead of []
|
|
|
|
* @returns {{set: Function, get: Function, remove: Function, exist: Function, getKeys: Function}}
|
|
|
|
* @constructor
|
|
|
|
*/
|
2016-04-01 11:48:17 +00:00
|
|
|
function KVMap() {
|
2015-10-30 15:15:48 +00:00
|
|
|
var _originalKeyFieldName = 'originalKey';
|
|
|
|
var _valueKeyFieldName = 'value';
|
|
|
|
var _dict = {};
|
2016-04-01 11:48:17 +00:00
|
|
|
var keyToString = function(key) { return key.toString(); };
|
2015-10-30 15:15:48 +00:00
|
|
|
var mapImpl = {
|
2016-04-01 11:48:17 +00:00
|
|
|
set: function(key, value) {
|
2015-10-30 15:15:48 +00:00
|
|
|
var recordObj = {};
|
|
|
|
recordObj[_originalKeyFieldName] = key;
|
|
|
|
recordObj[_valueKeyFieldName] = value;
|
|
|
|
_dict[keyToString(key)] = recordObj;
|
|
|
|
return true;
|
|
|
|
},
|
2016-04-01 11:48:17 +00:00
|
|
|
get: function(key) {
|
2015-10-30 15:15:48 +00:00
|
|
|
var storeObj = _dict[keyToString(key)];
|
2016-04-01 11:48:17 +00:00
|
|
|
if (storeObj) {
|
2015-10-30 15:15:48 +00:00
|
|
|
return storeObj[_valueKeyFieldName];
|
|
|
|
} else {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
},
|
2016-04-01 11:48:17 +00:00
|
|
|
remove: function(key) {
|
2015-10-30 15:15:48 +00:00
|
|
|
delete _dict[keyToString(key)];
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
exist: function(key) {
|
|
|
|
var result = _dict.hasOwnProperty(keyToString(key));
|
|
|
|
return result;
|
|
|
|
},
|
2016-04-01 11:48:17 +00:00
|
|
|
getKeys: function() {
|
2015-10-30 15:15:48 +00:00
|
|
|
var result = [];
|
2016-04-01 11:48:17 +00:00
|
|
|
for (var key in _dict) {
|
2015-10-30 15:15:48 +00:00
|
|
|
result.push(_dict[key][_originalKeyFieldName]);
|
|
|
|
}
|
|
|
|
return result;
|
2016-04-01 11:48:17 +00:00
|
|
|
},
|
2015-10-30 15:15:48 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
return mapImpl;
|
|
|
|
}
|