<commit_before>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

var __ = require('underscore');
var fs = require('fs');
var path = require('path');
var request = require('request');
var through = require('through');
var util = require('util');

var validation = require('../../../util/validation');
var profile = require('../../../util/profile');
var utils = require('../../../util/utils');

var $ = utils.getLocaleString;

exports.getGroup = function getGroup(client, name, callback) {
  client.resourceGroups.get(name, function (err, group) {
    if (err) {
      // 404 means doesn't exist
      if (err.statusCode === 404) {
        callback(null, null);
      } else {
        // some other error, let it out
        callback(err);
      }
    } else {
      // No error, group exists
      callback(null, group.resourceGroup);
    }
  });
};

exports.getResource = function getResource(client, resourceGroup, identity, callback) {
  client.resources.get(resourceGroup, identity, function (err, resource) {
    if (err) {
      // 404 means doesn't exist
      if (err.statusCode === 404) {
        callback(null, null);
      } else {
        // some other error, let it out
        callback(err);
      }
    } else {
      // No error, resource exists
      callback(null, resource.resource);
    }
  });
};

exports.createDeployment = function (cli, resourceGroup, name, options, _) {
  var subscription = profile.current.getSubscription(options.subscription);
  var client = utils.createResourceClient(subscription);

  var templateParameters = createDeploymentParameters(cli, subscription, resourceGroup, options, _);

  //if not provided, derive it from the template file name
  if (!name) {
    var templateName = options.galleryTemplate || options.templateFile || options.templateUri;
    var baseTemplateName = path.basename(templateName);
    //if the file extension is '.json', get rid of it.
    if (utils.stringEndsWith(baseTemplateName, '.json', true)) {
      baseTemplateName = path.basename(baseTemplateName, path.extname(baseTemplateName));
    }
    name = baseTemplateName;
  }

  var result = cli.interaction.withProgress($('Creating a deployment'),
    function (log, _) {
      var validationResponse = client.deployments.validate(resourceGroup, name, templateParameters, _);
      var createResponse = client.deployments.createOrUpdate(resourceGroup, name, templateParameters, _);
      createResponse.requiredProviders = getTemplateProviders(validationResponse);
      return createResponse;
    }, _);

  cli.output.info(util.format($('Created template deployment "%s"'), name));

  cli.interaction.withProgress($('Registering providers'),
    function (log, _) {
      for (var i = 0; i < result.requiredProviders.length; i++) {
        var namespace = result.requiredProviders[i];
        log.info(util.format($('Registering provider %s'), namespace));
        subscription.registerArmProvider(namespace, false, _);
      }
    },
    _);

  return result.deployment;

};

exports.validateTemplate = function (cli, resourceGroup, options, _) {
  var subscription = profile.current.getSubscription(options.subscription);
  var client = utils.createResourceClient(subscription);

  var templateParameters = createDeploymentParameters(cli, subscription, resourceGroup, options, _);

  var response = cli.interaction.withProgress($('Validating the template'),
    function (log, _) {
      return client.deployments.validate(resourceGroup, 'fakedDeploymentName', templateParameters, _);
    }, _);

  response.requiredProviders = getTemplateProviders(response);

  return response;
};

exports.getGalleryTemplateFile = function (subscription, galleryTemplateName, _) {
  var galleryClient = utils.createGalleryClient(subscription);
  var galleryItem = galleryClient.items.get(galleryTemplateName, _).item;
  return exports.getTemplateDownloadUrl(galleryItem);
};

exports.getTemplateDownloadUrl = function getTemplateDownloadUrl(templateData) {
  var key = templateData.definitionTemplates.defaultDeploymentTemplateId;
  var urls = Object.keys(templateData.definitionTemplates.deploymentTemplateFileUrls)
    .filter(function (url) { return utils.ignoreCaseEquals(key, url); });

  if (urls.length === 0) {
    throw new Error($('Error in template, the key %s is not found in deploymentTemplateFileUrls'));
  }

  return templateData.definitionTemplates.deploymentTemplateFileUrls[urls[0]];
};

exports.getAllEvents = function (subscription, groupName) {
  var output = through();
  var client = utils.createEventsClient(subscription);

  client.eventData.listEventsForResourceGroup({
    resourceGroupName: groupName,
    startTime: new Date(Date.now() - eventRetentionPeriodMS),
    endTime: new Date()
  }, function (err, response) {
    if (err) {
      return output.emit('error', err);
    }

    response.eventDataCollection.value.forEach(function (e) {
      output.queue(e);
    });
    output.end();
  });
  return output;
};

exports.getDeploymentLog = function (subscription, name, deploymentName) {
  var output = through();
  var client = utils.createResourceClient(subscription);

  client.deployments.get(name, deploymentName, function (err, result) {
    if (err) {
      return output.emit('error', err);
    }
    getDeploymentLogs(subscription, result.deployment.properties.correlationId).pipe(output);
  });
  return output;
};

exports.getLastDeploymentLog = function (subscription, name) {
  var output = through();
  var client = utils.createResourceClient(subscription);

  client.deployments.list(name, { top: 1 }, function (err, response) {
    if (err) { return output.emit('error', err); }
    if (response.deployments.length === 0) {
      output.emit('error', new Error($('Deployment not found')));
    }
    getDeploymentLogs(subscription, response.deployments[0].properties.correlationId).pipe(output);
  });
  return output;
};

exports.normalizeDownloadFileName = function normalizeDownloadFileName(name, file, quiet, confirmer, callback) {
  name = name + '.json';
  var downloadFile = path.resolve(file || name);

  function ensureDirExists(dirname) {
    if (!dirname) {
      return;
    }

    if (utils.pathExistsSync(dirname)) {
      if (!fs.statSync(dirname).isDirectory()) {
        throw new Error(util.format($('Path %s already exists and is not a directory.'), dirname));
      }
      return;
    }

    ensureDirExists(path.dirname(dirname));

    fs.mkdirSync(dirname);
  }

  function normalizeFile() {
    try {
      ensureDirExists(path.dirname(downloadFile));
      if (utils.pathExistsSync(downloadFile) && !quiet) {
        confirmer(
          util.format($('The file %s already exists. Overwrite? [y/n]: '), downloadFile),
            function (confirmed) {
              if (confirmed) {
                callback(null, downloadFile);
              } else {
                callback(null, null);
              }
            }
        );
      } else {
        callback(null, downloadFile);
      }
    } catch (ex) {
      callback(ex);
    }
  }

  function normalizeDirectory() {
    downloadFile = path.join(downloadFile, name);
    normalizeFile();
  }

  if (utils.pathExistsSync(downloadFile) && fs.statSync(downloadFile).isDirectory()) {
    normalizeDirectory();
  } else {
    normalizeFile();
  }
};

exports.warnOnUsingStorage = function (options, log) {
  if (options.storageAccount) {
    log.warn($('Storage account parameter is not used anymore and will be removed soon in a future release.'));
  }
};

function createDeploymentParameters(cli, subscription, resourceGroup, options, _) {
  var templateOptions = [options.galleryTemplate, options.templateFile, options.templateUri];
  var templateOptionsProvided = templateOptions.filter(function (value) { return value !== undefined; }).length;
  if (templateOptionsProvided > 1) {
    throw new Error($('Specify exactly one of the --gallery-template, --template-file, or template-uri options.'));
  } else if (templateOptionsProvided === 0) {
    throw new Error($('One of the --gallery-template, --template-file, or --template-uri options is required.'));
  }

  if (options.parameters && options.parametersFile) {
    throw new Error($('Either --parameters or --parameters-file need to be specified. Not both.'));
  }

  var deploymentParameters;
  if (options.parametersFile) {
    var jsonFile = fs.readFileSync(options.parametersFile, 'utf8');
    deploymentParameters = JSON.parse(utils.stripBOM(jsonFile));
  } else if (options.parameters) {
    deploymentParameters = JSON.parse(options.parameters);
  } else {
    var log = cli.output;
    log.info('Supply values for the following parameters');
    var paramsRequired = getTemplateParams(cli, subscription, options, _);
    deploymentParameters = {};

    Object.keys(paramsRequired).forEach_(_, 1, function (_, key) {
      var val = {};
      val['value'] = paramsRequired[key];
      deploymentParameters[key] = val;
    });

  }

  var templateParameters = {};
  templateParameters['properties'] = { mode: 'Incremental' };
  cli.interaction.withProgress($('Initializing template configurations and parameters'),
    function (log, _) {

      var templateUri = options.templateUri;
      if (!templateUri) {
        var templateContent = getTemplateContent(subscription,
           options.templateFile,
           options.galleryTemplate,
           _);
        templateParameters['properties']['template'] = templateContent;
      } else {
        templateParameters['properties']['templateLink'] = { uri: templateUri };
        if (options.templateVersion) {
          templateParameters.properties.templateLink.contentVersion = options.templateVersion;
        }
      }

      if (deploymentParameters) {
        templateParameters.properties.parameters = deploymentParameters;
      }

    }, _);
  return templateParameters;
}

var eventRetentionPeriodMS = 89 * 24 * 60 * 60 * 1000; // 89 days in milliseconds

function getDeploymentLogs(subscription, correlationId) {
  var output = through();
  var client = utils.createEventsClient(subscription);
  client.eventData.listEventsForCorrelationId({
    correlationId: correlationId,
    startTime: new Date(Date.now() - eventRetentionPeriodMS),
    endTime: new Date()
  }, function (err, response) {
    if (err) {
      return output.emit('error', err);
    }
    response.eventDataCollection.value.forEach(function (e) {
      output.queue(e);
    });
    output.end();
  });
  return output;
}

function getTemplateProviders(validationResponse) {
  return __.map(validationResponse.properties.providers, function (provider) {
    return provider.namespace.toLowerCase();
  });
}

function getTemplateContent(subscription, templateFile, galleryTemplateName, _) {
  function readTemplateFileContentFromUri(templateFileUri, callback) {
    request(templateFileUri, function (error, response, body) {
      callback(error, body);//need to filter on some errors?
    });
  }

  var templateFileUri;
  if (templateFile) {
    if (validation.isURL(templateFile)) {
      templateFileUri = templateFile;
    }
  } else if (galleryTemplateName) {
    templateFileUri = exports.getGalleryTemplateFile(subscription, galleryTemplateName, _);
  }

  var content = {};
  if (templateFileUri) {
    content = readTemplateFileContentFromUri(templateFileUri, _);
  } else if (templateFile) {
    content = utils.stripBOM(fs.readFileSync(templateFile));
  }

  return JSON.parse(content);
}

