1 if(!dojo._hasResource["dojox.data.SnapLogicStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.data.SnapLogicStore"] = true;
3 dojo.provide("dojox.data.SnapLogicStore");
5 dojo.require("dojo.io.script");
6 dojo.require("dojo.data.util.sorter");
8 dojo.declare("dojox.data.SnapLogicStore", null, {
16 constructor: function(/* Object */args){
18 // Initialize a SnapLogicStore object.
20 // An object that contains properties for initializing the new data store object. The
21 // following properties are understood:
23 // A URL to the SnapLogic pipeline's output routed through PipeToHttp. Typically, this
24 // will look like "http://<server-host>:<port>/pipe/<pipeline-url>/<pipeline-output-view>".
26 // An object whose properties define parameters to the pipeline. The values of these
27 // properties will be sent to the pipeline as parameters when it run.
32 this._parameters = args.parameters;
35 _assertIsItem: function(/* item */item){
37 // This function tests whether the item passed in is indeed an item in the store.
39 // The item to test for being contained by the store.
40 if(!this.isItem(item)){
41 throw new Error("dojox.data.SnapLogicStore: a function was passed an item argument that was not an item");
45 _assertIsAttribute: function(/* attribute-name-string */ attribute){
47 // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
49 // The attribute to test for being contained by the store.
50 if(typeof attribute !== "string"){
51 throw new Error("dojox.data.SnapLogicStore: a function was passed an attribute argument that was not an attribute name string");
55 getFeatures: function(){
57 // See dojo.data.api.Read.getFeatures()
59 'dojo.data.api.Read': true
63 getValue: function(item, attribute){
65 // See dojo.data.api.Read.getValue()
66 this._assertIsItem(item);
67 this._assertIsAttribute(attribute);
68 i = dojo.indexOf(item.attributes, attribute);
70 return item.values[i];
75 getAttributes: function(item){
77 // See dojo.data.api.Read.getAttributes()
78 this._assertIsItem(item);
79 return item.attributes;
82 hasAttribute: function(item, attribute){
84 // See dojo.data.api.Read.hasAttributes()
85 this._assertIsItem(item);
86 this._assertIsAttribute(attribute);
87 for(var i = 0; i < item.attributes.length; ++i){
88 if(attribute == item.attributes[i]){
95 isItemLoaded: function(item){
97 // See dojo.data.api.Read.isItemLoaded()
98 return this.isItem(item); // Boolean
101 loadItem: function(keywordArgs){
103 // See dojo.data.api.Read.loadItem()
106 getLabel: function(item){
108 // See dojo.data.api.Read.getLabel()
112 getLabelAttributes: function(item){
114 // See dojo.data.api.Read.getLabelAttributes()
118 containsValue: function(item, attribute, value){
120 // See dojo.data.api.Read.containsValue()
121 return this.getValue(item, attribute) === value; // Boolean
124 getValues: function(item, attribute){
126 // See dojo.data.api.Read.getValue()
127 this._assertIsItem(item);
128 this._assertIsAttribute(attribute);
129 i = dojo.indexOf(item.attributes, attribute);
131 return [item.values[i]]; // Array
136 isItem: function(item){
138 // See dojo.data.api.Read.isItem()
139 if(item && item._store === this){
145 close: function(request){
147 // See dojo.data.api.Read.close()
150 _fetchHandler: function(/* Object */request){
152 // Process data retrieved via fetch and send it back to requester.
154 // The data returend from the I/O transport. In the normal case, it will be an array of result rows
155 // from the pipeline. In the special case for record count optimization, response will be an array
156 // with a single element containing the total pipeline result row count. See fetch() for details
157 // on this optimization.
159 var scope = request.scope || dojo.global;
162 // Check for the record count optimization
163 request.onBegin.call(scope, request._countResponse[0], request);
166 if(request.onItem || request.onComplete){
167 response = request._dataResponse;
169 if (!response.length){
170 request.onError.call(scope,
171 new Error("dojox.data.SnapLogicStore: invalid response of length 0"),
174 }else if(request.query != 'record count'){
175 //If this was not a record count request, the first element returned will contain
177 field_names = response.shift();
180 for(var i = 0; i < response.length; ++i){
181 if(request._aborted){
185 items.push({attributes: field_names, values: response[i], _store: this});
188 if(request.sort && !request._aborted){
189 items.sort(dojo.data.util.sorter.createSortFunction(request.sort, self));
192 //This is a record count request, so manually set the field names.
193 items = [({attributes: ['count'], values: response, _store: this})];
197 for(var i = 0; i < items.length; ++i){
198 if (request._aborted) {
201 request.onItem.call(scope, items[i], request);
206 if(request.onComplete && !request._aborted){
207 request.onComplete.call(scope, items, request);
212 _partHandler: function(/* Object */request, /* String */part, /* Object */response){
214 // Handle the individual replies for both data and length requests.
216 // The request/handle object used with the original fetch() call.
218 // A value indicating which request this handler call is for (this.Parts).
220 // Response received from the underlying IO transport.
222 if(response instanceof Error){
223 if(part == this.Parts.DATA){
224 request._dataHandle = null;
226 request._countHandle = null;
228 request._aborted = true;
230 request.onError.call(request.scope, response, request);
233 if(request._aborted){
236 if(part == this.Parts.DATA){
237 request._dataResponse = response;
239 request._countResponse = response;
241 if((!request._dataHandle || request._dataResponse !== null) &&
242 (!request._countHandle || request._countResponse !== null)){
243 this._fetchHandler(request);
248 fetch: function(/* Object */request){
250 // See dojo.data.api.Read.close()
252 // See dojo.data.api.Read.close() for generic interface.
254 // In addition to the standard Read API fetch support, this store supports an optimization for
255 // for retrieving the total count of records in the Pipeline without retrieving the data. To
256 // use this optimization, simply provide an onBegin handler without an onItem or onComplete handler.
258 request._countResponse = null;
259 request._dataResponse = null;
260 request._aborted = false;
261 request.abort = function(){
262 if(!request._aborted){
263 request._aborted = true;
264 if(request._dataHandle && request._dataHandle.cancel){
265 request._dataHandle.cancel();
267 if(request._countHandle && request._countHandle.cancel){
268 request._countHandle.cancel();
273 // Only make the call for data if onItem or onComplete is used. Otherwise, onBegin will only
274 // require the total row count.
275 if(request.onItem || request.onComplete){
276 var content = this._parameters || {};
278 if(request.start < 0){
279 throw new Error("dojox.data.SnapLogicStore: request start value must be 0 or greater");
281 content['sn.start'] = request.start + 1;
284 if(request.count < 0){
285 throw new Error("dojox.data.SnapLogicStore: request count value 0 or greater");
287 content['sn.limit'] = request.count;
290 content['sn.content_type'] = 'application/javascript';
293 var handler = function(response, ioArgs){
294 if(response instanceof Error){
295 store._fetchHandler(response, request);
302 // preventCache: true,
303 timeout: 60000, //Starting a pipeline can take a long time.
304 callbackParamName: "sn.stream_header",
305 handle: dojo.hitch(this, "_partHandler", request, this.Parts.DATA)
308 request._dataHandle = dojo.io.script.get(getArgs);
313 content['sn.count'] = 'records';
314 content['sn.content_type'] = 'application/javascript';
320 callbackParamName: "sn.stream_header",
321 handle: dojo.hitch(this, "_partHandler", request, this.Parts.COUNT)
324 request._countHandle = dojo.io.script.get(getArgs);
327 return request; // Object