<commit_before>'use strict';

/*!
 * Module dependencies
 */
const debug = require('debug')('loopback:connector:couchbase3');

const couchbase = require('couchbase');
const Promise = require('bluebird');
const uuid = require('uuid');
const utils = require('./utils');

const NoSQL = require('loopback-connector-nosql');
const Accessor = NoSQL.Accessor;

// The default design documents.
const mapByModelName = `function(doc, meta) {
  if (doc._type) {
    emit(doc._type, null);
  }
}`;
const defaultDesignDocs = {
  connector: {
    views: {
      byModelName: {
        map: mapByModelName
      }
    }
  }
};

/**
 * The constructor for Couchbase connector
 *
 * @param {Object} settings The settings object
 * @param {DataSource} dataSource The data source instance
 * @constructor
 */
class Couchbase extends NoSQL {

  /**
   * ID type.
   */
  getDefaultIdType(prop) {
    return String;
  }

  /**
   * Connect to Couchbase
   */
  _connect(settings, database) {
    // Cluster.
    if (settings.cluster == null) {
      settings.cluster = {};
    }
    if (settings.cluster.url == null) {
      debug('Cluster URL settings missing; trying default');
      settings.cluster.url = 'couchbase://localhost';
    }
    if (settings.cluster.options == null) {
      settings.cluster.options = {};
    }
    // Bucket.
    if (settings.bucket == null) {
      settings.bucket = {};
    }
    if (settings.bucket.name == null) {
      debug('Bucket name settings missing; trying default');
      settings.bucket.name = 'default';
    }
    if (settings.bucket.password == null) {
      settings.bucket.password = '';
    }
    // Cluster.
    this._cluster = Promise.resolve(new couchbase.Cluster(settings.cluster.url, settings.cluster.options))
      .then(utils.promisifyAllResolveWithReturn);
    // A connection is established when a bucket is open.
    // @see http://developer.couchbase.com/documentation/server/4.0/sdks/node-2.0/performance-tuning.html
    return this._cluster.call('openBucketAsync', settings.bucket.name, settings.bucket.password)
      .then(Promise.promisifyAll);
  }

  /**
   * Disconnect from Couchbase
   */
  _disconnect(bucket) {
    // Cleanup.
    this._cluster = null;
    this._manager = null;
    // Disconnect.
    return bucket.disconnect();
  }

  /**
   * Ping db server.
   */
  ping(callback) {
    let promise;
    if (this._cluster == null) {
      promise = Promise.reject(new Error('not connected'));
    } else {
      promise = this.connect().call('getAsync', '1').return(true).catch(function(err) {
        if (err.message === 'The key does not exist on the server') {
          return true;
        }
        return Promise.reject(err);
      });
    }
    return promise.asCallback(callback);
  }

  /**
   * ViewQuery APIs.
   */

  /**
   * Shortcut.
   */
  view(designDoc, viewName, options) {
    return this.runViewQuery(this.newViewQuery(designDoc, viewName, options));
  }

  /**
   * Shortcut.
   */
  runViewQuery(query, params) {
    return this.connect().call('queryAsync', query, params);
  }