function getTemplateParams(cli, subscription, options, _)
{
  var templateContent = options.templateFile ?
    getTemplateContent(subscription, options.templateFile, options.galleryTemplate, _) :
    getTemplateContent(subscription, options.templateUri, options.galleryTemplate, _);

  var paramKeys = {};

  Object.keys(templateContent.parameters).forEach_(_, 1, function (_, param) {
    paramKeys[param] = templateContent.parameters[param].defaultValue;
    if (!templateContent.parameters[param].defaultValue) {
      paramKeys[param] = cli.interaction.promptIfNotGiven(param + ': ', paramKeys[param], _);
      switch (templateContent.parameters[param].type.toLowerCase()) {
        case 'int':
          paramKeys[param] = utils.parseInt(paramKeys[param]);
          break;

        case 'object':
        case 'bool':
        case 'array':
          paramKeys[param] = JSON.parse(paramKeys[param]);
          break;
      }
    }
  });

  return paramKeys;
}
<commit_msg>Remove auto-register when creating deployments<commit_after>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

var __ = require('underscore');
var fs = require('fs');
var path = require('path');
var request = require('request');
var through = require('through');
var util = require('util');

var validation = require('../../../util/validation');
var profile = require('../../../util/profile');
var utils = require('../../../util/utils');

var $ = utils.getLocaleString;

exports.getGroup = function getGroup(client, name, callback) {
  client.resourceGroups.get(name, function (err, group) {
    if (err) {
      // 404 means doesn't exist
      if (err.statusCode === 404) {
        callback(null, null);
      } else {
        // some other error, let it out
        callback(err);
      }
    } else {
      // No error, group exists
      callback(null, group.resourceGroup);
    }
  });
};

exports.getResource = function getResource(client, resourceGroup, identity, callback) {
  client.resources.get(resourceGroup, identity, function (err, resource) {
    if (err) {
      // 404 means doesn't exist
      if (err.statusCode === 404) {
        callback(null, null);
      } else {
        // some other error, let it out
        callback(err);
      }
    } else {
      // No error, resource exists
      callback(null, resource.resource);
    }
  });
};

exports.createDeployment = function (cli, resourceGroup, name, options, _) {
  var subscription = profile.current.getSubscription(options.subscription);
  var client = utils.createResourceClient(subscription);

  var templateParameters = createDeploymentParameters(cli, subscription, resourceGroup, options, _);

  //if not provided, derive it from the template file name
  if (!name) {
    var templateName = options.galleryTemplate || options.templateFile || options.templateUri;
    var baseTemplateName = path.basename(templateName);
    //if the file extension is '.json', get rid of it.
    if (utils.stringEndsWith(baseTemplateName, '.json', true)) {
      baseTemplateName = path.basename(baseTemplateName, path.extname(baseTemplateName));
    }
    name = baseTemplateName;
  }

  var result = cli.interaction.withProgress($('Creating a deployment'),
    function (log, _) {
      var validationResponse = client.deployments.validate(resourceGroup, name, templateParameters, _);
      var createResponse = client.deployments.createOrUpdate(resourceGroup, name, templateParameters, _);
      return createResponse;
    }, _);

  cli.output.info(util.format($('Created template deployment "%s"'), name));

  return result.deployment;

};

exports.validateTemplate = function (cli, resourceGroup, options, _) {
  var subscription = profile.current.getSubscription(options.subscription);
  var client = utils.createResourceClient(subscription);

  var templateParameters = createDeploymentParameters(cli, subscription, resourceGroup, options, _);

  var response = cli.interaction.withProgress($('Validating the template'),
    function (log, _) {
      return client.deployments.validate(resourceGroup, 'fakedDeploymentName', templateParameters, _);
    }, _);

  response.requiredProviders = getTemplateProviders(response);

  return response;
};

exports.getGalleryTemplateFile = function (subscription, galleryTemplateName, _) {
  var galleryClient = utils.createGalleryClient(subscription);
  var galleryItem = galleryClient.items.get(galleryTemplateName, _).item;
  return exports.getTemplateDownloadUrl(galleryItem);
};

exports.getTemplateDownloadUrl = function getTemplateDownloadUrl(templateData) {
  var key = templateData.definitionTemplates.defaultDeploymentTemplateId;
  var urls = Object.keys(templateData.definitionTemplates.deploymentTemplateFileUrls)
    .filter(function (url) { return utils.ignoreCaseEquals(key, url); });

  if (urls.length === 0) {
    throw new Error($('Error in template, the key %s is not found in deploymentTemplateFileUrls'));
  }

  return templateData.definitionTemplates.deploymentTemplateFileUrls[urls[0]];
};

exports.getAllEvents = function (subscription, groupName) {
  var output = through();
  var client = utils.createEventsClient(subscription);

  client.eventData.listEventsForResourceGroup({
    resourceGroupName: groupName,
    startTime: new Date(Date.now() - eventRetentionPeriodMS),
    endTime: new Date()
  }, function (err, response) {
    if (err) {
      return output.emit('error', err);
    }

    response.eventDataCollection.value.forEach(function (e) {
      output.queue(e);
    });
    output.end();
  });
  return output;
};

exports.getDeploymentLog = function (subscription, name, deploymentName) {
  var output = through();
  var client = utils.createResourceClient(subscription);

  client.deployments.get(name, deploymentName, function (err, result) {
    if (err) {
      return output.emit('error', err);
    }
    getDeploymentLogs(subscription, result.deployment.properties.correlationId).pipe(output);
  });
  return output;
};

exports.getLastDeploymentLog = function (subscription, name) {
  var output = through();
  var client = utils.createResourceClient(subscription);

  client.deployments.list(name, { top: 1 }, function (err, response) {
    if (err) { return output.emit('error', err); }
    if (response.deployments.length === 0) {
      output.emit('error', new Error($('Deployment not found')));
    }
    getDeploymentLogs(subscription, response.deployments[0].properties.correlationId).pipe(output);
  });
  return output;
};

exports.normalizeDownloadFileName = function normalizeDownloadFileName(name, file, quiet, confirmer, callback) {
  name = name + '.json';
  var downloadFile = path.resolve(file || name);

  function ensureDirExists(dirname) {
    if (!dirname) {
      return;
    }

    if (utils.pathExistsSync(dirname)) {
      if (!fs.statSync(dirname).isDirectory()) {
        throw new Error(util.format($('Path %s already exists and is not a directory.'), dirname));
      }
      return;
    }

    ensureDirExists(path.dirname(dirname));

    fs.mkdirSync(dirname);
  }

  function normalizeFile() {
    try {
      ensureDirExists(path.dirname(downloadFile));
      if (utils.pathExistsSync(downloadFile) && !quiet) {
        confirmer(
          util.format($('The file %s already exists. Overwrite? [y/n]: '), downloadFile),
            function (confirmed) {
              if (confirmed) {
                callback(null, downloadFile);
              } else {
                callback(null, null);
              }
            }
        );
      } else {
        callback(null, downloadFile);
      }
    } catch (ex) {
      callback(ex);
    }
  }

  function normalizeDirectory() {
    downloadFile = path.join(downloadFile, name);
    normalizeFile();
  }

  if (utils.pathExistsSync(downloadFile) && fs.statSync(downloadFile).isDirectory()) {
    normalizeDirectory();
  } else {
    normalizeFile();
  }
};

exports.warnOnUsingStorage = function (options, log) {
  if (options.storageAccount) {
    log.warn($('Storage account parameter is not used anymore and will be removed soon in a future release.'));
  }
};

function createDeploymentParameters(cli, subscription, resourceGroup, options, _) {
  var templateOptions = [options.galleryTemplate, options.templateFile, options.templateUri];
  var templateOptionsProvided = templateOptions.filter(function (value) { return value !== undefined; }).length;
  if (templateOptionsProvided > 1) {
    throw new Error($('Specify exactly one of the --gallery-template, --template-file, or template-uri options.'));
  } else if (templateOptionsProvided === 0) {
    throw new Error($('One of the --gallery-template, --template-file, or --template-uri options is required.'));
  }

  if (options.parameters && options.parametersFile) {
    throw new Error($('Either --parameters or --parameters-file need to be specified. Not both.'));
  }

  var deploymentParameters;
  if (options.parametersFile) {
    var jsonFile = fs.readFileSync(options.parametersFile, 'utf8');
    deploymentParameters = JSON.parse(utils.stripBOM(jsonFile));
  } else if (options.parameters) {
    deploymentParameters = JSON.parse(options.parameters);
  } else {
    var log = cli.output;
    log.info('Supply values for the following parameters');
    var paramsRequired = getTemplateParams(cli, subscription, options, _);
    deploymentParameters = {};

    Object.keys(paramsRequired).forEach_(_, 1, function (_, key) {
      var val = {};
      val['value'] = paramsRequired[key];
      deploymentParameters[key] = val;
    });

  }

  var templateParameters = {};
  templateParameters['properties'] = { mode: 'Incremental' };
  cli.interaction.withProgress($('Initializing template configurations and parameters'),
    function (log, _) {

      var templateUri = options.templateUri;
      if (!templateUri) {
        var templateContent = getTemplateContent(subscription,
           options.templateFile,
           options.galleryTemplate,
           _);
        templateParameters['properties']['template'] = templateContent;
      } else {
        templateParameters['properties']['templateLink'] = { uri: templateUri };
        if (options.templateVersion) {
          templateParameters.properties.templateLink.contentVersion = options.templateVersion;
        }
      }

      if (deploymentParameters) {
        templateParameters.properties.parameters = deploymentParameters;
      }

    }, _);
  return templateParameters;
}

var eventRetentionPeriodMS = 89 * 24 * 60 * 60 * 1000; // 89 days in milliseconds

function getDeploymentLogs(subscription, correlationId) {
  var output = through();
  var client = utils.createEventsClient(subscription);
  client.eventData.listEventsForCorrelationId({
    correlationId: correlationId,
    startTime: new Date(Date.now() - eventRetentionPeriodMS),
    endTime: new Date()
  }, function (err, response) {
    if (err) {
      return output.emit('error', err);
    }
    response.eventDataCollection.value.forEach(function (e) {
      output.queue(e);
    });
    output.end();
  });
  return output;
}

function getTemplateProviders(validationResponse) {
  return __.map(validationResponse.properties.providers, function (provider) {
    return provider.namespace.toLowerCase();
  });
}

