1/* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "IDBIndex.h" 28 29#if ENABLE(INDEXED_DATABASE) 30 31#include "IDBDatabaseException.h" 32#include "IDBKey.h" 33#include "IDBKeyRange.h" 34#include "IDBObjectStore.h" 35#include "IDBRequest.h" 36#include "IDBTransaction.h" 37#include "Logging.h" 38#include "ScriptExecutionContext.h" 39 40namespace WebCore { 41 42IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, IDBObjectStore* objectStore, IDBTransaction* transaction) 43 : m_metadata(metadata) 44 , m_objectStore(objectStore) 45 , m_transaction(transaction) 46 , m_deleted(false) 47{ 48 ASSERT(m_objectStore); 49 ASSERT(m_transaction); 50 ASSERT(m_metadata.id != IDBIndexMetadata::InvalidId); 51} 52 53IDBIndex::~IDBIndex() 54{ 55} 56 57PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec) 58{ 59 LOG(StorageAPI, "IDBIndex::openCursor"); 60 if (m_deleted) { 61 ec = IDBDatabaseException::InvalidStateError; 62 return 0; 63 } 64 if (!m_transaction->isActive()) { 65 ec = IDBDatabaseException::TransactionInactiveError; 66 return 0; 67 } 68 IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec); 69 if (ec) 70 return 0; 71 72 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 73 request->setCursorDetails(IndexedDB::CursorType::KeyAndValue, direction); 74 backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, false, IDBDatabaseBackend::NormalTask, request); 75 return request; 76} 77 78PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec) 79{ 80 LOG(StorageAPI, "IDBIndex::openCursor"); 81 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); 82 if (ec) 83 return 0; 84 return openCursor(context, keyRange.release(), direction, ec); 85} 86 87PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) 88{ 89 LOG(StorageAPI, "IDBIndex::count"); 90 if (m_deleted) { 91 ec = IDBDatabaseException::InvalidStateError; 92 return 0; 93 } 94 if (!m_transaction->isActive()) { 95 ec = IDBDatabaseException::TransactionInactiveError; 96 return 0; 97 } 98 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 99 backendDB()->count(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, request); 100 return request; 101} 102 103PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) 104{ 105 LOG(StorageAPI, "IDBIndex::count"); 106 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); 107 if (ec) 108 return 0; 109 return count(context, keyRange.release(), ec); 110} 111 112PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec) 113{ 114 LOG(StorageAPI, "IDBIndex::openKeyCursor"); 115 if (m_deleted) { 116 ec = IDBDatabaseException::InvalidStateError; 117 return 0; 118 } 119 if (!m_transaction->isActive()) { 120 ec = IDBDatabaseException::TransactionInactiveError; 121 return 0; 122 } 123 IndexedDB::CursorDirection direction = IDBCursor::stringToDirection(directionString, ec); 124 if (ec) 125 return 0; 126 127 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 128 request->setCursorDetails(IndexedDB::CursorType::KeyOnly, direction); 129 backendDB()->openCursor(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, direction, true, IDBDatabaseBackend::NormalTask, request); 130 return request; 131} 132 133PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCode& ec) 134{ 135 LOG(StorageAPI, "IDBIndex::openKeyCursor"); 136 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); 137 if (ec) 138 return 0; 139 return openKeyCursor(context, keyRange.release(), direction, ec); 140} 141 142PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) 143{ 144 LOG(StorageAPI, "IDBIndex::get"); 145 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); 146 if (ec) 147 return 0; 148 return get(context, keyRange.release(), ec); 149} 150 151PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) 152{ 153 LOG(StorageAPI, "IDBIndex::get"); 154 if (m_deleted) { 155 ec = IDBDatabaseException::InvalidStateError; 156 return 0; 157 } 158 if (!m_transaction->isActive()) { 159 ec = IDBDatabaseException::TransactionInactiveError; 160 return 0; 161 } 162 if (!keyRange) { 163 ec = IDBDatabaseException::DataError; 164 return 0; 165 } 166 167 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 168 backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, false, request); 169 return request; 170} 171 172PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) 173{ 174 LOG(StorageAPI, "IDBIndex::getKey"); 175 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(context, key, ec); 176 if (ec) 177 return 0; 178 179 return getKey(context, keyRange.release(), ec); 180} 181 182PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec) 183{ 184 LOG(StorageAPI, "IDBIndex::getKey"); 185 if (m_deleted) { 186 ec = IDBDatabaseException::InvalidStateError; 187 return 0; 188 } 189 if (!m_transaction->isActive()) { 190 ec = IDBDatabaseException::TransactionInactiveError; 191 return 0; 192 } 193 if (!keyRange) { 194 ec = IDBDatabaseException::DataError; 195 return 0; 196 } 197 198 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get()); 199 backendDB()->get(m_transaction->id(), m_objectStore->id(), m_metadata.id, keyRange, true, request); 200 return request; 201} 202 203IDBDatabaseBackend* IDBIndex::backendDB() const 204{ 205 return m_transaction->backendDB(); 206} 207 208} // namespace WebCore 209 210#endif // ENABLE(INDEXED_DATABASE) 211