<commit_before>"use strict"

import React from 'react'
import { Link } from 'react-router'
import Select from 'react-select'
import {StickyContainer,Sticky} from 'react-sticky'

import LineGraph from '../../../components/graphs/SimpleLineGraph'
import StartupsNaicsTooltip from './StartupsNaicsTooltip'
import RadarChart from '../../../components/vis/RadarChart/RadarChart'
import StartupsOverviewTable from './StartupsOverviewTable'

import { kmgtFormatter, kmgtDollarFormatter } from '../../misc/numberFormatters'

const integerFormatter = kmgtFormatter.bind(null, 0)
const floatFormatter = kmgtFormatter.bind(null, 1)
const dollarFormatter = kmgtDollarFormatter.bind(null, 0)

const graphMargin = {
  top    : 10,
  left   : 60,
  right  : 20,
  bottom : 20,
}

const radarGraphOptions = {
    w           : 190,
    h           : 190,
    ExtraWidthX : 130,
    TranslateX  : 50,
    color       : d3.scale.ordinal().range(['#4CAF50','#7D8FAF'])
}

const renderVisualizations = (props) => (

    <StickyContainer>
      <Sticky className="foo"
              style={{backgroundColor:'white', opacity: 1, zIndex:100}}
              stickyStyle={{backgroundColor:'white', opacity: 1, zIndex:100}}>

             {
                             props.yearQuarterWheelChange((e.deltaY) < 0 ? 1 : -1)
                             e.preventDefault()}}>

                {`Q${props.yearQuarter.quarter}-${props.yearQuarter.year}`}

             {
                             props.radarGraphFirmageChange((e.deltaY) < 0 ? 1 : -1)
                             e.preventDefault()}}>

                {`Firmage: ${props.radarGraphFirmageLabel}`}

      </Sticky>

            <LineGraph data={props.lineGraphRawData}
                       key='qwi-rawData-linegraph'
                       uniq='qwi-rawData-linegraph'
                       yFormat={(props.measureIsCurrency) ? dollarFormatter : integerFormatter}
                       xScaleType={'time'}
                       yAxis={true}
                       margin={graphMargin}
                       tooltip={true}
                       quarterChangeListener={props.lineGraphYearQuarterChange} />

            <LineGraph data={props.lineGraphLQData}
                       key='qwi-lqData-linegraph'
                       uniq='qwi-lqData-linegraph'
                       xScaleType={'time'}
                       xAxis={true}
                       xFormat={d => d ? d3.time.format('%Y')(new Date(d)) : ''}
                       yAxis={true}
                       yFormat={floatFormatter}
                       margin={graphMargin}
                       tooltip={true}
                       quarterChangeListener={props.lineGraphYearQuarterChange} />

            <StartupsNaicsTooltip data={props.tooltipData}
                                  measureIsCurrency={
                                    (props.focusedLineGraph === 'qwi-rawData-linegraph') && props.measureIsCurrency
                                  }
                                  uniq={props.field} />

              {`Share of ${props.measure} by industry for ${props.radarGraphFirmageLabel} firms`}

          <RadarChart divID='typeShare'
                      data={props.shareOfMetroTotalRadarGraphData}
                      options={radarGraphOptions} />

            {`Share of by ${props.measure} by industry across firmages.`}

          <RadarChart divID='typeQout'
                      data={props.shareByIndustryRadarGraphData}
                      options={radarGraphOptions} />

        <StartupsOverviewTable data={props.overviewTableData}
                               sortFieldChange={props.overviewTableSortFieldChange} />

    </StickyContainer>

)

class MetroQwi extends React.Component<void, Props, void> {

  componentDidMount () {
    let props = this.props

    if (props.loadData && !props.lineGraphRawData) {
      props.msaChange(props.msa);
      props.measureChange(props.measure);

      props.loadData(props.msa, props.measure)
    }
  }

  componentWillReceiveProps (nextProps){
    let props = this.props

    props.msaChange(nextProps.msa)         // No effect if same msa
    props.measureChange(nextProps.measure) // No effect if same measure

    if (!nextProps.lineGraphRawData) {
      props.loadData(nextProps.msa, nextProps.measure)
    }
  }

  render () {
    return (this.props.lineGraphRawData) ? renderVisualizations(this.props) : (Loading...)
  }
}

export default MetroQwi
<commit_msg>Stylin' the QWI page.<commit_after>"use strict"

import React from 'react'
import { Link } from 'react-router'
import Select from 'react-select'
import {StickyContainer,Sticky} from 'react-sticky'

import LineGraph from '../../../components/graphs/SimpleLineGraph'
import StartupsNaicsTooltip from './StartupsNaicsTooltip'
import RadarChart from '../../../components/vis/RadarChart/RadarChart'
import StartupsOverviewTable from './StartupsOverviewTable'

import { kmgtFormatter, kmgtDollarFormatter } from '../../misc/numberFormatters'

const integerFormatter = kmgtFormatter.bind(null, 0)
const floatFormatter = kmgtFormatter.bind(null, 1)
const dollarFormatter = kmgtDollarFormatter.bind(null, 0)

const graphMargin = {
  top    : 10,
  left   : 60,
  right  : 20,
  bottom : 20,
}

const radarGraphOptions = {
    w           : 190,
    h           : 190,
    ExtraWidthX : 130,
    TranslateX  : 50,
    color       : d3.scale.ordinal().range(['#4CAF50','#7D8FAF'])
}

const renderVisualizations = (props) => (

    <StickyContainer>
      <Sticky className="foo"
              style={{color:'white', backgroundColor:'#7D8FAF', opacity: 1, zIndex:100}}
              stickyStyle={{color:'white', backgroundColor:'#7D8FAF', opacity: 1, zIndex:100}}>

             {
                             props.yearQuarterWheelChange((e.deltaY) < 0 ? 1 : -1)
                             e.preventDefault()}}>

                {`Q${props.yearQuarter.quarter}-${props.yearQuarter.year}`}

             {
                             props.radarGraphFirmageChange((e.deltaY) < 0 ? 1 : -1)
                             e.preventDefault()}}>

                {`Firmage: ${props.radarGraphFirmageLabel}`}

      </Sticky>

            <LineGraph data={props.lineGraphRawData}
                       key='qwi-rawData-linegraph'
                       uniq='qwi-rawData-linegraph'
                       yFormat={(props.measureIsCurrency) ? dollarFormatter : integerFormatter}
                       xScaleType={'time'}
                       yAxis={true}
                       margin={graphMargin}
                       tooltip={true}
                       quarterChangeListener={props.lineGraphYearQuarterChange} />

            <LineGraph data={props.lineGraphLQData}
                       key='qwi-lqData-linegraph'
                       uniq='qwi-lqData-linegraph'
                       xScaleType={'time'}
                       xAxis={true}
                       xFormat={d => d ? d3.time.format('%Y')(new Date(d)) : ''}
                       yAxis={true}
                       yFormat={floatFormatter}
                       margin={graphMargin}
                       tooltip={true}
                       quarterChangeListener={props.lineGraphYearQuarterChange} />

            <StartupsNaicsTooltip data={props.tooltipData}
                                  measureIsCurrency={
                                    (props.focusedLineGraph === 'qwi-rawData-linegraph') && props.measureIsCurrency
                                  }
                                  uniq={props.field} />

              {`Share of ${props.measure} by industry for ${props.radarGraphFirmageLabel} firms`}

          <RadarChart divID='typeShare'
                      data={props.shareOfMetroTotalRadarGraphData}
                      options={radarGraphOptions} />

            {`Share of by ${props.measure} by industry across firmages.`}

          <RadarChart divID='typeQout'
                      data={props.shareByIndustryRadarGraphData}
                      options={radarGraphOptions} />

        <StartupsOverviewTable data={props.overviewTableData}
                               sortFieldChange={props.overviewTableSortFieldChange} />

    </StickyContainer>

)

class MetroQwi extends React.Component<void, Props, void> {

  componentDidMount () {
    let props = this.props

    if (props.loadData && !props.lineGraphRawData) {
      props.msaChange(props.msa);
      props.measureChange(props.measure);

      props.loadData(props.msa, props.measure)
    }
  }

  componentWillReceiveProps (nextProps){
    let props = this.props

    props.msaChange(nextProps.msa)         // No effect if same msa
    props.measureChange(nextProps.measure) // No effect if same measure

    if (!nextProps.lineGraphRawData) {
      props.loadData(nextProps.msa, nextProps.measure)
    }
  }

  render () {
    return (this.props.lineGraphRawData) ? renderVisualizations(this.props) : (Loading...)
  }
}

export default MetroQwi
<|endoftext|>


<commit_before>import React from 'react';

const VideoListItem = (props) => {
  return
Video

};

export default VideoListItem;<commit_msg>displaying and basic styling of video results<commit_after>import React from 'react';

const VideoListItem = ({video}) => {
  const imageUrl = video.snippet.thumbnails.default.url;

  return (

{video.snippet.title}

  );
};

export default VideoListItem;<|endoftext|>


<commit_before>/**
  * Copies a table into the clipboard.
  * This allows pasting the table into Microsoft Excel.
  *
  * @param tbl The DOM table object, you can get it via document.getElementById() or similar functions.
  * @return Return TRUE on success, otherwise FALSE.
  */
function copyTableIntoClipboard(tbl) {
    if (!tbl) {
		return false;
	}

	var str = "";

    for (var y=0, rowsLen=tbl.rows.length; y<rowsLen; y++) {
        var row = tbl.rows[y];

        for (var x=0, cellsLen=row.cells.length; x<cellsLen; x++) {
            var content = row.cells[x].innerText;

            str += content;

            if (x != cellsLen-1) {
                str += "\t";
            }
        }

        if (y != rowsLen-1) {
            str += "\n";
        }
    }
    return window.clipboardData.setData("Text", str);
}<commit_msg>Replaced whitespaces by tabs<commit_after>/**
  * Copies a table into the clipboard.
  * This allows pasting the table into Microsoft Excel.
  *
  * @param tbl The DOM table object, you can get it via document.getElementById() or similar functions.
  * @return Return TRUE on success, otherwise FALSE.
  */
