<commit_before>
var lo = require('lodash');
var Promise = require('bluebird');

var { allReflect, diff, isModelInstance, pkId, isHasOne, isHasMany, isBelongsTo, isBelongsToMany } = require('./util');
var helpers = require('./include-helpers');


function EmbedExport(sequelize) {

  /* Core api */
  var insert = (model, values, include, options) => apiWrap((inc, t) => insertDeep(model, values, inc, t), model, include, options)
  var update = (model, values, include, options) => apiWrap((inc, t) => updateDeep(model, values, inc, t), model, include, options) 

  /* Default options for core api */
  var defaults = { reload: true };

  var apiWrap = (action, model, include, options) => {
    options = lo.merge(defaults, options);
    include = lo.cloneDeep(include);
    var externalTx = lo.isObject(options.transaction);
    return (externalTx ? Promise.resolve(options.transaction) : sequelize.transaction())
      .then(t => action(include, t)
        .tap(commit(t, externalTx))
        .catch(rollback(t, externalTx))
        .then(inst => reload(model, inst, include, options.reload)))
  };

  var traverseDeep = (model, values, include, t, action) => 
    updateUpstream(model, values, include, t)
      .then(action)
      .then(inst => updateDownstream(inst, values, include, t))

  var insertDeep = (model, values, include, t) => traverseDeep(model, values, include || [], t, () => insertSelf(model, values, t))
  var updateDeep = (model, values, include, t) => traverseDeep(model, values, include || [], t, () => updateSelf(model, values, t))

  var commit = (t, skip) => () => {
    if (!skip) return t.commit()
  }

  var rollback = (t, skip) => err => Promise.try(() => {
    if (!skip && !t.finished) return t.rollback().catch(lo.noop);
  }).throw(err);

  var insertSelf = (model, values, t) => model.create(values, { transaction: t });

  var updateSelf = (model, values, t) => {
    var inst = isModelInstance(model, values) ? values : model.build(values, { isNewRecord: false });

    /* preserve version attribute for optimistic locking */
    var ver = model.options.version;
    if (ver) {
      ver = lo.isString(ver) ? ver : 'version';
      inst.set(ver, values[ver], { raw: true });
    }

    return inst.save({ transaction: t });
  }

  var updateUpstream = (model, values, include, t) => 
    updateBelongsTos(model, values, include.filter(isBelongsTo), t)

  var updateDownstream = (instance, values, include, t) => {
    var hasManyInclude = include.filter(isHasMany), hasOneInclude = include.filter(isHasOne);
    return allReflect([updateHasManys(instance, values, hasManyInclude, t), updateHasOnes(instance, values, hasOneInclude, t) ])
      .then(() => instance);
  }

  /* Builds a new instance from the original and applies values */
  var mergeInstance = (model, inst, vals, include) => {
    inst.set(vals)
    include.map(inc => {
      var a = inc.association, as = a.associationAccessor;<commit_msg>Always force update when version field is present<commit_after>
var lo = require('lodash');
var Promise = require('bluebird');

var { allReflect, diff, isModelInstance, pkId, isHasOne, isHasMany, isBelongsTo, isBelongsToMany } = require('./util');
var helpers = require('./include-helpers');


function EmbedExport(sequelize) {

  /* Core api */
  var insert = (model, values, include, options) => apiWrap((inc, t) => insertDeep(model, values, inc, t), model, include, options)
  var update = (model, values, include, options) => apiWrap((inc, t) => updateDeep(model, values, inc, t), model, include, options) 

  /* Default options for core api */
  var defaults = { reload: true };

  var apiWrap = (action, model, include, options) => {
    options = lo.merge(defaults, options);
    include = lo.cloneDeep(include);
    var externalTx = lo.isObject(options.transaction);
    return (externalTx ? Promise.resolve(options.transaction) : sequelize.transaction())
      .then(t => action(include, t)
        .tap(commit(t, externalTx))
        .catch(rollback(t, externalTx))
        .then(inst => reload(model, inst, include, options.reload)))
  };

  var traverseDeep = (model, values, include, t, action) => 
    updateUpstream(model, values, include, t)
      .then(action)
      .then(inst => updateDownstream(inst, values, include, t))

  var insertDeep = (model, values, include, t) => traverseDeep(model, values, include || [], t, () => insertSelf(model, values, t))
  var updateDeep = (model, values, include, t) => traverseDeep(model, values, include || [], t, () => updateSelf(model, values, t))

  var commit = (t, skip) => () => {
    if (!skip) return t.commit()
  }

  var rollback = (t, skip) => err => Promise.try(() => {
    if (!skip && !t.finished) return t.rollback().catch(lo.noop);
  }).throw(err);

  var insertSelf = (model, values, t) => model.create(values, { transaction: t });

  var updateSelf = (model, values, t) => {
    var inst = isModelInstance(model, values) ? values : model.build(values, { isNewRecord: false });

    /* preserve version attribute for optimistic locking */
    var ver = model.options.version;
    if (ver) {
      ver = lo.isString(ver) ? ver : 'version';
      inst.set(ver, values[ver], { raw: true });
      inst.changed(ver, true); // force update if versioned
    }

    return inst.save({ transaction: t });
  }

  var updateUpstream = (model, values, include, t) => 
    updateBelongsTos(model, values, include.filter(isBelongsTo), t)

  var updateDownstream = (instance, values, include, t) => {
    var hasManyInclude = include.filter(isHasMany), hasOneInclude = include.filter(isHasOne);
    return allReflect([updateHasManys(instance, values, hasManyInclude, t), updateHasOnes(instance, values, hasOneInclude, t) ])
      .then(() => instance);
  }

  /* Builds a new instance from the original and applies values */
  var mergeInstance = (model, inst, vals, include) => {
    inst.set(vals)
    include.map(inc => {
      var a = inc.association, as = a.associationAccessor;
{'fraction_non_alphanumeric': 0.15776293823038398, 'fraction_numerical': 0.0, 'mean_word_length': 3.8470873786407767, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 53, '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': '707804', 'n_tokens_mistral': 1877, 'n_tokens_neox': 1818, 'n_words': 522}