88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
// the `unique` module
|
|
var unique = {};
|
|
|
|
// global results store
|
|
// currently uniqueness is global to entire faker instance
|
|
// this means that faker should currently *never* return duplicate values across all API methods when using `Faker.unique`
|
|
// it's possible in the future that some users may want to scope found per function call instead of faker instance
|
|
var found = {};
|
|
|
|
// global exclude list of results
|
|
// defaults to nothing excluded
|
|
var exclude = [];
|
|
|
|
// current iteration or retries of unique.exec ( current loop depth )
|
|
var currentIterations = 0;
|
|
|
|
// uniqueness compare function
|
|
// default behavior is to check value as key against object hash
|
|
var defaultCompare = function(obj, key) {
|
|
if (typeof obj[key] === 'undefined') {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
// common error handler for messages
|
|
unique.errorMessage = function (now, code, opts) {
|
|
console.error('error', code);
|
|
console.log('found', Object.keys(found).length, 'unique entries before throwing error. \nretried:', currentIterations, '\ntotal time:', now - opts.startTime, 'ms');
|
|
throw new Error(code + ' for uniqueness check \n\nMay not be able to generate any more unique values with current settings. \nTry adjusting maxTime or maxRetries parameters for faker.unique()')
|
|
};
|
|
|
|
unique.exec = function (method, args, opts) {
|
|
//console.log(currentIterations)
|
|
|
|
var now = new Date().getTime();
|
|
|
|
opts = opts || {};
|
|
opts.maxTime = opts.maxTime || 3;
|
|
opts.maxRetries = opts.maxRetries || 50;
|
|
opts.exclude = opts.exclude || exclude;
|
|
opts.compare = opts.compare || defaultCompare;
|
|
|
|
if (typeof opts.currentIterations !== 'number') {
|
|
opts.currentIterations = 0;
|
|
}
|
|
|
|
if (typeof opts.startTime === 'undefined') {
|
|
opts.startTime = new Date().getTime();
|
|
}
|
|
|
|
var startTime = opts.startTime;
|
|
|
|
// support single exclude argument as string
|
|
if (typeof opts.exclude === 'string') {
|
|
opts.exclude = [opts.exclude];
|
|
}
|
|
|
|
if (opts.currentIterations > 0) {
|
|
// console.log('iterating', currentIterations)
|
|
}
|
|
|
|
// console.log(now - startTime)
|
|
if (now - startTime >= opts.maxTime) {
|
|
return unique.errorMessage(now, 'Exceeded maxTime:' + opts.maxTime, opts);
|
|
}
|
|
|
|
if (opts.currentIterations >= opts.maxRetries) {
|
|
return unique.errorMessage(now, 'Exceeded maxRetries:' + opts.maxRetries, opts);
|
|
}
|
|
|
|
// execute the provided method to find a potential satifised value
|
|
var result = method.apply(this, args);
|
|
|
|
// if the result has not been previously found, add it to the found array and return the value as it's unique
|
|
if (opts.compare(found, result) === -1 && opts.exclude.indexOf(result) === -1) {
|
|
found[result] = result;
|
|
opts.currentIterations = 0;
|
|
return result;
|
|
} else {
|
|
// console.log('conflict', result);
|
|
opts.currentIterations++;
|
|
return unique.exec(method, args, opts);
|
|
}
|
|
};
|
|
|
|
module.exports = unique;
|