<commit_before>/*jslint node: true */
/* Copyright (c) 2012 <NAME> */

"use strict";
var assert = require("assert");
var _ = require('lodash');
var mysql = require('mysql');
var uuid = require('node-uuid');

var NAME = "mysql-store";
var MIN_WAIT = 16;
var MAX_WAIT = 65336;
var OBJECT_TYPE = 'o';
var ARRAY_TYPE = 'a';
var DATE_TYPE = 'd';
var SENECA_TYPE_COLUMN = 'seneca';


module.exports = function(opts) {
  var seneca = this;
  var desc;
  var minwait;
  var collmap = {};
  var dbinst  = null;
  var waitmillis = MIN_WAIT;
  var spec;
  var connection;

  opts.minwait = opts.minwait || MIN_WAIT;
  opts.maxwait = opts.maxwait || MAX_WAIT;



  /**
   * check and report error conditions seneca.fail will execute the callback
   * in the case of an error. Optionally attempt reconnect to the store depending
   * on error condition
   */
  function error(args, err, cb) {
    if (err) {
      seneca.log(args.tag$, 'error: ' + err);
      // seneca.fail({code:'entity/error', store: NAME, error: err}, cb);
      seneca.fail('entity/error', err, cb);

      if (err.fatal) {
        if ('PROTOCOL_CONNECTION_LOST' !== err.code) {
          throw err;
        }

        if (MIN_WAIT === waitmillis) {
          collmap = {};
          reconnect();
        }
      }
    }
    return err;
  }



  function reconnect(){
    configure(spec, function(err, me) {
      if (err) {
        seneca.log(null, 'db reconnect (wait ' + waitmillis + 'ms) failed: ' + err);
        waitmillis = Math.min(2 * waitmillis, MAX_WAIT);
        setTimeout(function() {reconnect();}, waitmillis);
      }
      else {
        waitmillis = MIN_WAIT;
        seneca.log(null,'reconnect ok');
      }
    });
  }


  /**
   * configure the store - create a new store specific connection object
   *
   * params:
   * spec - store specific configuration
   * cb - callback
   */
  function configure(specification, cb) {
    assert(specification);
    assert(cb);
    spec = specification;

    var conf = 'string' == typeof(spec) ? null : spec;
    if (!conf) {
      conf = {};
      var urlM = /^mysql:\/\/((.*?):(.*?)@)?(.*?)(:?(\d+))?\/(.*?)$/.exec(spec);
      conf.name   = urlM[7];
      conf.port   = urlM[6];
      conf.server = urlM[4];
      conf.username = urlM[2];
      conf.password = urlM[3];
      conf.port = conf.port ? parseInt(conf.port,10) : null;
    }

    conf.database = conf.database || conf.name;
    connection = mysql.createConnection(conf);

    handleDisconnect();
    connection.connect(function(err) {
      if (!error({tag$:'init'},err,cb)) {
        waitmillis = MIN_WAIT;
        if (err) {
          cb(err);
        }
        else {
          seneca.log({tag$:'init'},'db open and authed for '+conf.username);
          cb(null, store);
        }
      }
      else {
        seneca.log({tag$:'init'},'db open');
        cb(null, store);
      }
    });
  }



  function handleDisconnect(cb) {
   connection.on( 'error', function(err) {
      if (!error({tag$:'init'}, err, cb) ) {
        waitmillis = MIN_WAIT;

        if (err) {
          cb(err);
        }<commit_msg>Restore previous behavior and add optional "conn" property to override the options for the connection.<commit_after>/*jslint node: true */
/* Copyright (c) 2012 <NAME> */

"use strict";
var assert = require("assert");
var _ = require('lodash');
var mysql = require('mysql');
var uuid = require('node-uuid');

var NAME = "mysql-store";
var MIN_WAIT = 16;
var MAX_WAIT = 65336;
var OBJECT_TYPE = 'o';
var ARRAY_TYPE = 'a';
var DATE_TYPE = 'd';
var SENECA_TYPE_COLUMN = 'seneca';


module.exports = function(opts) {
  var seneca = this;
  var desc;
  var minwait;
  var collmap = {};
  var dbinst  = null;
  var waitmillis = MIN_WAIT;
  var spec;
  var connection;

  opts.minwait = opts.minwait || MIN_WAIT;
  opts.maxwait = opts.maxwait || MAX_WAIT;



  /**
   * check and report error conditions seneca.fail will execute the callback
   * in the case of an error. Optionally attempt reconnect to the store depending
   * on error condition
   */
  function error(args, err, cb) {
    if (err) {
      seneca.log(args.tag$, 'error: ' + err);
      // seneca.fail({code:'entity/error', store: NAME, error: err}, cb);
      seneca.fail('entity/error', err, cb);

      if (err.fatal) {
        if ('PROTOCOL_CONNECTION_LOST' !== err.code) {
          throw err;
        }

        if (MIN_WAIT === waitmillis) {
          collmap = {};
          reconnect();
        }
      }
    }
    return err;
  }



  function reconnect(){
    configure(spec, function(err, me) {
      if (err) {
        seneca.log(null, 'db reconnect (wait ' + waitmillis + 'ms) failed: ' + err);
        waitmillis = Math.min(2 * waitmillis, MAX_WAIT);
        setTimeout(function() {reconnect();}, waitmillis);
      }
      else {
        waitmillis = MIN_WAIT;
        seneca.log(null,'reconnect ok');
      }
    });
  }


  /**
   * configure the store - create a new store specific connection object
   *
   * params:
   * spec - store specific configuration
   * cb - callback
   */
  function configure(specification, cb) {
    assert(specification);
    assert(cb);
    spec = specification;

    var conf = 'string' == typeof(spec) ? null : spec;
    if (!conf) {
      conf = {};
      var urlM = /^mysql:\/\/((.*?):(.*?)@)?(.*?)(:?(\d+))?\/(.*?)$/.exec(spec);
      conf.name   = urlM[7];
      conf.port   = urlM[6];
      conf.server = urlM[4];
      conf.username = urlM[2];
      conf.password = urlM[3];
      conf.port = conf.port ? parseInt(conf.port,10) : null;
    }

    var defaultConn = {
      host: conf.host,
      user: conf.user,
      password: <PASSWORD>,
      database: conf.name
    };
    var conn = conf.conn || defaultConn;
    connection = mysql.createConnection(conn);

    handleDisconnect();
    connection.connect(function(err) {
      if (!error({tag$:'init'},err,cb)) {
        waitmillis = MIN_WAIT;
        if (err) {
          cb(err);
        }
        else {
          seneca.log({tag$:'init'},'db open and authed for '+conf.username);
          cb(null, store);
        }
      }
      else {
        seneca.log({tag$:'init'},'db open');
        cb(null, store);
      }
    });
  }



  function handleDisconnect(cb) {
   connection.on( 'error', function(err) {
      if (!error({tag$:'init'}, err, cb) ) {
        waitmillis = MIN_WAIT;

        if (err) {
          cb(err);
        }
{'fraction_non_alphanumeric': 0.15899516305195818, 'fraction_numerical': 0.005929162115774692, 'mean_word_length': 2.305827746260959, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5351451', 'n_tokens_mistral': 2179, 'n_tokens_neox': 2109, 'n_words': 515}