function copyTableIntoClipboard(tbl) {
	if (!tbl) {
		return false;
	}

	var str = "";

	for (var y=0, rowsLen=tbl.rows.length; y<rowsLen; y++) {
		var row = tbl.rows[y];

		for (var x=0, cellsLen=row.cells.length; x<cellsLen; x++) {
			var content = row.cells[x].innerText;

			str += content;

			if (x != cellsLen-1) {
				str += "\t";
			}
		}

		if (y != rowsLen-1) {
			str += "\n";
		}
	}
	return window.clipboardData.setData("Text", str);
}<|endoftext|>


<commit_before>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

**/

var Bundler     = require("./bundler"),
    Cache       = require("./cache"),
    Metadata    = require("./metadata"),
    Pipelines   = global.shipp.pipelines,
    Promise     = require("bluebird"),
    Utils       = require("./utils"),
    makeQueries = Promise.promisify(Utils.makeQueries);

var CACHE_MS = 1000 * 60 * 60 * 24;

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {String} id Source identifier
  @param {String} template String template
  @param {String} type The type of file

**/

function extractMetadata(id, template, type) {

  var metadata,
      directives;

  if (Utils.isHTML(type)) {
    // Currently leaving out the PARAM directive (until better planned)
    directives = {
      "DATA"    : "query",
      "QUERY"   : "query",
      "COOKIE"  : "object",
      "SESSION" : "object",
      "CACHE"   : "boolean"
    };
    metadata = Metadata.extract(template.slice(0, 500), directives);
    metadata.isTemplate = Utils.isTemplateFile(id, type);
  } else {
    // For non-HTML files default to caching
    metadata = { cache: true };
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Function} Function that compiles a file

**/

function createCompiler(file, type) {
  if (file.bundle)
    return Bundler.fromFile(file, type).get;
  else
    return Promise.promisify(Pipelines.compileFile.bind(Pipelines, file.path));
}

/**

  Pulls data from cookies, session, params, query, slug and metadata into
  single data object.

  @param {Object} metadata Metadata object as returns by metadata.js
  @returns {Object} The data object

**/

function aggregateData(metadata, params) {

  // Data object will include locals, cookies, session, params, query, slug
  // and if applicable, database query results
  var data = Object.assign({}, global.shipp.locals, params.locals);

  // Attach special variables
  data.$assets  = Object.assign({}, global.shipp.assets);
  data.$body    = params.body;
  data.$cookies = params.cookies;
  data.$params  = params.params;
  data.$query   = params.query;
  data.$session = params.session;

  // Special slug
  if (params.slug)
    data.$slug = params.slug

  // Set cookies
  for (var key in metadata.cookies || {})
    data.$cookies[key] = metadata.cookies[key];

  // Set session
  for (key in metadata.session || {})
    data.$session[key] = metadata.session[key];

  return data;

}

// !!! TODO: compiler must be file as well (accept template or file)
// !!! TODO: refactor aggregateData

/**

  Creates a renderer for a blueprint

  @param {String} id Source identifier
  @param {Object} source Object of form { template, file } with either "template" or "file"
  @param {String} type The type of file
  @param {String} pipeline Pipeline to use for compiler
  @return {Function} Handler of form (params = {}, compressionMethod = "identity", maxCompression = false)

  results {
    compression,
    metadata,
    sourceId,
    type,
    contents
  }

**/

function createRenderer(id, source, type, pipeline) {

  // !!! TODO: Handle HTML here, how to map type
  var metadata = extractMetadata(source, type) || {};
  var compiler = createCompiler(source, pipeline);

  var tasks = [compiler];
  var isHTML = Utils.isHTML(type);

  // Add data query if necessary
  if (metadata.data)
    tasks.unshift(createQueryFn(metadata.data));

  return function(params, compressionMethod, maxCompression) {

    // params should include relevant information normally on a req or res object
    var data = isHTML ? aggregateData(metadata, params) : {};

    // Default compression to identity to maintain compatibility with BrowserSync and other tools
    compressionMethod = compressionMethod || "identity";
    maxCompression = maxCompression || false;

    return Utils.sequence(tasks, data).then(function(rendered) {

      var results = {
        compression: compressionMethod,
        metadata: metadata,
        sourceId: id,
        type: type
      };

      // Uncompressed
      if ("identity" === compressionMethod) {
        results.contents = rendered;
        return results;

      // Compressed
      } else {
        return new Promise(function(resolve, reject) {
          // Note that we are not defaulting to
          Utils.compress(compressionMethod, rendered, maxCompression, function(err, compressed) {
            if (err) return reject(err)
            results.contents = compressed;
            resolve(results);
          });
        })

      }

    })
  }

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    return makeQueries(queries, context).then(function(data) {
      return Promise.resolve(Object.assign(data, context));
    });
  };
}

/**

  Add a pipeline if it does not exist.

  @param {String} ext The file extension for the pipeline

**/

function addPipeline(ext) {

  if (Pipelines.hasPipeline(ext)) return;

  try {
    Pipelines.addPipeline(ext);
  } catch (err) {
    global.shipp.logger.warn("");
    global.shipp.logger.warn("WARNING! There is no pipeline available for *." + ext + " files.");
    global.shipp.logger.warn("If this is not fixed, these files will not be served nor compiled.");
    global.shipp.logger.warn("You should add an appropriate pipeline to your shipp.json file.\n");
    return;
  }

}

/**

  Creates compilation pipeline for a file, adds route handlers and global lookup.

  @param {Router} router Parent router
  @param {File} file File information as returned by Utils#parse
  @param {String} [options.url] The base URL for the route
  @param {String} [options.type] The file type (html, js, css)

**/

function addFile(router, file, options) {

  // Stop-gap method to identify bundles in real-time
  if ("js" === options.type && !file.bundle && Utils.isIndexFile(file))
    file.bundle = true;

  options = options || {};
  options.url = options.url || "/";

  // Add to list of extensions if not present
  addPipeline(file.ext);

  var metadata = extractMetadata(file, options.type),
      compiler = createCompiler(file, options.type),
      handler  = createHandler(file, options.type, compiler, metadata),
      key;

  route = Utils.makeRoute(options.url, file, options);
  router.get(route, handler);

  // Add to assets (used in templating, as well as asset pipelines)
  if (!Utils.isHTML(options.type))
    global.shipp.assets[Utils.makeKey(route)] = route;

}

/**

  Given a file, removes corresponding route handler and global assets.

  @param {Router} router Parent router
  @param {File} file File information as returned by Utils#parse
  @param {String} [options.url] The base URL for the route
  @param {String} [options.type] The file type (html, js, css)

**/

function removeFile(router, file, options) {

  var route;

  options = options || {};
  options.url = options.url || "/";

  route = Utils.makeRoute(options.url, file, options);

  // Remove previous route
  Utils.removeRoute(router, route);

  // Delete from assets (used in templating, as well as asset pipelines)
  if (!Utils.isHTML(options.type))
    delete global.shipp.assets[Utils.makeKey(route)];

}

/**

  Creates compilation pipelines for files and add route handlers.

  @param {String} options.exts The default file extension to apply
  @param {String} options.path Directory to process
  @param {String} options.url Base url to route from: url structure = base + directory structure
  @param {Boolean} [options.bundleFolders] If true, applies folder bundling
  @param {Boolean} [options.recursive] If true, processes the directory recursively (default: true)
  @returns {Router} An express-style router

**/

module.exports = function(options) {

  var router  = global.shipp.router(),
      ignored = [],
      type    = Array.isArray(options.exts) ? options.exts[0] : options.exts;

  // Since we can have multiple exts, we attach the type to the options object
  options.type = type;

  Utils.getFiles(options.path, options).forEach(function(file) {

    // Handle the file
    addFile(router, file, { type: type, url: options.url });

    // Remove ignored directories from watch list
    if (file.ignored) ignored = ignored.concat(file.ignored);

  });

  Utils.watch(options.path, "*", {

    chokidar: {
      ignoreInitial : true,
      ignored: ignored,
    },

    type: type,

    add: function(file, compiled) {
      addFile(router, Utils.parse(file, options.path), { type: type, url: options.url });
    },

    change: function(file, compiled) {

      var file = Utils.parse(file, options.path),
          route = Utils.makeRoute(options.url, file, { type: type });

      // Monitor metadata only for HTML-files
      // We choose not to store and diff metadata as the add/remove process is
      // extremely fast (circa 1ms).
      if ("html" === options.type) {
        removeFile(router, file, { type: type, url: options.url });
        addFile(router, file, { type: type, url: options.url });
      }

      global.shipp.emit("route:refresh", { route: route });

    },

    unlink: function(file, compiled) {
      removeFile(router, Utils.parse(file, options.path), { type: type, url: options.url });
    }

  });

  return router;

};
<commit_msg>compiler: adds comments and structures code<commit_after>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

  • extractMetadata
  - createCompiler (!!! TODO: NEEDS CACHING)
  • aggregateData
  • createRenderer (!!! TODO: UPDATE WITH SOURCE)
  • createQueryFn
  • addPipeline

**/

/**

  Dependencies and exports

**/

var Bundler     = require("./bundler");
var Metadata    = require("./metadata");
var Promise     = require("bluebird");
var Utils       = require("./utils");

var Pipelines   = global.shipp.pipelines;
var makeQueries = Promise.promisify(Utils.makeQueries);

module.exports = {
  extractMetadata: extractMetadata,
  createCompiler: createCompiler,
  aggregateData: aggregateData,
  createRenderer: createRenderer,
  createQueryFn: createQueryFn,
  addPipeline: addPipeline
};

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {String} id Source identifier
  @param {String} template String template
  @param {String} type The type of file

**/

