File: recordset/js/recordset-indexer.js
/**
* Provides the ability to store multiple custom hash tables referencing records in the recordset.
* @module recordset
* @submodule recordset-indexer
*/
/**
* Plugin that provides the ability to store multiple custom hash tables referencing records in the recordset.
* This utility does not support any collision handling. New hash table entries with a used key overwrite older ones.
* @class RecordsetIndexer
*/
function RecordsetIndexer(config) {
RecordsetIndexer.superclass.constructor.apply(this, arguments);
}
Y.mix(RecordsetIndexer, {
NS: "indexer",
NAME: "recordsetIndexer",
ATTRS: {
/**
* @description Collection of all the hashTables created by the plugin.
* The individual tables can be accessed by the key they are hashing against.
*
* @attribute hashTables
* @public
* @type object
*/
hashTables: {
value: {
}
},
keys: {
value: {
}
}
}
});
Y.extend(RecordsetIndexer, Y.Plugin.Base, {
initializer: function(config) {
var host = this.get('host');
//setup listeners on recordset events
this.onHostEvent('add', Y.bind("_defAddHash", this), host);
this.onHostEvent('remove', Y.bind('_defRemoveHash', this), host);
this.onHostEvent('update', Y.bind('_defUpdateHash', this), host);
},
destructor: function(config) {
},
/**
* @description Setup the hash table for a given key with all existing records in the recordset
*
* @method _setHashTable
* @param key {string} A key to hash by.
* @return obj {object} The created hash table
* @private
*/
_setHashTable: function(key) {
var host = this.get('host'),
obj = {},
i = 0,
len = host.getLength();
for (; i < len; i++) {
obj[host._items[i].getValue(key)] = host._items[i];
}
return obj;
},
//---------------------------------------------
// Syncing Methods
//---------------------------------------------
/**
* @description Updates all hash tables when a record is added to the recordset
*
* @method _defAddHash
* @private
*/
_defAddHash: function(e) {
var tbl = this.get('hashTables');
//Go through every hashtable that is stored.
//in each hashtable, look to see if the key is represented in the object being added.
Y.each(tbl,
function(v, key) {
Y.each(e.added || e.updated,
function(o) {
//if the object being added has a key which is being stored by hashtable v, add it into the table.
if (o.getValue(key)) {
v[o.getValue(key)] = o;
}
});
});
},
/**
* @description Updates all hash tables when a record is removed from the recordset
*
* @method _defRemoveHash
* @private
*/
_defRemoveHash: function(e) {
var tbl = this.get('hashTables'),
reckey;
//Go through every hashtable that is stored.
//in each hashtable, look to see if the key is represented in the object being deleted.
Y.each(tbl,
function(v, key) {
Y.each(e.removed || e.overwritten,
function(o) {
reckey = o.getValue(key);
//if the hashtable has a key storing a record, and the key and the record both match the record being deleted, delete that row from the hashtable
if (reckey && v[reckey] === o) {
delete v[reckey];
}
});
});
},
/**
* @description Updates all hash tables when the recordset is updated (a combination of add and remove)
*
* @method _defUpdateHash
* @private
*/
_defUpdateHash: function(e) {
//TODO: It will be more performant to create a new method rather than using _defAddHash, _defRemoveHash, due to the number of loops. See commented code.
e.added = e.updated;
e.removed = e.overwritten;
this._defAddHash(e);
this._defRemoveHash(e);
/*
var tbl = this.get('hashTables'), reckey;
Y.each(tbl, function(v, key) {
Y.each(e.updated, function(o, i) {
//delete record from hashtable if it has been overwritten
reckey = o.getValue(key);
if (reckey) {
v[reckey] = o;
}
//the undefined case is if more records are updated than currently exist in the recordset.
if (e.overwritten[i] && (v[e.overwritten[i].getValue(key)] === e.overwritten[i])) {
delete v[e.overwritten[i].getValue(key)];
}
// if (v[reckey] === o) {
// delete v[reckey];
// }
//
// //add the new updated record if it has a key that corresponds to a hash table
// if (o.getValue(key)) {
// v[o.getValue(key)] = o;
// }
});
});
*/
},
//---------------------------------------------
// Public Methods
//---------------------------------------------
/**
* @description Creates a new hash table.
*
* @method createTable
* @param key {string} A key to hash by.
* @return tbls[key] {object} The created hash table
* @public
*/
createTable: function(key) {
var tbls = this.get('hashTables');
tbls[key] = this._setHashTable(key);
this.set('hashTables', tbls);
return tbls[key];
},
/**
* @description Get a hash table that hashes records by a given key.
*
* @method getTable
* @param key {string} A key to hash by.
* @return table {object} The created hash table
* @public
*/
getTable: function(key) {
return this.get('hashTables')[key];
}
});
Y.namespace("Plugin").RecordsetIndexer = RecordsetIndexer;