blob: 3616b8416c53b0cb265bd934203e4c1910b2fb33 [file] [log] [blame]
/// <reference path="odata-utils.js" />
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// cache-source.js
(function (window, undefined) {
var datajs = window.datajs || {};
var odata = window.OData || {};
var parseInt10 = datajs.parseInt10;
var normalizeURICase = datajs.normalizeURICase;
// CONTENT START
var appendQueryOption = function (uri, queryOption) {
/// <summary>Appends the specified escaped query option to the specified URI.</summary>
/// <param name="uri" type="String">URI to append option to.</param>
/// <param name="queryOption" type="String">Escaped query option to append.</param>
var separator = (uri.indexOf("?") >= 0) ? "&" : "?";
return uri + separator + queryOption;
};
var appendSegment = function (uri, segment) {
/// <summary>Appends the specified segment to the given URI.</summary>
/// <param name="uri" type="String">URI to append a segment to.</param>
/// <param name="segment" type="String">Segment to append.</param>
/// <returns type="String">The original URI with a new segment appended.</returns>
var index = uri.indexOf("?");
var queryPortion = "";
if (index >= 0) {
queryPortion = uri.substr(index);
uri = uri.substr(0, index);
}
if (uri[uri.length - 1] !== "/") {
uri += "/";
}
return uri + segment + queryPortion;
};
var buildODataRequest = function (uri, options) {
/// <summary>Builds a request object to GET the specified URI.</summary>
/// <param name="uri" type="String">URI for request.</param>
/// <param name="options" type="Object">Additional options.</param>
return {
method: "GET",
requestUri: uri,
user: options.user,
password: options.password,
enableJsonpCallback: options.enableJsonpCallback,
callbackParameterName: options.callbackParameterName,
formatQueryString: options.formatQueryString
};
};
var findQueryOptionStart = function (uri, name) {
/// <summary>Finds the index where the value of a query option starts.</summary>
/// <param name="uri" type="String">URI to search in.</param>
/// <param name="name" type="String">Name to look for.</param>
/// <returns type="Number">The index where the query option starts.</returns>
var result = -1;
var queryIndex = uri.indexOf("?");
if (queryIndex !== -1) {
var start = uri.indexOf("?" + name + "=", queryIndex);
if (start === -1) {
start = uri.indexOf("&" + name + "=", queryIndex);
}
if (start !== -1) {
result = start + name.length + 2;
}
}
return result;
};
var queryForData = function (uri, options, success, error) {
/// <summary>Gets data from an OData service.</summary>
/// <param name="uri" type="String">URI to the OData service.</param>
/// <param name="options" type="Object">Object with additional well-known request options.</param>
/// <param name="success" type="Function">Success callback.</param>
/// <param name="error" type="Function">Error callback.</param>
/// <returns type="Object">Object with an abort method.</returns>
var request = queryForDataInternal(uri, options, [], success, error);
return request;
};
var queryForDataInternal = function (uri, options, data, success, error) {
/// <summary>Gets data from an OData service taking into consideration server side paging.</summary>
/// <param name="uri" type="String">URI to the OData service.</param>
/// <param name="options" type="Object">Object with additional well-known request options.</param>
/// <param name="data" type="Array">Array that stores the data provided by the OData service.</param>
/// <param name="success" type="Function">Success callback.</param>
/// <param name="error" type="Function">Error callback.</param>
/// <returns type="Object">Object with an abort method.</returns>
var request = buildODataRequest(uri, options);
var currentRequest = odata.request(request, function (newData) {
var next = newData.__next;
var results = newData.results;
data = data.concat(results);
if (next) {
currentRequest = queryForDataInternal(next, options, data, success, error);
} else {
success(data);
}
}, error, undefined, options.httpClient, options.metadata);
return {
abort: function () {
currentRequest.abort();
}
};
};
var ODataCacheSource = function (options) {
/// <summary>Creates a data cache source object for requesting data from an OData service.</summary>
/// <param name="options">Options for the cache data source.</param>
/// <returns type="ODataCacheSource">A new data cache source instance.</returns>
var that = this;
var uri = options.source;
that.identifier = normalizeURICase(encodeURI(decodeURI(uri)));
that.options = options;
that.count = function (success, error) {
/// <summary>Gets the number of items in the collection.</summary>
/// <param name="success" type="Function">Success callback with the item count.</param>
/// <param name="error" type="Function">Error callback.</param>
/// <returns type="Object">Request object with an abort method./<param>
var options = that.options;
return odata.request(
buildODataRequest(appendSegment(uri, "$count"), options),
function (data) {
var count = parseInt10(data.toString());
if (isNaN(count)) {
error({ message: "Count is NaN", count: count });
} else {
success(count);
}
}, error, undefined, options.httpClient, options.metadata);
};
that.read = function (index, count, success, error) {
/// <summary>Gets a number of consecutive items from the collection.</summary>
/// <param name="index" type="Number">Zero-based index of the items to retrieve.</param>
/// <param name="count" type="Number">Number of items to retrieve.</param>
/// <param name="success" type="Function">Success callback with the requested items.</param>
/// <param name="error" type="Function">Error callback.</param>
/// <returns type="Object">Request object with an abort method./<param>
var queryOptions = "$skip=" + index + "&$top=" + count;
return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error);
};
return that;
};
// DATAJS INTERNAL START
window.datajs.ODataCacheSource = ODataCacheSource;
// DATAJS INTERNAL END
// CONTENT END
})(this);