function getTemplateContent(subscription, templateFile, galleryTemplateName, _) {
  function readTemplateFileContentFromUri(templateFileUri, callback) {
    request(templateFileUri, function (error, response, body) {
      callback(error, body);//need to filter on some errors?
    });
  }

  var templateFileUri;
  if (templateFile) {
    if (validation.isURL(templateFile)) {
      templateFileUri = templateFile;
    }
  } else if (galleryTemplateName) {
    templateFileUri = exports.getGalleryTemplateFile(subscription, galleryTemplateName, _);
  }

  var content = {};
  if (templateFileUri) {
    content = readTemplateFileContentFromUri(templateFileUri, _);
  } else if (templateFile) {
    content = utils.stripBOM(fs.readFileSync(templateFile));
  }

  return JSON.parse(content);
}

function getTemplateParams(cli, subscription, options, _)
{
  var templateContent = options.templateFile ?
    getTemplateContent(subscription, options.templateFile, options.galleryTemplate, _) :
    getTemplateContent(subscription, options.templateUri, options.galleryTemplate, _);

  var paramKeys = {};

  Object.keys(templateContent.parameters).forEach_(_, 1, function (_, param) {
    paramKeys[param] = templateContent.parameters[param].defaultValue;
    if (!templateContent.parameters[param].defaultValue) {
      paramKeys[param] = cli.interaction.promptIfNotGiven(param + ': ', paramKeys[param], _);
      switch (templateContent.parameters[param].type.toLowerCase()) {
        case 'int':
          paramKeys[param] = utils.parseInt(paramKeys[param]);
          break;

        case 'object':
        case 'bool':
        case 'array':
          paramKeys[param] = JSON.parse(paramKeys[param]);
          break;
      }
    }
  });

  return paramKeys;
}
<|endoftext|>


<commit_before>/**
@ngdoc directive
@restrict E
@name bp.directive:bpNavbar
@requires bp.util.bpApp
@requires bp.util.bpView
@requires bp.directive:bpToolbar
@requires bp.directive:bpActionOverflow
@param {boolean=} bp-navbar-no-up Don't show the default up button from the state (false).
@param {string=} bp-navbar-title The title of the navbar. Defaults to the current state's title.
@example

  <bp-navbar bp-navbar-title="Hello World" bp-navbar-no-up>
    <bp-action class="icon-cross">Cancel</bp-action>
    <bp-action class="icon-checkmark">Save</bp-action>
  </bp-navbar>

@description `bpNavbar` is the beating heart of Bradypodion as it provides the structure for your application.

The navbar tries to fill itself with the right information based on the context of the current state.

  The {@link bp.directive:bpNavigation `bpNavigation`} directive offers a convenient way to inject navbars in all of your screens automatically.

## Title
Based on [ui.router's](http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state)
`$state.current` the `bp-navbar-title` is filled with `state.data.title` or `state.name` (First letter capitalized).

If you want to define a custom Title for the navbar just assign any string to the `bp-navbar-title` attribute.
If you don’t want any title at all just assign an empty string.

## Up Button

  "Up" Button should be more familiar to iOS developers as "Back" button,
  but it's named "Up" throughout the framework to maintain a consistent and semantically correct naming for all platforms.

The navbar automatically injects an up button for you. The state information is either taken directly from `$state.data.up` or read from the URL of the state.
If the URL of the current state is `/customers/:id` and `customers` is a valid state name then this will be the up button's target.
The up button's label is determined in the same way as the navbar's title.

## Actions

{@link bp.directive:bpAction `bpAction`}s are (currently) the only supported content within a navbar.
They are automatically processed to be icons on android and buttons on ios.
You can however force an action to be an icon on ios by adding the `bp-icon` CSS class.

### Action Overflow

The navbar offers space for two actions on both ios and android.
If you define more than those two actions on ios the navbar will automatically spawn a {@link bp.directive:bpToolbar `bpToolbar`} for you.
On android it will create a {@link bp.directive:bpActionOverflow `bpActionOverflow`} menu for you.

  On ios the injected up button counts against the action limit.
  So in most cases, unless you decide to set `bp-navbar-no-up` to true, there is space for one action.

*/

angular.module('bp')
  .directive('bpNavbar', function(
    bpApp,
    bpView,
    $timeout,
    $state,
    $compile,
    $log) {

  return {
    restrict: 'E',
    transclude: true,
    controller: function() {
      this.getTitleFromState = function(state) {
        if (angular.isObject(state.data) &&
          angular.isString(state.data.title)) {

          return state.data.title
        } else {
          return state.name.charAt(0).toUpperCase() + state.name.slice(1)
        }
      }
      this.convertActionToIcon = function($action) {
        if (angular.isElement($action)) {
          $action
            .attr('aria-label', $action.text())
            .text('')
            .removeClass('bp-button')
            .addClass('bp-icon')
        }
      }
    },
    compile: function(elem, attrs, transcludeFn) {
      var ios = bpApp.platform === 'android' ? false : true

      return function(scope, element, attrs, ctrl) {
        var state = $state.current
        element.attr('role', 'navigation')

        transcludeFn(scope, function(clone) {
          var $arrow, $frstAction, $scndAction, $toolbar, $up, title

          if (angular.isUndefined(attrs.bpNavbarTitle)) {
            title = ctrl.getTitleFromState(state)
          } else {
            title = attrs.bpNavbarTitle
          }

          var $title = $compile(angular.element('<bp-navbar-title>')
            .attr('role', 'heading')
            .text(title)
            )(scope)

          var $actions = clone.filter('bp-action')

          var up

          if (angular.isObject(state.data) &&
            angular.isString(state.data.up)) {
            up = state.data.up
          } else if (state.url) {
            var urlSegments = bpView._getURLSegments(state)
            up = urlSegments[urlSegments.length - 2]
          }

          if (up && !angular.isDefined(attrs.bpNavbarNoUp)) {

            var ref = bpView.parseState(up)
            var upState = $state.get(ref.state)
            if (upState) {
              var upTitle = ctrl.getTitleFromState(upState)
              $arrow = angular.element('<bp-button-up>')
              $up = $compile(angular.element('<bp-action>')
                .addClass('bp-action-up')
                .attr('bp-sref', up)
                .text(upTitle))(scope)
            } else {
              $log.error('up state detection failed. No up button compiled. Check your state configuration.')
            }
          }

          if (ios) {
            if ($actions.length > 2) {
              if (angular.isElement($up)) {
                $frstAction = $up.addClass('bp-button')
              }

              $actions.each(function() {
                ctrl.convertActionToIcon(angular.element(this))
              })
              $toolbar = angular.element('<bp-toolbar>').append($actions)
            } else {
              if (angular.isElement($up)) {
                $actions = $up.add($actions)
              }
              $frstAction = $actions.eq(0)
              $scndAction = $actions.eq(1)

              $actions.each(function() {
                var $action = angular.element(this)
                if ($action.hasClass('bp-icon')) {
                  ctrl.convertActionToIcon($action)
                } else {
                  $action.addClass('bp-button')
                }
              })
            }

            element
              .append($frstAction, $title, $scndAction, $arrow)
              .after($toolbar)

            if (angular.isElement($toolbar)) {
              element.on('$destroy', function() {
                $toolbar.remove()
              })
            }

            if (!scope.navbarTitle) {
              $timeout(function() {
                var frstW = angular.isElement($scndAction) ? $scndAction.outerWidth() : 0
                var scndW = angular.isElement($frstAction) ? $frstAction.outerWidth() : 0
                var diff  = frstW - scndW

                if (diff !== 0 && $frstAction.length) {
                  angular.element('
').css({
                      '-webkit-box-flex': '10',
                      'max-width': Math.abs(diff)
                    })[diff > 0 ? 'insertBefore' : 'insertAfter']($title)
                }
              }, 0, false)
            }
          } else {
            var $icon = angular.element('<bp-navbar-icon>')

            $frstAction = $actions.eq(0)
            $scndAction = $actions.eq(1)
            ctrl.convertActionToIcon($frstAction)
            ctrl.convertActionToIcon($scndAction)
            ctrl.convertActionToIcon($up)

            if ($actions.length > 2) {
              $toolbar = $compile(angular.element('<bp-action-overflow>')
                .append($actions.not($frstAction).not($scndAction)))(scope)
            }

            if (angular.isElement($up)) {
              $up.append('
', $icon)
              element.append($up, $title, $frstAction, $scndAction, $toolbar)
            } else {
              element.append($icon, $title, $frstAction, $scndAction, $toolbar)
            }
          }
        })
      }
    }
  }
})
<commit_msg>fix(navbar): log error when param in state url<commit_after>/**
@ngdoc directive
@restrict E
@name bp.directive:bpNavbar
@requires bp.util.bpApp
@requires bp.util.bpView
@requires bp.directive:bpToolbar
@requires bp.directive:bpActionOverflow
@param {boolean=} bp-navbar-no-up Don't show the default up button from the state (false).
@param {string=} bp-navbar-title The title of the navbar. Defaults to the current state's title.
@example

  <bp-navbar bp-navbar-title="Hello World" bp-navbar-no-up>
    <bp-action class="icon-cross">Cancel</bp-action>
    <bp-action class="icon-checkmark">Save</bp-action>
  </bp-navbar>

@description `bpNavbar` is the beating heart of Bradypodion as it provides the structure for your application.

The navbar tries to fill itself with the right information based on the context of the current state.

  The {@link bp.directive:bpNavigation `bpNavigation`} directive offers a convenient way to inject navbars in all of your screens automatically.

## Title
Based on [ui.router's](http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state)
`$state.current` the `bp-navbar-title` is filled with `state.data.title` or `state.name` (First letter capitalized).

If you want to define a custom Title for the navbar just assign any string to the `bp-navbar-title` attribute.
If you don’t want any title at all just assign an empty string.

## Up Button

  "Up" Button should be more familiar to iOS developers as "Back" button,
  but it's named "Up" throughout the framework to maintain a consistent and semantically correct naming for all platforms.

The navbar automatically injects an up button for you. The state information is either taken directly from `$state.data.up` or read from the URL of the state.
If the URL of the current state is `/customers/:id` and `customers` is a valid state name then this will be the up button's target.
The up button's label is determined in the same way as the navbar's title.

## Actions

{@link bp.directive:bpAction `bpAction`}s are (currently) the only supported content within a navbar.
They are automatically processed to be icons on android and buttons on ios.
You can however force an action to be an icon on ios by adding the `bp-icon` CSS class.

### Action Overflow

The navbar offers space for two actions on both ios and android.
If you define more than those two actions on ios the navbar will automatically spawn a {@link bp.directive:bpToolbar `bpToolbar`} for you.
On android it will create a {@link bp.directive:bpActionOverflow `bpActionOverflow`} menu for you.

  On ios the injected up button counts against the action limit.
  So in most cases, unless you decide to set `bp-navbar-no-up` to true, there is space for one action.

*/