function extractMetadata(id, template, type) {

  var metadata,
      directives;

  if (Utils.isHTML(type)) {
    // Currently leaving out the PARAM directive (until better planned)
    directives = {
      "DATA"    : "query",
      "QUERY"   : "query",
      "COOKIE"  : "object",
      "SESSION" : "object",
      "CACHE"   : "boolean"
    };
    metadata = Metadata.extract(template.slice(0, 500), directives);
    metadata.isTemplate = Utils.isTemplateFile(id, type);
  } else {
    // For non-HTML files default to caching
    metadata = { cache: true };
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Stat} file fs.Stat object representing file
  @param {String} [type] Type of file
  @returns {Function} Function that compiles a file

**/

function createCompiler(file, type) {
  if (file.bundle)
    return Bundler.fromFile(file, type).get;
  else
    return Promise.promisify(Pipelines.compileFile.bind(Pipelines, file.path));
}

/**

  Pulls data from cookies, session, params, query, slug and metadata into
  single data object.

  @param {Object} metadata Metadata object as returns by metadata.js
  @param {Object} params Params object as provided by handler.js
  @returns {Object} The data object

**/

function aggregateData(metadata, params) {

  // Data object will include locals, cookies, session, params, query, slug
  // and if applicable, database query results
  var data = Object.assign({}, global.shipp.locals, params.locals);

  // Attach special variables
  data.$assets  = Object.assign({}, global.shipp.assets);
  data.$body    = params.body;
  data.$cookies = params.cookies;
  data.$params  = params.params;
  data.$query   = params.query;
  data.$session = params.session;

  // Special slug
  if (params.slug)
    data.$slug = params.slug

  // Set cookies
  for (var key in metadata.cookies || {})
    data.$cookies[key] = metadata.cookies[key];

  // Set session
  for (key in metadata.session || {})
    data.$session[key] = metadata.session[key];

  return data;

}

// !!! TODO: compiler must be file as well (accept template or file)
// !!! TODO: refactor aggregateData

/**

  Creates a renderer for a blueprint

  @param {String} id Source identifier
  @param {Object} source Object of form { template, file } with either "template" or "file"
  @param {String} type The type of file
  @param {String} pipeline Pipeline to use for compiler
  @return {Function} Handler of form (params = {}, compressionMethod = "identity", maxCompression = false)

  results {
    compression,
    metadata,
    sourceId,
    type,
    contents
  }

**/

function createRenderer(id, source, type, pipeline) {

  // !!! TODO: Handle HTML here, how to map type
  // !!! TODO: add generic source handler
  var metadata = extractMetadata(source, type) || {};
  var compiler = createCompiler(source, pipeline);

  var tasks = [compiler];
  var isHTML = Utils.isHTML(type);

  // Add data query if necessary
  if (metadata.data)
    tasks.unshift(createQueryFn(metadata.data));

  return function(params, compressionMethod, maxCompression) {

    // params should include relevant information normally on a req or res object
    var data = isHTML ? aggregateData(metadata, params) : {};

    // Default compression to identity to maintain compatibility with BrowserSync and other tools
    compressionMethod = compressionMethod || "identity";
    maxCompression = maxCompression || false;

    return Utils.sequence(tasks, data).then(function(rendered) {

      var results = {
        compression: compressionMethod,
        metadata: metadata,
        sourceId: id,
        type: type
      };

      // Uncompressed
      if ("identity" === compressionMethod) {
        results.contents = rendered;
        return results;

      // Compressed
      } else {
        return new Promise(function(resolve, reject) {
          // Note that we are not defaulting to
          Utils.compress(compressionMethod, rendered, maxCompression, function(err, compressed) {
            if (err) return reject(err)
            results.contents = compressed;
            resolve(results);
          });
        })

      }

    })
  }

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    return makeQueries(queries, context).then(function(data) {
      return Promise.resolve(Object.assign(data, context));
    });
  };
}

/**

  Add a pipeline if it does not exist.

  @param {String} ext The file extension for the pipeline

**/

function addPipeline(ext) {

  if (Pipelines.hasPipeline(ext)) return;

  try {
    Pipelines.addPipeline(ext);
  } catch (err) {
    global.shipp.logger.warn("");
    global.shipp.logger.warn("WARNING! There is no pipeline available for *." + ext + " files.");
    global.shipp.logger.warn("If this is not fixed, these files will not be served nor compiled.");
    global.shipp.logger.warn("You should add an appropriate pipeline to your shipp.json file.\n");
    return;
  }

}

<|endoftext|>


<commit_before>#ifndef __CUBEHASH__
#define __CUBEHASH__

#include "lib/common.js"

#define CubeHash_RotL(a,b) (((a) << (b)) | ((a) >>> (32-b)))
rndphrase.CubeHash = {
    // For info on CubeHash see: http://cubehash.cr.yp.to/
    // Init vector was computed by 10r rounds as described in the specification
    INIT : [-2096419883, 658334063, -679114902,
            1246757400, -1523021469, -289996037, 1196718146, 1168084361,
            -2027445816, -1170162360, -822837272, 625197683, 1543712850,
            -1365258909, 759513533, -424228083, -13765010209, -2824905881,
            -9887154026, 19352563566, 5669379852, -31581549269, 21359466527,
            10648459874, -8561790247, 9779462261, -22434204802, -4124492433,
            19608647852, 9541915967, 5144979599, -4355863926],
    int_to_hex : function (v) {
        var s = "";
        for (; v !== 0; v >>>= 8) {
            s += ((v>>4)&0xF).toString(16) + (v&0xF).toString(16);
        }
        return s;
    },
    swap : function (arr, i, j) {
        var tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
        return arr;
    },
    transform : function (state)
    {
        var i, r;
        var y = new Array(16);
        for (r = 0;r < 8; ++r) {
            for (i = 0;i < 16; ++i) state[i+16] += y[i^8] = state[i];
            for (i = 0;i < 16; ++i) state[i]     = CubeHash_RotL(y[i],7)^state[i+16];
            for (i = 0;i < 16; ++i) y[i^2]       = state[i + 16];
            for (i = 0;i < 16; ++i) state[i+16]  = y[i] + state[i];
            for (i = 0;i < 16; ++i) y[i^4]       = state[i];
            for (i = 0;i < 16; ++i) state[i]     = CubeHash_RotL(y[i],11) ^ state[i+16];
            for (i = 0; i < 16; i+=2) {
                this.swap(state, i+16, i+17);
	          }
        }
	      for(i = 0; i < 16; ++i) {
            y[i] = 0;
        }
    },
    hash : function (data)
    {
        // init state
        var i,s="",state = new Array(32);
        for (i = 0; i < 32; i++) state[i] = this.INIT[i];
        // update with data
        data += String.fromCharCode(128);
        for (i = 0; i < data.length; i++) {
            state[0] ^= data.charCodeAt(i);
            this.transform(state);
        }
        // finalize
        state[31] ^= 1;
        for (i = 0; i < 10; i++) this.transform(state);
        // convert to hex
        for (i = 0; i < 8; i++) s += this.int_to_hex(state[i]);
        return s;
    },
    self_test : function () {
        var tests = ["", "Hello", "The quick brown fox jumps over the lazy dog"];
        var hashs = [
            "38d1e8a22d7baac6fd5262d83de89cacf784a02caa866335299987722aeabc59",
            "692638db57760867326f851bd2376533f37b640bd47a0ddc607a9456b692f70f",
            "94e0c958d85cdfaf554919980f0f50b945b88ad08413e0762d6ff0219aff3e55"];
        for(var i = 0; i < tests.length; i++) {
            if (this.hash(tests[i]) != hashs[i]) {
                return false;
            }
        }
        return true;
    }
};
#endif
<commit_msg>Add CubeHash references<commit_after>#ifndef __CUBEHASH__
#define __CUBEHASH__

#include "lib/common.js"

#define CubeHash_RotL(a,b) (((a) << (b)) | ((a) >>> (32-b)))
rndphrase.CubeHash = {
    // For info on CubeHash see: http://cubehash.cr.yp.to/
    // Init vector was computed by 10r rounds as described in the specification
    INIT : [-2096419883, 658334063, -679114902,
            1246757400, -1523021469, -289996037, 1196718146, 1168084361,
            -2027445816, -1170162360, -822837272, 625197683, 1543712850,
            -1365258909, 759513533, -424228083, -13765010209, -2824905881,
            -9887154026, 19352563566, 5669379852, -31581549269, 21359466527,
            10648459874, -8561790247, 9779462261, -22434204802, -4124492433,
            19608647852, 9541915967, 5144979599, -4355863926],
    int_to_hex : function (v) {
        var s = "";
        for (; v !== 0; v >>>= 8) {
            s += ((v>>4)&0xF).toString(16) + (v&0xF).toString(16);
        }
        return s;
    },
    swap : function (arr, i, j) {
        var tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
        return arr;
    },
    transform : function (state)
    {
        var i, r;
        var y = new Array(16);
        for (r = 0;r < 8; ++r) {
            for (i = 0;i < 16; ++i) state[i+16] += y[i^8] = state[i];
            for (i = 0;i < 16; ++i) state[i]     = CubeHash_RotL(y[i],7)^state[i+16];
            for (i = 0;i < 16; ++i) y[i^2]       = state[i + 16];
            for (i = 0;i < 16; ++i) state[i+16]  = y[i] + state[i];
            for (i = 0;i < 16; ++i) y[i^4]       = state[i];
            for (i = 0;i < 16; ++i) state[i]     = CubeHash_RotL(y[i],11) ^ state[i+16];
            for (i = 0; i < 16; i+=2) {
                this.swap(state, i+16, i+17);
	          }
        }
	      for(i = 0; i < 16; ++i) {
            y[i] = 0;
        }
    },
    hash : function (data)
    {
        // init state
        var i,s="",state = new Array(32);
        for (i = 0; i < 32; i++) state[i] = this.INIT[i];
        // update with data
        data += String.fromCharCode(128);
        for (i = 0; i < data.length; i++) {
            state[0] ^= data.charCodeAt(i);
            this.transform(state);
        }
        // finalize
        state[31] ^= 1;
        for (i = 0; i < 10; i++) this.transform(state);
        // convert to hex
        for (i = 0; i < 8; i++) s += this.int_to_hex(state[i]);
        return s;
    },
    self_test : function () {
        // http://cubehash.cr.yp.to
        // http://en.wikipedia.org/wiki/CubeHash
        var tests = ["", "Hello", "The quick brown fox jumps over the lazy dog"];
        var hashs = [
            "38d1e8a22d7baac6fd5262d83de89cacf784a02caa866335299987722aeabc59",
            "692638db57760867326f851bd2376533f37b640bd47a0ddc607a9456b692f70f",
            "94e0c958d85cdfaf554919980f0f50b945b88ad08413e0762d6ff0219aff3e55"];
        for(var i = 0; i < tests.length; i++) {
            if (this.hash(tests[i]) != hashs[i]) {
                return false;
            }
        }
        return true;
    }
};
#endif
<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var toDescriptor = require('to-descriptor');
var CPPDatabase = require('bindings')({
	bindings: 'better_sqlite3.node',
	module_root: path.resolve(__dirname, '..'),
}).Database;

