<commit_before>/**
 * @class AbstractBaseDao
 * @classdesc A NoSQL basic implementation optimized for redis.  It also serves as a facade
 * for other NoSQL databases like leveldb, couch, etc.
 *
 * @author: <EMAIL>
 * @created: 9/2/14
 */
const dash = require('lodash'),
    uuid = require('node-uuid');

const AbstractBaseDao = function(options) {
    'use strict';

    const dao = this,
        log = options.log,
        domain = options.domain,
        createType = options.createType;

    /**
     * create a unique model id
     * @returns a guid-like thing
     */
    this.createModelId = function() {
        return uuid.v4().replace(/-/g, '');
    };

    /**
     * create a domain key by combining domain, colon and the id
     *
     * @param id - the model id; if id is null an error is thrown
     * @returns domain key
     */
    this.createDomainKey = function(id) {
        if (!id) {
            throw new Error('domain key requires model id');
        }

        if (id.indexOf( domain ) === 0) {
            return id;
        } else {
            return [ domain, ':', id ].join('');
        }
    };

    /**
     * query the domain for rows.  this is a very simple implementation that pulls
     * all rows for the given domain.  for production you probably want to override
     * this with a fully implemented query method.  but if your row count is less than
     * a few hundred, then this should work.
     *
     * @param client - a nosql client, e.g. redis
     * @param request - the query request object
     * @param callback err, response
     */
    this.query = function(client, request, callback) {
        if (!callback && typeof request === 'function') {
            callback = request;
        }

        const keysCallback = function(err, keys) {
            let list = [];

            if (err) {
                log.error( err );
                callback( err );
            }

            const loopCallback = function(err, model) {
                if (err) {
                    log.error( err );
                } else if (model) {
                    list.push( model );
                }

                let key = keys.shift();

                if (key) {
                    dao.findById( client, key, loopCallback );
                } else {
                    return callback( err, list );
                }
            };

            loopCallback();
        };

        // TODO : replace with scan
        client.keys( dao.createDomainKey( '*' ), keysCallback );
    };

    /**
     * query a standard index set, fetch, parse and return the models
     *
     * @param client - redis client
     * @param idx - the index name (key)
     * @param completeCallback - err, list<commit_msg>added detailed todo for replacing keys with scan for key/value pair queries<commit_after>/**
 * @class AbstractBaseDao
 * @classdesc A NoSQL basic implementation optimized for redis.  It also serves as a facade
 * for other NoSQL databases like leveldb, couch, etc.
 *
 * @author: <EMAIL>
 * @created: 9/2/14
 */
const dash = require('lodash'),
    uuid = require('node-uuid');

const AbstractBaseDao = function(options) {
    'use strict';

    const dao = this,
        log = options.log,
        domain = options.domain,
        createType = options.createType;

    /**
     * create a unique model id
     * @returns a guid-like thing
     */
    this.createModelId = function() {
        return uuid.v4().replace(/-/g, '');
    };

    /**
     * create a domain key by combining domain, colon and the id
     *
     * @param id - the model id; if id is null an error is thrown
     * @returns domain key
     */
    this.createDomainKey = function(id) {
        if (!id) {
            throw new Error('domain key requires model id');
        }

        if (id.indexOf( domain ) === 0) {
            return id;
        } else {
            return [ domain, ':', id ].join('');
        }
    };

    /**
     * query the domain for rows.  this is a very simple implementation that pulls
     * all rows for the given domain.  for production you probably want to override
     * this with a fully implemented query method.  but if your row count is less than
     * a few hundred, then this should work.
     *
     * @param client - a nosql client, e.g. redis
     * @param request - the query request object
     * @param callback err, response
     */
    this.query = function(client, request, callback) {
        if (!callback && typeof request === 'function') {
            callback = request;
        }

        const keysCallback = function(err, keys) {
            let list = [];

            if (err) {
                log.error( err );
                callback( err );
            }

            const loopCallback = function(err, model) {
                if (err) {
                    log.error( err );
                } else if (model) {
                    list.push( model );
                }

                let key = keys.shift();

                if (key) {
                    dao.findById( client, key, loopCallback );
                } else {
                    return callback( err, list );
                }
            };

            loopCallback();
        };

        // TODO : replace with scan 0 match Domain:* count 100000; then change the callback
        client.keys( dao.createDomainKey( '*' ), keysCallback );
    };

    /**
     * query a standard index set, fetch, parse and return the models
     *
     * @param client - redis client
     * @param idx - the index name (key)
     * @param completeCallback - err, list
{'fraction_non_alphanumeric': 0.10659536541889483, 'fraction_numerical': 0.0033868092691622105, 'mean_word_length': 1.62196261682243, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6313634', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1466, 'n_words': 535}