webui-aria2/js/libs/dojox/store/LightstreamerStore.js.uncompressed.js
2012-05-01 19:52:07 +08:00

206 lines
7.2 KiB
JavaScript

//>>built
define("dojox/store/LightstreamerStore", [
"dojo/_base/lang",
"dojo/_base/array",
"dojo/_base/declare",
"dojo/_base/Deferred",
"dojo/store/util/QueryResults"
], function(dojo){
dojo.getObject("store", true, dojox);
// NOTE: The usual Lightstreamer web client MUST be loaded to use this store,
// and will not be wrapped as an AMD module for now.
var nextId = 0;
function translate(id, updateInfo, schema, o){
// private function to convert the returned object from an update to a JSON-like object.
o = o || {};
dojo.forEach(schema, function(field){
o[field] = updateInfo.getNewValue(field);
});
if(!("id" in o)){ o["id"] = id; }
return o;
}
/*=====
dojox.store.LightstreamerStore.__queryOptionsArgs = function(dataAdapter, itemsRange, requestedBufferSize, requestedMaxFrequency, selector, snapshotRequired, commandLogic){
// dataAdapter: String?
// The data adapter to be used for a query.
// itemsRange: Array?
// The range of items in the form of [ start, end ] to receive back from Lightstreamer.
// requestedBufferSize: Number?
// The length of the internal queuing buffers to be used by the server.
// requestedMaxFrequency: Number?
// The maximum update frequency (updates per second) to be used by Lightstreamer.
// selector: String?
// The name of a selector, to be recognized by the Metadata Adapter in Lightstreamer.
// snapshotRequired: Boolean?
// Whether or not to request snapshot delivery.
// commandLogic: Array?
// An array of arguments in the following form: [ flag, commandPos, keyPos, underSchema, underDataAdapter ]
this.dataAdapter = dataAdapter;
this.itemsRange = itemsRange;
this.requestedBufferSize = requestedBufferSize;
this.requestedMaxFrequency = requestedMaxFrequency;
this.selector = selector;
this.snapshotRequired = snapshotRequired;
this.commandLogic = commandLogic;
}
=====*/
dojo.declare("dojox.store.LightstreamerStore", [], {
_index: {}, // a cache for data objects returned
// pushPage: (Lightstreamer)pushPage
// The main connection created by the typical Lightstreamer Web Client
pushPage: null,
// group: String[]
// The group of items to be returned from the Lightstreamer Server.
group: [],
// schema: String[]
// The list of fields for each item you wish to get back from Lightstreamer
schema: [],
constructor: function(pushPage, group, schema, dataAdapter){
// summary:
// The constructor for the LightstreamerStore.
// pushPage: pushPage
// This is the pushPage created by using the typical Lightstreamer web client
// dataAdapter: String
// This is the data adapter to connect to (defined with the Lightstreamer server)
// group: String[]
// An array of the item names you wish to get back from Lightstreamer.
// schema: String[]
// The list of fields for each item you wish to get back from Lightstreamer.
this.pushPage = pushPage;
this.group = group;
this.schema = schema;
this.dataAdapter = dataAdapter || "DEFAULT";
},
query: function(query, options){
// summary:
// Start receiving streams from the Lightstreamer server.
//
// description:
// The main method of the LightstreamerStore, query opens up a data stream
// from a Lightstreamer server (based on the pushPage definition used in the
// constructor) and sets up a way to observe the returned results from said
// stream. It is based on Lightstreamer's NonVisualTable object, and by
// default will run the return from the Lightstreamer server through a
// private "translate" function, which takes the updateInfo object normally
// returned by Lightstreamer's web client and converts it into a straight
// JSON-like object that can be used for data consumption.
//
// query: String
// The name of the mode to use for the resulting stream. (RAW, MERGE, COMMAND or DISTINCT)
//
// options: LightstreamerStore.__QueryOptionsArgs
// Additional options to consume. See http://www.lightstreamer.com/docs/client_web_jsdoc/NonVisualTable.html
// for more information on these properties. All properties are optional.
//
// returns: dojo.store.util.QueryResults
// A query results object that can be used to observe data being returned,
// as well as stop the stream of data. Note that this results object is
// customized with an "observe" method and a "close" method; observe is the
// main hook into the constant data stream returned by Lightstreamer, and
// the close method will stop the query/stream.
//
// example:
// Query a server:
// | var results = myLSStore.query("MERGE", { dataAdapter: "QUOTE_ADAPTER", snapshotRequired: true });
// | results.observe(function(obj){
// | // do something with obj
// | });
options = options || {};
var results = new dojo.Deferred(),
snapshotReceived,
resultsArray = [],
self = this,
id = "store-" + nextId++,
pushPage = this.pushPage,
table = new NonVisualTable(this.group, this.schema, query);
if(!("dataAdapter" in options) && this.dataAdapter){
table.setDataAdapter(this.dataAdapter);
}
for(var prop in options) {
var setter = "set" + prop.charAt(0).toUpperCase() + prop.slice(1);
if(setter in table && dojo.isFunction(table[setter])){
table[setter][(dojo.isArray(options[prop])?"apply":"call")](table, options[prop]);
}
}
table.onItemUpdate = function(id, updateInfo){
var obj = translate(id, updateInfo, self.schema, self._index[id]);
var newObject;
if(!self._index[id]){
newObject = true;
self._index[id] = obj;
if(!snapshotReceived){
resultsArray.push(obj);
}
}
table[snapshotReceived?"onPostSnapShot":"onPreSnapShot"](obj, newObject);
};
if(query == "MERGE" || options.snapshotRequired === false){
snapshotReceived = true;
results.resolve(resultsArray);
} else { // eventually properly handle other subscription modes
table.onEndOfSnapshot = function(){
snapshotReceived = true;
results.resolve(resultsArray);
};
}
// note that these need to be two separate function objects.
table.onPreSnapShot = function(){};
table.onPostSnapShot = function(){};
// modify the deferred
results = dojo.store.util.QueryResults(results);
// set up the two main ways of working with results
var foreachHandler;
results.forEach = function(callback){
foreachHandler = dojo.connect(table, "onPreSnapShot", callback);
};
var observeHandler;
results.observe = function(listener){
observeHandler = dojo.connect(table, "onPostSnapShot", function(object, newObject){
listener.call(results, object, newObject ? -1 : undefined);
});
};
// set up the way to stop the stream
results.close = function(){
if(foreachHandler){ dojo.disconnect(foreachHandler); }
if(observeHandler){ dojo.disconnect(observeHandler); }
pushPage.removeTable(id);
table = null;
};
// start up the stream
pushPage.addTable(table, id);
return results;
},
get: function(id){
// summary:
// Return a (cached) object from the Lightstreamer.
// id: String
// The identity of the object to retrieve.
return this._index[id];
}
});
return dojox.store.LightstreamerStore;
});