function Database(filenameGiven, options) {
	if (typeof filenameGiven !== 'string') {
		throw new TypeError('Expected argument 0 to be a string filename.');
	}

	var filename = filenameGiven.trim();
	if (typeof options !== 'object' || options === null) {
		options = {};
	}

	if (!filename) {
		throw new TypeError('A database filename cannot be an empty string.');
	}
	if (/^file:/i.test(filename)) {
		throw new TypeError('URI filenames are reserved for internal use only.');
	}
	if (/^(:memory:)?$/i.test(filename)) {
		throw new TypeError('To create an in-memory database, specify a normal filename and use the "memory" option.');
	}

	if (options.memory) {
		if (process.platform === 'win32') {
			filename = filename.replace(/\\/g, '/').replace(/^[a-z]:\//i, '/$&');
		}
		filename = 'file:'
			+ filename
				.replace(/\?/g, '%3f')
				.replace(/\/\/+/g, '/')
				.replace(/#/g, '%23')
			+ '?mode=memory&cache=shared';
	}

	return new CPPDatabase(filename, filenameGiven, !!options.memory);
}
CPPDatabase.prototype.constructor = Database;
Database.prototype = Object.create(Object.prototype, toDescriptor(CPPDatabase.prototype));
Object.setPrototypeOf(Database.prototype, EventEmitter.prototype);
Object.setPrototypeOf(CPPDatabase.prototype, Database.prototype);
module.exports = Database;
<commit_msg>removed event emitter from database prototype<commit_after>'use strict';
var path = require('path');
var toDescriptor = require('to-descriptor');
var CPPDatabase = require('bindings')({
	bindings: 'better_sqlite3.node',
	module_root: path.resolve(__dirname, '..'),
}).Database;

function Database(filenameGiven, options) {
	if (typeof filenameGiven !== 'string') {
		throw new TypeError('Expected argument 0 to be a string filename.');
	}

	var filename = filenameGiven.trim();
	if (typeof options !== 'object' || options === null) {
		options = {};
	}

	if (!filename) {
		throw new TypeError('A database filename cannot be an empty string.');
	}
	if (/^file:/i.test(filename)) {
		throw new TypeError('URI filenames are reserved for internal use only.');
	}
	if (/^(:memory:)?$/i.test(filename)) {
		throw new TypeError('To create an in-memory database, specify a normal filename and use the "memory" option.');
	}

	if (options.memory) {
		if (process.platform === 'win32') {
			filename = filename.replace(/\\/g, '/').replace(/^[a-z]:\//i, '/$&');
		}
		filename = 'file:'
			+ filename
				.replace(/\?/g, '%3f')
				.replace(/\/\/+/g, '/')
				.replace(/#/g, '%23')
			+ '?mode=memory&cache=shared';
	}

	return new CPPDatabase(filename, filenameGiven, !!options.memory);
}
CPPDatabase.prototype.constructor = Database;
Database.prototype = Object.create(Object.prototype, toDescriptor(CPPDatabase.prototype));
Object.setPrototypeOf(CPPDatabase.prototype, Database.prototype);
module.exports = Database;
<|endoftext|>


<commit_before>var pg = require("pg");

var database = {
  query: function(connection, sql, callback) {
    pg.connect(connection, function(err, client, done) {
      if(err) {
        done();
        callback(err, []);
      } else {
        client.query(sql, function(error, result) {
          done();
          callback(error, result.rows);
        });
      }
    });
  }
};

module.exports = database;
<commit_msg>Handle undefined results from the db<commit_after>var pg = require("pg");

var database = {
  query: function(connection, sql, callback) {
    pg.connect(connection, function(err, client, done) {
      if(err) {
        done();
        callback(err, []);
      } else {
        client.query(sql, function(error, result) {
          done();
          callback(error, (result || {}).rows);
        });
      }
    });
  }
};

module.exports = database;
<|endoftext|>


<commit_before>(function(){
  var mongoose, _, Database, Clog;

  mongoose = require('mongoose');
  _        = require('underscore');

  Database = (function(){
    function Database(options){
      var _this = this;
      this.options = options || {
        db: {
          url: 'mongodb://localhost/test'
        }
      }
      this.client = mongoose.createConnection(this.options.db.url);
      this.client.on('error', function(){
        console.log('mongodb connection error');
      });
      this.client.on('open', function(){
        console.log('mongodb ready!');
        _this._init()
      });
    }

    Database.prototype = {
      _init: function(){
        var clogSchema = new mongoose.Schema({
          id: mongoose.Schema.Types.ObjectId,
          timestamp: Date,
          source: String,
          context: String,
          content: String,
          parent: {type: mongoose.Schema.Types.ObjectId, default: null},
          children: {type: [mongoose.Schema.Types.ObjectId], default: []}
        });
        Clog = this.client.model('Clog', clogSchema);
      },

      _result: function(cb){
        var _cb = cb;
        return function(err, result){
          if(err){
            console.log(err)
            throw new Error(err);
          }
          else{
            if(_.isFunction(_cb))
              _cb(result);
          }
        }
      },

      create: function(obj, cb){
        var clog = new Clog(obj);
        clog.id = clog._id;
        clog.save(this._result(cb));
      },

      read: function(id, cb){
        Clog.findById(id, this._result(cb));
      },

      update: function(id, update, cb){
        Clog.findByIdAndUpdate(id, update, this._result(cb));
      },

      del: function(id, cb){
        Clog.findByIdAndRemove(id, this._result(cb));
      },

      all: function(cb){
        //TODO: must think about this, e.g. about pagination/limit
        Clog.find({}, this._result(cb));
      },

      since: function(timestamp, cb){
        Clog.find({timestamp: { $gte: timestamp }}, this._result(cb));
      }
    }

    return Database;
  })();
  module.exports = Database;
}).call(this);<commit_msg>added env variable for mongo URL<commit_after>(function(){
  var mongoose, _, Database, Clog;

  mongoose = require('mongoose');
  _        = require('underscore');

  Database = (function(){
    function Database(options){
      var _this = this;
      this.options = options || {
        db: {
          url: process.env.MONGOHQ_URL || 'mongodb://localhost/test'
        }
      }
      this.client = mongoose.createConnection(this.options.db.url);
      this.client.on('error', function(){
        console.log('mongodb connection error');
      });
      this.client.on('open', function(){
        console.log('mongodb ready!');
        _this._init()
      });
    }

    Database.prototype = {
      _init: function(){
        var clogSchema = new mongoose.Schema({
          id: mongoose.Schema.Types.ObjectId,
          timestamp: Date,
          source: String,
          context: String,
          content: String,
          parent: {type: mongoose.Schema.Types.ObjectId, default: null},
          children: {type: [mongoose.Schema.Types.ObjectId], default: []}
        });
        Clog = this.client.model('Clog', clogSchema);
      },

      _result: function(cb){
        var _cb = cb;
        return function(err, result){
          if(err){
            console.log(err)
            throw new Error(err);
          }
          else{
            if(_.isFunction(_cb))
              _cb(result);
          }
        }
      },

      create: function(obj, cb){
        var clog = new Clog(obj);
        clog.id = clog._id;
        clog.save(this._result(cb));
      },

      read: function(id, cb){
        Clog.findById(id, this._result(cb));
      },

      update: function(id, update, cb){
        Clog.findByIdAndUpdate(id, update, this._result(cb));
      },

      del: function(id, cb){
        Clog.findByIdAndRemove(id, this._result(cb));
      },

      all: function(cb){
        //TODO: must think about this, e.g. about pagination/limit
        Clog.find({}, this._result(cb));
      },

      since: function(timestamp, cb){
        Clog.find({timestamp: { $gte: timestamp }}, this._result(cb));
      }
    }

    return Database;
  })();
  module.exports = Database;
}).call(this);<|endoftext|>


<commit_before>var Collection = require('./collection')
var mongodb = require('mongodb')
var xtend = require('xtend')
var thunky = require('thunky')
var parse = require('parse-mongo-url')

var noop = function () {}

var Database = function (connString, cols, options) {
  var self = this

  // TODO: Cleanup theses options - including xtend stuff in index.js
  if (typeof connString === 'string') {
    this._dbname = parse(connString).dbName

    // TODO: Fix - protocol, host and port should come from but should be 'added' in case they are missing - also take rs, mongos in consideration
    if (connString.indexOf('mongodb://') < 0) {
      connString = 'mongodb://localhost/' + connString
    }

    this._getConnection = thunky(function (cb) {
      mongodb.connect(connString, options, cb)
    })
  } else if (typeof connString._getConnection === 'function') { // mongojs
    this._dbname = connString._dbname
    this._getConnection = connString._getConnection
  } else { // try mongodb-native
    // TODO: Make this safe - even for rs connection strings
    this._dbname = parse(connString.options.url).dbName

    this._getConnection = thunky(function (cb) {
      cb(null, connString)
    })
  }

  this.ObjectId = mongodb.ObjectId

  // TODO: Should we leave this to mongodb?
  cols = cols || []
  cols.forEach(function (colName) {
    self[colName] = self.collection(colName)

    var parts = colName.split('.')

    var last = parts.pop()
    var parent = parts.reduce(function (parent, prefix) {
      parent[prefix] = parent[prefix] || {}
      return parent[prefix]
    }, self)

    parent[last] = self.collection(colName)
  })
}

// TODO: Fix event handling
Database.prototype.on = function (event, handler) {
  this._server.on(event, handler)
  return this
}

Database.prototype.collection = function (colName) {
  return new Collection({name: colName}, this._getConnection)
}

Database.prototype.close = function (force, cb) {
  if (typeof force === 'function') { return this.close(false, force) }

  cb = cb || noop
  this._getConnection(function (err, server) {
    if (err) return cb(err)

    server.close(force)
    cb()
  })
}

Database.prototype.runCommand = function (opts, cb) {
  cb = cb || noop
  if (typeof opts === 'string') {
    var tmp = opts
    opts = {}
    opts[tmp] = 1
  }

  this._getConnection(function (err, connection) {
    if (err) return cb(err)
    connection.command(opts, function (err, result) {
      if (err) return cb(err)
      cb(null, result)
    })
  })
}

Database.prototype.getCollectionNames = function (cb) {
  this.collection('system.namespaces').find({name: /^((?!\$).)*$/}, function (err, cols) {
    if (err) return cb(err)
    cb(null, cols.map(function (col) {
      return col.name.split('.').splice(1).join('.')
    }))
  })
}

Database.prototype.createCollection = function (name, opts, cb) {
  if (typeof opts === 'function') return this.createCollection(name, {}, opts)

  var cmd = {create: name}
  Object.keys(opts).forEach(function (opt) {
    cmd[opt] = opts[opt]
  })
  this.runCommand(cmd, cb)
}

Database.prototype.stats = function (scale, cb) {
  if (typeof scale === 'function') return this.stats(1, scale)
  this.runCommand({dbStats: 1, scale: scale}, cb)
}

Database.prototype.dropDatabase = function (cb) {
  this.runCommand('dropDatabase', cb)
}

Database.prototype.createUser = function (usr, cb) {
  var cmd = xtend({createUser: usr.user}, usr)
  delete cmd.user
  this.runCommand(cmd, cb)
}
Database.prototype.addUser = Database.prototype.createUser

Database.prototype.dropUser = function (username, cb) {
  this.runCommand({dropUser: username}, cb)
}
Database.prototype.removeUser = Database.prototype.dropUser

Database.prototype.eval = function (fn) {
  var cb = arguments[arguments.length - 1]
  this.runCommand({
    eval: fn.toString(),
    args: Array.prototype.slice.call(arguments, 1, arguments.length - 1)
  }, function (err, res) {
    if (err) return cb(err)
    cb(null, res.retval)
  })
}

Database.prototype.getLastErrorObj = function (cb) {
  this.runCommand('getLastError', cb)
}

Database.prototype.getLastError = function (cb) {
  this.runCommand('getLastError', function (err, res) {
    if (err) return cb(err)
    cb(null, res.err)
  })
}

Database.prototype.toString = function () {
  return this._dbname
}

module.exports = Database
<commit_msg>Make database an EventEmitter and emit events for error and connect<commit_after>var Collection = require('./collection')
var mongodb = require('mongodb')
var xtend = require('xtend')
var thunky = require('thunky')
var parse = require('parse-mongo-url')
var util = require('util')
var EventEmitter = require('events').EventEmitter

var noop = function () {}

var Database = function (connString, cols, options) {
  var self = this

  // TODO: Cleanup theses options - including xtend stuff in index.js
  if (typeof connString === 'string') {
    this._dbname = parse(connString).dbName

    // TODO: Fix - protocol, host and port should come from but should be 'added' in case they are missing - also take rs, mongos in consideration
    if (connString.indexOf('mongodb://') < 0) {
      connString = 'mongodb://localhost/' + connString
    }

    this._getConnection = thunky(function (cb) {
      mongodb.connect(connString, options, function (err, db) {
        if (err) {
          // TODO: Should we really emit error? This requires a listener attached? Only if listeners attached?
          if (self.listeners('error').length > 0) {
            self.emit('error', err)
          }

          return cb(err)
        }

        // TODO: Should we fire a connect event for all other cases too?
        self.emit('connect')
        cb(null, db)
      })
    })
  } else if (typeof connString._getConnection === 'function') { // mongojs
    this._dbname = connString._dbname
    this._getConnection = connString._getConnection
  } else { // try mongodb-native
    // TODO: Make this safe - even for rs connection strings
    this._dbname = parse(connString.options.url).dbName

    this._getConnection = thunky(function (cb) {
      cb(null, connString)
    })
  }

  this.ObjectId = mongodb.ObjectId

  // TODO: Should we leave this to mongodb?
  cols = cols || []
  cols.forEach(function (colName) {
    self[colName] = self.collection(colName)

    var parts = colName.split('.')

    var last = parts.pop()
    var parent = parts.reduce(function (parent, prefix) {
      parent[prefix] = parent[prefix] || {}
      return parent[prefix]
    }, self)

    parent[last] = self.collection(colName)
  })
}

util.inherits(Database, EventEmitter)

Database.prototype.collection = function (colName) {
  return new Collection({name: colName}, this._getConnection)
}

Database.prototype.close = function (force, cb) {
  if (typeof force === 'function') { return this.close(false, force) }

  var self = this

  cb = cb || noop
  this._getConnection(function (err, server) {
    if (err) return cb(err)

    server.close(force)

    self.emit('close')
    cb()
  })
}

Database.prototype.runCommand = function (opts, cb) {
  cb = cb || noop
  if (typeof opts === 'string') {
    var tmp = opts
    opts = {}
    opts[tmp] = 1
  }

  this._getConnection(function (err, connection) {
    if (err) return cb(err)
    connection.command(opts, function (err, result) {
      if (err) return cb(err)
      cb(null, result)
    })
  })
}

Database.prototype.getCollectionNames = function (cb) {
  this.collection('system.namespaces').find({name: /^((?!\$).)*$/}, function (err, cols) {
    if (err) return cb(err)
    cb(null, cols.map(function (col) {
      return col.name.split('.').splice(1).join('.')
    }))
  })
}

Database.prototype.createCollection = function (name, opts, cb) {
  if (typeof opts === 'function') return this.createCollection(name, {}, opts)

  var cmd = {create: name}
  Object.keys(opts).forEach(function (opt) {
    cmd[opt] = opts[opt]
  })
  this.runCommand(cmd, cb)
}

Database.prototype.stats = function (scale, cb) {
  if (typeof scale === 'function') return this.stats(1, scale)
  this.runCommand({dbStats: 1, scale: scale}, cb)
}

Database.prototype.dropDatabase = function (cb) {
  this.runCommand('dropDatabase', cb)
}

Database.prototype.createUser = function (usr, cb) {
  var cmd = xtend({createUser: usr.user}, usr)
  delete cmd.user
  this.runCommand(cmd, cb)
}
Database.prototype.addUser = Database.prototype.createUser

Database.prototype.dropUser = function (username, cb) {
  this.runCommand({dropUser: username}, cb)
}
Database.prototype.removeUser = Database.prototype.dropUser

Database.prototype.eval = function (fn) {
  var cb = arguments[arguments.length - 1]
  this.runCommand({
    eval: fn.toString(),
    args: Array.prototype.slice.call(arguments, 1, arguments.length - 1)
  }, function (err, res) {
    if (err) return cb(err)
    cb(null, res.retval)
  })
}

Database.prototype.getLastErrorObj = function (cb) {
  this.runCommand('getLastError', cb)
}

Database.prototype.getLastError = function (cb) {
  this.runCommand('getLastError', function (err, res) {
    if (err) return cb(err)
    cb(null, res.err)
  })
}

Database.prototype.toString = function () {
  return this._dbname
}

module.exports = Database
<|endoftext|>


<commit_before>var mysql = require('mysql'),
    templates = require("./sql_templates"),
    utils = require('../utils'),
    MySQL;

MySQL = module.exports = function MySQL(options) {
  this.connection = mysql.createClient(options);
};

MySQL.prototype = {
  constructor: MySQL,
  connect: function (fn) {
    this.connection.useDatabase(this.connection.database, fn);
  },
  disconnect: function (fn) {
    this.connection.end(fn);
  },
  getBin: function (params, fn) {
    var values = [params.id, params.revision];
    this.connection.query(templates.getBin, values, function (err, results) {
      if (err || !results.length) {
        return fn(!err && !results.length ? 'not-found' : err);
      }
      fn(null, results[0]);
    });
  },
  setBin: function (params, fn) {
    var values = [
      params.javascript,
      params.css,
      params.html,
      params.url,
      params.revision,
      params.streamingKey
    ], sql = templates.setBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRow) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinPanel: function (panel, params, fn) {
    var values = [
      params[panel],
      params.url,
      params.revision,
      params.streamingKey
    ],
    allowed = {html: 1, css: 1, javascript: 1},
    sql = templates.setBinPanel.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRow) {
          return fn(err || 'no-entry');
        }
        fn(null, result.insertId);
      });
    } else {
      fn('invalid-panel');
    }
  },
  getLatestBin: function (params, fn) {
    var values = [params.id],
        sql = templates.getLatestBin;

    this.connection.query(sql, values, function (err, results) {
      if (err || !results.length) {
        return fn(!err && !results.length ? 'not-found' : err);
      }
      fn(null, results[0]);
    });
  },
  getBinsByOwner: function (where) {
  },
  generateBinId: function (fn, attempts) {
    var id = utils.shortcode(), mysql = this;

    attempts = attempts || 1;
    if (attempts <= 10) {
      this.connection.query(templates.binExists, [id], function (err, results) {
        if (err) {
          fn(err);
        } else if (results.length) {
          attempts += 1;
          mysql.generateBinId(fn, attempts);
        } else {
          fn(null, id);
        }
      });
    } else {
      fn("too-many-tries"); // Need error objects.
    }
  }
};
<commit_msg>Now correctly checking for updated rows in mysql.js<commit_after>var mysql = require('mysql'),
    templates = require("./sql_templates"),
    utils = require('../utils'),
    MySQL;

