Socialify

Folder ..

Viewing unique.js
86 lines (69 loc) • 2.8 KB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// 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;