<commit_before>const _ = require('lodash/fp')
const db = require('./db')
const migration = require('./config-migration')
const { asyncLocalStorage } = require('./async-storage')
const { getOperatorId } = require('./operator')

const OLD_SETTINGS_LOADER_SCHEMA_VERSION = 1
const NEW_SETTINGS_LOADER_SCHEMA_VERSION = 2
const PASSWORD_FILLED = '<PASSWORD>'
const SECRET_FIELDS = [
  'bitgo.BTCWalletPassphrase',
  'bitgo.LTCWalletPassphrase',
  'bitgo.ZECWalletPassphrase',
  'bitgo.BCHWalletPassphrase',
  'bitgo.DASHWalletPassphrase',
  'bitstamp.secret',
  'infura.apiSecret',
  'itbit.clientSecret',
  'kraken.privateKey',
  'binanceus.privateKey',
  'ftx.privateKey',
  'cex.privateKey',
  'twilio.authToken'
]

const accountsSql = `update user_config set data = $2, valid = $3, schema_version = $4 where type = $1;
insert into user_config (type, data, valid, schema_version)
select $1, $2, $3, $4 where $1 not in (select type from user_config)`
function saveAccounts (accounts) {
  return loadAccounts()
    .then(currentAccounts => {
      const newAccounts = _.merge(currentAccounts, accounts)
      return db.none(accountsSql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
    })
}
function resetAccounts (schemaVersion) {
  return db.none(
    accountsSql,
    [
      'accounts',
      { accounts: NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },
      true,
      schemaVersion
    ]
  )
}

function loadAccounts (schemaVersion) {
  const sql = `select data
  from user_config
  where type=$1
  and schema_version=$2
  and valid
  order by id desc
  limit 1`

  return db.oneOrNone(sql, ['accounts', schemaVersion || NEW_SETTINGS_LOADER_SCHEMA_VERSION])
    .then(_.compose(_.defaultTo({}), _.get('data.accounts')))
}

function showAccounts (schemaVersion) {
  return loadAccounts(schemaVersion)
    .then(accounts => {
      const filledSecretPaths = _.compact(_.map(path => {
        if (!_.isEmpty(_.get(path, accounts))) {
          return path
        }
      }, SECRET_FIELDS))
      return _.compose(_.map(path => _.assoc(path, PASSWORD_FILLED), filledSecretPaths))(accounts)
    })
}

const configSql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)'
function saveConfig (config) {
  return Promise.all([loadLatestConfigOrNone(), getOperatorId('middleware')])
    .then(([currentConfig, operatorId]) => {
      const newConfig = _.assign(currentConfig, config)
      return db.tx(t => {
        return t.none(configSql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
          .then(() => t.none('NOTIFY $1:name, $2', ['reload', JSON.stringify({ schema: asyncLocalStorage.getStore().get('schema'), operatorId })]))
      }).catch(console.error)
    })
}

function migrationSaveConfig (config) {
  return loadLatestConfigOrNone()
    .then(currentConfig => {
      const newConfig = _.assign(currentConfig, config)
      return db.tx(t => {
        return t.none(configSql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
          .then(() => t.none('NOTIFY $1:name, $2', ['poller', JSON.stringify({ type: 'reload', schema: asyncLocalStorage.getStore().get('schema') })]))
      }).catch(console.error)
    })
}

function resetConfig (schemaVersion) {
  return db.none(
    configSql, 
    [
      'config',
      { config: schemaVersion === NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },<commit_msg>fix: simplify migration save config<commit_after>const _ = require('lodash/fp')
const db = require('./db')
const migration = require('./config-migration')
const { asyncLocalStorage } = require('./async-storage')
const { getOperatorId } = require('./operator')

const OLD_SETTINGS_LOADER_SCHEMA_VERSION = 1
const NEW_SETTINGS_LOADER_SCHEMA_VERSION = 2
const PASSWORD_FILLED = 'PASSWORD_FILLED'
const SECRET_FIELDS = [
  'bitgo.BTCWalletPassphrase',
  'bitgo.LTCWalletPassphrase',
  'bitgo.ZECWalletPassphrase',
  'bitgo.BCHWalletPassphrase',
  'bitgo.DASHWalletPassphrase',
  'bitstamp.secret',
  'infura.apiSecret',
  'itbit.clientSecret',
  'kraken.privateKey',
  'binanceus.privateKey',
  'ftx.privateKey',
  'cex.privateKey',
  'twilio.authToken'
]

const accountsSql = `update user_config set data = $2, valid = $3, schema_version = $4 where type = $1;
insert into user_config (type, data, valid, schema_version)
select $1, $2, $3, $4 where $1 not in (select type from user_config)`
function saveAccounts (accounts) {
  return loadAccounts()
    .then(currentAccounts => {
      const newAccounts = _.merge(currentAccounts, accounts)
      return db.none(accountsSql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
    })
}
function resetAccounts (schemaVersion) {
  return db.none(
    accountsSql,
    [
      'accounts',
      { accounts: NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },
      true,
      schemaVersion
    ]
  )
}

function loadAccounts (schemaVersion) {
  const sql = `select data
  from user_config
  where type=$1
  and schema_version=$2
  and valid
  order by id desc
  limit 1`

  return db.oneOrNone(sql, ['accounts', schemaVersion || NEW_SETTINGS_LOADER_SCHEMA_VERSION])
    .then(_.compose(_.defaultTo({}), _.get('data.accounts')))
}

function showAccounts (schemaVersion) {
  return loadAccounts(schemaVersion)
    .then(accounts => {
      const filledSecretPaths = _.compact(_.map(path => {
        if (!_.isEmpty(_.get(path, accounts))) {
          return path
        }
      }, SECRET_FIELDS))
      return _.compose(_.map(path => _.assoc(path, PASSWORD_FILLED), filledSecretPaths))(accounts)
    })
}

const configSql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)'
function saveConfig (config) {
  return Promise.all([loadLatestConfigOrNone(), getOperatorId('middleware')])
    .then(([currentConfig, operatorId]) => {
      const newConfig = _.assign(currentConfig, config)
      return db.tx(t => {
        return t.none(configSql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
          .then(() => t.none('NOTIFY $1:name, $2', ['reload', JSON.stringify({ schema: asyncLocalStorage.getStore().get('schema'), operatorId })]))
      }).catch(console.error)
    })
}

function migrationSaveConfig (config) {
  return loadLatestConfigOrNone()
    .then(currentConfig => {
      const newConfig = _.assign(currentConfig, config)
      return db.none(configSql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
        .catch(console.error)
    })
}

function resetConfig (schemaVersion) {
  return db.none(
    configSql, 
    [
      'config',
      { config: schemaVersion === NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },
{'fraction_non_alphanumeric': 0.14074074074074075, 'fraction_numerical': 0.006222222222222222, 'mean_word_length': 4.141660319878142, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 22, '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': '4907855', 'n_tokens_mistral': 2215, 'n_tokens_neox': 2232, 'n_words': 458}