UNPKG

@harishreddym/baqend

Version:

Baqend JavaScript SDK

131 lines (106 loc) 3.42 kB
'use strict'; const PluralAttribute = require('./PluralAttribute'); const PersistentError = require('../error/PersistentError'); /** * @alias metamodel.MapAttribute * @extends metamodel.PluralAttribute */ class MapAttribute extends PluralAttribute { /** * Get the type id for this map type * @return {string} */ static get ref() { return '/db/collection.Map'; } /** * @inheritDoc * @type PluralAttribute.CollectionType */ get collectionType() { return PluralAttribute.CollectionType.MAP; } /** * @param {string} name * @param {metamodel.Type} keyType * @param {metamodel.Type} elementType * @param {Object=} flags */ constructor(name, keyType, elementType, flags) { super(name, elementType, flags); /** @type metamodel.Type */ this.keyType = keyType; this.typeConstructor = Map; } /** * @inheritDoc */ getJsonValue(state, object, options) { const value = this.getValue(object); if (!(value instanceof this.typeConstructor)) { return null; } const persisting = {}; const persistedState = PluralAttribute.getAttachedState(value) || {}; let changed = PluralAttribute.getAttachedSize(value) !== value.size; const json = {}; const iter = value.entries(); for (let el = iter.next(); !el.done; el = iter.next()) { const entry = el.value; if (entry[0] === null || entry[0] === undefined) { throw new PersistentError('Map keys can\'t be null nor undefined.'); } const jsonKey = this.keyType.toJsonValue(state, entry[0], options); json[jsonKey] = this.elementType.toJsonValue(state, entry[1], options); persisting[jsonKey] = [entry[0], entry[1]]; changed = changed || (persistedState[jsonKey] || [])[1] !== entry[1]; } if (options.persisting) { PluralAttribute.attachState(value, persisting); PluralAttribute.attachSize(value, value.size); } if (state.isPersistent && changed) { state.setDirty(); } return json; } /** * @inheritDoc */ setJsonValue(state, obj, json, options) { let value = null; if (json) { value = this.getValue(obj); if (!(value instanceof this.typeConstructor)) { value = new this.typeConstructor(); // eslint-disable-line new-cap } const persisting = {}; const persistedState = PluralAttribute.getAttachedState(value) || {}; value.clear(); const jsonKeys = Object.keys(json); for (let i = 0, len = jsonKeys.length; i < len; i += 1) { const jsonKey = jsonKeys[i]; const persistedEntry = persistedState[jsonKey] || []; // ensures that "false" keys will be converted to false const key = this.keyType.fromJsonValue(state, jsonKey, persistedEntry[0], options); const val = this.elementType.fromJsonValue(state, json[jsonKey], persistedEntry[1], options); persisting[jsonKey] = [key, val]; value.set(key, val); } if (options.persisting) { PluralAttribute.attachState(value, persisting); PluralAttribute.attachSize(value, value.size); } } this.setValue(obj, value); } /** * @inheritDoc */ toJSON() { return Object.assign({}, super.toJSON(), { type: MapAttribute.ref + '[' + this.keyType.ref + ',' + this.elementType.ref + ']', }); } } module.exports = MapAttribute;