<commit_before>'use strict';

/**
 * Create a new Operation in the database.
 * This should be used to keep track of long running operations, that
 * require sending status updates to the user.
 * After creating an operation instance it is possible to store logs.
 *
 * @param {Object} db Database connection to use.
 *
 * @return {Operation} Instance of Operation
 *
 * @throws {MissingDB} If initialized without a db
 * @throws {OpComplete} If starting an operation already completed
 * @throws {OpRunning} If starting an operation that is already running
 * @throws {OpNotFound} If loading a non existent operation
 * @throws {OpNotRunning} If finishing a non running operation
 */
export default class Operation {
  constructor (db) {
    if (!db) throw new Error('Missing db instance');

    this.db = db;
    this
      ._setId(null)
      ._setName(null)
      ._setStatus(null);
  }

  _setStatus (status) {
    this.status = status;
    return this;
  }

  _setId (id) {
    this.id = id;
    return this;
  }

  _setName (name) {
    this.name = name;
    return this;
  }

  _load (opts) {
    return this.db(Operation.opTable)
      .select('*')
      .where(opts)
      .then(res => {
        if (!res.length) return Promise.reject(new Error('Operation does not exist'));
        let op = res[0];

        return this
          ._setId(op.id)
          ._setName(op.name)
          ._setStatus(op.status);
      }, err => Promise.reject(err));
  }

  /**
   * Start a new operation with the given name for the project/scenario.
   * There can't be two operations with the same name/project/scenario running
   * at the same time.<commit_msg>Ensure correct order of operations<commit_after>'use strict';

/**
 * Create a new Operation in the database.
 * This should be used to keep track of long running operations, that
 * require sending status updates to the user.
 * After creating an operation instance it is possible to store logs.
 *
 * @param {Object} db Database connection to use.
 *
 * @return {Operation} Instance of Operation
 *
 * @throws {MissingDB} If initialized without a db
 * @throws {OpComplete} If starting an operation already completed
 * @throws {OpRunning} If starting an operation that is already running
 * @throws {OpNotFound} If loading a non existent operation
 * @throws {OpNotRunning} If finishing a non running operation
 */
export default class Operation {
  constructor (db) {
    if (!db) throw new Error('Missing db instance');

    this.db = db;
    this
      ._setId(null)
      ._setName(null)
      ._setStatus(null);
  }

  _setStatus (status) {
    this.status = status;
    return this;
  }

  _setId (id) {
    this.id = id;
    return this;
  }

  _setName (name) {
    this.name = name;
    return this;
  }

  _load (opts) {
    return this.db(Operation.opTable)
      .select('*')
      .where(opts)
      .orderBy('created_at', 'desc')
      .then(res => {
        if (!res.length) return Promise.reject(new Error('Operation does not exist'));
        let op = res[0];

        return this
          ._setId(op.id)
          ._setName(op.name)
          ._setStatus(op.status);
      }, err => Promise.reject(err));
  }

  /**
   * Start a new operation with the given name for the project/scenario.
   * There can't be two operations with the same name/project/scenario running
   * at the same time.
{'fraction_non_alphanumeric': 0.1051693404634581, 'fraction_numerical': 0.0005941770647653001, 'mean_word_length': 2.7578125, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '78234', 'n_tokens_mistral': 996, 'n_tokens_neox': 970, 'n_words': 363}