  /**
   * Build a new view query.
   *
   * @see http://docs.couchbase.com/sdk-api/couchbase-node-client-2.1.2/ViewQuery.html
   * @param  {String} designDoc
   * @param  {String} viewName
   * @param  {Object} options
   * @return {Object}
   */
  newViewQuery(designDoc, viewName, options) {
    // With some defaults.
    let query = couchbase.ViewQuery.from(designDoc, viewName).on_error(2).order(1).stale(1);
    if (options == null) {
      return query;
    }
    // The SDK made it easier for some options formats.
    // Call.
    [
      'stale', 'order', 'group', 'group_level', 'key', 'keys', 'include_docs', 'full_set', 'on_error'<commit_msg>- Make the order of viewQuery result configurable - Add support for limit of viewQuery result<commit_after>'use strict';

/*!
 * Module dependencies
 */
const debug = require('debug')('loopback:connector:couchbase3');

const couchbase = require('couchbase');
const Promise = require('bluebird');
const uuid = require('uuid');
const utils = require('./utils');

const NoSQL = require('loopback-connector-nosql');
const Accessor = NoSQL.Accessor;

// The default design documents.
const mapByModelName = `function(doc, meta) {
  if (doc._type) {
    emit(doc._type, null);
  }
}`;
const defaultDesignDocs = {
  connector: {
    views: {
      byModelName: {
        map: mapByModelName
      }
    }
  }
};

/**
 * The constructor for Couchbase connector
 *
 * @param {Object} settings The settings object
 * @param {DataSource} dataSource The data source instance
 * @constructor
 */
class Couchbase extends NoSQL {

  /**
   * ID type.
   */
  getDefaultIdType(prop) {
    return String;
  }

  /**
   * Connect to Couchbase
   */
  _connect(settings, database) {
    // Cluster.
    if (settings.cluster == null) {
      settings.cluster = {};
    }
    if (settings.cluster.url == null) {
      debug('Cluster URL settings missing; trying default');
      settings.cluster.url = 'couchbase://localhost';
    }
    if (settings.cluster.options == null) {
      settings.cluster.options = {};
    }
    // Bucket.
    if (settings.bucket == null) {
      settings.bucket = {};
    }
    if (settings.bucket.name == null) {
      debug('Bucket name settings missing; trying default');
      settings.bucket.name = 'default';
    }
    if (settings.bucket.password == null) {
      settings.bucket.password = '';
    }
    // Cluster.
    this._cluster = Promise.resolve(new couchbase.Cluster(settings.cluster.url, settings.cluster.options))
      .then(utils.promisifyAllResolveWithReturn);
    // A connection is established when a bucket is open.
    // @see http://developer.couchbase.com/documentation/server/4.0/sdks/node-2.0/performance-tuning.html
    return this._cluster.call('openBucketAsync', settings.bucket.name, settings.bucket.password)
      .then(Promise.promisifyAll);
  }

  /**
   * Disconnect from Couchbase
   */
  _disconnect(bucket) {
    // Cleanup.
    this._cluster = null;
    this._manager = null;
    // Disconnect.
    return bucket.disconnect();
  }

  /**
   * Ping db server.
   */
  ping(callback) {
    let promise;
    if (this._cluster == null) {
      promise = Promise.reject(new Error('not connected'));
    } else {
      promise = this.connect().call('getAsync', '1').return(true).catch(function(err) {
        if (err.message === 'The key does not exist on the server') {
          return true;
        }
        return Promise.reject(err);
      });
    }
    return promise.asCallback(callback);
  }

  /**
   * ViewQuery APIs.
   */

  /**
   * Shortcut.
   */
  view(designDoc, viewName, options) {
    return this.runViewQuery(this.newViewQuery(designDoc, viewName, options));
  }

  /**
   * Shortcut.
   */
  runViewQuery(query, params) {
    return this.connect().call('queryAsync', query, params);
  }

  /**
   * Build a new view query.
   *
   * @see http://docs.couchbase.com/sdk-api/couchbase-node-client-2.1.2/ViewQuery.html
   * @param  {String} designDoc
   * @param  {String} viewName
   * @param  {Object} options
   * @return {Object}
   */
  newViewQuery(designDoc, viewName, options) {
    const ViewQuery = couchbase.ViewQuery;
    // With some defaults.
    let query = ViewQuery.from(designDoc, viewName)
      .on_error(ViewQuery.ErrorMode.STOP)
      .order(ViewQuery.Order.ASCENDING)
      .stale(ViewQuery.Update.BEFORE);

    if (options == null) {
      return query;
    }
    // The SDK made it easier for some options formats.
    // Call.
    [
      'stale', 'order', 'group', 'group_level', 'key', 'keys', 'include_docs', 'full_set', 'on_error', 'limit'
{'fraction_non_alphanumeric': 0.14651679519017122, 'fraction_numerical': 0.0027447392497712718, 'mean_word_length': 2.7528200098087297, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2593930', 'n_tokens_mistral': 2414, 'n_tokens_neox': 2387, 'n_words': 526}