MySQL = module.exports = function MySQL(options) {
  this.connection = mysql.createClient(options);
};

MySQL.prototype = {
  constructor: MySQL,
  connect: function (fn) {
    this.connection.useDatabase(this.connection.database, fn);
  },
  disconnect: function (fn) {
    this.connection.end(fn);
  },
  getBin: function (params, fn) {
    var values = [params.id, params.revision];
    this.connection.query(templates.getBin, values, function (err, results) {
      if (err || !results.length) {
        return fn(!err && !results.length ? 'not-found' : err);
      }
      fn(null, results[0]);
    });
  },
  setBin: function (params, fn) {
    var values = [
      params.javascript,
      params.css,
      params.html,
      params.url,
      params.revision,
      params.streamingKey
    ], sql = templates.setBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinPanel: function (panel, params, fn) {
    var values = [
      params[panel],
      params.url,
      params.revision,
      params.streamingKey
    ],
    allowed = {html: 1, css: 1, javascript: 1},
    sql = templates.setBinPanel.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRows) {
          return fn(err || 'no-entry');
        }
        fn(null, result.insertId);
      });
    } else {
      fn('invalid-panel');
    }
  },
  getLatestBin: function (params, fn) {
    var values = [params.id],
        sql = templates.getLatestBin;

    this.connection.query(sql, values, function (err, results) {
      if (err || !results.length) {
        return fn(!err && !results.length ? 'not-found' : err);
      }
      fn(null, results[0]);
    });
  },
  getBinsByOwner: function (where) {
  },
  generateBinId: function (fn, attempts) {
    var id = utils.shortcode(), mysql = this;

    attempts = attempts || 1;
    if (attempts <= 10) {
      this.connection.query(templates.binExists, [id], function (err, results) {
        if (err) {
          fn(err);
        } else if (results.length) {
          attempts += 1;
          mysql.generateBinId(fn, attempts);
        } else {
          fn(null, id);
        }
      });
    } else {
      fn("too-many-tries"); // Need error objects.
    }
  }
};
<|endoftext|>


