1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/child/indexed_db/webidbdatabase_impl.h" 6 7#include <string> 8#include <vector> 9 10#include "content/child/indexed_db/indexed_db_dispatcher.h" 11#include "content/child/indexed_db/indexed_db_key_builders.h" 12#include "content/child/thread_safe_sender.h" 13#include "content/child/worker_task_runner.h" 14#include "content/common/indexed_db/indexed_db_messages.h" 15#include "third_party/WebKit/public/platform/WebBlobInfo.h" 16#include "third_party/WebKit/public/platform/WebIDBKeyPath.h" 17#include "third_party/WebKit/public/platform/WebIDBMetadata.h" 18#include "third_party/WebKit/public/platform/WebString.h" 19#include "third_party/WebKit/public/platform/WebVector.h" 20 21using blink::WebBlobInfo; 22using blink::WebIDBCallbacks; 23using blink::WebIDBCursor; 24using blink::WebIDBDatabase; 25using blink::WebIDBDatabaseCallbacks; 26using blink::WebIDBMetadata; 27using blink::WebIDBKey; 28using blink::WebIDBKeyPath; 29using blink::WebIDBKeyRange; 30using blink::WebString; 31using blink::WebVector; 32 33namespace content { 34 35WebIDBDatabaseImpl::WebIDBDatabaseImpl(int32 ipc_database_id, 36 int32 ipc_database_callbacks_id, 37 ThreadSafeSender* thread_safe_sender) 38 : ipc_database_id_(ipc_database_id), 39 ipc_database_callbacks_id_(ipc_database_callbacks_id), 40 thread_safe_sender_(thread_safe_sender) {} 41 42WebIDBDatabaseImpl::~WebIDBDatabaseImpl() { 43 // It's not possible for there to be pending callbacks that address this 44 // object since inside WebKit, they hold a reference to the object which owns 45 // this object. But, if that ever changed, then we'd need to invalidate 46 // any such pointers. 47 thread_safe_sender_->Send( 48 new IndexedDBHostMsg_DatabaseDestroyed(ipc_database_id_)); 49 IndexedDBDispatcher* dispatcher = 50 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 51 dispatcher->DatabaseDestroyed(ipc_database_id_); 52} 53 54void WebIDBDatabaseImpl::createObjectStore(long long transaction_id, 55 long long object_store_id, 56 const WebString& name, 57 const WebIDBKeyPath& key_path, 58 bool auto_increment) { 59 IndexedDBHostMsg_DatabaseCreateObjectStore_Params params; 60 params.ipc_database_id = ipc_database_id_; 61 params.transaction_id = transaction_id; 62 params.object_store_id = object_store_id; 63 params.name = name; 64 params.key_path = IndexedDBKeyPathBuilder::Build(key_path); 65 params.auto_increment = auto_increment; 66 67 thread_safe_sender_->Send( 68 new IndexedDBHostMsg_DatabaseCreateObjectStore(params)); 69} 70 71void WebIDBDatabaseImpl::deleteObjectStore(long long transaction_id, 72 long long object_store_id) { 73 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseDeleteObjectStore( 74 ipc_database_id_, transaction_id, object_store_id)); 75} 76 77void WebIDBDatabaseImpl::createTransaction( 78 long long transaction_id, 79 WebIDBDatabaseCallbacks* callbacks, 80 const WebVector<long long>& object_store_ids, 81 blink::WebIDBTransactionMode mode) { 82 IndexedDBDispatcher* dispatcher = 83 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 84 dispatcher->RequestIDBDatabaseCreateTransaction( 85 ipc_database_id_, transaction_id, callbacks, object_store_ids, mode); 86} 87 88void WebIDBDatabaseImpl::close() { 89 IndexedDBDispatcher* dispatcher = 90 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 91 dispatcher->RequestIDBDatabaseClose(ipc_database_id_, 92 ipc_database_callbacks_id_); 93} 94 95void WebIDBDatabaseImpl::versionChangeIgnored() { 96 IndexedDBDispatcher* dispatcher = 97 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 98 dispatcher->NotifyIDBDatabaseVersionChangeIgnored(ipc_database_id_); 99} 100 101void WebIDBDatabaseImpl::get(long long transaction_id, 102 long long object_store_id, 103 long long index_id, 104 const WebIDBKeyRange& key_range, 105 bool key_only, 106 WebIDBCallbacks* callbacks) { 107 IndexedDBDispatcher* dispatcher = 108 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 109 dispatcher->RequestIDBDatabaseGet(ipc_database_id_, 110 transaction_id, 111 object_store_id, 112 index_id, 113 IndexedDBKeyRangeBuilder::Build(key_range), 114 key_only, 115 callbacks); 116} 117 118void WebIDBDatabaseImpl::put(long long transaction_id, 119 long long object_store_id, 120 const blink::WebData& value, 121 const blink::WebVector<WebBlobInfo>& web_blob_info, 122 const WebIDBKey& key, 123 blink::WebIDBPutMode put_mode, 124 WebIDBCallbacks* callbacks, 125 const WebVector<long long>& web_index_ids, 126 const WebVector<WebIndexKeys>& web_index_keys) { 127 IndexedDBDispatcher* dispatcher = 128 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 129 dispatcher->RequestIDBDatabasePut(ipc_database_id_, 130 transaction_id, 131 object_store_id, 132 value, 133 web_blob_info, 134 IndexedDBKeyBuilder::Build(key), 135 put_mode, 136 callbacks, 137 web_index_ids, 138 web_index_keys); 139} 140 141void WebIDBDatabaseImpl::setIndexKeys( 142 long long transaction_id, 143 long long object_store_id, 144 const WebIDBKey& primary_key, 145 const WebVector<long long>& index_ids, 146 const WebVector<WebIndexKeys>& index_keys) { 147 IndexedDBHostMsg_DatabaseSetIndexKeys_Params params; 148 params.ipc_database_id = ipc_database_id_; 149 params.transaction_id = transaction_id; 150 params.object_store_id = object_store_id; 151 params.primary_key = IndexedDBKeyBuilder::Build(primary_key); 152 153 DCHECK_EQ(index_ids.size(), index_keys.size()); 154 params.index_keys.resize(index_ids.size()); 155 for (size_t i = 0, len = index_ids.size(); i < len; ++i) { 156 params.index_keys[i].first = index_ids[i]; 157 params.index_keys[i].second.resize(index_keys[i].size()); 158 for (size_t j = 0; j < index_keys[i].size(); ++j) { 159 params.index_keys[i].second[j] = 160 IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys[i][j])); 161 } 162 } 163 164 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseSetIndexKeys(params)); 165} 166 167void WebIDBDatabaseImpl::setIndexesReady( 168 long long transaction_id, 169 long long object_store_id, 170 const WebVector<long long>& web_index_ids) { 171 std::vector<int64> index_ids(web_index_ids.data(), 172 web_index_ids.data() + web_index_ids.size()); 173 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseSetIndexesReady( 174 ipc_database_id_, transaction_id, object_store_id, index_ids)); 175} 176 177void WebIDBDatabaseImpl::openCursor(long long transaction_id, 178 long long object_store_id, 179 long long index_id, 180 const WebIDBKeyRange& key_range, 181 blink::WebIDBCursorDirection direction, 182 bool key_only, 183 blink::WebIDBTaskType task_type, 184 WebIDBCallbacks* callbacks) { 185 IndexedDBDispatcher* dispatcher = 186 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 187 dispatcher->RequestIDBDatabaseOpenCursor( 188 ipc_database_id_, 189 transaction_id, 190 object_store_id, 191 index_id, 192 IndexedDBKeyRangeBuilder::Build(key_range), 193 direction, 194 key_only, 195 task_type, 196 callbacks); 197} 198 199void WebIDBDatabaseImpl::count(long long transaction_id, 200 long long object_store_id, 201 long long index_id, 202 const WebIDBKeyRange& key_range, 203 WebIDBCallbacks* callbacks) { 204 IndexedDBDispatcher* dispatcher = 205 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 206 dispatcher->RequestIDBDatabaseCount( 207 ipc_database_id_, 208 transaction_id, 209 object_store_id, 210 index_id, 211 IndexedDBKeyRangeBuilder::Build(key_range), 212 callbacks); 213} 214 215void WebIDBDatabaseImpl::deleteRange(long long transaction_id, 216 long long object_store_id, 217 const WebIDBKeyRange& key_range, 218 WebIDBCallbacks* callbacks) { 219 IndexedDBDispatcher* dispatcher = 220 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 221 dispatcher->RequestIDBDatabaseDeleteRange( 222 ipc_database_id_, 223 transaction_id, 224 object_store_id, 225 IndexedDBKeyRangeBuilder::Build(key_range), 226 callbacks); 227} 228 229void WebIDBDatabaseImpl::clear(long long transaction_id, 230 long long object_store_id, 231 WebIDBCallbacks* callbacks) { 232 IndexedDBDispatcher* dispatcher = 233 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 234 dispatcher->RequestIDBDatabaseClear( 235 ipc_database_id_, transaction_id, object_store_id, callbacks); 236} 237 238void WebIDBDatabaseImpl::createIndex(long long transaction_id, 239 long long object_store_id, 240 long long index_id, 241 const WebString& name, 242 const WebIDBKeyPath& key_path, 243 bool unique, 244 bool multi_entry) { 245 IndexedDBHostMsg_DatabaseCreateIndex_Params params; 246 params.ipc_database_id = ipc_database_id_; 247 params.transaction_id = transaction_id; 248 params.object_store_id = object_store_id; 249 params.index_id = index_id; 250 params.name = name; 251 params.key_path = IndexedDBKeyPathBuilder::Build(key_path); 252 params.unique = unique; 253 params.multi_entry = multi_entry; 254 255 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseCreateIndex(params)); 256} 257 258void WebIDBDatabaseImpl::deleteIndex(long long transaction_id, 259 long long object_store_id, 260 long long index_id) { 261 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseDeleteIndex( 262 ipc_database_id_, transaction_id, object_store_id, index_id)); 263} 264 265void WebIDBDatabaseImpl::abort(long long transaction_id) { 266 thread_safe_sender_->Send( 267 new IndexedDBHostMsg_DatabaseAbort(ipc_database_id_, transaction_id)); 268} 269 270void WebIDBDatabaseImpl::commit(long long transaction_id) { 271 thread_safe_sender_->Send( 272 new IndexedDBHostMsg_DatabaseCommit(ipc_database_id_, transaction_id)); 273} 274 275void WebIDBDatabaseImpl::ackReceivedBlobs(const WebVector<WebString>& uuids) { 276 DCHECK(uuids.size()); 277 std::vector<std::string> param(uuids.size()); 278 for (size_t i = 0; i < uuids.size(); ++i) 279 param[i] = uuids[i].latin1().data(); 280 thread_safe_sender_->Send(new IndexedDBHostMsg_AckReceivedBlobs(param)); 281} 282 283} // namespace content 284