angular.module('bp')
  .directive('bpNavbar', function(
    bpApp,
    bpView,
    $timeout,
    $state,
    $compile,
    $log) {

  return {
    restrict: 'E',
    transclude: true,
    controller: function() {
      this.getTitleFromState = function(state) {
        if (angular.isObject(state.data) &&
          angular.isString(state.data.title)) {

          return state.data.title
        } else {
          return state.name.charAt(0).toUpperCase() + state.name.slice(1)
        }
      }
      this.convertActionToIcon = function($action) {
        if (angular.isElement($action)) {
          $action
            .attr('aria-label', $action.text())
            .text('')
            .removeClass('bp-button')
            .addClass('bp-icon')
        }
      }
    },
    compile: function(elem, attrs, transcludeFn) {
      var ios = bpApp.platform === 'android' ? false : true

      return function(scope, element, attrs, ctrl) {
        var state = $state.current
        element.attr('role', 'navigation')

        transcludeFn(scope, function(clone) {
          var $arrow, $frstAction, $scndAction, $toolbar, $up, title

          if (angular.isUndefined(attrs.bpNavbarTitle)) {
            title = ctrl.getTitleFromState(state)
          } else {
            title = attrs.bpNavbarTitle
          }

          var $title = $compile(angular.element('<bp-navbar-title>')
            .attr('role', 'heading')
            .text(title)
            )(scope)

          var $actions = clone.filter('bp-action')

          var up

          if (angular.isObject(state.data) &&
            angular.isString(state.data.up)) {
            up = state.data.up
          } else if (state.url) {
            var urlSegments = bpView._getURLSegments(state)
            up = urlSegments[urlSegments.length - 2]
          }

          if (up && up[0] == ':') {
            $log.error('cannot detect up state from parameter. Please set the up property on the data object in your state configuration.')
          }

          if (up && up[0] !== ':' && !angular.isDefined(attrs.bpNavbarNoUp)) {
            var ref = bpView.parseState(up)
            var upState = $state.get(ref.state)
            if (upState) {
              var upTitle = ctrl.getTitleFromState(upState)
              $arrow = angular.element('<bp-button-up>')
              $up = $compile(angular.element('<bp-action>')
                .addClass('bp-action-up')
                .attr('bp-sref', up)
                .text(upTitle))(scope)
            } else {
              $log.error('up state detection failed. No up button compiled. Check your state configuration.')
            }
          }

          if (ios) {
            if ($actions.length > 2) {
              if (angular.isElement($up)) {
                $frstAction = $up.addClass('bp-button')
              }

              $actions.each(function() {
                ctrl.convertActionToIcon(angular.element(this))
              })
              $toolbar = angular.element('<bp-toolbar>').append($actions)
            } else {
              if (angular.isElement($up)) {
                $actions = $up.add($actions)
              }
              $frstAction = $actions.eq(0)
              $scndAction = $actions.eq(1)

              $actions.each(function() {
                var $action = angular.element(this)
                if ($action.hasClass('bp-icon')) {
                  ctrl.convertActionToIcon($action)
                } else {
                  $action.addClass('bp-button')
                }
              })
            }

            element
              .append($frstAction, $title, $scndAction, $arrow)
              .after($toolbar)

            if (angular.isElement($toolbar)) {
              element.on('$destroy', function() {
                $toolbar.remove()
              })
            }

            if (!scope.navbarTitle) {
              $timeout(function() {
                var frstW = angular.isElement($scndAction) ? $scndAction.outerWidth() : 0
                var scndW = angular.isElement($frstAction) ? $frstAction.outerWidth() : 0
                var diff  = frstW - scndW

                if (diff !== 0 && $frstAction.length) {
                  angular.element('
').css({
                      '-webkit-box-flex': '10',
                      'max-width': Math.abs(diff)
                    })[diff > 0 ? 'insertBefore' : 'insertAfter']($title)
                }
              }, 0, false)
            }
          } else {
            var $icon = angular.element('<bp-navbar-icon>')

            $frstAction = $actions.eq(0)
            $scndAction = $actions.eq(1)
            ctrl.convertActionToIcon($frstAction)
            ctrl.convertActionToIcon($scndAction)
            ctrl.convertActionToIcon($up)

            if ($actions.length > 2) {
              $toolbar = $compile(angular.element('<bp-action-overflow>')
                .append($actions.not($frstAction).not($scndAction)))(scope)
            }

            if (angular.isElement($up)) {
              $up.append('
', $icon)
              element.append($up, $title, $frstAction, $scndAction, $toolbar)
            } else {
              element.append($icon, $title, $frstAction, $scndAction, $toolbar)
            }
          }
        })
      }
    }
  }
})
<|endoftext|>


<commit_before>var Topic = require('../db/dbconfig').Topic;

module.exports = {
  getAllTopics: function (req, res) {
    Topic.findAll({})
    .then(function (topics) {
      res.status(200).json(topics);
    })
    .catch(function (err) {
      console.error(err);
    });
  },

  findOrCreateTopic: function (req, res) {
    var topicData = {
      name: req.body.name
    };
    Topic.findOrCreate({where: topicData})
    .then(function (topic) {
      res.status(201).json(topic);
    })
    .catch(function (err) {
      console.error (err);
    });
  },

  getTopicByName: function (req, res) {
    var topicName = req.params.topicName;
    Topic.find({
      where: {name: topicName}
    })
    .then(function (topic) {
      res.status(200).json(topic);
    })
    .catch(function (err) {
      console.error (err);
    });
  },

  deleteTopic: function (req, res) {
    var topicName = req.params.topicName;
    Topic.destroy({
      where: {name: topicName}
    })
    .then(function () {
      res.status(201);
    })
    .catch(function (err) {
      console.error (err);
    });
  },
};
<commit_msg>(feat) Force topic name to all uppercase string<commit_after>var Topic = require('../db/dbconfig').Topic;

module.exports = {
  getAllTopics: function (req, res) {
    Topic.findAll({})
    .then(function (topics) {
      res.status(200).json(topics);
    })
    .catch(function (err) {
      console.error(err);
    });
  },

  findOrCreateTopic: function (req, res) {
    var topicData = {
      name: req.body.name.toUpperCase()
    };
    Topic.findOrCreate({where: topicData})
    .then(function (topic) {
      res.status(201).json(topic);
    })
    .catch(function (err) {
      console.error (err);
    });
  },

  getTopicByName: function (req, res) {
    var topicName = req.params.topicName;
    Topic.find({
      where: {name: topicName}
    })
    .then(function (topic) {
      res.status(200).json(topic);
    })
    .catch(function (err) {
      console.error (err);
    });
  },

  deleteTopic: function (req, res) {
    var topicName = req.params.topicName;
    Topic.destroy({
      where: {name: topicName}
    })
    .then(function () {
      res.status(201);
    })
    .catch(function (err) {
      console.error (err);
    });
  },
};
<|endoftext|>


<commit_before>const random = require('random-js')();
const {
  INPUT, OUTPUT, HOUSE, DB
} = require('../word');

async function getAllHouseScores(originalMessage, callback) {
  const channel = await this.slackBot.getChannelById(originalMessage.channel);

  this.slackBot.postMessageToChannel(channel.name, 'The House Points are: \n', { as_user: true }, () => {
    Object.values(HOUSE).forEach(house => {
      this.getPointsFromDatabase.call(this, originalMessage, house, callback);
    });
  });
}

async function resetTheScores(originalMessage) {
  const channel = await this.slackBot.getChannelById(originalMessage.channel);
  Object.values(HOUSE).forEach(h => {
    const house = new Parse.Object(DB.HOUSE.CALL);
    house.save({ name: h, val: 0 });
  });
  this.slackBot.postMessageToChannel(channel.name, OUTPUT.RESET_SCORE);
}

function welcomeMessageManual(originalMessage) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.SAY_HELLO);
}

// Slacks API converts an @username reference in a message to the userid this converts it back to username.
async function convertToUserName(key) {
  const users = await this.slackBot.getUsers();
  return users.find((userid) => {
    if (userid.id === key || userid.name === key) {
      return userid.name;
    }
    return false;
  });
}

function greetNewStudent(originalMessage, student, house) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.canIJoin(student, house));
}

function addStudentToHouse(originalMessage, house) {
  // const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];
  const student = originalMessage.user;
  const studentUsername = convertToUserName(student);
  let notAlreadyStudent = true;
  const text = originalMessage.text.toLowerCase();

  this.db.all('SELECT * FROM students', (err, respond) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    if (respond !== undefined) {
      respond.find((dbUser) => {
        if (dbUser.user_id === student) {
          // this.slackBot.announcePlainString(originalMessage, studentUsername + ' You are already in a house. Once You have been sorted in that house you shall remain. But fear not, if you give it a chance you will see there is much to gain.', bot);
          notAlreadyStudent = false;
          return true;
        }
        return false;
      });
    }
    if (notAlreadyStudent === true) {
      // current not allow multiple house since callback return true
      Object.values(HOUSE).filter(t => text.includes(t) || house === t).some(v => {
        this.db.run('INSERT INTO students (user_id, username, house) VALUES (?, ?, ?)', student, studentUsername, v, (_err) => {
          if (_err) {
            return console.error('DATABASE ERROR', _err);
          }
          greetNewStudent(originalMessage, studentUsername, v);
        });
        return true;
      });
    }
  });
}

function rollTheDice(originalMessage) {
  const house = random.integer(0, 3);

  addStudentToHouse.call(this, originalMessage, Object.values(HOUSE)[house], null);
}

async function obliviate(originalMessage) {
  const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];
  const channel = await this.slackBot.getChannelById(originalMessage.channel);
  const query = new Parse.Query(DB.STUDENT.CALL);

  if (student === convertToUserName(originalMessage.user)) {
    query.equalTo('user_id','');
    query.find().then(function(results) {
        return Parse.Object.destroyAll(results);
    }).then(function() {
        // Done
    }, function(error) {
        // Error
    });
    this.slackBot.postMessageToChannel(channel.name, OUTPUT.OBLIVIATE);
    }
  }

function studentStats(originalMessage) {
  const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];

  if (convertToUserName(student) !== 'dumbledore') {
    this.db.get('SELECT * FROM students WHERE user_id = ?', student, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.student(record));
      } else {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.NOT_FOUND);
      }
    });
  } else {
    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.DUMBLEDORE);
  }
}

