const HError = require('./HError')
function _serializeValueFuncFactory(config = ['BaseRecord']) {
const GeoPoint = require('./GeoPoint')
const GeoPolygon = require('./GeoPolygon')
return value => {
if (config.includes('Geo') && (value instanceof GeoPoint || value instanceof GeoPolygon)) {
return value.toGeoJSON()
}
if (config.includes('BaseRecord') && value instanceof BaseRecord) {
return value._recordID == null ? '' : value._recordID.toString()
} else {
return value
}
}
}
/**
* @memberof BaaS
* @package
*/
class BaseRecord {
constructor(recordID) {
this._recordID = recordID
this._recordValueInit()
}
_recordValueInit() {
this._record = {
$set: {},
$unset: {},
}
}
/**
* 给字段赋值
* @method
* @param {string} key 字段名称
* @param {string} value 值
* @return {this}
*//**
* 批量给字段赋值
* @method
* @param {Object<string, any>} particialRecord 由字段名称与值组成的键值对对象
* @return {this}
*/
set(...args) {
const serializeValue = _serializeValueFuncFactory(['BaseRecord', 'Geo'])
const serializeArrayValue = _serializeValueFuncFactory(['Geo'])
if (args.length === 1) {
if (typeof args[0] === 'object') {
let objectArg = args[0]
let recordToSet = {}
Object.keys(args[0]).forEach((key) => {
if (this._record.$unset.hasOwnProperty(key)) {
throw new HError(605)
}
let value = objectArg[key]
if (Array.isArray(value)) {
recordToSet[key] = value.map(item => serializeArrayValue(item))
} else {
recordToSet[key] = serializeValue(value)
}
})
this._record.$set = recordToSet
} else {
throw new HError(605)
}
} else if (args.length === 2) {
if (this._record.$unset.hasOwnProperty(args[0])) {
throw new HError(605)
}
let value = args[1]
if (Array.isArray(value)) {
this._record.$set[args[0]] = value.map(item => serializeArrayValue(item))
} else {
this._record.$set[args[0]] = serializeValue(value)
}
} else {
throw new HError(605)
}
return this
}
/**
* 移除字段
* @method
* @param {string} key 字段名称
* @return {this}
*//**
* 批量移除字段
* @method
* @param {Object<string, any>} particialRecord 由字段名称与值组成的键值对对象,
* 接口会忽略 Object 里所有的 value,参照所有的 key 来执行移除操作。
* @return {this}
*/
unset(...args) {
if (typeof args[0] === 'object') {
let recordToUnset = {}
Object.keys(args[0]).forEach((key) => {
if (this._record.$set.hasOwnProperty(key)) {
throw new HError(605)
}
recordToUnset[key] = ''
})
this._record.$unset = recordToUnset
} else if (typeof args[0] === 'string') {
if (this._record.$set.hasOwnProperty(args[0])) {
throw new HError(605)
}
this._record.$unset[args[0]] = ''
} else {
throw new HError(605)
}
return this
}
/**
* 自增(原子操作)。
* @method
* @param {string} key 字段名称
* @param {number} value 值
* @return {this}
*/
incrementBy(key, value) {
this._record.$set[key] = {$incr_by: value}
return this
}
/**
* 数组添加元素。
* @method
* @param {string} key 字段名称
* @param {string} value 值
* @return {this}
*/
append(key, value) {
const serializeArrayValue = _serializeValueFuncFactory(['Geo'])
if (!(value instanceof Array)) {
value = [value]
}
value = value.map(item => serializeArrayValue(item))
this._record.$set[key] = {$append: value}
return this
}
/**
* 数组添加元素(原子操作)。
* @method
* @param {string} key 字段名称
* @param {string[]|string} value 值
* @return {this}
*/
uAppend(key, value) {
const serializeArrayValue = _serializeValueFuncFactory(['Geo'])
if (!(value instanceof Array)) {
value = [value]
}
value = value.map(item => serializeArrayValue(item))
this._record.$set[key] = {$append_unique: value}
return this
}
/**
* 数组移除元素。
* @method
* @param {string} key 字段名称
* @param {string} value 值
* @return {this}
*/
remove(key, value) {
const serializeArrayValue = _serializeValueFuncFactory(['Geo'])
if (!(value instanceof Array)) {
value = [value]
}
value = value.map(item => serializeArrayValue(item))
this._record.$set[key] = {$remove: value}
return this
}
/**
* Object 类型字段修改。
* @method
* @param {string} key 字段名称
* @param {object} value 值
* @return {this}
*/
patchObject(key, value) {
if (Object.prototype.toString.call(value) !== '[object Object]') {
throw new HError(605)
}
this._record.$set[key] = {$update: value}
return this
}
/**
* Array 类型字段修改,移除数组末位元素。
* @method
* @param {string} key 字段名称
* @return {this}
*/
pop(key) {
if (typeof key !== 'string' || key.length === 0) {
throw new HError(605)
}
this._record.$set[key] = {$pop: 1}
return this
}
/**
* Array 类型字段修改,移除数组首位元素。
* @method
* @param {string} key 字段名称
* @return {this}
*/
shift(key) {
if (typeof key !== 'string' || key.length === 0) {
throw new HError(605)
}
this._record.$set[key] = {$pop: -1}
return this
}
}
BaseRecord._serializeValueFuncFactory = _serializeValueFuncFactory
module.exports = BaseRecord