<commit_before>var mysql = require('mysql'),
    templates = require("./sql_templates"),
    utils = require('../utils');

module.exports = utils.inherit(Object, {
  defaults: null,
  constructor: function MySQL(options) {
    this.options    = options;
    this.defaults   = {html: '', css: '', javascript: ''};
    this.connection = mysql.createPool(options);
    // note: the this.connection.connect() is implicit
  },
  connect: function (fn) {
    // Allow us to override the default charset. node-mysql does not allow us
    // to provide utf8mb4 as a charset, as it uses predefined constants. So we
    // work around this by passing a string. If the user has overridden this
    // in their config then we skip this step.
/*    if (typeof this.options.charset === 'string') {
      var params = [this.options.charset]; //, this.options.collate];
      this.connection.query('SET NAMES ?', params, fn);
    } else {*/
      fn();
//    }
  },
  disconnect: function (fn) {
    this.connection.end(fn);
  },
  getBin: function (params, fn) {
    // This is not the 'id' it's the URL field.
    var values = [params.id, params.revision],
        _this = this;

    this.connection.query(templates.getBin, values, function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0] && _this.applyBinDefaults(results[0]));
    });
  },
  setBin: function (params, fn) {
    var now = new Date(), values = [
      params.javascript || '',
      params.css || '',
      params.html || '',
      now,
      now,
      params.url,
      params.revision,
      params.streamingKey,
      params.settings
    ], sql = templates.setBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinOwner: function (params, fn) {
    var sql = templates.setBinOwner,
        values = [params.name, params.url, params.revision, new Date(), params.summary, params.html, params.css, params.javascript];

    // TODO: Re-factor common callbacks into helpers.
    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinPanel: function (panel, params, fn) {
    var values = [
          params[panel],
          params.settings,
          new Date(),
          params.url,
          params.revision,
          params.streamingKey
        ],
        allowed = {html: 1, css: 1, javascript: 1},
        sql = templates.setBinPanel.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRows) {
          return fn(err || 'no-entry');
        }
        fn(null, result.insertId);
      });
    } else {
      fn('invalid-panel');
    }
  },
  getLatestBin: function (params, fn) {
    var values = [params.id],
        sql = templates.getLatestBin,
        _this = this;

    this.connection.query(sql, values, function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0] && _this.applyBinDefaults(results[0]));
    });
  },
  getLatestBinForUser: function (id, n, fn) {
    var sql = templates.getLatestBinForUser,
        query = this.connection.query.bind(this.connection),
        _this = this;

    query(sql, [id, n], function (err, result) {
      var sql = templates.getBinByUrlAndRevision;

      if (err) {
        return fn(err);
      }

      // i.e. if they've never saved anything before
      if (result.length === 0) {
        return fn(null, null);
      }

      _this.getBin({ id: result[0].url, revision: result[0].revision }, fn);
    });
  },
  getBinsByUser: function (id, fn) {
    var sql = templates.getBinsByUser,
        query = this.connection.query.bind(this.connection),
        _this = this;

    query(sql, [id], function (err, results) {
      if (err) {
        return fn(err);
      }

      var sql = templates.getBinByUrlAndRevision,
          collected = [];

      // i.e. if they've never saved anything before
      results.forEach(function (result) {
        collected.push(_this.applyBinDefaults(result));
      });
      fn(null, collected);
    });
  },
  // Get all bins from the owners field
  getAllOwners: function (fn) {
    // Get all the 'owned' bins
    this.connection.query(templates.getAllOwners, [], fn);
  },
  getOwnersBlock: function (start, size, fn) {
    // Get all the 'owned' bins
    this.connection.query(templates.getOwnersBlock, [start, size], fn);
  },
  generateBinId: function (fn, attempts) {
    attempts = attempts || 1;

    var id = utils.shortcode(3 + attempts), mysql = this;

    if (attempts <= 10) {
      this.connection.query(templates.binExists, [id], function (err, results) {
        if (err) {
          fn(err);
        } else if (results.length) {
          attempts += 1;
          mysql.generateBinId(fn, attempts);
        } else {
          fn(null, id);
        }
      });
    } else {
      fn(new Error("too-many-tries"))
    }
  },
  archiveBin: function (bin, fn) {
    var values = [bin.archive, bin.name, bin.url, bin.revision],
        sql = templates.archiveBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result);
    });
  },
  getUser: function (id, fn) {
    var _this = this;
    this.connection.query(templates.getUser, [id], function (err, results) {
      if (err) {
        return fn(err);
      } else if (results.length === 0) {
        _this.connection.query(templates.getUserByEmail, [id], function (err, results) {
          if (err) {
            return fn(err);
          }

          fn(null, results[0]);
        });
      } else {
        fn(null, results[0]);
      }
    });
  },
  getUserByApiKey: function (apiKey, fn) {
    this.connection.query(templates.getUserByApiKey, [apiKey], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  getUserByEmail: function (email, fn) {
    this.connection.query(templates.getUserByEmail, [email], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  setUser: function (params, fn) {
    var now = new Date(), values = [
      params.name,
      params.key,
      params.email,
      now,
      now,
      now,
      params.github_token || null,
      params.github_id || null,
    ], sql = templates.setUser;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  touchOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.name, params.url, params.revision];

    this.connection.query(templates.touchOwners, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }

      if (typeof fn === 'function') {
        fn(null, result.insertId);
      }
    });
  },
  updateOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.summary, params.panel_open, params.name, params.url, params.revision];

    var panel = params.panel,
        allowed = {html: 1, css: 1, javascript: 1},
        sql = templates.updateOwners.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRows) {
          return fn(err);
        }

        if (typeof fn === 'function') {
          fn(null, result.insertId);
        }
      });
    } else {
      fn('invalid-panel');
    }
  },
  populateOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.summary, params.html, params.css, params.javascript, params.name, params.url, params.revision];

    this.connection.query(templates.populateOwners, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }

      if (typeof fn === 'function') {
        fn(null, result.insertId);
      }
    });
  },
  touchLogin: function (id, fn) {
    var now = new Date();
    this.connection.query(templates.touchLogin, [now, id], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserEmail: function (id, email, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserEmail, [email, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserGithubData: function (id, ghId, token, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserGithubData, [ghId, token, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserKey: function (id, key, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserKey, [key, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  // Different to updateUserKey() in that it also sets the created timestamp
  // which is required to differentiate between a JSBin 2 user and a new
  // one.
  upgradeUserKey: function (id, key, fn) {
    var now = new Date();
    this.connection.query(templates.upgradeUserKey, [key, now, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  getUserByForgotToken: function (token, fn) {
    var sql = templates.getUserForForgotToken;

    this.connection.query(sql, [token, new Date()], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  setForgotToken: function (user, token, fn) {
    var sql = templates.setForgotToken,
        expires = this.expireDate(),
        params = [user, token, expires, new Date()];

    this.connection.query(sql, params, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  expireForgotToken: function (token, fn) {
    var sql = templates.deleteExpiredForgotToken;

    // Allow all old tokens to be expired with same call.
    if (typeof token === 'function') {
      fn = token;
      token = null;
    }

    this.connection.query(sql, [new Date(), token, null], function (err, results) {
      fn(err || null);
    });
  },
  expireForgotTokenByUser: function (user, fn) {
    var sql = templates.deleteExpiredForgotToken;

    this.connection.query(sql, [new Date(), null, user], function (err, results) {
      fn(err || null);
    });
  },
  expireDate: function () {
    var expires = new Date();
    expires.setUTCDate(expires.getUTCDate() + 1);
    return expires;
  },
  applyBinDefaults: function (bin) {
    for (var prop in this.defaults) {
      if (bin[prop] == null) { // Using == to catch null and undefined.
        bin[prop] = this.defaults[prop];
      }
    }

    if (!bin.last_updated || bin.last_updated == '0000-00-00 00:00:00' || isNaN(bin.last_updated.getTime())) bin.last_updated = new Date('2012-07-23 00:00:00');

    try {
      bin.settings = JSON.parse(bin.settings || '{}');
    } catch (e) {
      // this is likely because the settings were screwed in a beta build
      bin.settings = {};
    }

    return bin;
  },
  reportBin: function (params, fn) {
    var now = new Date(), values = [
      now,
      params.url,
      params.revision
    ], sql = templates.reportBin;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  isOwnerOf: function (params, fn) {
    var values = [
      params.name,
      params.url
    ], sql = templates.isOwnerOf;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, { found: !!result.length, isowner: result.length ? result[0].owner === 1 : false });
    });
  },
  getUserBinCount: function (id, fn) {
    var values = [id],
        sql = templates.getUserBinCount;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, { found: !!result.length, total: result.length ? result[0].total : 0 });
    });
  },
    // getOne('<sql template>', [constraint1, constraint2, ...], fn)
  getOne: function (queryKey, params, fn) {
    this.connection.query(templates[queryKey], params, function (err, result) {
      if (err) {
        fn(err, null);
      } else {
        fn(null, result.length ? result[0] : null);
      }
    });
  },
  isPrivate: function(bin, fn) {
    var sql = templates.isPrivate;
    this.connection.query(sql, [bin.url, bin.revision], function(err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, result[0] ? !!result[0].private : false);
    });
  }
});
<commit_msg>Updating isPrivate, Adding getBinOwner<commit_after>var mysql = require('mysql'),
    templates = require("./sql_templates"),
    utils = require('../utils');

module.exports = utils.inherit(Object, {
  defaults: null,
  constructor: function MySQL(options) {
    this.options    = options;
    this.defaults   = {html: '', css: '', javascript: ''};
    this.connection = mysql.createPool(options);
    // note: the this.connection.connect() is implicit
  },
  connect: function (fn) {
    // Allow us to override the default charset. node-mysql does not allow us
    // to provide utf8mb4 as a charset, as it uses predefined constants. So we
    // work around this by passing a string. If the user has overridden this
    // in their config then we skip this step.
/*    if (typeof this.options.charset === 'string') {
      var params = [this.options.charset]; //, this.options.collate];
      this.connection.query('SET NAMES ?', params, fn);
    } else {*/
      fn();
//    }
  },
  disconnect: function (fn) {
    this.connection.end(fn);
  },
  getBin: function (params, fn) {
    // This is not the 'id' it's the URL field.
    var values = [params.id, params.revision],
        _this = this;

    this.connection.query(templates.getBin, values, function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0] && _this.applyBinDefaults(results[0]));
    });
  },
  setBin: function (params, fn) {
    var now = new Date(), values = [
      params.javascript || '',
      params.css || '',
      params.html || '',
      now,
      now,
      params.url,
      params.revision,
      params.streamingKey,
      params.settings
    ], sql = templates.setBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinOwner: function (params, fn) {
    var sql = templates.setBinOwner,
        values = [params.name, params.url, params.revision, new Date(), params.summary, params.html, params.css, params.javascript];

    // TODO: Re-factor common callbacks into helpers.
    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  setBinPanel: function (panel, params, fn) {
    var values = [
          params[panel],
          params.settings,
          new Date(),
          params.url,
          params.revision,
          params.streamingKey
        ],
        allowed = {html: 1, css: 1, javascript: 1},
        sql = templates.setBinPanel.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRows) {
          return fn(err || 'no-entry');
        }
        fn(null, result.insertId);
      });
    } else {
      fn('invalid-panel');
    }
  },
  getLatestBin: function (params, fn) {
    var values = [params.id],
        sql = templates.getLatestBin,
        _this = this;

    this.connection.query(sql, values, function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0] && _this.applyBinDefaults(results[0]));
    });
  },
  getLatestBinForUser: function (id, n, fn) {
    var sql = templates.getLatestBinForUser,
        query = this.connection.query.bind(this.connection),
        _this = this;

    query(sql, [id, n], function (err, result) {
      var sql = templates.getBinByUrlAndRevision;

      if (err) {
        return fn(err);
      }

      // i.e. if they've never saved anything before
      if (result.length === 0) {
        return fn(null, null);
      }

      _this.getBin({ id: result[0].url, revision: result[0].revision }, fn);
    });
  },
  getBinsByUser: function (id, fn) {
    var sql = templates.getBinsByUser,
        query = this.connection.query.bind(this.connection),
        _this = this;

    query(sql, [id], function (err, results) {
      if (err) {
        return fn(err);
      }

      var sql = templates.getBinByUrlAndRevision,
          collected = [];

      // i.e. if they've never saved anything before
      results.forEach(function (result) {
        collected.push(_this.applyBinDefaults(result));
      });
      fn(null, collected);
    });
  },
  // Get all bins from the owners field
  getAllOwners: function (fn) {
    // Get all the 'owned' bins
    this.connection.query(templates.getAllOwners, [], fn);
  },
  getOwnersBlock: function (start, size, fn) {
    // Get all the 'owned' bins
    this.connection.query(templates.getOwnersBlock, [start, size], fn);
  },
  generateBinId: function (fn, attempts) {
    attempts = attempts || 1;

    var id = utils.shortcode(3 + attempts), mysql = this;

    if (attempts <= 10) {
      this.connection.query(templates.binExists, [id], function (err, results) {
        if (err) {
          fn(err);
        } else if (results.length) {
          attempts += 1;
          mysql.generateBinId(fn, attempts);
        } else {
          fn(null, id);
        }
      });
    } else {
      fn(new Error("too-many-tries"))
    }
  },
  archiveBin: function (bin, fn) {
    var values = [bin.archive, bin.name, bin.url, bin.revision],
        sql = templates.archiveBin;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result);
    });
  },
  getUser: function (id, fn) {
    var _this = this;
    this.connection.query(templates.getUser, [id], function (err, results) {
      if (err) {
        return fn(err);
      } else if (results.length === 0) {
        _this.connection.query(templates.getUserByEmail, [id], function (err, results) {
          if (err) {
            return fn(err);
          }

          fn(null, results[0]);
        });
      } else {
        fn(null, results[0]);
      }
    });
  },
  getUserByApiKey: function (apiKey, fn) {
    this.connection.query(templates.getUserByApiKey, [apiKey], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  getUserByEmail: function (email, fn) {
    this.connection.query(templates.getUserByEmail, [email], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  setUser: function (params, fn) {
    var now = new Date(), values = [
      params.name,
      params.key,
      params.email,
      now,
      now,
      now,
      params.github_token || null,
      params.github_id || null,
    ], sql = templates.setUser;

    this.connection.query(sql, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  touchOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.name, params.url, params.revision];

    this.connection.query(templates.touchOwners, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }

      if (typeof fn === 'function') {
        fn(null, result.insertId);
      }
    });
  },
  updateOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.summary, params.panel_open, params.name, params.url, params.revision];

    var panel = params.panel,
        allowed = {html: 1, css: 1, javascript: 1},
        sql = templates.updateOwners.replace(':panel', panel);

    if (allowed[panel]) {
      this.connection.query(sql, values, function (err, result) {
        if (err || !result.affectedRows) {
          return fn(err);
        }

        if (typeof fn === 'function') {
          fn(null, result.insertId);
        }
      });
    } else {
      fn('invalid-panel');
    }
  },
  populateOwners: function (params, fn) {
    // params.date is only for use when populating the summary field
    var values = [params.date || new Date(), params.summary, params.html, params.css, params.javascript, params.name, params.url, params.revision];

    this.connection.query(templates.populateOwners, values, function (err, result) {
      if (err || !result.affectedRows) {
        return fn(err);
      }

      if (typeof fn === 'function') {
        fn(null, result.insertId);
      }
    });
  },
  touchLogin: function (id, fn) {
    var now = new Date();
    this.connection.query(templates.touchLogin, [now, id], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserEmail: function (id, email, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserEmail, [email, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserGithubData: function (id, ghId, token, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserGithubData, [ghId, token, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  updateUserKey: function (id, key, fn) {
    var now = new Date();
    this.connection.query(templates.updateUserKey, [key, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  // Different to updateUserKey() in that it also sets the created timestamp
  // which is required to differentiate between a JSBin 2 user and a new
  // one.
  upgradeUserKey: function (id, key, fn) {
    var now = new Date();
    this.connection.query(templates.upgradeUserKey, [key, now, now, id], function (err) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  getUserByForgotToken: function (token, fn) {
    var sql = templates.getUserForForgotToken;

    this.connection.query(sql, [token, new Date()], function (err, results) {
      if (err) {
        return fn(err);
      }
      fn(null, results[0]);
    });
  },
  setForgotToken: function (user, token, fn) {
    var sql = templates.setForgotToken,
        expires = this.expireDate(),
        params = [user, token, expires, new Date()];

    this.connection.query(sql, params, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, result.insertId);
    });
  },
  expireForgotToken: function (token, fn) {
    var sql = templates.deleteExpiredForgotToken;

    // Allow all old tokens to be expired with same call.
    if (typeof token === 'function') {
      fn = token;
      token = null;
    }

    this.connection.query(sql, [new Date(), token, null], function (err, results) {
      fn(err || null);
    });
  },
  expireForgotTokenByUser: function (user, fn) {
    var sql = templates.deleteExpiredForgotToken;

    this.connection.query(sql, [new Date(), null, user], function (err, results) {
      fn(err || null);
    });
  },
  expireDate: function () {
    var expires = new Date();
    expires.setUTCDate(expires.getUTCDate() + 1);
    return expires;
  },
  applyBinDefaults: function (bin) {
    for (var prop in this.defaults) {
      if (bin[prop] == null) { // Using == to catch null and undefined.
        bin[prop] = this.defaults[prop];
      }
    }

    if (!bin.last_updated || bin.last_updated == '0000-00-00 00:00:00' || isNaN(bin.last_updated.getTime())) bin.last_updated = new Date('2012-07-23 00:00:00');

    try {
      bin.settings = JSON.parse(bin.settings || '{}');
    } catch (e) {
      // this is likely because the settings were screwed in a beta build
      bin.settings = {};
    }

    return bin;
  },
  reportBin: function (params, fn) {
    var now = new Date(), values = [
      now,
      params.url,
      params.revision
    ], sql = templates.reportBin;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null);
    });
  },
  isOwnerOf: function (params, fn) {
    var values = [
      params.name,
      params.url
    ], sql = templates.isOwnerOf;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, { found: !!result.length, isowner: result.length ? result[0].owner === 1 : false });
    });
  },
  getUserBinCount: function (id, fn) {
    var values = [id],
        sql = templates.getUserBinCount;

    this.connection.query(sql, values, function (err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, { found: !!result.length, total: result.length ? result[0].total : 0 });
    });
  },
    // getOne('<sql template>', [constraint1, constraint2, ...], fn)
  getOne: function (queryKey, params, fn) {
    this.connection.query(templates[queryKey], params, function (err, result) {
      if (err) {
        fn(err, null);
      } else {
        fn(null, result.length ? result[0] : null);
      }
    });
  },
  getVisibility: function(bin, fn) {
    var sql = templates.getVisibility;
    this.connection.query(sql, [bin.url, bin.revision], function(err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, result[0] ? result[0].visibility : false);
    });
  },
  getBinOwner: function(bin, fn) {
    var sql = templates.getBinOwner;
    this.connection.query(sql, [bin.url, bin.revision], function(err, result) {
      if (err) {
        return fn(err);
      }
      fn(null, result[0] ? result[0] : false);
    });
  }

});
<|endoftext|>