function bestStudent(originalMessage) {
  Object.values(HOUSE).forEach((house) => {
    this.db.get('SELECT * FROM students WHERE house = ? ORDER BY points_earned DESC', house, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.getBestStudent(record));
      }
    });
  });
  this.slackBot.announcePlainString(originalMessage, OUTPUT.ABOUT_FROGS);
}

function worstStudent(originalMessage) {
  Object.values(HOUSE).forEach((house) => {
    this.db.get('SELECT * FROM students WHERE house = ? ORDER BY points_taken DESC', house, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.getMeanestStudent(record));
      }
    });
  });
}

function getAllStudentsFromHouse(originalMessage, house) {
  this.db.all('SELECT * FROM students WHERE house = ? ', house, (err, record) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }

    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.fromHouse(house, record));
  });
}

function tellMeAbout(originalMessage, house) {
  const text = originalMessage.text.toLowerCase();

  if (text.includes('@')) {
    studentStats.call(this, originalMessage);
  } else if (house) {
    getAllStudentsFromHouse.call(this, originalMessage, house);
  } else if (text.includes(INPUT.PROFESSOR.JASON_MOM)) {
    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.JASON_MOM);
  }
}

function getAllStudents(originalMessage) {
  this.db.all('SELECT * FROM students', (err) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    Object.values(HOUSE).forEach((house) => {
      getAllStudentsFromHouse.call(this, originalMessage, house);
    });
  });
}

function explainSorting(originalMessage) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.START_SORTING);
}

function saveGitName(originalMessage) {
  const gitName = originalMessage.text.split('=')[1];
  const { user } = originalMessage;

  this.db.run('UPDATE students SET github_name = ? WHERE user_id = ?', gitName, user, (err) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    this.slackBot.announcePlainString(originalMessage, OUTPUT.saveGitName(convertToUserName(user), gitName));
  });
}

async function forceSortRemaining(originalMessage) {
  const users = await this.slackBot.getUsers();

  users.members.forEach((user) => {
    originalMessage.user = user.id;
    rollTheDice.call(this, originalMessage);
  });
}

function replyWithDumbledore(originalMessage) {
  const text = originalMessage.text.toLowerCase();
  const house = Object.values(HOUSE).find(v => text.includes(v));

  const parseCase = {
    [INPUT.PROFESSOR.GET_WINNER]: () => getAllHouseScores.call(this, originalMessage, this.slackBot.getAllHousePointsCallback),
    [INPUT.PROFESSOR.RESET_SCORE]: () => resetTheScores.call(this, originalMessage),
    [INPUT.PROFESSOR.SAY_HELLO]: () => welcomeMessageManual.call(this, originalMessage),
    [INPUT.PROFESSOR.CAN_I_JOIN]: () => addStudentToHouse.call(this, originalMessage, null, null /* this._studentJoinedHouse */),
    [INPUT.PROFESSOR.SORTING_HAT]: () => rollTheDice.call(this, originalMessage),
    [INPUT.PROFESSOR.OBLIVIATE]: () => obliviate.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_BEST_STUDENT]: () => bestStudent.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_MEANEST_STUDENT]: () => worstStudent.call(this, originalMessage),
    [INPUT.PROFESSOR.TELL_ME_ABOUT]: () => tellMeAbout.call(this, originalMessage, house),
    [INPUT.PROFESSOR.START_SORTING]: () => explainSorting.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_HOGWARTS_ROSTER]: () => getAllStudents.call(this, originalMessage),
    [INPUT.PROFESSOR.SAVE_GIT_NAME]: () => saveGitName.call(this, originalMessage),
    [INPUT.PROFESSOR.SORT_REST]: () => forceSortRemaining.call(this, originalMessage)
  };

  Object.keys(parseCase).forEach(key => {
    if (text.includes(key)) {
      parseCase[key]();
    }
  });
}

module.exports = replyWithDumbledore;
<commit_msg>checked_eslint_rule<commit_after>const random = require('random-js')();
const {
  INPUT, OUTPUT, HOUSE, DB
} = require('../word');

async function getAllHouseScores(originalMessage, callback) {
  const channel = await this.slackBot.getChannelById(originalMessage.channel);

  this.slackBot.postMessageToChannel(channel.name, 'The House Points are: \n', { as_user: true }, () => {
    Object.values(HOUSE).forEach(house => {
      this.getPointsFromDatabase.call(this, originalMessage, house, callback);
    });
  });
}

async function resetTheScores(originalMessage) {
  const channel = await this.slackBot.getChannelById(originalMessage.channel);
  Object.values(HOUSE).forEach(h => {
    const house = new Parse.Object(DB.HOUSE.CALL);
    house.save({ name: h, val: 0 });
  });
  this.slackBot.postMessageToChannel(channel.name, OUTPUT.RESET_SCORE);
}

function welcomeMessageManual(originalMessage) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.SAY_HELLO);
}

// Slacks API converts an @username reference in a message to the userid this converts it back to username.
async function convertToUserName(key) {
  const users = await this.slackBot.getUsers();
  return users.find((userid) => {
    if (userid.id === key || userid.name === key) {
      return userid.name;
    }
    return false;
  });
}

function greetNewStudent(originalMessage, student, house) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.canIJoin(student, house));
}

function addStudentToHouse(originalMessage, house) {
  // const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];
  const student = originalMessage.user;
  const studentUsername = convertToUserName(student);
  let notAlreadyStudent = true;
  const text = originalMessage.text.toLowerCase();

  this.db.all('SELECT * FROM students', (err, respond) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    if (respond !== undefined) {
      respond.find((dbUser) => {
        if (dbUser.user_id === student) {
          // this.slackBot.announcePlainString(originalMessage, studentUsername + ' You are already in a house. Once You have been sorted in that house you shall remain. But fear not, if you give it a chance you will see there is much to gain.', bot);
          notAlreadyStudent = false;
          return true;
        }
        return false;
      });
    }
    if (notAlreadyStudent === true) {
      // current not allow multiple house since callback return true
      Object.values(HOUSE).filter(t => text.includes(t) || house === t).some(v => {
        this.db.run('INSERT INTO students (user_id, username, house) VALUES (?, ?, ?)', student, studentUsername, v, (_err) => {
          if (_err) {
            return console.error('DATABASE ERROR', _err);
          }
          greetNewStudent(originalMessage, studentUsername, v);
        });
        return true;
      });
    }
  });
}

function rollTheDice(originalMessage) {
  const house = random.integer(0, 3);

  addStudentToHouse.call(this, originalMessage, Object.values(HOUSE)[house], null);
}

async function obliviate(originalMessage) {
  const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];
  const channel = await this.slackBot.getChannelById(originalMessage.channel);
  const query = new Parse.Query(DB.STUDENT.CALL);

  if (student === convertToUserName(originalMessage.user)) {
    query.equalTo('user_id', '');
    query.find().then(function (results) {
      return Parse.Object.destroyAll(results);
    }).then(function () {
      // Done
    }, function (error) {
      // Error
      if (error) {
        return console.error('DATABASE ERROR', error);
      }
    });
    this.slackBot.postMessageToChannel(channel.name, OUTPUT.OBLIVIATE);
  }
}

function studentStats(originalMessage) {
  const student = originalMessage.text.substring(originalMessage.text.indexOf('@') + 1).split('>')[0];

  if (convertToUserName(student) !== 'dumbledore') {
    this.db.get('SELECT * FROM students WHERE user_id = ?', student, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.student(record));
      } else {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.NOT_FOUND);
      }
    });
  } else {
    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.PERSON.DUMBLEDORE);
  }
}

function bestStudent(originalMessage) {
  Object.values(HOUSE).forEach((house) => {
    this.db.get('SELECT * FROM students WHERE house = ? ORDER BY points_earned DESC', house, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.getBestStudent(record));
      }
    });
  });
  this.slackBot.announcePlainString(originalMessage, OUTPUT.ABOUT_FROGS);
}

function worstStudent(originalMessage) {
  Object.values(HOUSE).forEach((house) => {
    this.db.get('SELECT * FROM students WHERE house = ? ORDER BY points_taken DESC', house, (err, record) => {
      if (err) {
        return console.error('DATABASE ERROR', err);
      }
      if (record !== undefined) {
        this.slackBot.announcePlainString(originalMessage, OUTPUT.getMeanestStudent(record));
      }
    });
  });
}

function getAllStudentsFromHouse(originalMessage, house) {
  this.db.all('SELECT * FROM students WHERE house = ? ', house, (err, record) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }

    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.fromHouse(house, record));
  });
}

function tellMeAbout(originalMessage, house) {
  const text = originalMessage.text.toLowerCase();

  if (text.includes('@')) {
    studentStats.call(this, originalMessage);
  } else if (house) {
    getAllStudentsFromHouse.call(this, originalMessage, house);
  } else if (text.includes(INPUT.PROFESSOR.JASON_MOM)) {
    this.slackBot.announcePlainString(originalMessage, OUTPUT.TELL_ME_ABOUT.JASON_MOM);
  }
}

function getAllStudents(originalMessage) {
  this.db.all('SELECT * FROM students', (err) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    Object.values(HOUSE).forEach((house) => {
      getAllStudentsFromHouse.call(this, originalMessage, house);
    });
  });
}

function explainSorting(originalMessage) {
  this.slackBot.announcePlainString(originalMessage, OUTPUT.START_SORTING);
}

function saveGitName(originalMessage) {
  const gitName = originalMessage.text.split('=')[1];
  const { user } = originalMessage;

  this.db.run('UPDATE students SET github_name = ? WHERE user_id = ?', gitName, user, (err) => {
    if (err) {
      return console.error('DATABASE ERROR', err);
    }
    this.slackBot.announcePlainString(originalMessage, OUTPUT.saveGitName(convertToUserName(user), gitName));
  });
}

async function forceSortRemaining(originalMessage) {
  const users = await this.slackBot.getUsers();

  users.members.forEach((user) => {
    originalMessage.user = user.id;
    rollTheDice.call(this, originalMessage);
  });
}

