<commit_before>import Accesses from './accesses';
import Accounts from './accounts';
import Alerts from './alerts';
import Budgets from './budgets';
import Categories from './categories';
import Settings from './settings';
import Transactions from './transactions';

import Bank from './deprecated-bank';
import TransactionType from './deprecated-operationtype';

import User from './users';
import { ConfigGhostSettings } from './static-data';

import { makeLogger, UNKNOWN_OPERATION_TYPE } from '../helpers';

let log = makeLogger('models/migrations');

// For a given access, retrieves the custom fields and gives them to the
// changeFn, which must return a new version of the custom fields (deleted
// fields won't be kept in database). After which they're saved (it's not
// changeFn's responsability to call save/update).
async function updateCustomFields(userId, access, changeFn) {
    // "deep copy", lol
    let newCustomFields = JSON.parse(access.customFields || '[]');
    newCustomFields = changeFn(newCustomFields);

    log.debug(`Updating custom fields for ${access.id}`);
    await Accesses.update(userId, access.id, {
        customFields: JSON.stringify(newCustomFields)
    });
}

function reduceOperationsDate(oldest, operation) {
    return Math.min(oldest, +new Date(operation.dateImport));
}

function makeRenameField(Model, formerFieldName, newFieldName) {
    return async function(userId) {
        try {
            let allEntities = await Model.all(userId);
            for (let entity of allEntities) {
                if (typeof entity.id === 'undefined') {
                    // Could happen for e.g. ghost settings.
                    continue;
                }
                await Model.update(userId, entity.id, {
                    [newFieldName]: entity[formerFieldName],
                    [formerFieldName]: null
                });
            }
            return true;
        } catch (e) {
            log.error(
                `Error while renaming field ${Model.toString()}.${formerFieldName} to ${newFieldName}`,
                e.toString()
            );
            return false;
        }
    };
}

/**
 * This is an array of all the migrations to apply on the database, in order to
 * automatically keep database schema in sync with Kresus code.
 *
 * _Note_: As only the necessary migrations are run at each startup, you should
 * NEVER update a given migration, but instead add a new migration to reflect
 * the changes you want to apply on the db. Updating an existing migration
 * might not update the database as expected.
 */<commit_msg>Log field migration when applying it.<commit_after>import Accesses from './accesses';
import Accounts from './accounts';
import Alerts from './alerts';
import Budgets from './budgets';
import Categories from './categories';
import Settings from './settings';
import Transactions from './transactions';

import Bank from './deprecated-bank';
import TransactionType from './deprecated-operationtype';

import User from './users';
import { ConfigGhostSettings } from './static-data';

import { makeLogger, UNKNOWN_OPERATION_TYPE } from '../helpers';

let log = makeLogger('models/migrations');

// For a given access, retrieves the custom fields and gives them to the
// changeFn, which must return a new version of the custom fields (deleted
// fields won't be kept in database). After which they're saved (it's not
// changeFn's responsability to call save/update).
async function updateCustomFields(userId, access, changeFn) {
    // "deep copy", lol
    let newCustomFields = JSON.parse(access.customFields || '[]');
    newCustomFields = changeFn(newCustomFields);

    log.debug(`Updating custom fields for ${access.id}`);
    await Accesses.update(userId, access.id, {
        customFields: JSON.stringify(newCustomFields)
    });
}

function reduceOperationsDate(oldest, operation) {
    return Math.min(oldest, +new Date(operation.dateImport));
}

function makeRenameField(Model, formerFieldName, newFieldName) {
    return async function(userId) {
        let { displayName = '(some model)' } = Model;
        try {
            log.info(`Renaming ${displayName}.${formerFieldName} to ${newFieldName}`);
            let allEntities = await Model.all(userId);
            for (let entity of allEntities) {
                if (typeof entity.id === 'undefined') {
                    // Could happen for e.g. ghost settings.
                    continue;
                }
                await Model.update(userId, entity.id, {
                    [newFieldName]: entity[formerFieldName],
                    [formerFieldName]: null
                });
            }
            return true;
        } catch (e) {
            log.error(
                `Error while renaming field ${displayName}.${formerFieldName} to ${newFieldName}:`,
                e.toString()
            );
            return false;
        }
    };
}

/**
 * This is an array of all the migrations to apply on the database, in order to
 * automatically keep database schema in sync with Kresus code.
 *
 * _Note_: As only the necessary migrations are run at each startup, you should
 * NEVER update a given migration, but instead add a new migration to reflect
 * the changes you want to apply on the db. Updating an existing migration
 * might not update the database as expected.
 */
{'fraction_non_alphanumeric': 0.10434134525805851, 'fraction_numerical': 0.0, 'mean_word_length': 2.6995175740868365, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6409275', 'n_tokens_mistral': 1373, 'n_tokens_neox': 1372, 'n_words': 504}