123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939 |
- var util = require('./util');
- var Queue = require('./Queue');
- function DataSet (data, options) {
-
- if (data && !Array.isArray(data)) {
- options = data;
- data = null;
- }
- this._options = options || {};
- this._data = {};
- this.length = 0;
- this._fieldId = this._options.fieldId || 'id';
- this._type = {};
-
-
- if (this._options.type) {
- var fields = Object.keys(this._options.type);
- for (var i = 0, len = fields.length; i < len; i++) {
- var field = fields[i];
- var value = this._options.type[field];
- if (value == 'Date' || value == 'ISODate' || value == 'ASPDate') {
- this._type[field] = 'Date';
- }
- else {
- this._type[field] = value;
- }
- }
- }
- this._subscribers = {};
-
- if (data) {
- this.add(data);
- }
- this.setOptions(options);
- }
- DataSet.prototype.setOptions = function(options) {
- if (options && options.queue !== undefined) {
- if (options.queue === false) {
-
- if (this._queue) {
- this._queue.destroy();
- delete this._queue;
- }
- }
- else {
-
- if (!this._queue) {
- this._queue = Queue.extend(this, {
- replace: ['add', 'update', 'remove']
- });
- }
- if (typeof options.queue === 'object') {
- this._queue.setOptions(options.queue);
- }
- }
- }
- };
- DataSet.prototype.on = function(event, callback) {
- var subscribers = this._subscribers[event];
- if (!subscribers) {
- subscribers = [];
- this._subscribers[event] = subscribers;
- }
- subscribers.push({
- callback: callback
- });
- };
- DataSet.prototype.off = function(event, callback) {
- var subscribers = this._subscribers[event];
- if (subscribers) {
- this._subscribers[event] = subscribers.filter(listener => listener.callback != callback);
- }
- };
- DataSet.prototype._trigger = function (event, params, senderId) {
- if (event == '*') {
- throw new Error('Cannot trigger event *');
- }
- var subscribers = [];
- if (event in this._subscribers) {
- subscribers = subscribers.concat(this._subscribers[event]);
- }
- if ('*' in this._subscribers) {
- subscribers = subscribers.concat(this._subscribers['*']);
- }
- for (var i = 0, len = subscribers.length; i < len; i++) {
- var subscriber = subscribers[i];
- if (subscriber.callback) {
- subscriber.callback(event, params, senderId || null);
- }
- }
- };
- DataSet.prototype.add = function (data, senderId) {
- var addedIds = [],
- id,
- me = this;
- if (Array.isArray(data)) {
-
- for (var i = 0, len = data.length; i < len; i++) {
- id = me._addItem(data[i]);
- addedIds.push(id);
- }
- }
- else if (data && typeof data === 'object') {
-
- id = me._addItem(data);
- addedIds.push(id);
- }
- else {
- throw new Error('Unknown dataType');
- }
- if (addedIds.length) {
- this._trigger('add', {items: addedIds}, senderId);
- }
- return addedIds;
- };
- DataSet.prototype.update = function (data, senderId) {
- var addedIds = [];
- var updatedIds = [];
- var oldData = [];
- var updatedData = [];
- var me = this;
- var fieldId = me._fieldId;
- var addOrUpdate = function (item) {
- var id = item[fieldId];
- if (me._data[id]) {
- var oldItem = util.extend({}, me._data[id]);
-
- id = me._updateItem(item);
- updatedIds.push(id);
- updatedData.push(item);
- oldData.push(oldItem);
- }
- else {
-
- id = me._addItem(item);
- addedIds.push(id);
- }
- };
- if (Array.isArray(data)) {
-
- for (var i = 0, len = data.length; i < len; i++) {
- if (data[i] && typeof data[i] === 'object'){
- addOrUpdate(data[i]);
- } else {
- console.warn('Ignoring input item, which is not an object at index ' + i);
- }
- }
- }
- else if (data && typeof data === 'object') {
-
- addOrUpdate(data);
- }
- else {
- throw new Error('Unknown dataType');
- }
- if (addedIds.length) {
- this._trigger('add', {items: addedIds}, senderId);
- }
- if (updatedIds.length) {
- var props = { items: updatedIds, oldData: oldData, data: updatedData };
-
-
-
-
-
-
-
- this._trigger('update', props, senderId);
- }
- return addedIds.concat(updatedIds);
- };
- DataSet.prototype.get = function (args) {
- var me = this;
-
- var id, ids, options;
- var firstType = util.getType(arguments[0]);
- if (firstType == 'String' || firstType == 'Number') {
-
- id = arguments[0];
- options = arguments[1];
- }
- else if (firstType == 'Array') {
-
- ids = arguments[0];
- options = arguments[1];
- }
- else {
-
- options = arguments[0];
- }
-
- var returnType;
- if (options && options.returnType) {
- var allowedValues = ['Array', 'Object'];
- returnType = allowedValues.indexOf(options.returnType) == -1 ? 'Array' : options.returnType;
- }
- else {
- returnType = 'Array';
- }
-
- var type = options && options.type || this._options.type;
- var filter = options && options.filter;
- var items = [], item, itemIds, itemId, i, len;
-
- if (id != undefined) {
-
- item = me._getItem(id, type);
- if (item && filter && !filter(item)) {
- item = null;
- }
- }
- else if (ids != undefined) {
-
- for (i = 0, len = ids.length; i < len; i++) {
- item = me._getItem(ids[i], type);
- if (!filter || filter(item)) {
- items.push(item);
- }
- }
- }
- else {
-
- itemIds = Object.keys(this._data);
- for (i = 0, len = itemIds.length; i < len; i++) {
- itemId = itemIds[i];
- item = me._getItem(itemId, type);
- if (!filter || filter(item)) {
- items.push(item);
- }
- }
- }
-
- if (options && options.order && id == undefined) {
- this._sort(items, options.order);
- }
-
- if (options && options.fields) {
- var fields = options.fields;
- if (id != undefined) {
- item = this._filterFields(item, fields);
- }
- else {
- for (i = 0, len = items.length; i < len; i++) {
- items[i] = this._filterFields(items[i], fields);
- }
- }
- }
-
- if (returnType == 'Object') {
- var result = {},
- resultant;
- for (i = 0, len = items.length; i < len; i++) {
- resultant = items[i];
- result[resultant.id] = resultant;
- }
- return result;
- }
- else {
- if (id != undefined) {
-
- return item;
- }
- else {
-
- return items;
- }
- }
- };
- DataSet.prototype.getIds = function (options) {
- var data = this._data,
- filter = options && options.filter,
- order = options && options.order,
- type = options && options.type || this._options.type,
- itemIds = Object.keys(data),
- i,
- len,
- id,
- item,
- items,
- ids = [];
- if (filter) {
-
- if (order) {
-
- items = [];
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- item = this._getItem(id, type);
- if (filter(item)) {
- items.push(item);
- }
- }
- this._sort(items, order);
- for (i = 0, len = items.length; i < len; i++) {
- ids.push(items[i][this._fieldId]);
- }
- }
- else {
-
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- item = this._getItem(id, type);
- if (filter(item)) {
- ids.push(item[this._fieldId]);
- }
- }
- }
- }
- else {
-
- if (order) {
-
- items = [];
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- items.push(data[id]);
- }
- this._sort(items, order);
- for (i = 0, len = items.length; i < len; i++) {
- ids.push(items[i][this._fieldId]);
- }
- }
- else {
-
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- item = data[id];
- ids.push(item[this._fieldId]);
- }
- }
- }
- return ids;
- };
- DataSet.prototype.getDataSet = function () {
- return this;
- };
- DataSet.prototype.forEach = function (callback, options) {
- var filter = options && options.filter,
- type = options && options.type || this._options.type,
- data = this._data,
- itemIds = Object.keys(data),
- i,
- len,
- item,
- id;
- if (options && options.order) {
-
- var items = this.get(options);
- for (i = 0, len = items.length; i < len; i++) {
- item = items[i];
- id = item[this._fieldId];
- callback(item, id);
- }
- }
- else {
-
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- item = this._getItem(id, type);
- if (!filter || filter(item)) {
- callback(item, id);
- }
- }
- }
- };
- DataSet.prototype.map = function (callback, options) {
- var filter = options && options.filter,
- type = options && options.type || this._options.type,
- mappedItems = [],
- data = this._data,
- itemIds = Object.keys(data),
- i,
- len,
- id,
- item;
-
- for (i = 0, len = itemIds.length; i < len; i++) {
- id = itemIds[i];
- item = this._getItem(id, type);
- if (!filter || filter(item)) {
- mappedItems.push(callback(item, id));
- }
- }
-
- if (options && options.order) {
- this._sort(mappedItems, options.order);
- }
- return mappedItems;
- };
- DataSet.prototype._filterFields = function (item, fields) {
- if (!item) {
- return item;
- }
- var filteredItem = {},
- itemFields = Object.keys(item),
- len = itemFields.length,
- i,
- field;
- if(Array.isArray(fields)){
- for (i = 0; i < len; i++) {
- field = itemFields[i];
- if (fields.indexOf(field) != -1) {
- filteredItem[field] = item[field];
- }
- }
- }else{
- for (i = 0; i < len; i++) {
- field = itemFields[i];
- if (fields.hasOwnProperty(field)) {
- filteredItem[fields[field]] = item[field];
- }
- }
- }
- return filteredItem;
- };
- DataSet.prototype._sort = function (items, order) {
- if (util.isString(order)) {
-
- var name = order;
- items.sort(function (a, b) {
- var av = a[name];
- var bv = b[name];
- return (av > bv) ? 1 : ((av < bv) ? -1 : 0);
- });
- }
- else if (typeof order === 'function') {
-
- items.sort(order);
- }
-
-
- else {
- throw new TypeError('Order must be a function or a string');
- }
- };
- DataSet.prototype.remove = function (id, senderId) {
- var removedIds = [],
- removedItems = [],
- ids = [],
- i, len, itemId, item;
-
- ids = Array.isArray(id) ? id : [id];
- for (i = 0, len = ids.length; i < len; i++) {
- item = this._remove(ids[i]);
- if (item) {
- itemId = item[this._fieldId];
- if (itemId != undefined) {
- removedIds.push(itemId);
- removedItems.push(item);
- }
- }
- }
- if (removedIds.length) {
- this._trigger('remove', {items: removedIds, oldData: removedItems}, senderId);
- }
- return removedIds;
- };
- DataSet.prototype._remove = function (id) {
- var item,
- ident;
-
- if (util.isNumber(id) || util.isString(id)) {
- ident = id;
- }
- else if (id && typeof id === 'object') {
- ident = id[this._fieldId];
- }
-
- if (ident !== undefined && this._data[ident]) {
- item = this._data[ident];
- delete this._data[ident];
- this.length--;
- return item;
- }
- return null;
- };
- DataSet.prototype.clear = function (senderId) {
- var i, len;
- var ids = Object.keys(this._data);
- var items = [];
- for (i = 0, len = ids.length; i < len; i++) {
- items.push(this._data[ids[i]]);
- }
- this._data = {};
- this.length = 0;
- this._trigger('remove', {items: ids, oldData: items}, senderId);
- return ids;
- };
- DataSet.prototype.max = function (field) {
- var data = this._data,
- itemIds = Object.keys(data),
- max = null,
- maxField = null,
- i,
- len;
- for (i = 0, len = itemIds.length; i < len; i++) {
- var id = itemIds[i];
- var item = data[id];
- var itemField = item[field];
- if (itemField != null && (!max || itemField > maxField)) {
- max = item;
- maxField = itemField;
- }
- }
- return max;
- };
- DataSet.prototype.min = function (field) {
- var data = this._data,
- itemIds = Object.keys(data),
- min = null,
- minField = null,
- i,
- len;
- for (i = 0, len = itemIds.length; i < len; i++) {
- var id = itemIds[i];
- var item = data[id];
- var itemField = item[field];
- if (itemField != null && (!min || itemField < minField)) {
- min = item;
- minField = itemField;
- }
- }
- return min;
- };
- DataSet.prototype.distinct = function (field) {
- var data = this._data;
- var itemIds = Object.keys(data);
- var values = [];
- var fieldType = this._options.type && this._options.type[field] || null;
- var count = 0;
- var i,
- j,
- len;
- for (i = 0, len = itemIds.length; i < len; i++) {
- var id = itemIds[i];
- var item = data[id];
- var value = item[field];
- var exists = false;
- for (j = 0; j < count; j++) {
- if (values[j] == value) {
- exists = true;
- break;
- }
- }
- if (!exists && (value !== undefined)) {
- values[count] = value;
- count++;
- }
- }
- if (fieldType) {
- for (i = 0, len = values.length; i < len; i++) {
- values[i] = util.convert(values[i], fieldType);
- }
- }
- return values;
- };
- DataSet.prototype._addItem = function (item) {
- var id = item[this._fieldId];
- if (id != undefined) {
-
- if (this._data[id]) {
-
- throw new Error('Cannot add item: item with id ' + id + ' already exists');
- }
- }
- else {
-
- id = util.randomUUID();
- item[this._fieldId] = id;
- }
- var d = {},
- fields = Object.keys(item),
- i,
- len;
- for (i = 0, len = fields.length; i < len; i++) {
- var field = fields[i];
- var fieldType = this._type[field];
- d[field] = util.convert(item[field], fieldType);
- }
- this._data[id] = d;
- this.length++;
- return id;
- };
- DataSet.prototype._getItem = function (id, types) {
- var field, value, i, len;
-
- var raw = this._data[id];
- if (!raw) {
- return null;
- }
-
- var converted = {},
- fields = Object.keys(raw);
- if (types) {
- for (i = 0, len = fields.length; i < len; i++) {
- field = fields[i];
- value = raw[field];
- converted[field] = util.convert(value, types[field]);
- }
- }
- else {
-
- for (i = 0, len = fields.length; i < len; i++) {
- field = fields[i];
- value = raw[field];
- converted[field] = value;
- }
- }
- if (!converted[this._fieldId]) {
- converted[this._fieldId] = raw.id;
- }
- return converted;
- };
- DataSet.prototype._updateItem = function (item) {
- var id = item[this._fieldId];
- if (id == undefined) {
- throw new Error('Cannot update item: item has no id (item: ' + JSON.stringify(item) + ')');
- }
- var d = this._data[id];
- if (!d) {
-
- throw new Error('Cannot update item: no item with id ' + id + ' found');
- }
-
- var fields = Object.keys(item);
- for (var i = 0, len = fields.length; i < len; i++) {
- var field = fields[i];
- var fieldType = this._type[field];
- d[field] = util.convert(item[field], fieldType);
- }
- return id;
- };
- module.exports = DataSet;
|