dojo.provide("dojox.data.SnapLogicStore"); dojo.require("dojo.io.script"); dojo.require("dojo.data.util.sorter"); dojo.declare("dojox.data.SnapLogicStore", null, { Parts: { DATA: "data", COUNT: "count" }, url: "", constructor: function(/* Object */args){ // summary: // Initialize a SnapLogicStore object. // args: // An object that contains properties for initializing the new data store object. The // following properties are understood: // url: // A URL to the SnapLogic pipeline's output routed through PipeToHttp. Typically, this // will look like "http://:/pipe//". // parameters: // An object whose properties define parameters to the pipeline. The values of these // properties will be sent to the pipeline as parameters when it run. // if(args.url){ this.url = args.url; } this._parameters = args.parameters; }, _assertIsItem: function(/* item */item){ // summary: // This function tests whether the item passed in is indeed an item in the store. // item: // The item to test for being contained by the store. if(!this.isItem(item)){ throw new Error("dojox.data.SnapLogicStore: a function was passed an item argument that was not an item"); } }, _assertIsAttribute: function(/* attribute-name-string */ attribute){ // summary: // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store. // attribute: // The attribute to test for being contained by the store. if(typeof attribute !== "string"){ throw new Error("dojox.data.SnapLogicStore: a function was passed an attribute argument that was not an attribute name string"); } }, getFeatures: function(){ // summary: // See dojo.data.api.Read.getFeatures() return { 'dojo.data.api.Read': true }; }, getValue: function(item, attribute, defaultValue){ // summary: // See dojo.data.api.Read.getValue() this._assertIsItem(item); this._assertIsAttribute(attribute); var i = dojo.indexOf(item.attributes, attribute); if(i !== -1){ return item.values[i]; } return defaultValue; }, getAttributes: function(item){ // summary: // See dojo.data.api.Read.getAttributes() this._assertIsItem(item); return item.attributes; }, hasAttribute: function(item, attribute){ // summary: // See dojo.data.api.Read.hasAttributes() this._assertIsItem(item); this._assertIsAttribute(attribute); for(var i = 0; i < item.attributes.length; ++i){ if(attribute == item.attributes[i]){ return true; } } return false; }, isItemLoaded: function(item){ // summary: // See dojo.data.api.Read.isItemLoaded() return this.isItem(item); // Boolean }, loadItem: function(keywordArgs){ // summary: // See dojo.data.api.Read.loadItem() }, getLabel: function(item){ // summary: // See dojo.data.api.Read.getLabel() return undefined; }, getLabelAttributes: function(item){ // summary: // See dojo.data.api.Read.getLabelAttributes() return null; }, containsValue: function(item, attribute, value){ // summary: // See dojo.data.api.Read.containsValue() return this.getValue(item, attribute) === value; // Boolean }, getValues: function(item, attribute){ // summary: // See dojo.data.api.Read.getValue() this._assertIsItem(item); this._assertIsAttribute(attribute); var i = dojo.indexOf(item.attributes, attribute); if(i !== -1){ return [item.values[i]]; // Array } return []; }, isItem: function(item){ // summary: // See dojo.data.api.Read.isItem() if(item && item._store === this){ return true; } return false; }, close: function(request){ // summary: // See dojo.data.api.Read.close() }, _fetchHandler: function(/* Object */request){ // summary: // Process data retrieved via fetch and send it back to requester. // response: // The data returend from the I/O transport. In the normal case, it will be an array of result rows // from the pipeline. In the special case for record count optimization, response will be an array // with a single element containing the total pipeline result row count. See fetch() for details // on this optimization. var scope = request.scope || dojo.global; if(request.onBegin){ // Check for the record count optimization request.onBegin.call(scope, request._countResponse[0], request); } if(request.onItem || request.onComplete){ var response = request._dataResponse; if (!response.length){ request.onError.call(scope, new Error("dojox.data.SnapLogicStore: invalid response of length 0"), request); return; }else if(request.query != 'record count'){ //If this was not a record count request, the first element returned will contain //the field names. var field_names = response.shift(); var items = []; for(var i = 0; i < response.length; ++i){ if(request._aborted){ break; } items.push({attributes: field_names, values: response[i], _store: this}); } if(request.sort && !request._aborted){ items.sort(dojo.data.util.sorter.createSortFunction(request.sort, self)); } }else{ //This is a record count request, so manually set the field names. items = [({attributes: ['count'], values: response, _store: this})]; } if(request.onItem){ for(var i = 0; i < items.length; ++i){ if (request._aborted) { break; } request.onItem.call(scope, items[i], request); } items = null; } if(request.onComplete && !request._aborted){ request.onComplete.call(scope, items, request); } } }, _partHandler: function(/* Object */request, /* String */part, /* Object */response){ // summary: // Handle the individual replies for both data and length requests. // request: // The request/handle object used with the original fetch() call. // part: // A value indicating which request this handler call is for (this.Parts). // response: // Response received from the underlying IO transport. if(response instanceof Error){ if(part == this.Parts.DATA){ request._dataHandle = null; }else{ request._countHandle = null; } request._aborted = true; if(request.onError){ request.onError.call(request.scope, response, request); } }else{ if(request._aborted){ return; } if(part == this.Parts.DATA){ request._dataResponse = response; }else{ request._countResponse = response; } if((!request._dataHandle || request._dataResponse !== null) && (!request._countHandle || request._countResponse !== null)){ this._fetchHandler(request); } } }, fetch: function(/* Object */request){ // summary: // See dojo.data.api.Read.close() // request: // See dojo.data.api.Read.close() for generic interface. // // In addition to the standard Read API fetch support, this store supports an optimization for // for retrieving the total count of records in the Pipeline without retrieving the data. To // use this optimization, simply provide an onBegin handler without an onItem or onComplete handler. request._countResponse = null; request._dataResponse = null; request._aborted = false; request.abort = function(){ if(!request._aborted){ request._aborted = true; if(request._dataHandle && request._dataHandle.cancel){ request._dataHandle.cancel(); } if(request._countHandle && request._countHandle.cancel){ request._countHandle.cancel(); } } }; // Only make the call for data if onItem or onComplete is used. Otherwise, onBegin will only // require the total row count. if(request.onItem || request.onComplete){ var content = this._parameters || {}; if(request.start){ if(request.start < 0){ throw new Error("dojox.data.SnapLogicStore: request start value must be 0 or greater"); } content['sn.start'] = request.start + 1; } if(request.count){ if(request.count < 0){ throw new Error("dojox.data.SnapLogicStore: request count value 0 or greater"); } content['sn.limit'] = request.count; } content['sn.content_type'] = 'application/javascript'; var store = this; var handler = function(response, ioArgs){ if(response instanceof Error){ store._fetchHandler(response, request); } }; var getArgs = { url: this.url, content: content, // preventCache: true, timeout: 60000, //Starting a pipeline can take a long time. callbackParamName: "sn.stream_header", handle: dojo.hitch(this, "_partHandler", request, this.Parts.DATA) }; request._dataHandle = dojo.io.script.get(getArgs); } if(request.onBegin){ var content = {}; content['sn.count'] = 'records'; content['sn.content_type'] = 'application/javascript'; var getArgs = { url: this.url, content: content, timeout: 60000, callbackParamName: "sn.stream_header", handle: dojo.hitch(this, "_partHandler", request, this.Parts.COUNT) }; request._countHandle = dojo.io.script.get(getArgs); } return request; // Object } });