diff --git a/Gruntfile.js b/Gruntfile.js
index faff8d0..fb523bf 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -36,7 +36,7 @@ module.exports = function(grunt) {
"toBrowser" : {
"release" : {
- options: { index : "index-browser.js" },
+ options: { index : "index.js" },
src: ["lib/**/*.js", '!**/*-node.*'],
dest: "_build/lib/<%= artifactname %>.js"
}
diff --git a/README.md b/README.md
index 62ee639..11bc843 100644
--- a/README.md
+++ b/README.md
@@ -19,13 +19,13 @@ under the License.
## Olingo OData Client for JavaScript
The Olingo OData Client for JavaScript (odatajs) is a library written in JavaScript that enables browser based frontend applications to easily use the OData protocol for communication with application servers.
-This library "odatajs-4.0.0.min.js" supports only the OData V4 protocol.
+This library "odatajs-4.0.1.min.js" supports only the OData V4 protocol.
For using the OData protocols V1-V3 please refer to the [datajs library](http://datajs.codeplex.com/)
The odatajs library can be included in any html page with the script tag (for example)
```
-
+
```
and its features can be used through the `odatajs` namespace (or `window.odatajs`). The odatajs library can be used together with the datajs library which uses the `window.OData` namespace.
diff --git a/grunt-config/custom-tasks/rat/package.json b/grunt-config/custom-tasks/rat/package.json
index 0c374c7..3d1a5bb 100644
--- a/grunt-config/custom-tasks/rat/package.json
+++ b/grunt-config/custom-tasks/rat/package.json
@@ -18,9 +18,6 @@
"grunt": "~0.4.0",
"xml2js": "^0.4.4"
},
- "peerDependencies": {
- "grunt": "~0.4.0"
- },
"engines": {
"node": ">=0.8.0"
}
diff --git a/grunt-config/custom-tasks/sign.js b/grunt-config/custom-tasks/sign.js
index 3db3f73..ce15b4e 100644
--- a/grunt-config/custom-tasks/sign.js
+++ b/grunt-config/custom-tasks/sign.js
@@ -24,7 +24,7 @@ module.exports = function(grunt) {
var path = require('path');
var fs = require( 'fs' );
- var chalk = require('./rat/node_modules/chalk');
+ var chalk = require('chalk');
var globalDone = this.async();
diff --git a/grunt-config/custom-tasks/toBrowser/toBrowser.js b/grunt-config/custom-tasks/toBrowser/toBrowser.js
index ad2e8c8..24b4a32 100644
--- a/grunt-config/custom-tasks/toBrowser/toBrowser.js
+++ b/grunt-config/custom-tasks/toBrowser/toBrowser.js
@@ -49,13 +49,13 @@ module.exports = function(grunt) {
//console.log('exists :'+srcPath+srcName+'-browser.js' );
tarName = srcName;
- if (srcName.indexOf('-browser') > 0) {
- tarName = tarName.substring(0,srcName.indexOf('-browser'));
- //console.log('new srcName :'+srcName );
- } else if (grunt.file.exists(srcPath+srcName+'-browser.js')) {
- //console.log('exists :yes');
- continue; //skip that file
- }
+ // if (srcName.indexOf('-browser') > 0) {
+ // tarName = tarName.substring(0,srcName.indexOf('-browser'));
+ // //console.log('new srcName :'+srcName );
+ // } else if (grunt.file.exists(srcPath+srcName+'-browser.js')) {
+ // //console.log('exists :yes');
+ // continue; //skip that file
+ // }
workLoad.push({
diff --git a/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js b/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
index 9c335db..28c5218 100644
--- a/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
+++ b/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
+(function(){
var init = function(exports, module, require) {
'<% initFunction %>'
};
@@ -29,7 +30,6 @@ var require = function(path) {
if (modules[name]) { return modules[name].exports; }
modules[name] = { exports : {}};
- console.log(name);
if (name === 'sou') {
var i = 0;
}
@@ -39,5 +39,5 @@ var require = function(path) {
window.odatajs = {};
init.call(this,window.odatajs,window.odatajs,require);
-
+})();
diff --git a/grunt-config/nugetpack.nuspec b/grunt-config/nugetpack.nuspec
index a0c7861..3a23d58 100644
--- a/grunt-config/nugetpack.nuspec
+++ b/grunt-config/nugetpack.nuspec
@@ -4,7 +4,7 @@
Olingo OData Client for JavaScript
odatajs
restful api open protocol odata client javascript
- 4.0.0
+ 4.0.1
Apache Olingo (Challen He, Kobler-Morris Sven)
Apache Olingo
http://www.apache.org/licenses/LICENSE-2.0
diff --git a/grunt-config/release-config.js b/grunt-config/release-config.js
index 3df970e..07219f6 100644
--- a/grunt-config/release-config.js
+++ b/grunt-config/release-config.js
@@ -71,7 +71,7 @@ module.exports = function(grunt) {
},
"release-nuget": {
files: [
- { expand: true, cwd: '_build', src: ['odatajs.4.0.0.nupkg'], dest: './_dist/<%= artifactname %>', filter: 'isFile' },
+ { expand: true, cwd: '_build', src: ['odatajs.4.0.1.nupkg'], dest: './_dist/<%= artifactname %>', filter: 'isFile' },
]
},
"release-doc" : {
diff --git a/grunt-config/sign-config.js b/grunt-config/sign-config.js
index 6c827e3..d543730 100644
--- a/grunt-config/sign-config.js
+++ b/grunt-config/sign-config.js
@@ -28,7 +28,7 @@ module.exports = function(grunt) {
cwd : './_dist/<%= artifactname %>/',
src : [
'<%= artifactname %>-lib.zip',
- 'odatajs.4.0.0.nupkg',
+ 'odatajs.4.0.1.nupkg',
'<%= artifactname %>-doc.zip',
'<%= artifactname %>-sources.zip'
]
@@ -39,7 +39,7 @@ module.exports = function(grunt) {
cwd : './_dist/<%= artifactname %>/',
src : [
'<%= artifactname %>-lib.zip',
- 'odatajs.4.0.0.nupkg',
+ 'odatajs.4.0.1.nupkg',
'<%= artifactname %>-doc.zip',
'<%= artifactname %>-sources.zip'
]
@@ -50,7 +50,7 @@ module.exports = function(grunt) {
cwd : './_dist/<%= artifactname %>/',
src : [
'<%= artifactname %>-lib.zip',
- 'odatajs.4.0.0.nupkg',
+ 'odatajs.4.0.1.nupkg',
'<%= artifactname %>-doc.zip',
'<%= artifactname %>-sources.zip'
]
diff --git a/index-browser.js b/index-browser.js
deleted file mode 100644
index 0524487..0000000
--- a/index-browser.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// version information
-exports.version = { major: 4, minor: 0, build: 0 };
-
-// core stuff, always needed
-exports.deferred = require('./lib/deferred.js');
-exports.utils = require('./lib/utils.js');
-
-// only needed for xml metadata
-exports.xml = require('./lib/xml.js');
-
-// only need in browser case
-exports.oData = require('./lib/odata.js');
-exports.store = require('./lib/store.js');
-exports.cache = require('./lib/cache.js');
-
-
-
diff --git a/index.js b/index.js
index 85aea5b..2431a7c 100644
--- a/index.js
+++ b/index.js
@@ -22,11 +22,10 @@ var odatajs = {};
odatajs.version = {
major: 4,
minor: 0,
- build: 0
+ build: 1
};
// core stuff, alway needed
-odatajs.deferred = require('./lib/deferred.js');
odatajs.utils = require('./lib/utils.js');
// only neede for xml metadata
@@ -34,13 +33,13 @@ odatajs.xml = require('./lib/xml.js');
// only need in browser case
odatajs.oData = require('./lib/odata.js');
-odatajs.store = require('./lib/store.js');
-odatajs.cache = require('./lib/cache.js');
-if (typeof window !== 'undefined') {
+if (odatajs.utils.inBrowser()) {
//expose to browsers window object
window.odatajs = odatajs;
-} else {
+}
+
+if(typeof module !== 'undefined'){
//expose in commonjs style
odatajs.node = "node";
module.exports = odatajs;
diff --git a/lib/cache.js b/lib/cache.js
deleted file mode 100644
index dce74b6..0000000
--- a/lib/cache.js
+++ /dev/null
@@ -1,1445 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
- /** @module cache */
-
-//var odatajs = require('./odatajs/utils.js');
-var utils = require('./utils.js');
-var deferred = require('./deferred.js');
-var storeReq = require('./store.js');
-var cacheSource = require('./cache/source.js');
-
-
-var assigned = utils.assigned;
-var delay = utils.delay;
-var extend = utils.extend;
-var djsassert = utils.djsassert;
-var isArray = utils.isArray;
-var normalizeURI = utils.normalizeURI;
-var parseInt10 = utils.parseInt10;
-var undefinedDefault = utils.undefinedDefault;
-
-var createDeferred = deferred.createDeferred;
-var DjsDeferred = deferred.DjsDeferred;
-
-
-var getJsonValueArraryLength = utils.getJsonValueArraryLength;
-var sliceJsonValueArray = utils.sliceJsonValueArray;
-var concatJsonValueArray = utils.concatJsonValueArray;
-
-
-
-/** Appends a page's data to the operation data.
- * @param {Object} operation - Operation with (i)ndex, (c)ount and (d)ata.
- * @param {Object} page - Page with (i)ndex, (c)ount and (d)ata.
- */
-function appendPage(operation, page) {
-
- var intersection = intersectRanges(operation, page);
- var start = 0;
- var end = 0;
- if (intersection) {
- start = intersection.i - page.i;
- end = start + (operation.c - getJsonValueArraryLength(operation.d));
- }
-
- operation.d = concatJsonValueArray(operation.d, sliceJsonValueArray(page.d, start, end));
-}
-
-/** Returns the {(i)ndex, (c)ount} range for the intersection of x and y.
- * @param {Object} x - Range with (i)ndex and (c)ount members.
- * @param {Object} y - Range with (i)ndex and (c)ount members.
- * @returns {Object} The intersection (i)ndex and (c)ount; undefined if there is no intersection.
- */
-function intersectRanges(x, y) {
-
- var xLast = x.i + x.c;
- var yLast = y.i + y.c;
- var resultIndex = (x.i > y.i) ? x.i : y.i;
- var resultLast = (xLast < yLast) ? xLast : yLast;
- var result;
- if (resultLast >= resultIndex) {
- result = { i: resultIndex, c: resultLast - resultIndex };
- }
-
- return result;
-}
-
-/** Checks whether val is a defined number with value zero or greater.
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkZeroGreater(val, name) {
-
- if (val === undefined || typeof val !== "number") {
- throw { message: "'" + name + "' must be a number." };
- }
-
- if (isNaN(val) || val < 0 || !isFinite(val)) {
- throw { message: "'" + name + "' must be greater than or equal to zero." };
- }
-}
-
-/** Checks whether val is undefined or a number with value greater than zero.
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkUndefinedGreaterThanZero(val, name) {
-
- if (val !== undefined) {
- if (typeof val !== "number") {
- throw { message: "'" + name + "' must be a number." };
- }
-
- if (isNaN(val) || val <= 0 || !isFinite(val)) {
- throw { message: "'" + name + "' must be greater than zero." };
- }
- }
-}
-
-/** Checks whether val is undefined or a number
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkUndefinedOrNumber(val, name) {
- if (val !== undefined && (typeof val !== "number" || isNaN(val) || !isFinite(val))) {
- throw { message: "'" + name + "' must be a number." };
- }
-}
-
-/** Performs a linear search on the specified array and removes the first instance of 'item'.
- * @param {Array} arr - Array to search.
- * @param {*} item - Item being sought.
- * @returns {Boolean} true if the item was removed otherwise false
- */
-function removeFromArray(arr, item) {
-
- var i, len;
- for (i = 0, len = arr.length; i < len; i++) {
- if (arr[i] === item) {
- arr.splice(i, 1);
- return true;
- }
- }
-
- return false;
-}
-
-/** Estimates the size of an object in bytes.
- * Object trees are traversed recursively
- * @param {Object} object - Object to determine the size of.
- * @returns {Number} Estimated size of the object in bytes.
- */
-function estimateSize(object) {
- var size = 0;
- var type = typeof object;
-
- if (type === "object" && object) {
- for (var name in object) {
- size += name.length * 2 + estimateSize(object[name]);
- }
- } else if (type === "string") {
- size = object.length * 2;
- } else {
- size = 8;
- }
- return size;
-}
-
-/** Snaps low and high indices into page sizes and returns a range.
- * @param {Number} lowIndex - Low index to snap to a lower value.
- * @param {Number} highIndex - High index to snap to a higher value.
- * @param {Number} pageSize - Page size to snap to.
- * @returns {Object} A range with (i)ndex and (c)ount of elements.
- */
-function snapToPageBoundaries(lowIndex, highIndex, pageSize) {
- lowIndex = Math.floor(lowIndex / pageSize) * pageSize;
- highIndex = Math.ceil((highIndex + 1) / pageSize) * pageSize;
- return { i: lowIndex, c: highIndex - lowIndex };
-}
-
-// The DataCache is implemented using state machines. The following constants are used to properly
-// identify and label the states that these machines transition to.
-var CACHE_STATE_DESTROY = "destroy";
-var CACHE_STATE_IDLE = "idle";
-var CACHE_STATE_INIT = "init";
-var CACHE_STATE_READ = "read";
-var CACHE_STATE_PREFETCH = "prefetch";
-var CACHE_STATE_WRITE = "write";
-
-// DataCacheOperation state machine states.
-// Transitions on operations also depend on the cache current of the cache.
-var OPERATION_STATE_CANCEL = "cancel";
-var OPERATION_STATE_END = "end";
-var OPERATION_STATE_ERROR = "error";
-var OPERATION_STATE_START = "start";
-var OPERATION_STATE_WAIT = "wait";
-
-// Destroy state machine states
-var DESTROY_STATE_CLEAR = "clear";
-
-// Read / Prefetch state machine states
-var READ_STATE_DONE = "done";
-var READ_STATE_LOCAL = "local";
-var READ_STATE_SAVE = "save";
-var READ_STATE_SOURCE = "source";
-
-/** Creates a new operation object.
- * @class DataCacheOperation
- * @param {Function} stateMachine - State machine that describes the specific behavior of the operation.
- * @param {DjsDeferred} promise - Promise for requested values.
- * @param {Boolean} isCancelable - Whether this operation can be canceled or not.
- * @param {Number} index - Index of first item requested.
- * @param {Number} count - Count of items requested.
- * @param {Array} data - Array with the items requested by the operation.
- * @param {Number} pending - Total number of pending prefetch records.
- * @returns {DataCacheOperation} A new data cache operation instance.
- */
-function DataCacheOperation(stateMachine, promise, isCancelable, index, count, data, pending) {
-
- var stateData;
- var cacheState;
- var that = this;
-
- that.p = promise;
- that.i = index;
- that.c = count;
- that.d = data;
- that.s = OPERATION_STATE_START;
-
- that.canceled = false;
- that.pending = pending;
- that.oncomplete = null;
-
- /** Transitions this operation to the cancel state and sets the canceled flag to true.
- * The function is a no-op if the operation is non-cancelable.
- * @method DataCacheOperation#cancel
- */
- that.cancel = function cancel() {
-
- if (!isCancelable) {
- return;
- }
-
- var state = that.s;
- if (state !== OPERATION_STATE_ERROR && state !== OPERATION_STATE_END && state !== OPERATION_STATE_CANCEL) {
- that.canceled = true;
- that.transition(OPERATION_STATE_CANCEL, stateData);
- }
- };
-
- /** Transitions this operation to the end state.
- * @method DataCacheOperation#complete
- */
- that.complete = function () {
-
- djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.complete() - operation is in the end state", that);
- that.transition(OPERATION_STATE_END, stateData);
- };
-
- /** Transitions this operation to the error state.
- * @method DataCacheOperation#error
- */
- that.error = function (err) {
- if (!that.canceled) {
- djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.error() - operation is in the end state", that);
- djsassert(that.s !== OPERATION_STATE_ERROR, "DataCacheOperation.error() - operation is in the error state", that);
- that.transition(OPERATION_STATE_ERROR, err);
- }
- };
-
- /** Executes the operation's current state in the context of a new cache state.
- * @method DataCacheOperation#run
- * @param {Object} state - New cache state.
- */
- that.run = function (state) {
-
- cacheState = state;
- that.transition(that.s, stateData);
- };
-
- /** Transitions this operation to the wait state.
- * @method DataCacheOperation#wait
- */
- that.wait = function (data) {
-
- djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.wait() - operation is in the end state", that);
- that.transition(OPERATION_STATE_WAIT, data);
- };
-
- /** State machine that describes all operations common behavior.
- * @method DataCacheOperation#operationStateMachine
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
- * @param {Object} [data] - Additional data passed to the state.
- */
- var operationStateMachine = function (opTargetState, cacheState, data) {
-
- switch (opTargetState) {
- case OPERATION_STATE_START:
- // Initial state of the operation. The operation will remain in this state until the cache has been fully initialized.
- if (cacheState !== CACHE_STATE_INIT) {
- stateMachine(that, opTargetState, cacheState, data);
- }
- break;
-
- case OPERATION_STATE_WAIT:
- // Wait state indicating that the operation is active but waiting for an asynchronous operation to complete.
- stateMachine(that, opTargetState, cacheState, data);
- break;
-
- case OPERATION_STATE_CANCEL:
- // Cancel state.
- stateMachine(that, opTargetState, cacheState, data);
- that.fireCanceled();
- that.transition(OPERATION_STATE_END);
- break;
-
- case OPERATION_STATE_ERROR:
- // Error state. Data is expected to be an object detailing the error condition.
- stateMachine(that, opTargetState, cacheState, data);
- that.canceled = true;
- that.fireRejected(data);
- that.transition(OPERATION_STATE_END);
- break;
-
- case OPERATION_STATE_END:
- // Final state of the operation.
- if (that.oncomplete) {
- that.oncomplete(that);
- }
- if (!that.canceled) {
- that.fireResolved();
- }
- stateMachine(that, opTargetState, cacheState, data);
- break;
-
- default:
- // Any other state is passed down to the state machine describing the operation's specific behavior.
-
- if (true) {
- // Check that the state machine actually handled the sate.
- var handled = stateMachine(that, opTargetState, cacheState, data);
- djsassert(handled, "Bad operation state: " + opTargetState + " cacheState: " + cacheState, this);
- } else {
-
- stateMachine(that, opTargetState, cacheState, data);
-
- }
-
- break;
- }
- };
-
-
-
- /** Transitions this operation to a new state.
- * @method DataCacheOperation#transition
- * @param {Object} state - State to transition the operation to.
- * @param {Object} [data] -
- */
- that.transition = function (state, data) {
- that.s = state;
- stateData = data;
- operationStateMachine(state, cacheState, data);
- };
-
- return that;
-}
-
-/** Fires a resolved notification as necessary.
- * @method DataCacheOperation#fireResolved
- */
-DataCacheOperation.prototype.fireResolved = function () {
-
- // Fire the resolve just once.
- var p = this.p;
- if (p) {
- this.p = null;
- p.resolve(this.d);
- }
-};
-
-/** Fires a rejected notification as necessary.
- * @method DataCacheOperation#fireRejected
- */
-DataCacheOperation.prototype.fireRejected = function (reason) {
-
- // Fire the rejection just once.
- var p = this.p;
- if (p) {
- this.p = null;
- p.reject(reason);
- }
-};
-
-/** Fires a canceled notification as necessary.
- * @method DataCacheOperation#fireCanceled
- */
-DataCacheOperation.prototype.fireCanceled = function () {
-
- this.fireRejected({ canceled: true, message: "Operation canceled" });
-};
-
-
-/** Creates a data cache for a collection that is efficiently loaded on-demand.
- * @class DataCache
- * @param options - Options for the data cache, including name, source, pageSize,
- * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
- * @returns {DataCache} A new data cache instance.
- */
-function DataCache(options) {
-
- var state = CACHE_STATE_INIT;
- var stats = { counts: 0, netReads: 0, prefetches: 0, cacheReads: 0 };
-
- var clearOperations = [];
- var readOperations = [];
- var prefetchOperations = [];
-
- var actualCacheSize = 0; // Actual cache size in bytes.
- var allDataLocal = false; // Whether all data is local.
- var cacheSize = undefinedDefault(options.cacheSize, 1048576); // Requested cache size in bytes, default 1 MB.
- var collectionCount = 0; // Number of elements in the server collection.
- var highestSavedPage = 0; // Highest index of all the saved pages.
- var highestSavedPageSize = 0; // Item count of the saved page with the highest index.
- var overflowed = cacheSize === 0; // If the cache has overflowed (actualCacheSize > cacheSize or cacheSize == 0);
- var pageSize = undefinedDefault(options.pageSize, 50); // Number of elements to store per page.
- var prefetchSize = undefinedDefault(options.prefetchSize, pageSize); // Number of elements to prefetch from the source when the cache is idling.
- var version = "1.0";
- var cacheFailure;
-
- var pendingOperations = 0;
-
- var source = options.source;
- if (typeof source === "string") {
- // Create a new cache source.
- source = new cacheSource.ODataCacheSource(options);
- }
- source.options = options;
-
- // Create a cache local store.
- var store = storeReq.createStore(options.name, options.mechanism);
-
- var that = this;
-
- that.onidle = options.idle;
- that.stats = stats;
-
- /** Counts the number of items in the collection.
- * @method DataCache#count
- * @returns {Object} A promise with the number of items.
- */
- that.count = function () {
-
- if (cacheFailure) {
- throw cacheFailure;
- }
-
- var deferred = createDeferred();
- var canceled = false;
-
- if (allDataLocal) {
- delay(function () {
- deferred.resolve(collectionCount);
- });
-
- return deferred.promise();
- }
-
- // TODO: Consider returning the local data count instead once allDataLocal flag is set to true.
- var request = source.count(function (count) {
- request = null;
- stats.counts++;
- deferred.resolve(count);
- }, function (err) {
- request = null;
- deferred.reject(extend(err, { canceled: canceled }));
- });
-
- return extend(deferred.promise(), {
-
- /** Aborts the count operation (used within promise callback)
- * @method DataCache#cancelCount
- */
- cancel: function () {
-
- if (request) {
- canceled = true;
- request.abort();
- request = null;
- }
- }
- });
- };
-
- /** Cancels all running operations and clears all local data associated with this cache.
- * New read requests made while a clear operation is in progress will not be canceled.
- * Instead they will be queued for execution once the operation is completed.
- * @method DataCache#clear
- * @returns {Object} A promise that has no value and can't be canceled.
- */
- that.clear = function () {
-
- if (cacheFailure) {
- throw cacheFailure;
- }
-
- if (clearOperations.length === 0) {
- var deferred = createDeferred();
- var op = new DataCacheOperation(destroyStateMachine, deferred, false);
- queueAndStart(op, clearOperations);
- return deferred.promise();
- }
- return clearOperations[0].p;
- };
-
- /** Filters the cache data based a predicate.
- * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
- * @method DataCache#filterForward
- * @param {Number} index - The index of the item to start filtering forward from.
- * @param {Number} count - Maximum number of items to include in the result.
- * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
- * @returns {DjsDeferred} A promise for an array of results.
- */
- that.filterForward = function (index, count, predicate) {
- return filter(index, count, predicate, false);
- };
-
- /** Filters the cache data based a predicate.
- * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
- * @method DataCache#filterBack
- * @param {Number} index - The index of the item to start filtering backward from.
- * @param {Number} count - Maximum number of items to include in the result.
- * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
- * @returns {DjsDeferred} A promise for an array of results.
- */
- that.filterBack = function (index, count, predicate) {
- return filter(index, count, predicate, true);
- };
-
- /** Reads a range of adjacent records.
- * New read requests made while a clear operation is in progress will not be canceled.
- * Instead they will be queued for execution once the operation is completed.
- * @method DataCache#readRange
- * @param {Number} index - Zero-based index of record range to read.
- * @param {Number} count - Number of records in the range.
- * @returns {DjsDeferred} A promise for an array of records; less records may be returned if the
- * end of the collection is found.
- */
- that.readRange = function (index, count) {
-
- checkZeroGreater(index, "index");
- checkZeroGreater(count, "count");
-
- if (cacheFailure) {
- throw cacheFailure;
- }
-
- var deferred = createDeferred();
-
- // Merging read operations would be a nice optimization here.
- var op = new DataCacheOperation(readStateMachine, deferred, true, index, count, {}, 0);
- queueAndStart(op, readOperations);
-
- return extend(deferred.promise(), {
- cancel: function () {
- /** Aborts the readRange operation (used within promise callback)
- * @method DataCache#cancelReadRange
- */
- op.cancel();
- }
- });
- };
-
- /** Creates an Observable object that enumerates all the cache contents.
- * @method DataCache#toObservable
- * @returns A new Observable object that enumerates all the cache contents.
- */
- that.ToObservable = that.toObservable = function () {
- if ( !utils.inBrowser()) {
- throw { message: "Only in broser supported" };
- }
-
- if (!window.Rx || !window.Rx.Observable) {
- throw { message: "Rx library not available - include rx.js" };
- }
-
- if (cacheFailure) {
- throw cacheFailure;
- }
-
- //return window.Rx.Observable.create(function (obs) {
- return new window.Rx.Observable(function (obs) {
- var disposed = false;
- var index = 0;
-
- var errorCallback = function (error) {
- if (!disposed) {
- obs.onError(error);
- }
- };
-
- var successCallback = function (data) {
- if (!disposed) {
- var i, len;
- for (i = 0, len = data.value.length; i < len; i++) {
- // The wrapper automatically checks for Dispose
- // on the observer, so we don't need to check it here.
- //obs.next(data.value[i]);
- obs.onNext(data.value[i]);
- }
-
- if (data.value.length < pageSize) {
- //obs.completed();
- obs.onCompleted();
- } else {
- index += pageSize;
- that.readRange(index, pageSize).then(successCallback, errorCallback);
- }
- }
- };
-
- that.readRange(index, pageSize).then(successCallback, errorCallback);
-
- return { Dispose: function () {
- obs.dispose(); // otherwise the check isStopped obs.onNext(data.value[i]);
- disposed = true;
- } };
- });
- };
-
- /** Creates a function that handles a callback by setting the cache into failure mode.
- * @method DataCache~cacheFailureCallback
- * @param {String} message - Message text.
- * @returns {Function} Function to use as error callback.
- * This function will specifically handle problems with critical store resources
- * during cache initialization.
- */
- var cacheFailureCallback = function (message) {
-
-
- return function (error) {
- cacheFailure = { message: message, error: error };
-
- // Destroy any pending clear or read operations.
- // At this point there should be no prefetch operations.
- // Count operations will go through but are benign because they
- // won't interact with the store.
- djsassert(prefetchOperations.length === 0, "prefetchOperations.length === 0");
- var i, len;
- for (i = 0, len = readOperations.length; i < len; i++) {
- readOperations[i].fireRejected(cacheFailure);
- }
- for (i = 0, len = clearOperations.length; i < len; i++) {
- clearOperations[i].fireRejected(cacheFailure);
- }
-
- // Null out the operation arrays.
- readOperations = clearOperations = null;
- };
- };
-
- /** Updates the cache's state and signals all pending operations of the change.
- * @method DataCache~changeState
- * @param {Object} newState - New cache state.
- * This method is a no-op if the cache's current state and the new state are the same.
- */
- var changeState = function (newState) {
-
- if (newState !== state) {
- state = newState;
- var operations = clearOperations.concat(readOperations, prefetchOperations);
- var i, len;
- for (i = 0, len = operations.length; i < len; i++) {
- operations[i].run(state);
- }
- }
- };
-
- /** Removes all the data stored in the cache.
- * @method DataCache~clearStore
- * @returns {DjsDeferred} A promise with no value.
- */
- var clearStore = function () {
- djsassert(state === CACHE_STATE_DESTROY || state === CACHE_STATE_INIT, "DataCache.clearStore() - cache is not on the destroy or initialize state, current sate = " + state);
-
- var deferred = new DjsDeferred();
- store.clear(function () {
-
- // Reset the cache settings.
- actualCacheSize = 0;
- allDataLocal = false;
- collectionCount = 0;
- highestSavedPage = 0;
- highestSavedPageSize = 0;
- overflowed = cacheSize === 0;
-
- // version is not reset, in case there is other state in eg V1.1 that is still around.
-
- // Reset the cache stats.
- stats = { counts: 0, netReads: 0, prefetches: 0, cacheReads: 0 };
- that.stats = stats;
-
- store.close();
- deferred.resolve();
- }, function (err) {
- deferred.reject(err);
- });
- return deferred;
- };
-
- /** Removes an operation from the caches queues and changes the cache state to idle.
- * @method DataCache~dequeueOperation
- * @param {DataCacheOperation} operation - Operation to dequeue.
- * This method is used as a handler for the operation's oncomplete event.
- */
- var dequeueOperation = function (operation) {
-
- var removed = removeFromArray(clearOperations, operation);
- if (!removed) {
- removed = removeFromArray(readOperations, operation);
- if (!removed) {
- removeFromArray(prefetchOperations, operation);
- }
- }
-
- pendingOperations--;
- changeState(CACHE_STATE_IDLE);
- };
-
- /** Requests data from the cache source.
- * @method DataCache~fetchPage
- * @param {Number} start - Zero-based index of items to request.
- * @returns {DjsDeferred} A promise for a page object with (i)ndex, (c)ount, (d)ata.
- */
- var fetchPage = function (start) {
-
- djsassert(state !== CACHE_STATE_DESTROY, "DataCache.fetchPage() - cache is on the destroy state");
- djsassert(state !== CACHE_STATE_IDLE, "DataCache.fetchPage() - cache is on the idle state");
-
- var deferred = new DjsDeferred();
- var canceled = false;
-
- var request = source.read(start, pageSize, function (data) {
- var length = getJsonValueArraryLength(data);
- var page = { i: start, c: length, d: data };
- deferred.resolve(page);
- }, function (err) {
- deferred.reject(err);
- });
-
- return extend(deferred, {
- cancel: function () {
- if (request) {
- request.abort();
- canceled = true;
- request = null;
- }
- }
- });
- };
-
- /** Filters the cache data based a predicate.
- * @method DataCache~filter
- * @param {Number} index - The index of the item to start filtering from.
- * @param {Number} count - Maximum number of items to include in the result.
- * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
- * @param {Boolean} backwards - True if the filtering should move backward from the specified index, falsey otherwise.
- * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
- * @returns {DjsDeferred} A promise for an array of results.
- */
- var filter = function (index, count, predicate, backwards) {
-
- index = parseInt10(index);
- count = parseInt10(count);
-
- if (isNaN(index)) {
- throw { message: "'index' must be a valid number.", index: index };
- }
- if (isNaN(count)) {
- throw { message: "'count' must be a valid number.", count: count };
- }
-
- if (cacheFailure) {
- throw cacheFailure;
- }
-
- index = Math.max(index, 0);
-
- var deferred = createDeferred();
- var returnData = {};
- returnData.value = [];
- var canceled = false;
- var pendingReadRange = null;
-
- var readMore = function (readIndex, readCount) {
- if (!canceled) {
- if (count > 0 && returnData.value.length >= count) {
- deferred.resolve(returnData);
- } else {
- pendingReadRange = that.readRange(readIndex, readCount).then(function (data) {
- if (data["@odata.context"] && !returnData["@odata.context"]) {
- returnData["@odata.context"] = data["@odata.context"];
- }
-
- for (var i = 0, length = data.value.length; i < length && (count < 0 || returnData.value.length < count); i++) {
- var dataIndex = backwards ? length - i - 1 : i;
- var item = data.value[dataIndex];
- if (predicate(item)) {
- var element = {
- index: readIndex + dataIndex,
- item: item
- };
-
- backwards ? returnData.value.unshift(element) : returnData.value.push(element);
- }
- }
-
- // Have we reached the end of the collection?
- if ((!backwards && data.value.length < readCount) || (backwards && readIndex <= 0)) {
- deferred.resolve(returnData);
- } else {
- var nextIndex = backwards ? Math.max(readIndex - pageSize, 0) : readIndex + readCount;
- readMore(nextIndex, pageSize);
- }
- }, function (err) {
- deferred.reject(err);
- });
- }
- }
- };
-
- // Initially, we read from the given starting index to the next/previous page boundary
- var initialPage = snapToPageBoundaries(index, index, pageSize);
- var initialIndex = backwards ? initialPage.i : index;
- var initialCount = backwards ? index - initialPage.i + 1 : initialPage.i + initialPage.c - index;
- readMore(initialIndex, initialCount);
-
- return extend(deferred.promise(), {
- /** Aborts the filter operation (used within promise callback)
- * @method DataCache#cancelFilter
- */
- cancel: function () {
-
- if (pendingReadRange) {
- pendingReadRange.cancel();
- }
- canceled = true;
- }
- });
- };
-
- /** Fires an onidle event if any functions are assigned.
- * @method DataCache~fireOnIdle
- */
- var fireOnIdle = function () {
-
- if (that.onidle && pendingOperations === 0) {
- that.onidle();
- }
- };
-
- /** Creates and starts a new prefetch operation.
- * @method DataCache~prefetch
- * @param {Number} start - Zero-based index of the items to prefetch.
- * This method is a no-op if any of the following conditions is true:
- * 1.- prefetchSize is 0
- * 2.- All data has been read and stored locally in the cache.
- * 3.- There is already an all data prefetch operation queued.
- * 4.- The cache has run out of available space (overflowed).
- */
- var prefetch = function (start) {
-
-
- if (allDataLocal || prefetchSize === 0 || overflowed) {
- return;
- }
-
- djsassert(state === CACHE_STATE_READ, "DataCache.prefetch() - cache is not on the read state, current state: " + state);
-
- if (prefetchOperations.length === 0 || (prefetchOperations[0] && prefetchOperations[0].c !== -1)) {
- // Merging prefetch operations would be a nice optimization here.
- var op = new DataCacheOperation(prefetchStateMachine, null, true, start, prefetchSize, null, prefetchSize);
- queueAndStart(op, prefetchOperations);
- }
- };
-
- /** Queues an operation and runs it.
- * @param {DataCacheOperation} op - Operation to queue.
- * @param {Array} queue - Array that will store the operation.
- */
- var queueAndStart = function (op, queue) {
-
- op.oncomplete = dequeueOperation;
- queue.push(op);
- pendingOperations++;
- op.run(state);
- };
-
- /** Requests a page from the cache local store.
- * @method DataCache~readPage
- * @param {Number} key - Zero-based index of the reuqested page.
- * @returns {DjsDeferred} A promise for a found flag and page object with (i)ndex, (c)ount, (d)ata, and (t)icks.
- */
- var readPage = function (key) {
-
- djsassert(state !== CACHE_STATE_DESTROY, "DataCache.readPage() - cache is on the destroy state");
-
- var canceled = false;
- var deferred = extend(new DjsDeferred(), {
- /** Aborts the readPage operation. (used within promise callback)
- * @method DataCache#cancelReadPage
- */
- cancel: function () {
- canceled = true;
- }
- });
-
- var error = storeFailureCallback(deferred, "Read page from store failure");
-
- store.contains(key, function (contained) {
- if (canceled) {
- return;
- }
- if (contained) {
- store.read(key, function (_, data) {
- if (!canceled) {
- deferred.resolve(data !== undefined, data);
- }
- }, error);
- return;
- }
- deferred.resolve(false);
- }, error);
- return deferred;
- };
-
- /** Saves a page to the cache local store.
- * @method DataCache~savePage
- * @param {Number} key - Zero-based index of the requested page.
- * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata, and (t)icks.
- * @returns {DjsDeferred} A promise with no value.
- */
- var savePage = function (key, page) {
-
- djsassert(state !== CACHE_STATE_DESTROY, "DataCache.savePage() - cache is on the destroy state");
- djsassert(state !== CACHE_STATE_IDLE, "DataCache.savePage() - cache is on the idle state");
-
- var canceled = false;
-
- var deferred = extend(new DjsDeferred(), {
- /** Aborts the savePage operation. (used within promise callback)
- * @method DataCache#cancelReadPage
- */
- cancel: function () {
- canceled = true;
- }
- });
-
- var error = storeFailureCallback(deferred, "Save page to store failure");
-
- var resolve = function () {
- deferred.resolve(true);
- };
-
- if (page.c > 0) {
- var pageBytes = estimateSize(page);
- overflowed = cacheSize >= 0 && cacheSize < actualCacheSize + pageBytes;
-
- if (!overflowed) {
- store.addOrUpdate(key, page, function () {
- updateSettings(page, pageBytes);
- saveSettings(resolve, error);
- }, error);
- } else {
- resolve();
- }
- } else {
- updateSettings(page, 0);
- saveSettings(resolve, error);
- }
- return deferred;
- };
-
- /** Saves the cache's current settings to the local store.
- * @method DataCache~saveSettings
- * @param {Function} success - Success callback.
- * @param {Function} error - Errror callback.
- */
- var saveSettings = function (success, error) {
-
- var settings = {
- actualCacheSize: actualCacheSize,
- allDataLocal: allDataLocal,
- cacheSize: cacheSize,
- collectionCount: collectionCount,
- highestSavedPage: highestSavedPage,
- highestSavedPageSize: highestSavedPageSize,
- pageSize: pageSize,
- sourceId: source.identifier,
- version: version
- };
-
- store.addOrUpdate("__settings", settings, success, error);
- };
-
- /** Creates a function that handles a store error.
- * @method DataCache~storeFailureCallback
- * @param {DjsDeferred} deferred - Deferred object to resolve.
- * @returns {Function} Function to use as error callback.
-
- * This function will specifically handle problems when interacting with the store.
- */
- var storeFailureCallback = function (deferred/*, message*/) {
-
-
- return function (/*error*/) {
- // var console = windo1w.console;
- // if (console && console.log) {
- // console.log(message);
- // console.dir(error);
- // }
- deferred.resolve(false);
- };
- };
-
- /** Updates the cache's settings based on a page object.
- * @method DataCache~updateSettings
- * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata.
- * @param {Number} pageBytes - Size of the page in bytes.
- */
- var updateSettings = function (page, pageBytes) {
-
- var pageCount = page.c;
- var pageIndex = page.i;
-
- // Detect the collection size.
- if (pageCount === 0) {
- if (highestSavedPage === pageIndex - pageSize) {
- collectionCount = highestSavedPage + highestSavedPageSize;
- }
- } else {
- highestSavedPage = Math.max(highestSavedPage, pageIndex);
- if (highestSavedPage === pageIndex) {
- highestSavedPageSize = pageCount;
- }
- actualCacheSize += pageBytes;
- if (pageCount < pageSize && !collectionCount) {
- collectionCount = pageIndex + pageCount;
- }
- }
-
- // Detect the end of the collection.
- if (!allDataLocal && collectionCount === highestSavedPage + highestSavedPageSize) {
- allDataLocal = true;
- }
- };
-
- /** State machine describing the behavior for cancelling a read or prefetch operation.
- * @method DataCache~cancelStateMachine
- * @param {DataCacheOperation} operation - Operation being run.
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
- * @param {Object} [data] -
- * This state machine contains behavior common to read and prefetch operations.
- */
- var cancelStateMachine = function (operation, opTargetState, cacheState, data) {
-
-
- var canceled = operation.canceled && opTargetState !== OPERATION_STATE_END;
- if (canceled) {
- if (opTargetState === OPERATION_STATE_CANCEL) {
- // Cancel state.
- // Data is expected to be any pending request made to the cache.
- if (data && data.cancel) {
- data.cancel();
- }
- }
- }
- return canceled;
- };
-
- /** State machine describing the behavior of a clear operation.
- * @method DataCache~destroyStateMachine
- * @param {DataCacheOperation} operation - Operation being run.
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
-
- * Clear operations have the highest priority and can't be interrupted by other operations; however,
- * they will preempt any other operation currently executing.
- */
- var destroyStateMachine = function (operation, opTargetState, cacheState) {
-
-
- var transition = operation.transition;
-
- // Signal the cache that a clear operation is running.
- if (cacheState !== CACHE_STATE_DESTROY) {
- changeState(CACHE_STATE_DESTROY);
- return true;
- }
-
- switch (opTargetState) {
- case OPERATION_STATE_START:
- // Initial state of the operation.
- transition(DESTROY_STATE_CLEAR);
- break;
-
- case OPERATION_STATE_END:
- // State that signals the operation is done.
- fireOnIdle();
- break;
-
- case DESTROY_STATE_CLEAR:
- // State that clears all the local data of the cache.
- clearStore().then(function () {
- // Terminate the operation once the local store has been cleared.
- operation.complete();
- });
- // Wait until the clear request completes.
- operation.wait();
- break;
-
- default:
- return false;
- }
- return true;
- };
-
- /** State machine describing the behavior of a prefetch operation.
- * @method DataCache~prefetchStateMachine
- * @param {DataCacheOperation} operation - Operation being run.
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
- * @param {Object} [data] -
-
- * Prefetch operations have the lowest priority and will be interrupted by operations of
- * other kinds. A preempted prefetch operation will resume its execution only when the state
- * of the cache returns to idle.
- *
- * If a clear operation starts executing then all the prefetch operations are canceled,
- * even if they haven't started executing yet.
- */
- var prefetchStateMachine = function (operation, opTargetState, cacheState, data) {
-
-
- // Handle cancelation
- if (!cancelStateMachine(operation, opTargetState, cacheState, data)) {
-
- var transition = operation.transition;
-
- // Handle preemption
- if (cacheState !== CACHE_STATE_PREFETCH) {
- if (cacheState === CACHE_STATE_DESTROY) {
- if (opTargetState !== OPERATION_STATE_CANCEL) {
- operation.cancel();
- }
- } else if (cacheState === CACHE_STATE_IDLE) {
- // Signal the cache that a prefetch operation is running.
- changeState(CACHE_STATE_PREFETCH);
- }
- return true;
- }
-
- switch (opTargetState) {
- case OPERATION_STATE_START:
- // Initial state of the operation.
- if (prefetchOperations[0] === operation) {
- transition(READ_STATE_LOCAL, operation.i);
- }
- break;
-
- case READ_STATE_DONE:
- // State that determines if the operation can be resolved or has to
- // continue processing.
- // Data is expected to be the read page.
- var pending = operation.pending;
-
- if (pending > 0) {
- pending -= Math.min(pending, data.c);
- }
-
- // Are we done, or has all the data been stored?
- if (allDataLocal || pending === 0 || data.c < pageSize || overflowed) {
- operation.complete();
- } else {
- // Continue processing the operation.
- operation.pending = pending;
- transition(READ_STATE_LOCAL, data.i + pageSize);
- }
- break;
-
- default:
- return readSaveStateMachine(operation, opTargetState, cacheState, data, true);
- }
- }
- return true;
- };
-
- /** State machine describing the behavior of a read operation.
- * @method DataCache~readStateMachine
- * @param {DataCacheOperation} operation - Operation being run.
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
- * @param {Object} [data] -
-
- * Read operations have a higher priority than prefetch operations, but lower than
- * clear operations. They will preempt any prefetch operation currently running
- * but will be interrupted by a clear operation.
- *
- * If a clear operation starts executing then all the currently running
- * read operations are canceled. Read operations that haven't started yet will
- * wait in the start state until the destory operation finishes.
- */
- var readStateMachine = function (operation, opTargetState, cacheState, data) {
-
-
- // Handle cancelation
- if (!cancelStateMachine(operation, opTargetState, cacheState, data)) {
-
- var transition = operation.transition;
-
- // Handle preemption
- if (cacheState !== CACHE_STATE_READ && opTargetState !== OPERATION_STATE_START) {
- if (cacheState === CACHE_STATE_DESTROY) {
- if (opTargetState !== OPERATION_STATE_START) {
- operation.cancel();
- }
- } else if (cacheState !== CACHE_STATE_WRITE) {
- // Signal the cache that a read operation is running.
- djsassert(state == CACHE_STATE_IDLE || state === CACHE_STATE_PREFETCH, "DataCache.readStateMachine() - cache is not on the read or idle state.");
- changeState(CACHE_STATE_READ);
- }
-
- return true;
- }
-
- switch (opTargetState) {
- case OPERATION_STATE_START:
- // Initial state of the operation.
- // Wait until the cache is idle or prefetching.
- if (cacheState === CACHE_STATE_IDLE || cacheState === CACHE_STATE_PREFETCH) {
- // Signal the cache that a read operation is running.
- changeState(CACHE_STATE_READ);
- if (operation.c >= 0) {
- // Snap the requested range to a page boundary.
- var range = snapToPageBoundaries(operation.i, operation.c, pageSize);
- transition(READ_STATE_LOCAL, range.i);
- } else {
- transition(READ_STATE_DONE, operation);
- }
- }
- break;
-
- case READ_STATE_DONE:
- // State that determines if the operation can be resolved or has to
- // continue processing.
- // Data is expected to be the read page.
- appendPage(operation, data);
- var len = getJsonValueArraryLength(operation.d);
- // Are we done?
- if (operation.c === len || data.c < pageSize) {
- // Update the stats, request for a prefetch operation.
- stats.cacheReads++;
- prefetch(data.i + data.c);
- // Terminate the operation.
- operation.complete();
- } else {
- // Continue processing the operation.
- transition(READ_STATE_LOCAL, data.i + pageSize);
- }
- break;
-
- default:
- return readSaveStateMachine(operation, opTargetState, cacheState, data, false);
- }
- }
-
- return true;
- };
-
- /** State machine describing the behavior for reading and saving data into the cache.
- * @method DataCache~readSaveStateMachine
- * @param {DataCacheOperation} operation - Operation being run.
- * @param {Object} opTargetState - Operation state to transition to.
- * @param {Object} cacheState - Current cache state.
- * @param {Object} [data] -
- * @param {Boolean} isPrefetch - Flag indicating whether a read (false) or prefetch (true) operation is running.
- * This state machine contains behavior common to read and prefetch operations.
- */
- var readSaveStateMachine = function (operation, opTargetState, cacheState, data, isPrefetch) {
-
- var error = operation.error;
- var transition = operation.transition;
- var wait = operation.wait;
- var request;
-
- switch (opTargetState) {
- case OPERATION_STATE_END:
- // State that signals the operation is done.
- fireOnIdle();
- break;
-
- case READ_STATE_LOCAL:
- // State that requests for a page from the local store.
- // Data is expected to be the index of the page to request.
- request = readPage(data).then(function (found, page) {
- // Signal the cache that a read operation is running.
- if (!operation.canceled) {
- if (found) {
- // The page is in the local store, check if the operation can be resolved.
- transition(READ_STATE_DONE, page);
- } else {
- // The page is not in the local store, request it from the source.
- transition(READ_STATE_SOURCE, data);
- }
- }
- });
- break;
-
- case READ_STATE_SOURCE:
- // State that requests for a page from the cache source.
- // Data is expected to be the index of the page to request.
- request = fetchPage(data).then(function (page) {
- // Signal the cache that a read operation is running.
- if (!operation.canceled) {
- // Update the stats and save the page to the local store.
- if (isPrefetch) {
- stats.prefetches++;
- } else {
- stats.netReads++;
- }
- transition(READ_STATE_SAVE, page);
- }
- }, error);
- break;
-
- case READ_STATE_SAVE:
- // State that saves a page to the local store.
- // Data is expected to be the page to save.
- // Write access to the store is exclusive.
- if (cacheState !== CACHE_STATE_WRITE) {
- changeState(CACHE_STATE_WRITE);
- request = savePage(data.i, data).then(function (saved) {
- if (!operation.canceled) {
- if (!saved && isPrefetch) {
- operation.pending = 0;
- }
- // Check if the operation can be resolved.
- transition(READ_STATE_DONE, data);
- }
- changeState(CACHE_STATE_IDLE);
- });
- }
- break;
-
- default:
- // Unknown state that can't be handled by this state machine.
- return false;
- }
-
- if (request) {
- // The operation might have been canceled between stack frames do to the async calls.
- if (operation.canceled) {
- request.cancel();
- } else if (operation.s === opTargetState) {
- // Wait for the request to complete.
- wait(request);
- }
- }
-
- return true;
- };
-
- // Initialize the cache.
- store.read("__settings", function (_, settings) {
- if (assigned(settings)) {
- var settingsVersion = settings.version;
- if (!settingsVersion || settingsVersion.indexOf("1.") !== 0) {
- cacheFailureCallback("Unsupported cache store version " + settingsVersion)();
- return;
- }
-
- if (pageSize !== settings.pageSize || source.identifier !== settings.sourceId) {
- // The shape or the source of the data was changed so invalidate the store.
- clearStore().then(function () {
- // Signal the cache is fully initialized.
- changeState(CACHE_STATE_IDLE);
- }, cacheFailureCallback("Unable to clear store during initialization"));
- } else {
- // Restore the saved settings.
- actualCacheSize = settings.actualCacheSize;
- allDataLocal = settings.allDataLocal;
- cacheSize = settings.cacheSize;
- collectionCount = settings.collectionCount;
- highestSavedPage = settings.highestSavedPage;
- highestSavedPageSize = settings.highestSavedPageSize;
- version = settingsVersion;
-
- // Signal the cache is fully initialized.
- changeState(CACHE_STATE_IDLE);
- }
- } else {
- // This is a brand new cache.
- saveSettings(function () {
- // Signal the cache is fully initialized.
- changeState(CACHE_STATE_IDLE);
- }, cacheFailureCallback("Unable to write settings during initialization."));
- }
- }, cacheFailureCallback("Unable to read settings from store."));
-
- return that;
-}
-
-/** Creates a data cache for a collection that is efficiently loaded on-demand.
- * @param options
- * Options for the data cache, including name, source, pageSize, TODO check doku
- * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
- * @returns {DataCache} A new data cache instance.
- */
-function createDataCache (options) {
- checkUndefinedGreaterThanZero(options.pageSize, "pageSize");
- checkUndefinedOrNumber(options.cacheSize, "cacheSize");
- checkUndefinedOrNumber(options.prefetchSize, "prefetchSize");
-
- if (!assigned(options.name)) {
- throw { message: "Undefined or null name", options: options };
- }
-
- if (!assigned(options.source)) {
- throw { message: "Undefined source", options: options };
- }
-
- return new DataCache(options);
-}
-
-
-/** estimateSize (see {@link estimateSize}) */
-exports.estimateSize = estimateSize;
-
-/** createDataCache */
-exports.createDataCache = createDataCache;
-
-
-
diff --git a/lib/cache/source.js b/lib/cache/source.js
deleted file mode 100644
index 08dea0a..0000000
--- a/lib/cache/source.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
- /** @module cache/source */
-
-var utils = require("./../utils.js");
-var odataRequest = require("./../odata.js");
-
-var parseInt10 = utils.parseInt10;
-var normalizeURICase = utils.normalizeURICase;
-
-
-
-
-/** Appends the specified escaped query option to the specified URI.
- * @param {String} uri - URI to append option to.
- * @param {String} queryOption - Escaped query option to append.
- */
-function appendQueryOption(uri, queryOption) {
- var separator = (uri.indexOf("?") >= 0) ? "&" : "?";
- return uri + separator + queryOption;
-}
-
-/** Appends the specified segment to the given URI.
- * @param {String} uri - URI to append a segment to.
- * @param {String} segment - Segment to append.
- * @returns {String} The original URI with a new segment appended.
- */
-function appendSegment(uri, segment) {
- 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;
-}
-
-/** Builds a request object to GET the specified URI.
- * @param {String} uri - URI for request.
- * @param {Object} options - Additional options.
- */
-function buildODataRequest(uri, options) {
- return {
- method: "GET",
- requestUri: uri,
- user: options.user,
- password: options.password,
- enableJsonpCallback: options.enableJsonpCallback,
- callbackParameterName: options.callbackParameterName,
- formatQueryString: options.formatQueryString
- };
-}
-
-/** Finds the index where the value of a query option starts.
- * @param {String} uri - URI to search in.
- * @param {String} name - Name to look for.
- * @returns {Number} The index where the query option starts.
- */
-function findQueryOptionStart(uri, name) {
- 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;
-}
-
-/** Gets data from an OData service.
- * @param {String} uri - URI to the OData service.
- * @param {Object} options - Object with additional well-known request options.
- * @param {Function} success - Success callback.
- * @param {Function} error - Error callback.
- * @returns {Object} Object with an abort method.
- */
-function queryForData (uri, options, success, error) {
- return queryForDataInternal(uri, options, {}, success, error);
-}
-
-/** Gets data from an OData service taking into consideration server side paging.
- * @param {String} uri - URI to the OData service.
- * @param {Object} options - Object with additional well-known request options.
- * @param {Array} data - Array that stores the data provided by the OData service.
- * @param {Function} success - Success callback.
- * @param {Function} error - Error callback.
- * @returns {Object} Object with an abort method.
- */
-function queryForDataInternal(uri, options, data, success, error) {
-
- var request = buildODataRequest(uri, options);
- var currentRequest = odataRequest.request(request, function (newData) {
- var nextLink = newData["@odata.nextLink"];
- if (nextLink) {
- var index = uri.indexOf(".svc/", 0);
- if (index != -1) {
- nextLink = uri.substring(0, index + 5) + nextLink;
- }
- }
-
- if (data.value && newData.value) {
- data.value = data.value.concat(newData.value);
- }
- else {
- for (var property in newData) {
- if (property != "@odata.nextLink") {
- data[property] = newData[property];
- }
- }
- }
-
- if (nextLink) {
- currentRequest = queryForDataInternal(nextLink, options, data, success, error);
- }
- else {
- success(data);
- }
- }, error, undefined, options.httpClient, options.metadata);
-
- return {
- abort: function () {
- currentRequest.abort();
- }
- };
-}
-
-/** Creates a data cache source object for requesting data from an OData service.
- * @class ODataCacheSource
- * @param options - Options for the cache data source.
- * @returns {ODataCacheSource} A new data cache source instance.
- */
-function ODataCacheSource (options) {
- var that = this;
- var uri = options.source;
-
- that.identifier = normalizeURICase(encodeURI(decodeURI(uri)));
- that.options = options;
-
- /** Gets the number of items in the collection.
- * @method ODataCacheSource#count
- * @param {Function} success - Success callback with the item count.
- * @param {Function} error - Error callback.
- * @returns {Object} Request object with an abort method.
- */
- that.count = function (success, error) {
- var options = that.options;
- return odataRequest.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
- );
- };
-
- /** Gets a number of consecutive items from the collection.
- * @method ODataCacheSource#read
- * @param {Number} index - Zero-based index of the items to retrieve.
- * @param {Number} count - Number of items to retrieve.
- * @param {Function} success - Success callback with the requested items.
- * @param {Function} error - Error callback.
- * @returns {Object} Request object with an abort method.
- */
- that.read = function (index, count, success, error) {
-
- var queryOptions = "$skip=" + index + "&$top=" + count;
- return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error);
- };
-
- return that;
-}
-
-
-
-/** ODataCacheSource (see {@link ODataCacheSource}) */
-exports.ODataCacheSource = ODataCacheSource;
\ No newline at end of file
diff --git a/lib/deferred.js b/lib/deferred.js
deleted file mode 100644
index 520a857..0000000
--- a/lib/deferred.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odatajs/deferred */
-
-
-
-/** Creates a new function to forward a call.
- * @param {Object} thisValue - Value to use as the 'this' object.
- * @param {String} name - Name of function to forward to.
- * @param {Object} returnValue - Return value for the forward call (helps keep identity when chaining calls).
- * @returns {Function} A new function that will forward a call.
- */
-function forwardCall(thisValue, name, returnValue) {
- return function () {
- thisValue[name].apply(thisValue, arguments);
- return returnValue;
- };
-}
-
-/** Initializes a new DjsDeferred object.
- *
- * - Compability Note A - Ordering of callbacks through chained 'then' invocations
- *
- * The Wiki entry at http://wiki.commonjs.org/wiki/Promises/A
- * implies that .then() returns a distinct object.
- *
- * For compatibility with http://api.jquery.com/category/deferred-object/
- * we return this same object. This affects ordering, as
- * the jQuery version will fire callbacks in registration
- * order regardless of whether they occur on the result
- * or the original object.
- *
- * - Compability Note B - Fulfillment value
- *
- * The Wiki entry at http://wiki.commonjs.org/wiki/Promises/A
- * implies that the result of a success callback is the
- * fulfillment value of the object and is received by
- * other success callbacks that are chained.
- *
- * For compatibility with http://api.jquery.com/category/deferred-object/
- * we disregard this value instead.
- *
- * @class DjsDeferred
- */
- function DjsDeferred() {
- this._arguments = undefined;
- this._done = undefined;
- this._fail = undefined;
- this._resolved = false;
- this._rejected = false;
-}
-
-
-DjsDeferred.prototype = {
-
- /** Adds success and error callbacks for this deferred object.
- * See Compatibility Note A.
- * @method DjsDeferred#then
- * @param {function} [fulfilledHandler] - Success callback ( may be null)
- * @param {function} [errorHandler] - Error callback ( may be null)
- */
- then: function (fulfilledHandler, errorHandler) {
-
- if (fulfilledHandler) {
- if (!this._done) {
- this._done = [fulfilledHandler];
- } else {
- this._done.push(fulfilledHandler);
- }
- }
-
- if (errorHandler) {
- if (!this._fail) {
- this._fail = [errorHandler];
- } else {
- this._fail.push(errorHandler);
- }
- }
-
- //// See Compatibility Note A in the DjsDeferred constructor.
- //// if (!this._next) {
- //// this._next = createDeferred();
- //// }
- //// return this._next.promise();
-
- if (this._resolved) {
- this.resolve.apply(this, this._arguments);
- } else if (this._rejected) {
- this.reject.apply(this, this._arguments);
- }
-
- return this;
- },
-
- /** Invokes success callbacks for this deferred object.
- * All arguments are forwarded to success callbacks.
- * @method DjsDeferred#resolve
- */
- resolve: function (/* args */) {
- if (this._done) {
- var i, len;
- for (i = 0, len = this._done.length; i < len; i++) {
- //// See Compability Note B - Fulfillment value.
- //// var nextValue =
- this._done[i].apply(null, arguments);
- }
-
- //// See Compatibility Note A in the DjsDeferred constructor.
- //// this._next.resolve(nextValue);
- //// delete this._next;
-
- this._done = undefined;
- this._resolved = false;
- this._arguments = undefined;
- } else {
- this._resolved = true;
- this._arguments = arguments;
- }
- },
-
- /** Invokes error callbacks for this deferred object.
- * All arguments are forwarded to error callbacks.
- * @method DjsDeferred#reject
- */
- reject: function (/* args */) {
-
- if (this._fail) {
- var i, len;
- for (i = 0, len = this._fail.length; i < len; i++) {
- this._fail[i].apply(null, arguments);
- }
-
- this._fail = undefined;
- this._rejected = false;
- this._arguments = undefined;
- } else {
- this._rejected = true;
- this._arguments = arguments;
- }
- },
-
- /** Returns a version of this object that has only the read-only methods available.
- * @method DjsDeferred#promise
- * @returns An object with only the promise object.
- */
-
- promise: function () {
- var result = {};
- result.then = forwardCall(this, "then", result);
- return result;
- }
-};
-
-/** Creates a deferred object.
- * @returns {DjsDeferred} A new deferred object. If jQuery is installed, then a jQueryDeferred object is returned, which provides a superset of features.
-*/
-function createDeferred() {
- if (window.jQuery && window.jQuery.Deferred) {
- return new window.jQuery.Deferred();
- } else {
- return new DjsDeferred();
- }
-}
-
-
-
-
-/** createDeferred (see {@link module:datajs/deferred~createDeferred}) */
-exports.createDeferred = createDeferred;
-
-/** DjsDeferred (see {@link DjsDeferred}) */
-exports.DjsDeferred = DjsDeferred;
\ No newline at end of file
diff --git a/lib/odata.js b/lib/odata.js
index 6f660f6..cf7d1ab 100644
--- a/lib/odata.js
+++ b/lib/odata.js
@@ -21,16 +21,17 @@
/** @module odata */
// Imports
+var utils = require('./utils.js');
+
var odataUtils = exports.utils = require('./odata/odatautils.js');
var odataHandler = exports.handler = require('./odata/handler.js');
var odataMetadata = exports.metadata = require('./odata/metadata.js');
-var odataNet = exports.net = require('./odata/net.js');
+var webNet = require('./odata/net-browser.js');
+var odataNet = exports.net = utils.inBrowser() ? webNet : require('' + './odata/net.js');
var odataJson = exports.json = require('./odata/json.js');
exports.batch = require('./odata/batch.js');
-
-var utils = require('./utils.js');
var assigned = utils.assigned;
var defined = utils.defined;
diff --git a/lib/odata/net-browser.js b/lib/odata/net-browser.js
index 8d956ff..647d0b1 100644
--- a/lib/odata/net-browser.js
+++ b/lib/odata/net-browser.js
@@ -262,13 +262,21 @@ exports.defaultHttpClient = {
}
}
+ if (request.withCredentials) {
+ xhr.withCredentials = true;
+ }
+
// Set the timeout if available.
if (request.timeoutMS) {
xhr.timeout = request.timeoutMS;
xhr.ontimeout = handleTimeout;
}
-
- xhr.send(request.body);
+
+ if(typeof request.body === 'undefined'){
+ xhr.send();
+ } else {
+ xhr.send(request.body);
+ }
} else {
if (!canUseJSONP(request)) {
throw { message: "Request is not local and cannot be done through JSONP." };
diff --git a/lib/odata/net.js b/lib/odata/net.js
index be45295..9bc561e 100644
--- a/lib/odata/net.js
+++ b/lib/odata/net.js
@@ -21,6 +21,7 @@
var http = require('http');
+var https = require('https');
var utils = require('./../utils.js');
var url = require("url");
@@ -117,8 +118,12 @@ exports.defaultHttpClient = {
}
}
-
- var xhr = http.request(options);
+ var httpModule = http;
+ if(options.protocol && options.protocol.indexOf('https:') === 0) {
+ httpModule = https;
+ }
+
+ var xhr = httpModule.request(options);
result.abort = function () {
if (done) {
diff --git a/lib/store.js b/lib/store.js
deleted file mode 100644
index d7e321d..0000000
--- a/lib/store.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-//'use strict';
-
- /** @module store */
-
-
-
-
-
-exports.defaultStoreMechanism = "best";
-
-/** Creates a new store object.
- * @param {String} name - Store name.
- * @param {String} [mechanism] -
- * @returns {Object} Store object.
-*/
-exports.createStore = function (name, mechanism) {
-
-
- if (!mechanism) {
- mechanism = exports.defaultStoreMechanism;
- }
-
- if (mechanism === "best") {
- mechanism = (DomStore.isSupported()) ? "dom" : "memory";
- }
-
- var factory = mechanisms[mechanism];
- if (factory) {
- return factory.create(name);
- }
-
- throw { message: "Failed to create store", name: name, mechanism: mechanism };
-};
-
-exports.DomStore = DomStore = require('./store/dom.js');
-exports.IndexedDBStore = IndexedDBStore = require('./store/indexeddb.js');
-exports.MemoryStore = MemoryStore = require('./store/memory.js');
-
-var mechanisms = {
- indexeddb: IndexedDBStore,
- dom: DomStore,
- memory: MemoryStore
-};
-
-exports.mechanisms = mechanisms;
-
-
-
-
diff --git a/lib/store/dom.js b/lib/store/dom.js
deleted file mode 100644
index e14bb6b..0000000
--- a/lib/store/dom.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/dom */
-
-
-
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-var localStorage = null;
-
-/** This method is used to override the Date.toJSON method and is called only by
- * JSON.stringify. It should never be called directly.
- * @summary Converts a Date object into an object representation friendly to JSON serialization.
- * @returns {Object} Object that represents the Date.
- */
-function domStoreDateToJSON() {
- var newValue = { v: this.valueOf(), t: "[object Date]" };
- // Date objects might have extra properties on them so we save them.
- for (var name in this) {
- newValue[name] = this[name];
- }
- return newValue;
-}
-
-/** This method is used during JSON parsing and invoked only by the reviver function.
- * It should never be called directly.
- * @summary JSON reviver function for converting an object representing a Date in a JSON stream to a Date object
- * @param value _
- * @param value - Object to convert.
- * @returns {Date} Date object.
- */
-function domStoreJSONToDate(_, value) {
- if (value && value.t === "[object Date]") {
- var newValue = new Date(value.v);
- for (var name in value) {
- if (name !== "t" && name !== "v") {
- newValue[name] = value[name];
- }
- }
- value = newValue;
- }
- return value;
-}
-
-/** Qualifies the key with the name of the store.
- * @param {Object} store - Store object whose name will be used for qualifying the key.
- * @param {String} key - Key string.
- * @returns {String} Fully qualified key string.
- */
-function qualifyDomStoreKey(store, key) {
- return store.name + "#!#" + key;
-}
-
-/** Gets the key part of a fully qualified key string.
- * @param {Object} store - Store object whose name will be used for qualifying the key.
- * @param {String} key - Fully qualified key string.
- * @returns {String} Key part string
- */
-function unqualifyDomStoreKey(store, key) {
- return key.replace(store.name + "#!#", "");
-}
-
-/** Constructor for store objects that use DOM storage as the underlying mechanism.
- * @class DomStore
- * @constructor
- * @param {String} name - Store name.
- */
-function DomStore(name) {
- this.name = name;
-}
-
-/** Creates a store object that uses DOM Storage as its underlying mechanism.
- * @method module:store/dom~DomStore.create
- * @param {String} name - Store name.
- * @returns {Object} Store object.
- */
-DomStore.create = function (name) {
-
- if (DomStore.isSupported()) {
- localStorage = localStorage || window.localStorage;
- return new DomStore(name);
- }
-
- throw { message: "Web Storage not supported by the browser" };
-};
-
-/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
- * @method DomStore.isSupported
- * @returns {Boolean} - True if the mechanism is supported by the browser; otherwise false.
-*/
-DomStore.isSupported = function () {
- return !!window.localStorage;
-};
-
-/** Adds a new value identified by a key to the store.
- * @method module:store/dom~DomStore#add
- * @param {String} key - Key string.
- * @param value - Value that is going to be added to the store.
- * @param {Function} success - Callback for a successful add operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- * This method errors out if the store already contains the specified key.
- */
-DomStore.prototype.add = function (key, value, success, error) {
- error = error || this.defaultError;
- var store = this;
- this.contains(key, function (contained) {
- if (!contained) {
- store.addOrUpdate(key, value, success, error);
- } else {
- delay(error, { message: "key already exists", key: key });
- }
- }, error);
-};
-
-/** This method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
- * @summary Adds or updates a value identified by a key to the store.
- * @method module:store/dom~DomStore#addOrUpdate
- * @param {String} key - Key string.
- * @param value - Value that is going to be added or updated to the store.
- * @param {Function} success - Callback for a successful add or update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.addOrUpdate = function (key, value, success, error) {
- error = error || this.defaultError;
-
- if (key instanceof Array) {
- error({ message: "Array of keys not supported" });
- } else {
- var fullKey = qualifyDomStoreKey(this, key);
- var oldDateToJSON = Date.prototype.toJSON;
- try {
- var storedValue = value;
- if (storedValue !== undefined) {
- // Dehydrate using json
- Date.prototype.toJSON = domStoreDateToJSON;
- storedValue = window.JSON.stringify(value);
- }
- // Save the json string.
- localStorage.setItem(fullKey, storedValue);
- delay(success, key, value);
- }
- catch (e) {
- if (e.code === 22 || e.number === 0x8007000E) {
- delay(error, { name: "QUOTA_EXCEEDED_ERR", error: e });
- } else {
- delay(error, e);
- }
- }
- finally {
- Date.prototype.toJSON = oldDateToJSON;
- }
- }
-};
-
-/** In case of an error, this method will not restore any keys that might have been deleted at that point.
- * @summary Removes all the data associated with this store object.
- * @method module:store/dom~DomStore#clear
- * @param {Function} success - Callback for a successful clear operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.clear = function (success, error) {
-
- error = error || this.defaultError;
- try {
- var i = 0, len = localStorage.length;
- while (len > 0 && i < len) {
- var fullKey = localStorage.key(i);
- var key = unqualifyDomStoreKey(this, fullKey);
- if (fullKey !== key) {
- localStorage.removeItem(fullKey);
- len = localStorage.length;
- } else {
- i++;
- }
- }
- delay(success);
- }
- catch (e) {
- delay(error, e);
- }
-};
-
-/** This function does nothing in DomStore as it does not have a connection model
- * @method module:store/dom~DomStore#close
- */
-DomStore.prototype.close = function () {
-};
-
-/** Checks whether a key exists in the store.
- * @method module:store/dom~DomStore#contains
- * @param {String} key - Key string.
- * @param {Function} success - Callback indicating whether the store contains the key or not.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
-*/
-DomStore.prototype.contains = function (key, success, error) {
- error = error || this.defaultError;
- try {
- var fullKey = qualifyDomStoreKey(this, key);
- var value = localStorage.getItem(fullKey);
- delay(success, value !== null);
- } catch (e) {
- delay(error, e);
- }
-};
-
-DomStore.prototype.defaultError = throwErrorCallback;
-
-/** Gets all the keys that exist in the store.
- * @method module:store/dom~DomStore#getAllKeys
- * @param {Function} success - Callback for a successful get operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.getAllKeys = function (success, error) {
-
- error = error || this.defaultError;
-
- var results = [];
- var i, len;
-
- try {
- for (i = 0, len = localStorage.length; i < len; i++) {
- var fullKey = localStorage.key(i);
- var key = unqualifyDomStoreKey(this, fullKey);
- if (fullKey !== key) {
- results.push(key);
- }
- }
- delay(success, results);
- }
- catch (e) {
- delay(error, e);
- }
-};
-
-/** Identifies the underlying mechanism used by the store.*/
-DomStore.prototype.mechanism = "dom";
-
-/** Reads the value associated to a key in the store.
- * @method module:store/dom~DomStore#read
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful reads operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.read = function (key, success, error) {
-
- error = error || this.defaultError;
-
- if (key instanceof Array) {
- error({ message: "Array of keys not supported" });
- } else {
- try {
- var fullKey = qualifyDomStoreKey(this, key);
- var value = localStorage.getItem(fullKey);
- if (value !== null && value !== "undefined") {
- // Hydrate using json
- value = window.JSON.parse(value, domStoreJSONToDate);
- }
- else {
- value = undefined;
- }
- delay(success, key, value);
- } catch (e) {
- delay(error, e);
- }
- }
-};
-
-/** Removes a key and its value from the store.
- * @method module:store/dom~DomStore#remove
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful remove operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.remove = function (key, success, error) {
- error = error || this.defaultError;
-
- if (key instanceof Array) {
- error({ message: "Batches not supported" });
- } else {
- try {
- var fullKey = qualifyDomStoreKey(this, key);
- localStorage.removeItem(fullKey);
- delay(success);
- } catch (e) {
- delay(error, e);
- }
- }
-};
-
-/** Updates the value associated to a key in the store.
- * @method module:store/dom~DomStore#update
- * @param {String} key - Key string.
- * @param value - New value.
- * @param {Function} success - Callback for a successful update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked
- * This method errors out if the specified key is not found in the store.
- */
-DomStore.prototype.update = function (key, value, success, error) {
- error = error || this.defaultError;
- var store = this;
- this.contains(key, function (contained) {
- if (contained) {
- store.addOrUpdate(key, value, success, error);
- } else {
- delay(error, { message: "key not found", key: key });
- }
- }, error);
-};
-
-module.exports = DomStore;
\ No newline at end of file
diff --git a/lib/store/indexeddb.js b/lib/store/indexeddb.js
deleted file mode 100644
index d7527c1..0000000
--- a/lib/store/indexeddb.js
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/indexeddb */
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-
-var indexedDB = utils.inBrowser() ? window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB : undefined;
-var IDBKeyRange = utils.inBrowser() ? window.IDBKeyRange || window.webkitIDBKeyRange : undefined;
-var IDBTransaction = utils.inBrowser() ? window.IDBTransaction || window.webkitIDBTransaction || {} : {} ;
-
-var IDBT_READ_ONLY = IDBTransaction.READ_ONLY || "readonly";
-var IDBT_READ_WRITE = IDBTransaction.READ_WRITE || "readwrite";
-
-/** Returns either a specific error handler or the default error handler
- * @param {Function} error - The specific error handler
- * @param {Function} defaultError - The default error handler
- * @returns {Function} The error callback
- */
-function getError(error, defaultError) {
-
- return function (e) {
- var errorFunc = error || defaultError;
- if (!errorFunc) {
- return;
- }
-
- // Old api quota exceeded error support.
- if (Object.prototype.toString.call(e) === "[object IDBDatabaseException]") {
- if (e.code === 11 /* IndexedDb disk quota exceeded */) {
- errorFunc({ name: "QuotaExceededError", error: e });
- return;
- }
- errorFunc(e);
- return;
- }
-
- var errName;
- try {
- var errObj = e.target.error || e;
- errName = errObj.name;
- } catch (ex) {
- errName = (e.type === "blocked") ? "IndexedDBBlocked" : "UnknownError";
- }
- errorFunc({ name: errName, error: e });
- };
-}
-
-/** Opens the store object's indexed db database.
- * @param {IndexedDBStore} store - The store object
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-function openStoreDb(store, success, error) {
-
- var storeName = store.name;
- var dbName = "_odatajs_" + storeName;
-
- var request = indexedDB.open(dbName);
- request.onblocked = error;
- request.onerror = error;
-
- request.onupgradeneeded = function () {
- var db = request.result;
- if (!db.objectStoreNames.contains(storeName)) {
- db.createObjectStore(storeName);
- }
- };
-
- request.onsuccess = function (event) {
- var db = request.result;
- if (!db.objectStoreNames.contains(storeName)) {
- // Should we use the old style api to define the database schema?
- if ("setVersion" in db) {
- var versionRequest = db.setVersion("1.0");
- versionRequest.onsuccess = function () {
- var transaction = versionRequest.transaction;
- transaction.oncomplete = function () {
- success(db);
- };
- db.createObjectStore(storeName, null, false);
- };
- versionRequest.onerror = error;
- versionRequest.onblocked = error;
- return;
- }
-
- // The database doesn't have the expected store.
- // Fabricate an error object for the event for the schema mismatch
- // and error out.
- event.target.error = { name: "DBSchemaMismatch" };
- error(event);
- return;
- }
-
- db.onversionchange = function(event) {
- event.target.close();
- };
- success(db);
- };
-}
-
-/** Opens a new transaction to the store
- * @param {IndexedDBStore} store - The store object
- * @param {Integer} mode - The read/write mode of the transaction (constants from IDBTransaction)
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-function openTransaction(store, mode, success, error) {
-
- var storeName = store.name;
- var storeDb = store.db;
- var errorCallback = getError(error, store.defaultError);
-
- if (storeDb) {
- success(storeDb.transaction(storeName, mode));
- return;
- }
-
- openStoreDb(store, function (db) {
- store.db = db;
- success(db.transaction(storeName, mode));
- }, errorCallback);
-}
-
-/** Creates a new IndexedDBStore.
- * @class IndexedDBStore
- * @constructor
- * @param {String} name - The name of the store.
- * @returns {Object} The new IndexedDBStore.
- */
-function IndexedDBStore(name) {
- this.name = name;
-}
-
-/** Creates a new IndexedDBStore.
- * @method module:store/indexeddb~IndexedDBStore.create
- * @param {String} name - The name of the store.
- * @returns {Object} The new IndexedDBStore.
- */
-IndexedDBStore.create = function (name) {
- if (IndexedDBStore.isSupported()) {
- return new IndexedDBStore(name);
- }
-
- throw { message: "IndexedDB is not supported on this browser" };
-};
-
-/** Returns whether IndexedDB is supported.
- * @method module:store/indexeddb~IndexedDBStore.isSupported
- * @returns {Boolean} True if IndexedDB is supported, false otherwise.
- */
-IndexedDBStore.isSupported = function () {
- return !!indexedDB;
-};
-
-/** Adds a key/value pair to the store
- * @method module:store/indexeddb~IndexedDBStore#add
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
-*/
-IndexedDBStore.prototype.add = function (key, value, success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- var keys = [];
- var values = [];
-
- if (key instanceof Array) {
- keys = key;
- values = value;
- } else {
- keys = [key];
- values = [value];
- }
-
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- transaction.onabort = getError(error, defaultError, key, "add");
- transaction.oncomplete = function () {
- if (key instanceof Array) {
- success(keys, values);
- } else {
- success(key, value);
- }
- };
-
- for (var i = 0; i < keys.length && i < values.length; i++) {
- transaction.objectStore(name).add({ v: values[i] }, keys[i]);
- }
- }, error);
-};
-
-/** Adds or updates a key/value pair in the store
- * @method module:store/indexeddb~IndexedDBStore#addOrUpdate
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.addOrUpdate = function (key, value, success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- var keys = [];
- var values = [];
-
- if (key instanceof Array) {
- keys = key;
- values = value;
- } else {
- keys = [key];
- values = [value];
- }
-
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- transaction.onabort = getError(error, defaultError);
- transaction.oncomplete = function () {
- if (key instanceof Array) {
- success(keys, values);
- } else {
- success(key, value);
- }
- };
-
- for (var i = 0; i < keys.length && i < values.length; i++) {
- var record = { v: values[i] };
- transaction.objectStore(name).put(record, keys[i]);
- }
- }, error);
-};
-
-/** Clears the store
- * @method module:store/indexeddb~IndexedDBStore#clear
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.clear = function (success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- transaction.onerror = getError(error, defaultError);
- transaction.oncomplete = function () {
- success();
- };
-
- transaction.objectStore(name).clear();
- }, error);
-};
-
-/** Closes the connection to the database
- * @method module:store/indexeddb~IndexedDBStore#close
-*/
-IndexedDBStore.prototype.close = function () {
-
- if (this.db) {
- this.db.close();
- this.db = null;
- }
-};
-
-/** Returns whether the store contains a key
- * @method module:store/indexeddb~IndexedDBStore#contains
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.contains = function (key, success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- openTransaction(this, IDBT_READ_ONLY, function (transaction) {
- var objectStore = transaction.objectStore(name);
- var request = objectStore.get(key);
-
- transaction.oncomplete = function () {
- success(!!request.result);
- };
- transaction.onerror = getError(error, defaultError);
- }, error);
-};
-
-IndexedDBStore.prototype.defaultError = throwErrorCallback;
-
-/** Gets all the keys from the store
- * @method module:store/indexeddb~IndexedDBStore#getAllKeys
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.getAllKeys = function (success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- var results = [];
-
- transaction.oncomplete = function () {
- success(results);
- };
-
- var request = transaction.objectStore(name).openCursor();
-
- request.onerror = getError(error, defaultError);
- request.onsuccess = function (event) {
- var cursor = event.target.result;
- if (cursor) {
- results.push(cursor.key);
- // Some tools have issues because continue is a javascript reserved word.
- cursor["continue"].call(cursor);
- }
- };
- }, error);
-};
-
-/** Identifies the underlying mechanism used by the store.
-*/
-IndexedDBStore.prototype.mechanism = "indexeddb";
-
-/** Reads the value for the specified key
- * @method module:store/indexeddb~IndexedDBStore#read
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- * If the key does not exist, the success handler will be called with value = undefined
- */
-IndexedDBStore.prototype.read = function (key, success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- var keys = (key instanceof Array) ? key : [key];
-
- openTransaction(this, IDBT_READ_ONLY, function (transaction) {
- var values = [];
-
- transaction.onerror = getError(error, defaultError, key, "read");
- transaction.oncomplete = function () {
- if (key instanceof Array) {
- success(keys, values);
- } else {
- success(keys[0], values[0]);
- }
- };
-
- for (var i = 0; i < keys.length; i++) {
- // Some tools have issues because get is a javascript reserved word.
- var objectStore = transaction.objectStore(name);
- var request = objectStore.get.call(objectStore, keys[i]);
- request.onsuccess = function (event) {
- var record = event.target.result;
- values.push(record ? record.v : undefined);
- };
- }
- }, error);
-};
-
-/** Removes the specified key from the store
- * @method module:store/indexeddb~IndexedDBStore#remove
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.remove = function (key, success, error) {
-
- var name = this.name;
- var defaultError = this.defaultError;
- var keys = (key instanceof Array) ? key : [key];
-
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- transaction.onerror = getError(error, defaultError);
- transaction.oncomplete = function () {
- success();
- };
-
- for (var i = 0; i < keys.length; i++) {
- // Some tools have issues because continue is a javascript reserved word.
- var objectStore = transaction.objectStore(name);
- objectStore["delete"].call(objectStore, keys[i]);
- }
- }, error);
-};
-
-/** Updates a key/value pair in the store
- * @method module:store/indexeddb~IndexedDBStore#update
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.update = function (key, value, success, error) {
- var name = this.name;
- var defaultError = this.defaultError;
- var keys = [];
- var values = [];
-
- if (key instanceof Array) {
- keys = key;
- values = value;
- } else {
- keys = [key];
- values = [value];
- }
-
- openTransaction(this, IDBT_READ_WRITE, function (transaction) {
- transaction.onabort = getError(error, defaultError);
- transaction.oncomplete = function () {
- if (key instanceof Array) {
- success(keys, values);
- } else {
- success(key, value);
- }
- };
-
- for (var i = 0; i < keys.length && i < values.length; i++) {
- var request = transaction.objectStore(name).openCursor(IDBKeyRange.only(keys[i]));
- var record = { v: values[i] };
- request.pair = { key: keys[i], value: record };
- request.onsuccess = function (event) {
- var cursor = event.target.result;
- if (cursor) {
- cursor.update(event.target.pair.value);
- } else {
- transaction.abort();
- }
- }
- }
- }, error);
-};
-
-
-module.exports = IndexedDBStore;
\ No newline at end of file
diff --git a/lib/store/memory.js b/lib/store/memory.js
deleted file mode 100644
index a9c69d4..0000000
--- a/lib/store/memory.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/memory */
-
-
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-/** Constructor for store objects that use a sorted array as the underlying mechanism.
- * @class MemoryStore
- * @constructor
- * @param {String} name - Store name.
- */
-function MemoryStore(name) {
-
- var holes = [];
- var items = [];
- var keys = {};
-
- this.name = name;
-
- var getErrorCallback = function (error) {
- return error || this.defaultError;
- };
-
- /** Validates that the specified key is not undefined, not null, and not an array
- * @param key - Key value.
- * @param {Function} error - Error callback.
- * @returns {Boolean} True if the key is valid. False if the key is invalid and the error callback has been queued for execution.
- */
- function validateKeyInput(key, error) {
-
- var messageString;
-
- if (key instanceof Array) {
- messageString = "Array of keys not supported";
- }
-
- if (key === undefined || key === null) {
- messageString = "Invalid key";
- }
-
- if (messageString) {
- delay(error, { message: messageString });
- return false;
- }
- return true;
- }
-
- /** This method errors out if the store already contains the specified key.
- * @summary Adds a new value identified by a key to the store.
- * @method module:store/memory~MemoryStore#add
- * @param {String} key - Key string.
- * @param value - Value that is going to be added to the store.
- * @param {Function} success - Callback for a successful add operation.
- * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
- this.add = function (key, value, success, error) {
- error = getErrorCallback(error);
-
- if (validateKeyInput(key, error)) {
- if (!keys.hasOwnProperty(key)) {
- this.addOrUpdate(key, value, success, error);
- } else {
- error({ message: "key already exists", key: key });
- }
- }
- };
-
- /** This method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
- * @summary Adds or updates a value identified by a key to the store.
- * @method module:store/memory~MemoryStore#addOrUpdate
- * @param {String} key - Key string.
- * @param value - Value that is going to be added or updated to the store.
- * @param {Function} success - Callback for a successful add or update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
- this.addOrUpdate = function (key, value, success, error) {
-
- error = getErrorCallback(error);
-
- if (validateKeyInput(key, error)) {
- var index = keys[key];
- if (index === undefined) {
- if (holes.length > 0) {
- index = holes.splice(0, 1);
- } else {
- index = items.length;
- }
- }
- items[index] = value;
- keys[key] = index;
- delay(success, key, value);
- }
- };
-
- /** Removes all the data associated with this store object.
- * @method module:store/memory~MemoryStore#clear
- * @param {Function} success - Callback for a successful clear operation.
- */
- this.clear = function (success) {
- items = [];
- keys = {};
- holes = [];
- delay(success);
- };
-
- /** Checks whether a key exists in the store.
- * @method module:store/memory~MemoryStore#contains
- * @param {String} key - Key string.
- * @param {Function} success - Callback indicating whether the store contains the key or not.
- */
- this.contains = function (key, success) {
- var contained = keys.hasOwnProperty(key);
- delay(success, contained);
- };
-
- /** Gets all the keys that exist in the store.
- * @method module:store/memory~MemoryStore#getAllKeys
- * @param {Function} success - Callback for a successful get operation.
- */
- this.getAllKeys = function (success) {
-
- var results = [];
- for (var name in keys) {
- results.push(name);
- }
- delay(success, results);
- };
-
- /** Reads the value associated to a key in the store.
- * @method module:store/memory~MemoryStore#read
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful reads operation.
- * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
- this.read = function (key, success, error) {
- error = getErrorCallback(error);
-
- if (validateKeyInput(key, error)) {
- var index = keys[key];
- delay(success, key, items[index]);
- }
- };
-
- /** Removes a key and its value from the store.
- * @method module:store/memory~MemoryStore#remove
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful remove operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
- this.remove = function (key, success, error) {
- error = getErrorCallback(error);
-
- if (validateKeyInput(key, error)) {
- var index = keys[key];
- if (index !== undefined) {
- if (index === items.length - 1) {
- items.pop();
- } else {
- items[index] = undefined;
- holes.push(index);
- }
- delete keys[key];
-
- // The last item was removed, no need to keep track of any holes in the array.
- if (items.length === 0) {
- holes = [];
- }
- }
-
- delay(success);
- }
- };
-
- /** Updates the value associated to a key in the store.
- * @method module:store/memory~MemoryStore#update
- * @param {String} key - Key string.
- * @param value - New value.
- * @param {Function} success - Callback for a successful update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- * This method errors out if the specified key is not found in the store.
- */
- this.update = function (key, value, success, error) {
- error = getErrorCallback(error);
- if (validateKeyInput(key, error)) {
- if (keys.hasOwnProperty(key)) {
- this.addOrUpdate(key, value, success, error);
- } else {
- error({ message: "key not found", key: key });
- }
- }
- };
-}
-
-/** Creates a store object that uses memory storage as its underlying mechanism.
- * @method MemoryStore.create
- * @param {String} name - Store name.
- * @returns {Object} Store object.
- */
-MemoryStore.create = function (name) {
- return new MemoryStore(name);
-};
-
-/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
- * @method MemoryStore.isSupported
- * @returns {Boolean} True if the mechanism is supported by the browser; otherwise false.
- */
-MemoryStore.isSupported = function () {
- return true;
-};
-
-/** This function does nothing in MemoryStore as it does not have a connection model.
-*/
-MemoryStore.prototype.close = function () {
-};
-
-MemoryStore.prototype.defaultError = throwErrorCallback;
-
-/** Identifies the underlying mechanism used by the store.
-*/
-MemoryStore.prototype.mechanism = "memory";
-
-
-/** MemoryStore (see {@link MemoryStore}) */
-module.exports = MemoryStore;
\ No newline at end of file
diff --git a/package.json b/package.json
index 044cb81..ad709a0 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,15 @@
{
- "name": "odatajs",
- "version": "4.0.0",
+ "name": "jaydata-odatajs",
+ "version": "4.0.1",
"postfix": "",
"releaseCandidate": "",
"title": "Olingo OData Client for JavaScript",
"description": "the Olingo OData Client for JavaScript library is a new cross-browser JavaScript library that enables data-centric web applications by leveraging modern protocols such as JSON and OData and HTML5-enabled browser features. It's designed to be small, fast and easy to use.",
"homepage": "http://olingo.apache.org",
- "main": "index-node.js",
- "main-browser": "index.js",
+ "main": "index.js",
"repository": {
"type": "git",
- "url": "http://git-wip-us.apache.org/repos/asf/olingo-odata4-js.git"
+ "url": "http://github.com/jaystack/olingo-odata4-js.git"
},
"engines": {
"node": ">= 0.10.0"
@@ -27,13 +26,24 @@
{
"name": "Challen He",
"email": "challenh@apache.org"
+ },
+ {
+ "name": "Viktor Lázár",
+ "email": "viktor.lazar@jaystack.com"
+ },
+ {
+ "name": "Viktor Borza",
+ "email": "viktor.borza@jaystack.com"
}
],
- "scripts": {
- "preinstall": "npm --prefix ./grunt-config/custom-tasks/rat install"
+ "dependencies": {
+ "xmldom": "^0.1.19"
},
"devDependencies": {
+ "async": "^1.5.0",
+ "catharsis": "^0.8.7",
"chai": "^2.0.0",
+ "chalk": "^1.1.1",
"grunt": "^0.4.5",
"grunt-connect-proxy": "^0.1.10",
"grunt-contrib-clean": "^0.6.0",
@@ -44,6 +54,8 @@
"grunt-jsdoc": "^0.5.6",
"grunt-nuget": "^0.1.3",
"mocha": "^2.1.0",
+ "taffydb": "^2.7.2",
+ "xml2js": "^0.4.15",
"xmldom": "^0.1.19"
}
}