<commit_before>const idb = require('idb');
const Message = require('../../types/message');


exports.run = async (transaction) => {
  const db = idb.upgradeDBFromTransaction(transaction);
  const tx = db.transaction;
  const messagesStore = tx.objectStore('messages');

  console.log('Initialize messages schema version');
  await exports._initializeMessageSchemaVersion(messagesStore);

  console.log('Create index from attachment schema version to attachment');
  messagesStore.createIndex('schemaVersion', 'schemaVersion', { unique: false });

  await db.transaction.complete;
};

// NOTE: We disable `no-await-in-loop` because we want this migration to happen
// in sequence and not in parallel:
// https://eslint.org/docs/rules/no-await-in-loop#when-not-to-use-it
exports._initializeMessageSchemaVersion = async (messagesStore) => {
  let cursor = await messagesStore.openCursor();
  while (cursor) {
    const message = cursor.value;
    console.log('Initialize schema version for message:', message.id);

    const messageWithSchemaVersion = Message.initializeSchemaVersion(message);
    try {
      // eslint-disable-next-line no-await-in-loop
      await messagesStore.put(messageWithSchemaVersion, message.id);
    } catch (error) {
      console.log('Failed to put message with initialized schema version:', message.id);
    }

    // eslint-disable-next-line no-await-in-loop
    cursor = await cursor.continue();
  }
};<commit_msg>Rewrite migration 17 without `idb`<commit_after>const Message = require('../../types/message');


exports.run = async (transaction) => {
  const messagesStore = transaction.objectStore('messages');

  console.log('Initialize messages schema version');
  const numUpgradedMessages = await _initializeMessageSchemaVersion(messagesStore);
  console.log('Complete messages schema version initialization', { numUpgradedMessages });

  console.log('Create index from attachment schema version to attachment');
  messagesStore.createIndex('schemaVersion', 'schemaVersion', { unique: false });
};

const _initializeMessageSchemaVersion = messagesStore =>
  new Promise((resolve, reject) => {
    const messagePutOperations = [];

    const cursorRequest = messagesStore.openCursor();
    cursorRequest.onsuccess = (event) => {
      const cursor = event.target.result;
      const hasMoreData = Boolean(cursor);
      if (!hasMoreData) {
        // eslint-disable-next-line more/no-then
        return Promise.all(messagePutOperations)
          .then(() => resolve(messagePutOperations.length));
      }

      const message = cursor.value;
      const messageWithSchemaVersion = Message.initializeSchemaVersion(message);
      messagePutOperations.push(new Promise((resolvePut) => {
        console.log(
          'Initialize schema version for message:',
          messageWithSchemaVersion.id
        );

        resolvePut(putItem(
          messagesStore,
          messageWithSchemaVersion,
          messageWithSchemaVersion.id
        ));
      }));

      return cursor.continue();
    };

    cursorRequest.onerror = event =>
      reject(event.target.error);
  });

//    putItem :: IDBObjectStore -> Item -> Key -> Promise Item
const putItem = (store, item, key) =>
  new Promise((resolve, reject) => {
    try {
      const request = store.put(item, key);
      request.onsuccess = event =>
        resolve(event.target.result);
      request.onerror = event =>
        reject(event.target.error);
    } catch (error) {
      reject(error);
    }
  });
{'fraction_non_alphanumeric': 0.1228220508426164, 'fraction_numerical': 0.0005712653527563553, 'mean_word_length': 3.5362694300518136, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 1, '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': '6323979', 'n_tokens_mistral': 926, 'n_tokens_neox': 922, 'n_words': 217}