<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: store/memory.js</title>
    
    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">
    
    <h1 class="page-title">Source: store/memory.js</h1>
    
    


    
    <section>
        <article>
            <pre class="prettyprint source"><code>/*
 * 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;</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>

<br clear="both">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