function replyWithDumbledore(originalMessage) {
  const text = originalMessage.text.toLowerCase();
  const house = Object.values(HOUSE).find(v => text.includes(v));

  const parseCase = {
    [INPUT.PROFESSOR.GET_WINNER]: () => getAllHouseScores.call(this, originalMessage, this.slackBot.getAllHousePointsCallback),
    [INPUT.PROFESSOR.RESET_SCORE]: () => resetTheScores.call(this, originalMessage),
    [INPUT.PROFESSOR.SAY_HELLO]: () => welcomeMessageManual.call(this, originalMessage),
    [INPUT.PROFESSOR.CAN_I_JOIN]: () => addStudentToHouse.call(this, originalMessage, null, null /* this._studentJoinedHouse */),
    [INPUT.PROFESSOR.SORTING_HAT]: () => rollTheDice.call(this, originalMessage),
    [INPUT.PROFESSOR.OBLIVIATE]: () => obliviate.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_BEST_STUDENT]: () => bestStudent.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_MEANEST_STUDENT]: () => worstStudent.call(this, originalMessage),
    [INPUT.PROFESSOR.TELL_ME_ABOUT]: () => tellMeAbout.call(this, originalMessage, house),
    [INPUT.PROFESSOR.START_SORTING]: () => explainSorting.call(this, originalMessage),
    [INPUT.PROFESSOR.GET_HOGWARTS_ROSTER]: () => getAllStudents.call(this, originalMessage),
    [INPUT.PROFESSOR.SAVE_GIT_NAME]: () => saveGitName.call(this, originalMessage),
    [INPUT.PROFESSOR.SORT_REST]: () => forceSortRemaining.call(this, originalMessage)
  };

  Object.keys(parseCase).forEach(key => {
    if (text.includes(key)) {
      parseCase[key]();
    }
  });
}

module.exports = replyWithDumbledore;
<|endoftext|>


<commit_before>'use strict';

module.exports = function (projectsData) {
  function index(req, res) {
    res.render('./project/index', {
      isAuthenticated: req.isAuthenticated(),
      result: req.user
    });
  }

  function createProject(req, res) {
    const isAuthenticated = req.isAuthenticated();
    if (!isAuthenticated) {
      return res.redirect('/account/login');
    }

    return projectsData.createProject(req.body)
      .then(res.render('./project/success', {
        result: {
          user: req.user
        },
        name: req.body.name
      }));
  }

  function listAllProjects(req, res) {
    return projectsData.getAllProjects()
      .then((data) => {
        res.render('./project/projects-list', {
          result: {
            user: req.user
          },
          data
        });
      });
  }

  return {
    index,
    createProject,
    listAllProjects
  };
};<commit_msg>fit passed object to _header.pug<commit_after>'use strict';

module.exports = function (projectsData) {
  function index(req, res) {
    res.render('./project/index', {
      isAuthenticated: req.isAuthenticated(),
      result: req
    });
  }

  function createProject(req, res) {
    const isAuthenticated = req.isAuthenticated();
    if (!isAuthenticated) {
      return res.redirect('/account/login');
    }

    return projectsData.createProject(req.body)
      .then(res.render('./project/success', {
        result: {
          user: req.user
        },
        name: req.body.name
      }));
  }

  function listAllProjects(req, res) {
    return projectsData.getAllProjects()
      .then((data) => {
        res.render('./project/projects-list', {
          result: {
            user: req.user
          },
          data
        });
      });
  }

  return {
    index,
    createProject,
    listAllProjects
  };
};<|endoftext|>


<commit_before>'use strict';

/**
 * @file Route handler for `/v1/stats`
 */

const models = require('../../models');
const Stats = models.stats;
const moment = require('moment');

module.exports = {

    getPricelist: function*(next) {

        // Define some timespans for which we want price lists
        const days = [1, 2, 3, 6, 7, 8, 13, 14, 15];
        const timespans = days.map(function(d) {
            return {
                start: moment().subtract(d, 'days').format('YYYY-MM-DD'),
                end: moment().format('YYYY-MM-DD')
            }
        });

        // grab one pricelist per timespan
        const pricelists = [];
        for (let i = 0; i < timespans.length; i++) {
            pricelists.push(yield Stats.getPricelist(timespans[i]));
        }

        // now build one giant object that contains everything useful
        const result = {
            gold: {},
            platinum: {}
        };

        for (let i = 0; i < pricelists.length; i++) {

            const pricelist = pricelists[i];

            ['gold', 'platinum'].forEach(function(currency) {

                // only look at data that has the same currency
                const relevantPricelistData = pricelist.filter(function(e) {
                    return e.currency.toLowerCase() === currency;
                });

                relevantPricelistData.forEach(function(articleData) {

                    // if there is no entry for an article in the current resultset, add it
                    if (!result[currency][articleData.uuid]) {
                        result[currency][articleData.uuid] = {};
                    }

                    // anyway add the data for that article from the current pricelist to the result set
                    const articleKey = articleData.uuid;
                    let tmp = {
                        q: articleData.q,
                        t: articleData.t,
                        mi: articleData.mi,
                        ma: articleData.ma,
                        a: articleData.a
                    };
                    result[currency][articleKey][days[i].toString()] = tmp;

                });

            });

        }

        this.body = result;
        this.status = 200;

        yield next;

    },

    /**
     * @function Finds most sold articles
     */
    getMostSoldArticles: function*(next) {

        const limit = parseInt(this.request.query.limit) || 30;
        const start = this.request.query.start ||  moment().subtract(3, 'days').format('YYYY-MM-DD');
        const end = this.request.query.end || moment().format('YYYY-MM-DD');

        const mostSold = yield Stats.getMostSoldArticles(start, end, limit);

        this.body = mostSold;
        this.status = 200;

        yield next;

    }

};
<commit_msg>Add 30 period to pricelists<commit_after>'use strict';

/**
 * @file Route handler for `/v1/stats`
 */

const models = require('../../models');
const Stats = models.stats;
const moment = require('moment');

module.exports = {

    getPricelist: function*(next) {

        // Define some timespans for which we want price lists
        const days = [1, 2, 3, 6, 7, 8, 13, 14, 15, 30];
        const timespans = days.map(function(d) {
            return {
                start: moment().subtract(d, 'days').format('YYYY-MM-DD'),
                end: moment().format('YYYY-MM-DD')
            }
        });

        // grab one pricelist per timespan
        const pricelists = [];
        for (let i = 0; i < timespans.length; i++) {
            pricelists.push(yield Stats.getPricelist(timespans[i]));
        }

        // now build one giant object that contains everything useful
        const result = {
            gold: {},
            platinum: {}
        };

        for (let i = 0; i < pricelists.length; i++) {

            const pricelist = pricelists[i];

            ['gold', 'platinum'].forEach(function(currency) {

                // only look at data that has the same currency
                const relevantPricelistData = pricelist.filter(function(e) {
                    return e.currency.toLowerCase() === currency;
                });

                relevantPricelistData.forEach(function(articleData) {

                    // if there is no entry for an article in the current resultset, add it
                    if (!result[currency][articleData.uuid]) {
                        result[currency][articleData.uuid] = {};
                    }

                    // anyway add the data for that article from the current pricelist to the result set
                    const articleKey = articleData.uuid;
                    let tmp = {
                        q: articleData.q,
                        t: articleData.t,
                        mi: articleData.mi,
                        ma: articleData.ma,
                        a: articleData.a
                    };
                    result[currency][articleKey][days[i].toString()] = tmp;

                });

            });

        }

        this.body = result;
        this.status = 200;

        yield next;

    },

    /**
     * @function Finds most sold articles
     */
    getMostSoldArticles: function*(next) {

        const limit = parseInt(this.request.query.limit) || 30;
        const start = this.request.query.start ||  moment().subtract(3, 'days').format('YYYY-MM-DD');
        const end = this.request.query.end || moment().format('YYYY-MM-DD');

        const mostSold = yield Stats.getMostSoldArticles(start, end, limit);

        this.body = mostSold;
        this.status = 200;

        yield next;

    }

};
<|endoftext|>


<commit_before>var Utils     = require("../../utils")
  , DataTypes = require("../../data-types")
  , util      = require("util")

