const UB = require('@unitybase/ub')
/* global ubs_settings */
ubs_settings.on('update:after', flushCacheAfter.bind(ubs_settings, 'selectAfterUpdate'))
ubs_settings.on('insert:after', flushCacheAfter.bind(ubs_settings, 'selectAfterInsert'))
ubs_settings.on('delete:after', flushCacheAfter.bind(ubs_settings, 'selectBeforeDelete'))
/**
* Flush a cache for key after insert/update/delete
* @private
* @param {string} storeDataName
* @param {ubMethodParams} ctx
*/
function flushCacheAfter (storeDataName, ctx) {
let settingKey
const oldCurrentDataName = ctx.dataStore.currentDataName
ctx.dataStore.currentDataName = storeDataName
try {
if (!ctx.dataStore.eof) { // dataLoader or migration can skip select afterXXX
settingKey = ctx.dataStore.get('settingKey')
}
} finally {
ctx.dataStore.currentDataName = oldCurrentDataName
}
if (!settingKey) {
settingKey = UB.Repository('ubs_settings')
.attrs(['settingKey'])
.where('ID', '=', ctx.mParams.execParams.ID)
.selectScalar()
}
if (settingKey) {
const supportLanguages = ubs_settings.entity.connectionConfig.supportLang
for (const lang of supportLanguages) {
UB.App.globalCachePut(computeCacheKey(settingKey, lang), null)
}
console.debug('ubs_setting: flush cache for', settingKey)
}
}
/**
* Load a single configuration value
*
* @method loadKey
* @memberOf ubs_settings_ns.prototype
* @memberOfModule @unitybase/ubs
* @param {string} settingKey
* @param {string|boolean|number|null} [defaultValue=null] The value returned if setting key not found
* @returns {null|number|string|boolean}
*/
ubs_settings.loadKey = function loadKey (settingKey, defaultValue = null) {
const cached = UB.App.globalCacheGet(computeCacheKey(settingKey))
let kType, kVal
if (cached) {
const parsed = JSON.parse(cached)
kType = parsed.kType
kVal = parsed.kVal
console.debug('ubs_setting: cached value is used for', settingKey)
} else {
const store = UB.Repository('ubs_settings')
.attrs(['ID', 'type', 'settingKey', 'settingValue'])
.where('[settingKey]', '=', settingKey)
.select()
if (store.eof) {
console.warn('There is no setting with key:' + settingKey)
kType = (typeof defaultValue === 'boolean')
? 'BOOLEAN'
: (typeof defaultValue === 'number')
? 'NUMBER'
: 'STRING'
kVal = kType === 'STRING' ? defaultValue : JSON.stringify(defaultValue)
} else {
kType = store.get('type')
kVal = store.get('settingValue')
store.next()
if (!store.eof) {
console.error('There is more than one settings with key: ' + settingKey)
}
}
UB.App.globalCachePut(computeCacheKey(settingKey), JSON.stringify({ kType, kVal }))
}
const res = convert(kType, kVal, settingKey)
return res
}
/**
* Load a configuration object for number of keys
*
* @deprecated Consider to use `ubs_settings.loadKey` - it's cached in globalCache
* @method loadKeys
* @memberOf ubs_settings_ns.prototype
* @memberOfModule @unitybase/ubs
* @param {Array<string>|string} settingKeys A mask or array of keys.
* @returns {object}
*/
ubs_settings.loadKeys = function loadKeys (settingKeys) {
const store = UB.Repository('ubs_settings')
.attrs(['ID', 'type', 'settingKey', 'settingValue'])
.where('[settingKey]', typeof settingKeys === 'string' ? 'startsWith' : 'in', settingKeys)
.select()
const configObject = {}
for (; !store.eof; store.next()) {
const settingKey = store.get('settingKey')
configObject[settingKey] = convert(store.get('type'), store.get('settingValue'), settingKey)
}
return configObject
}
let _settingsStore
/**
* @private
* @returns {TubDataStore}
*/
function getSettingsStore () {
if (!_settingsStore) {
_settingsStore = UB.DataStore('ubs_settings')
}
return _settingsStore
}
/**
* Create a new Key or set value for existing key
*
* @method addOrUpdateKey
* @memberOf ubs_settings_ns.prototype
* @memberOfModule @unitybase/ubs
* @param {ubs_settings_ns} keyData
*/
ubs_settings.addOrUpdateKey = function (keyData) {
const existedKeyData = UB.Repository('ubs_settings')
.attrs(['ID', 'mi_modifyDate'])
.where('[settingKey]', '=', keyData.settingKey)
.selectSingle()
if (existedKeyData) {
getSettingsStore().run('update', {
execParams: {
ID: existedKeyData.ID,
settingValue: keyData.settingValue,
mi_modifyDate: existedKeyData.mi_modifyDate
}
})
} else {
getSettingsStore().run('insert', { execParams: keyData })
}
}
/**
* Alias for a loadKey
*
* @deprecated Use ubs_setting.loadKey instead
* @method getSettingValue
* @memberOf ubs_settings_ns.prototype
* @memberOfModule @unitybase/ubs
* @param {string} settingKey
* @param {string|boolean|number|null} [defaultValue=null] The value returned if setting key not found
* @returns {string|boolean|number|null}
*/
ubs_settings.getSettingValue = ubs_settings.loadKey
/**
* Compute cache key for setting key (
* @param {string} settingKey
* @param {string} lang
*/
function computeCacheKey (settingKey, lang) {
return 'ubs_setting:' + (lang || Session.userLang) + ':' + settingKey
}
function convertBoolean (value, settingKey) {
if ((value === 'true') || (value === '1')) return true
if ((value === 'false') || (value === '0')) return false
console.error('Unknown value: ', value, 'for boolean key ', settingKey)
return value
}
function convert (type, value, settingKey) {
switch (type.toUpperCase ? type.toUpperCase() : type) {
case 'BOOLEAN':
return convertBoolean(value, settingKey)
case 'STRING':
return value
case 'INT':
case 'NUMBER':
return parseInt(value, 10)
default :
console.error('Unknown type:', type, 'for key:', settingKey)
return value
}
}