123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- 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;
- });
|