module.exports = (function() {
  var QueryGenerator = {
    createTableQuery: function(tableName, attributes, options) {
      options = Utils._.extend({
        engine: 'InnoDB',
        charset: null
      }, options || {})

      var query   = "CREATE TABLE IF NOT EXISTS <%= table %> (<%= attributes%>) ENGINE=<%= engine %> <%= charset %>"
        , primaryKeys = []
        , attrStr = []

      for (var attr in attributes) {
        if (attributes.hasOwnProperty(attr)) {
          var dataType = attributes[attr]

          if (Utils._.includes(dataType, 'PRIMARY KEY')) {
            primaryKeys.push(attr)
            attrStr.push(Utils.addTicks(attr) + " " + dataType.replace(/PRIMARY KEY/, ''))
          } else {
            attrStr.push(Utils.addTicks(attr) + " " + dataType)
          }
        }
      }

      var values = {
        table: Utils.addTicks(tableName),
        attributes: attrStr.join(", "),
        engine: options.engine,
        charset: (options.charset ? "DEFAULT CHARSET=" + options.charset : "")
      }
      , pkString = primaryKeys.map(function(pk) { return Utils.addTicks(pk) }).join(", ")

      if(pkString.length > 0) {
        values.attributes += ", PRIMARY KEY (" + pkString + ")"
      }

      return Utils._.template(query)(values).trim() + ";"
    },

    dropTableQuery: function(tableName, options) {
      options = options || {}

      var query = "DROP TABLE IF EXISTS <%= table %>;"

      return Utils._.template(query)({table: Utils.addTicks(tableName)})
    },

    renameTableQuery: function(before, after) {
      var query = "RENAME TABLE `<%= before %>` TO `<%= after %>`;"
      return Utils._.template(query)({ before: before, after: after })
    },

    showTablesQuery: function() {
      return 'SHOW TABLES;'
    },

    addColumnQuery: function(tableName, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` ADD <%= attributes %>;"
        , attrString = []

      for (var attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= attrName %>` <%= definition %>')({
          attrName: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    removeColumnQuery: function(tableName, attributeName) {
      var query = "ALTER TABLE `<%= tableName %>` DROP `<%= attributeName %>`;"
      return Utils._.template(query)({ tableName: tableName, attributeName: attributeName })
    },

    changeColumnQuery: function(tableName, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` CHANGE <%= attributes %>;"
      var attrString = []

      for (attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= attrName %>` `<%= attrName %>` <%= definition %>')({
          attrName: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    renameColumnQuery: function(tableName, attrBefore, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` CHANGE <%= attributes %>;"
      var attrString = []

      for (var attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= before %>` `<%= after %>` <%= definition %>')({
          before: attrBefore,
          after: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    selectQuery: function(tableName, options) {
      var query = "SELECT <%= attributes %> FROM <%= table %>"
        , table = null

      options            = options || {}
      options.table      = table = Array.isArray(tableName) ? tableName.map(function(tbl){ return Utils.addTicks(tbl) }).join(", ") : Utils.addTicks(tableName)
      options.attributes = options.attributes && options.attributes.map(function(attr){
        if(Array.isArray(attr) && attr.length == 2) {
          return [attr[0], Utils.addTicks(attr[1])].join(' as ')
        } else {
          return attr.indexOf(Utils.TICK_CHAR) < 0 ? Utils.addTicks(attr) : attr
        }
      }).join(", ")
      options.attributes = options.attributes || '*'

      if (options.include) {
        var optAttributes = [options.table + '.*']

        for (var daoName in options.include) {
          if (options.include.hasOwnProperty(daoName)) {
            var dao         = options.include[daoName]
              , daoFactory  = dao.daoFactoryManager.getDAO(tableName, {
                  attribute: 'tableName'
                })
              , _tableName  = Utils.addTicks(dao.tableName)
              , association = dao.getAssociation(daoFactory)

            if (association.connectorDAO) {
              var foreignIdentifier = Utils._.keys(association.connectorDAO.rawAttributes).filter(function(attrName) {
                return (!!attrName.match(/.+Id$/) || !!attrName.match(/.+_id$/)) && (attrName !== association.identifier)
              })[0]

              query += ' LEFT OUTER JOIN ' + Utils.addTicks(association.connectorDAO.tableName) + ' ON '
              query += Utils.addTicks(association.connectorDAO.tableName) + '.'
              query += Utils.addTicks(foreignIdentifier) + '='
              query += Utils.addTicks(table) + '.' + Utils.addTicks('id')

              query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
              query += Utils.addTicks(dao.tableName) + '.'
              query += Utils.addTicks('id') + '='
              query += Utils.addTicks(association.connectorDAO.tableName) + '.' + Utils.addTicks(association.identifier)
            } else {
              query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
              query += Utils.addTicks(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.'
              query += Utils.addTicks(association.identifier) + '='
              query += Utils.addTicks(table) + '.' + Utils.addTicks('id')
            }

            optAttributes = optAttributes.concat(
              Utils._.keys(dao.attributes).map(function(attr) {
                var identifier = [_tableName, Utils.addTicks(attr)]
                return identifier.join('.') + ' AS ' + Utils.addTicks(identifier.join('.'))
              })
            )
          }
        }

        options.attributes = optAttributes.join(', ')
      }

      if(options.where) {
        options.where = this.getWhereConditions(options.where, tableName)
        query += " WHERE <%= where %>"
      }

      if(options.order) {
        query += " ORDER BY <%= order %>"
      }

      if(options.group) {
        options.group = Utils.addTicks(options.group)
        query += " GROUP BY <%= group %>"
      }

      if(options.limit && !(options.include && (options.limit === 1))) {
        if(options.offset) {
          query += " LIMIT <%= offset %>, <%= limit %>"
        } else {
          query += " LIMIT <%= limit %>"
        }
      }

      query += ";"

      return Utils._.template(query)(options)
    },

    insertQuery: function(tableName, attrValueHash) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)

      var query = "INSERT INTO <%= table %> (<%= attributes %>) VALUES (<%= values %>);"

      var replacements  = {
        table: Utils.addTicks(tableName),
        attributes: Utils._.keys(attrValueHash).map(function(attr){return Utils.addTicks(attr)}).join(","),
        values: Utils._.values(attrValueHash).map(function(value){
          return Utils.escape((value instanceof Date) ? Utils.toSqlDate(value) : value)
        }).join(",")
      }

      return Utils._.template(query)(replacements)
    },

    updateQuery: function(tableName, attrValueHash, where) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)

      var query  = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %>"
        , values = []

      for (var key in attrValueHash) {
        var value  = attrValueHash[key]
          , _value = (value instanceof Date) ? Utils.toSqlDate(value) : value

        values.push(Utils.addTicks(key) + "=" + Utils.escape(_value))
      }

      var replacements = {
        table: Utils.addTicks(tableName),
        values: values.join(","),
        where: QueryGenerator.getWhereConditions(where)
      }

      return Utils._.template(query)(replacements)
    },

    deleteQuery: function(tableName, where, options) {
      options = options || {}
      options.limit = options.limit || 1

      var query = "DELETE FROM <%= table %> WHERE <%= where %> LIMIT <%= limit %>"
      var replacements = {
        table: Utils.addTicks(tableName),
        where: QueryGenerator.getWhereConditions(where),
        limit: Utils.escape(options.limit)
      }

      return Utils._.template(query)(replacements)
    },

    addIndexQuery: function(tableName, attributes, options) {
      var transformedAttributes = attributes.map(function(attribute) {
        if(typeof attribute == 'string')
          return attribute
        else {
          var result = ""

          if(!attribute.attribute)
            throw new Error('The following index attribute has no attribute: ' + util.inspect(attribute))

          result += attribute.attribute

          if(attribute.length)
            result += '(' + attribute.length + ')'

          if(attribute.order)
            result += ' ' + attribute.order

          return result
        }
      })

      var onlyAttributeNames = attributes.map(function(attribute) {
        return (typeof attribute == 'string') ? attribute : attribute.attribute
      })

      options = Utils._.extend({
        indicesType: null,
        indexName: Utils._.underscored(tableName + '_' + onlyAttributeNames.join('_')),
        parser: null
      }, options || {})

      return Utils._.compact([
        "CREATE", options.indicesType, "INDEX", options.indexName,
        (options.indexType ? ('USING ' + options.indexType) : undefined),
        "ON", tableName, '(' + transformedAttributes.join(', ') + ')',
        (options.parser ? "WITH PARSER " + options.parser : undefined)
      ]).join(' ')
    },

    showIndexQuery: function(tableName, options) {
      var sql = "SHOW INDEX FROM <%= tableName %><%= options %>"
      return Utils._.template(sql)({
        tableName: tableName,
        options: (options || {}).database ? ' FROM ' + options.database : ''
      })
    },

    removeIndexQuery: function(tableName, indexNameOrAttributes) {
      var sql       = "DROP INDEX <%= indexName %> ON <%= tableName %>"
        , indexName = indexNameOrAttributes

      if(typeof indexName != 'string')
        indexName = Utils._.underscored(tableName + '_' + indexNameOrAttributes.join('_'))

      return Utils._.template(sql)({ tableName: tableName, indexName: indexName })
    },

    getWhereConditions: function(smth, tableName) {
      var result = null

      if(Utils.isHash(smth)) {
        smth   = Utils.prependTableNameToHash(tableName, smth)
        result = this.hashToWhereConditions(smth)
      } else if (typeof smth === 'number') {
        smth   = Utils.prependTableNameToHash(tableName, { id: smth })
        result = this.hashToWhereConditions(smth)
      } else if (typeof smth === "string") {
        result = smth
      } else if (Array.isArray(smth)) {
        result = Utils.format(smth)
      }

      return result
    },

    hashToWhereConditions: function(hash) {
      var result = []

      for (var key in hash) {
        var value = hash[key]

         //handle qualified key names
        var _key   = key.split('.').map(function(col){return Utils.addTicks(col)}).join(".")
          , _value = null

        if (Array.isArray(value)) {
          // is value an array?
          if(value.length == 0) { value = [null] }
          _value = "(" + value.map(function(subValue) {
            return Utils.escape(subValue);
          }).join(',') + ")"

          result.push([_key, _value].join(" IN "))
        } else if ((value) && (typeof value == 'object')) {
          // is value an object?

          //using as sentinel for join column => value
          _value = value.join.split('.').map(function(col){ return Utils.addTicks(col) }).join(".")
          result.push([_key, _value].join("="))
        } else {
          _value = Utils.escape(value)
          result.push((_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("="))
        }
      }

      return result.join(" AND ")
    },

    attributesToSQL: function(attributes) {
      var result = {}

      for (var name in attributes) {
        var dataType = attributes[name]

        if(Utils.isHash(dataType)) {
          var template     = "<%= type %>"
            , replacements = { type: dataType.type }

          if(dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) {
            template += " NOT NULL"
          }

          if(dataType.autoIncrement) {
            template += " auto_increment"
          }

          if((dataType.defaultValue != undefined) && (dataType.defaultValue != DataTypes.NOW)) {
            template += " DEFAULT <%= defaultValue %>"
            replacements.defaultValue = Utils.escape(dataType.defaultValue)
          }

          if(dataType.unique) {
            template += " UNIQUE"
          }

          if(dataType.primaryKey) {
            template += " PRIMARY KEY"
          }

          result[name] = Utils._.template(template)(replacements)
        } else {
          result[name] = dataType
        }
      }

      return result
    },

    findAutoIncrementField: function(factory) {
      var fields = []

      for (var name in factory.attributes) {
        if (factory.attributes.hasOwnProperty(name)) {
          var definition = factory.attributes[name]

          if (definition && (definition.indexOf('auto_increment') > -1)) {
            fields.push(name)
          }
        }
      }

      return fields
    }
  }

  return Utils._.extend(Utils._.clone(require("../query-generator")), QueryGenerator)
})()
<commit_msg>switch position for order and group options, cause when order and group both provided, sql broken<commit_after>var Utils     = require("../../utils")
  , DataTypes = require("../../data-types")
  , util      = require("util")

module.exports = (function() {
  var QueryGenerator = {
    createTableQuery: function(tableName, attributes, options) {
      options = Utils._.extend({
        engine: 'InnoDB',
        charset: null
      }, options || {})

      var query   = "CREATE TABLE IF NOT EXISTS <%= table %> (<%= attributes%>) ENGINE=<%= engine %> <%= charset %>"
        , primaryKeys = []
        , attrStr = []

      for (var attr in attributes) {
        if (attributes.hasOwnProperty(attr)) {
          var dataType = attributes[attr]

          if (Utils._.includes(dataType, 'PRIMARY KEY')) {
            primaryKeys.push(attr)
            attrStr.push(Utils.addTicks(attr) + " " + dataType.replace(/PRIMARY KEY/, ''))
          } else {
            attrStr.push(Utils.addTicks(attr) + " " + dataType)
          }
        }
      }

      var values = {
        table: Utils.addTicks(tableName),
        attributes: attrStr.join(", "),
        engine: options.engine,
        charset: (options.charset ? "DEFAULT CHARSET=" + options.charset : "")
      }
      , pkString = primaryKeys.map(function(pk) { return Utils.addTicks(pk) }).join(", ")

      if(pkString.length > 0) {
        values.attributes += ", PRIMARY KEY (" + pkString + ")"
      }

      return Utils._.template(query)(values).trim() + ";"
    },

    dropTableQuery: function(tableName, options) {
      options = options || {}

      var query = "DROP TABLE IF EXISTS <%= table %>;"

      return Utils._.template(query)({table: Utils.addTicks(tableName)})
    },

    renameTableQuery: function(before, after) {
      var query = "RENAME TABLE `<%= before %>` TO `<%= after %>`;"
      return Utils._.template(query)({ before: before, after: after })
    },

    showTablesQuery: function() {
      return 'SHOW TABLES;'
    },

    addColumnQuery: function(tableName, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` ADD <%= attributes %>;"
        , attrString = []

      for (var attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= attrName %>` <%= definition %>')({
          attrName: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    removeColumnQuery: function(tableName, attributeName) {
      var query = "ALTER TABLE `<%= tableName %>` DROP `<%= attributeName %>`;"
      return Utils._.template(query)({ tableName: tableName, attributeName: attributeName })
    },

    changeColumnQuery: function(tableName, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` CHANGE <%= attributes %>;"
      var attrString = []

      for (attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= attrName %>` `<%= attrName %>` <%= definition %>')({
          attrName: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    renameColumnQuery: function(tableName, attrBefore, attributes) {
      var query      = "ALTER TABLE `<%= tableName %>` CHANGE <%= attributes %>;"
      var attrString = []

      for (var attrName in attributes) {
        var definition = attributes[attrName]

        attrString.push(Utils._.template('`<%= before %>` `<%= after %>` <%= definition %>')({
          before: attrBefore,
          after: attrName,
          definition: definition
        }))
      }

      return Utils._.template(query)({ tableName: tableName, attributes: attrString.join(', ') })
    },

    selectQuery: function(tableName, options) {
      var query = "SELECT <%= attributes %> FROM <%= table %>"
        , table = null

      options            = options || {}
      options.table      = table = Array.isArray(tableName) ? tableName.map(function(tbl){ return Utils.addTicks(tbl) }).join(", ") : Utils.addTicks(tableName)
      options.attributes = options.attributes && options.attributes.map(function(attr){
        if(Array.isArray(attr) && attr.length == 2) {
          return [attr[0], Utils.addTicks(attr[1])].join(' as ')
        } else {
          return attr.indexOf(Utils.TICK_CHAR) < 0 ? Utils.addTicks(attr) : attr
        }
      }).join(", ")
      options.attributes = options.attributes || '*'

      if (options.include) {
        var optAttributes = [options.table + '.*']

        for (var daoName in options.include) {
          if (options.include.hasOwnProperty(daoName)) {
            var dao         = options.include[daoName]
              , daoFactory  = dao.daoFactoryManager.getDAO(tableName, {
                  attribute: 'tableName'
                })
              , _tableName  = Utils.addTicks(dao.tableName)
              , association = dao.getAssociation(daoFactory)

            if (association.connectorDAO) {
              var foreignIdentifier = Utils._.keys(association.connectorDAO.rawAttributes).filter(function(attrName) {
                return (!!attrName.match(/.+Id$/) || !!attrName.match(/.+_id$/)) && (attrName !== association.identifier)
              })[0]

              query += ' LEFT OUTER JOIN ' + Utils.addTicks(association.connectorDAO.tableName) + ' ON '
              query += Utils.addTicks(association.connectorDAO.tableName) + '.'
              query += Utils.addTicks(foreignIdentifier) + '='
              query += Utils.addTicks(table) + '.' + Utils.addTicks('id')

              query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
              query += Utils.addTicks(dao.tableName) + '.'
              query += Utils.addTicks('id') + '='
              query += Utils.addTicks(association.connectorDAO.tableName) + '.' + Utils.addTicks(association.identifier)
            } else {
              query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
              query += Utils.addTicks(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.'
              query += Utils.addTicks(association.identifier) + '='
              query += Utils.addTicks(table) + '.' + Utils.addTicks('id')
            }

            optAttributes = optAttributes.concat(
              Utils._.keys(dao.attributes).map(function(attr) {
                var identifier = [_tableName, Utils.addTicks(attr)]
                return identifier.join('.') + ' AS ' + Utils.addTicks(identifier.join('.'))
              })
            )
          }
        }

        options.attributes = optAttributes.join(', ')
      }

      if(options.where) {
        options.where = this.getWhereConditions(options.where, tableName)
        query += " WHERE <%= where %>"
      }

      if(options.group) {
        options.group = Utils.addTicks(options.group)
        query += " GROUP BY <%= group %>"
      }

      if(options.order) {
        query += " ORDER BY <%= order %>"
      }

      if(options.limit && !(options.include && (options.limit === 1))) {
        if(options.offset) {
          query += " LIMIT <%= offset %>, <%= limit %>"
        } else {
          query += " LIMIT <%= limit %>"
        }
      }

      query += ";"

      return Utils._.template(query)(options)
    },

    insertQuery: function(tableName, attrValueHash) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)

      var query = "INSERT INTO <%= table %> (<%= attributes %>) VALUES (<%= values %>);"

      var replacements  = {
        table: Utils.addTicks(tableName),
        attributes: Utils._.keys(attrValueHash).map(function(attr){return Utils.addTicks(attr)}).join(","),
        values: Utils._.values(attrValueHash).map(function(value){
          return Utils.escape((value instanceof Date) ? Utils.toSqlDate(value) : value)
        }).join(",")
      }

      return Utils._.template(query)(replacements)
    },

    updateQuery: function(tableName, attrValueHash, where) {
      attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)

      var query  = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %>"
        , values = []

      for (var key in attrValueHash) {
        var value  = attrValueHash[key]
          , _value = (value instanceof Date) ? Utils.toSqlDate(value) : value

        values.push(Utils.addTicks(key) + "=" + Utils.escape(_value))
      }

      var replacements = {
        table: Utils.addTicks(tableName),
        values: values.join(","),
        where: QueryGenerator.getWhereConditions(where)
      }

      return Utils._.template(query)(replacements)
    },

    deleteQuery: function(tableName, where, options) {
      options = options || {}
      options.limit = options.limit || 1

      var query = "DELETE FROM <%= table %> WHERE <%= where %> LIMIT <%= limit %>"
      var replacements = {
        table: Utils.addTicks(tableName),
        where: QueryGenerator.getWhereConditions(where),
        limit: Utils.escape(options.limit)
      }

      return Utils._.template(query)(replacements)
    },

    addIndexQuery: function(tableName, attributes, options) {
      var transformedAttributes = attributes.map(function(attribute) {
        if(typeof attribute == 'string')
          return attribute
        else {
          var result = ""

          if(!attribute.attribute)
            throw new Error('The following index attribute has no attribute: ' + util.inspect(attribute))

          result += attribute.attribute

          if(attribute.length)
            result += '(' + attribute.length + ')'

          if(attribute.order)
            result += ' ' + attribute.order

          return result
        }
      })

      var onlyAttributeNames = attributes.map(function(attribute) {
        return (typeof attribute == 'string') ? attribute : attribute.attribute
      })

      options = Utils._.extend({
        indicesType: null,
        indexName: Utils._.underscored(tableName + '_' + onlyAttributeNames.join('_')),
        parser: null
      }, options || {})

      return Utils._.compact([
        "CREATE", options.indicesType, "INDEX", options.indexName,
        (options.indexType ? ('USING ' + options.indexType) : undefined),
        "ON", tableName, '(' + transformedAttributes.join(', ') + ')',
        (options.parser ? "WITH PARSER " + options.parser : undefined)
      ]).join(' ')
    },

    showIndexQuery: function(tableName, options) {
      var sql = "SHOW INDEX FROM <%= tableName %><%= options %>"
      return Utils._.template(sql)({
        tableName: tableName,
        options: (options || {}).database ? ' FROM ' + options.database : ''
      })
    },

    removeIndexQuery: function(tableName, indexNameOrAttributes) {
      var sql       = "DROP INDEX <%= indexName %> ON <%= tableName %>"
        , indexName = indexNameOrAttributes

      if(typeof indexName != 'string')
        indexName = Utils._.underscored(tableName + '_' + indexNameOrAttributes.join('_'))

      return Utils._.template(sql)({ tableName: tableName, indexName: indexName })
    },

    getWhereConditions: function(smth, tableName) {
      var result = null

      if(Utils.isHash(smth)) {
        smth   = Utils.prependTableNameToHash(tableName, smth)
        result = this.hashToWhereConditions(smth)
      } else if (typeof smth === 'number') {
        smth   = Utils.prependTableNameToHash(tableName, { id: smth })
        result = this.hashToWhereConditions(smth)
      } else if (typeof smth === "string") {
        result = smth
      } else if (Array.isArray(smth)) {
        result = Utils.format(smth)
      }

      return result
    },

    hashToWhereConditions: function(hash) {
      var result = []

      for (var key in hash) {
        var value = hash[key]

         //handle qualified key names
        var _key   = key.split('.').map(function(col){return Utils.addTicks(col)}).join(".")
          , _value = null

        if (Array.isArray(value)) {
          // is value an array?
          if(value.length == 0) { value = [null] }
          _value = "(" + value.map(function(subValue) {
            return Utils.escape(subValue);
          }).join(',') + ")"

          result.push([_key, _value].join(" IN "))
        } else if ((value) && (typeof value == 'object')) {
          // is value an object?

          //using as sentinel for join column => value
          _value = value.join.split('.').map(function(col){ return Utils.addTicks(col) }).join(".")
          result.push([_key, _value].join("="))
        } else {
          _value = Utils.escape(value)
          result.push((_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("="))
        }
      }

      return result.join(" AND ")
    },

    attributesToSQL: function(attributes) {
      var result = {}

      for (var name in attributes) {
        var dataType = attributes[name]

        if(Utils.isHash(dataType)) {
          var template     = "<%= type %>"
            , replacements = { type: dataType.type }

          if(dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) {
            template += " NOT NULL"
          }

          if(dataType.autoIncrement) {
            template += " auto_increment"
          }

          if((dataType.defaultValue != undefined) && (dataType.defaultValue != DataTypes.NOW)) {
            template += " DEFAULT <%= defaultValue %>"
            replacements.defaultValue = Utils.escape(dataType.defaultValue)
          }

          if(dataType.unique) {
            template += " UNIQUE"
          }

          if(dataType.primaryKey) {
            template += " PRIMARY KEY"
          }

          result[name] = Utils._.template(template)(replacements)
        } else {
          result[name] = dataType
        }
      }

      return result
    },

    findAutoIncrementField: function(factory) {
      var fields = []

      for (var name in factory.attributes) {
        if (factory.attributes.hasOwnProperty(name)) {
          var definition = factory.attributes[name]

          if (definition && (definition.indexOf('auto_increment') > -1)) {
            fields.push(name)
          }
        }
      }

      return fields
    }
  }

  return Utils._.extend(Utils._.clone(require("../query-generator")), QueryGenerator)
})()
<|endoftext|>