<commit_before>'use strict';

var defineProperty   = Object.defineProperty
  , push             = require('es5-ext/lib/Array/push/apply')
  , isError          = require('es5-ext/lib/Error/is-error')
  , throwError       = require('es5-ext/lib/Error/throw')
  , isFunction       = require('es5-ext/lib/Function/is-function')
  , noop             = require('es5-ext/lib/Function/noop')
  , curry            = require('es5-ext/lib/Function/curry').call
  , sequence         = require('es5-ext/lib/Function/sequence').call
  , silent           = require('es5-ext/lib/Function/silent').bind
  , c                = require('es5-ext/lib/Object/descriptors/c')
  , v                = require('es5-ext/lib/Object/descriptors/v')
  , create           = require('es5-ext/lib/Object/plain/create')
  , merge            = require('es5-ext/lib/Object/plain/merge').call
  , nextTick         = require('clock/lib/next-tick')

  , isPromise        = require('./is-promise')
  , base             = require('./base').get()

  , createPromise, createDeferred, promise, resolved, unresolved, deferred;

createPromise = function (base, props) {
	var p = function (win, fail) {
		var d = createDeferred();
		p._base.then(win, fail, d.resolve);
		return d.promise;
	};
	return create(base, props)._link(merge((p.then = p), promise));
};

