206 lines
7.2 KiB
JavaScript
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;
|
|
});
|