# all files / keystone/lib/list/ getUniqueValue.js

8.33% Statements 2/24
0% Branches 0/10
0% Functions 0/4
9.09% Lines 2/22

    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

    1×

    1×
     /**
     * Gets a unique value from a generator method by checking for documents with the same value.
     *
     * To avoid infinite loops when a unique value cannot be found, it will bail and pass back an
     * undefined value after 10 attemptes.
     *
     * WARNING: Because there will always be a small amount of time between checking for an
     * existing value and saving a document, race conditions can occur and it is possible that
     * another document has the 'unique' value assigned at the same time.
     *
     * Because of this, if true uniqueness is required, you should also create a unique index on
     * the database path, and handle duplicate errors thrown on save.
     *
     * @param {String} path to check for uniqueness
     * @param {Function} generator method to call to generate a new value
     * @param {Number} the maximum number of attempts (optional, defaults to 10)
     * @param {Function} callback(err, uniqueValue)
     */
    function getUniqueValue (path, generator, limit, callback) {
    	var model = this.model;
    	var count = 0;
    	var value;
    	if (typeof limit === 'function') {
    		callback = limit;
    		limit = 10;
    	}
    	if (Array.isArray(generator)) {
    		var fn = generator[0];
    		var args = generator.slice(1);
    		generator = function () {
    			return fn.apply(this, args);
    		};
    	}
    	var check = function () {
    		if (count++ > 10) {
    			return callback(undefined, undefined);
    		}
    		value = generator();
    		model.count().where(path, value).exec(function (err, matches) {
    			if (err) return callback(err);
    			if (matches) return check();
    			callback(undefined, value);
    		});
    	};
    	check();
    }

    module.exports = getUniqueValue;