promise = merge(base.promise, {
	end: function (handler) {
		this._base.end(handler);
		return this;
	}
});

resolved = merge(base.resolved, {
	then: function (win, fail, resolve) {
		var cb = this._failed ? fail : win;
		nextTick(isFunction(cb) ? sequence(silent(cb, this._value), resolve) :
			curry(resolve, (cb == null) ? this._value : cb));
	},
	end: function (handler) {
		if (this._failed) {
			nextTick(
				isFunction(handler) ? curry(handler, this._value) :
					throwError.bind(this._value));
		}
	},
	_resolved: true,
	_link: function (promise) {
		var old, dscr;
		dscr = v(this);
		if ((old = promise._base)) {
			clearTimeout(old._timeout);
			if (old._monitor) {
				clearTimeout(old._monitor);
			}
			old._promises.forEach(function (promise) {
				defineProperty(promise, '_base', dscr);
			}, this);
			old._pending.forEach(function (data) {
				this[data[0]].apply(this, data[1]);
			}, this);
			delete old._pending;
			delete old._promises;
		}
		defineProperty(promise, '_base', dscr);
		return promise;
	}
});

unresolved = merge(base.unresolved, {
	then: function (win, fail, resolve) {
		this._pending.push(['then', arguments]);
	},
	end: function (handler) {
		this._pending.push(['end', arguments]);
	},
	_resolved: false,
	_link: function (promise) {
		var old, dscr;
		dscr = c(this);
		if ((old = promise._base)) {
			clearTimeout(old._timeout);
			if (old._monitor) {
				clearTimeout(old._monitor);
			}
			old._promises.forEach(function (promise) {
				defineProperty(promise, '_base', dscr);
				this._promises.push(promise);
			}, this);
			push(this._pending, old._pending);
			delete old._pending;
			delete old._promises;
		}
		this._promises.push(promise);
		defineProperty(promise, '_base', dscr);
		return promise;
	}
});

deferred = {
	resolved: false,
	resolve: function (value) {
		var newBase, oldBase, reset, pending;
		if (this.resolved) {
			throw new Error("Promise is already resolved");
		}
		this.resolved = true;
		if (isPromise(value)) {
			newBase = value._base;
		} else {
			newBase = create(resolved, {
				_value: value,
				_failed: isError(value)
			});
		}
		return newBase._link(this.promise);
	}
};

module.exports = createDeferred = function (value) {
	var o;
	if (arguments.length) {
		if (value && isPromise(value)) {
			return value;
		}
		return createPromise(resolved, {
			_value: value,
			_failed: isError(value)
		});
	}

	o = create(deferred, {
		promise: createPromise(unresolved, {
			_pending: [],
			_promises: [],
			_timeout: setTimeout(noop, Infinity),
			_monitor: createDeferred.MONITOR && createDeferred.MONITOR()
		})
	});

	return {
		resolve: o.resolve.bind(o),
		promise: o.promise
	};
};
<commit_msg>Some extensions relied on '_promise' property on base object, after recent cleanup it wasn't there. It appears it should be set for resolved bases - brought it back.<commit_after>'use strict';

var defineProperty   = Object.defineProperty
  , push             = require('es5-ext/lib/Array/push/apply')
  , isError          = require('es5-ext/lib/Error/is-error')
  , throwError       = require('es5-ext/lib/Error/throw')
  , isFunction       = require('es5-ext/lib/Function/is-function')
  , noop             = require('es5-ext/lib/Function/noop')
  , curry            = require('es5-ext/lib/Function/curry').call
  , sequence         = require('es5-ext/lib/Function/sequence').call
  , silent           = require('es5-ext/lib/Function/silent').bind
  , c                = require('es5-ext/lib/Object/descriptors/c')
  , v                = require('es5-ext/lib/Object/descriptors/v')
  , create           = require('es5-ext/lib/Object/plain/create')
  , merge            = require('es5-ext/lib/Object/plain/merge').call
  , nextTick         = require('clock/lib/next-tick')

  , isPromise        = require('./is-promise')
  , base             = require('./base').get()

  , createPromise, createDeferred, promise, resolved, unresolved, deferred;

createPromise = function (base, props) {
	var p = function (win, fail) {
		var d = createDeferred();
		p._base.then(win, fail, d.resolve);
		return d.promise;
	};
	return create(base, props)._link(merge((p.then = p), promise));
};

promise = merge(base.promise, {
	end: function (handler) {
		this._base.end(handler);
		return this;
	}
});

resolved = merge(base.resolved, {
	then: function (win, fail, resolve) {
		var cb = this._failed ? fail : win;
		nextTick(isFunction(cb) ? sequence(silent(cb, this._value), resolve) :
			curry(resolve, (cb == null) ? this._value : cb));
	},
	end: function (handler) {
		if (this._failed) {
			nextTick(
				isFunction(handler) ? curry(handler, this._value) :
					throwError.bind(this._value));
		}
	},
	_resolved: true,
	_link: function (promise) {
		var old, dscr;
		dscr = v(this);
		old = promise._base;
		this._promise = promise;
		defineProperty(promise, '_base', dscr);
		if (old) {
			clearTimeout(old._timeout);
			if (old._monitor) {
				clearTimeout(old._monitor);
			}
			old._promises.forEach(function (promise) {
				defineProperty(promise, '_base', dscr);
			}, this);
			old._pending.forEach(function (data) {
				this[data[0]].apply(this, data[1]);
			}, this);
			delete old._pending;
			delete old._promises;
		}
		return promise;
	}
});

unresolved = merge(base.unresolved, {
	then: function (win, fail, resolve) {
		this._pending.push(['then', arguments]);
	},
	end: function (handler) {
		this._pending.push(['end', arguments]);
	},
	_resolved: false,
	_link: function (promise) {
		var old, dscr;
		dscr = c(this);
		if ((old = promise._base)) {
			clearTimeout(old._timeout);
			if (old._monitor) {
				clearTimeout(old._monitor);
			}
			old._promises.forEach(function (promise) {
				defineProperty(promise, '_base', dscr);
				this._promises.push(promise);
			}, this);
			push(this._pending, old._pending);
			delete old._pending;
			delete old._promises;
		}
		this._promises.push(promise);
		defineProperty(promise, '_base', dscr);
		return promise;
	}
});

deferred = {
	resolved: false,
	resolve: function (value) {
		var newBase, oldBase, reset, pending;
		if (this.resolved) {
			throw new Error("Promise is already resolved");
		}
		this.resolved = true;
		if (isPromise(value)) {
			newBase = value._base;
		} else {
			newBase = create(resolved, {
				_value: value,
				_failed: isError(value)
			});
		}
		return newBase._link(this.promise);
	}
};

module.exports = createDeferred = function (value) {
	var o;
	if (arguments.length) {
		if (value && isPromise(value)) {
			return value;
		}
		return createPromise(resolved, {
			_value: value,
			_failed: isError(value)
		});
	}

	o = create(deferred, {
		promise: createPromise(unresolved, {
			_pending: [],
			_promises: [],
			_timeout: setTimeout(noop, Infinity),
			_monitor: createDeferred.MONITOR && createDeferred.MONITOR()
		})
	});

	return {
		resolve: o.resolve.bind(o),
		promise: o.promise
	};
};
<|endoftext|>