Path: blob/trunk/third_party/closure/goog/db/cursor.js
2868 views
// Copyright 2012 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Wrapper for a IndexedDB cursor.16*17*/181920goog.provide('goog.db.Cursor');2122goog.require('goog.async.Deferred');23goog.require('goog.db.Error');24goog.require('goog.db.KeyRange');25goog.require('goog.debug');26goog.require('goog.events.EventTarget');27282930/**31* Creates a new IDBCursor wrapper object. Should not be created directly,32* access cursor through object store.33* @see goog.db.ObjectStore#openCursor34*35* @constructor36* @extends {goog.events.EventTarget}37* @final38*/39goog.db.Cursor = function() {40goog.db.Cursor.base(this, 'constructor');41};42goog.inherits(goog.db.Cursor, goog.events.EventTarget);434445/**46* Underlying IndexedDB cursor object.47*48* @type {IDBCursor}49* @private50*/51goog.db.Cursor.prototype.cursor_ = null;525354/**55* Advances the cursor to the next position along its direction. When new data56* is available, the NEW_DATA event will be fired. If the cursor has reached the57* end of the range it will fire the COMPLETE event. If opt_key is specified it58* will advance to the key it matches in its direction.59*60* This wraps the native #continue method on the underlying object.61*62* @param {IDBKeyType=} opt_key The optional key to advance to.63*/64goog.db.Cursor.prototype.next = function(opt_key) {65if (opt_key) {66this.cursor_['continue'](opt_key);67} else {68this.cursor_['continue']();69}70};717273/**74* Updates the value at the current position of the cursor in the object store.75* If the cursor points to a value that has just been deleted, a new value is76* created.77*78* @param {*} value The value to be stored.79* @return {!goog.async.Deferred} The resulting deferred request.80*/81goog.db.Cursor.prototype.update = function(value) {82var msg = 'updating via cursor with value ';83var d = new goog.async.Deferred();84var request;8586try {87request = this.cursor_.update(value);88} catch (err) {89msg += goog.debug.deepExpose(value);90d.errback(goog.db.Error.fromException(err, msg));91return d;92}93request.onsuccess = function(ev) { d.callback(); };94request.onerror = function(ev) {95msg += goog.debug.deepExpose(value);96d.errback(goog.db.Error.fromRequest(ev.target, msg));97};98return d;99};100101102/**103* Deletes the value at the cursor's position, without changing the cursor's104* position. Once the value is deleted, the cursor's value is set to null.105*106* @return {!goog.async.Deferred} The resulting deferred request.107*/108goog.db.Cursor.prototype.remove = function() {109var msg = 'deleting via cursor';110var d = new goog.async.Deferred();111var request;112113try {114request = this.cursor_['delete']();115} catch (err) {116d.errback(goog.db.Error.fromException(err, msg));117return d;118}119request.onsuccess = function(ev) { d.callback(); };120request.onerror = function(ev) {121d.errback(goog.db.Error.fromRequest(ev.target, msg));122};123return d;124};125126127/**128* @return {*} The value for the value at the cursor's position. Undefined129* if no current value, or null if value has just been deleted.130*/131goog.db.Cursor.prototype.getValue = function() {132return this.cursor_['value'];133};134135136/**137* @return {IDBKeyType} The key for the value at the cursor's position. If138* the cursor is outside its range, this is undefined.139*/140goog.db.Cursor.prototype.getKey = function() {141return this.cursor_.key;142};143144145/**146* Opens a value cursor from IDBObjectStore or IDBIndex over the specified key147* range. Returns a cursor object which is able to iterate over the given range.148* @param {!(IDBObjectStore|IDBIndex)} source Data source to open cursor.149* @param {!goog.db.KeyRange=} opt_range The key range. If undefined iterates150* over the whole data source.151* @param {!goog.db.Cursor.Direction=} opt_direction The direction. If undefined152* moves in a forward direction with duplicates.153* @return {!goog.db.Cursor} The cursor.154* @throws {goog.db.Error} If there was a problem opening the cursor.155*/156goog.db.Cursor.openCursor = function(source, opt_range, opt_direction) {157var cursor = new goog.db.Cursor();158var request;159160try {161var range = opt_range ? opt_range.range() : null;162if (opt_direction) {163request = source.openCursor(range, opt_direction);164} else {165request = source.openCursor(range);166}167} catch (ex) {168cursor.dispose();169throw goog.db.Error.fromException(ex, source.name);170}171request.onsuccess = function(e) {172cursor.cursor_ = e.target.result || null;173if (cursor.cursor_) {174cursor.dispatchEvent(goog.db.Cursor.EventType.NEW_DATA);175} else {176cursor.dispatchEvent(goog.db.Cursor.EventType.COMPLETE);177}178};179request.onerror = function(e) {180cursor.dispatchEvent(goog.db.Cursor.EventType.ERROR);181};182return cursor;183};184185186/**187* Possible cursor directions.188* @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBCursor189*190* @enum {string}191*/192goog.db.Cursor.Direction = {193NEXT: 'next',194NEXT_NO_DUPLICATE: 'nextunique',195PREV: 'prev',196PREV_NO_DUPLICATE: 'prevunique'197};198199200/**201* Event types that the cursor can dispatch. COMPLETE events are dispatched when202* a cursor is depleted of values, a NEW_DATA event if there is new data203* available, and ERROR if an error occurred.204*205* @enum {string}206*/207goog.db.Cursor.EventType = {208COMPLETE: 'c',209ERROR: 'e',210NEW_DATA: 'n'211};212213214