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 21 using blink::WebBlobInfo; 22 using blink::WebIDBCallbacks; 23 using blink::WebIDBCursor; 24 using blink::WebIDBDatabase; 25 using blink::WebIDBDatabaseCallbacks; 26 using blink::WebIDBMetadata; 27 using blink::WebIDBKey; 28 using blink::WebIDBKeyPath; 29 using blink::WebIDBKeyRange; 30 using blink::WebString; 31 using blink::WebVector; 32 33 namespace content { 34 35 WebIDBDatabaseImpl::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 42 WebIDBDatabaseImpl::~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 54 void 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 71 void 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 77 void WebIDBDatabaseImpl::createTransaction( 78 long long transaction_id, 79 WebIDBDatabaseCallbacks* callbacks, 80 const WebVector<long long>& object_store_ids, 81 WebIDBDatabase::TransactionMode 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 88 void 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 95 void WebIDBDatabaseImpl::get(long long transaction_id, 96 long long object_store_id, 97 long long index_id, 98 const WebIDBKeyRange& key_range, 99 bool key_only, 100 WebIDBCallbacks* callbacks) { 101 IndexedDBDispatcher* dispatcher = 102 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 103 dispatcher->RequestIDBDatabaseGet(ipc_database_id_, 104 transaction_id, 105 object_store_id, 106 index_id, 107 IndexedDBKeyRangeBuilder::Build(key_range), 108 key_only, 109 callbacks); 110 } 111 112 void WebIDBDatabaseImpl::put(long long transaction_id, 113 long long object_store_id, 114 const blink::WebData& value, 115 const blink::WebVector<WebBlobInfo>& web_blob_info, 116 const WebIDBKey& key, 117 PutMode put_mode, 118 WebIDBCallbacks* callbacks, 119 const WebVector<long long>& web_index_ids, 120 const WebVector<WebIndexKeys>& web_index_keys) { 121 IndexedDBDispatcher* dispatcher = 122 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 123 dispatcher->RequestIDBDatabasePut(ipc_database_id_, 124 transaction_id, 125 object_store_id, 126 value, 127 web_blob_info, 128 IndexedDBKeyBuilder::Build(key), 129 put_mode, 130 callbacks, 131 web_index_ids, 132 web_index_keys); 133 } 134 135 void WebIDBDatabaseImpl::setIndexKeys( 136 long long transaction_id, 137 long long object_store_id, 138 const WebIDBKey& primary_key, 139 const WebVector<long long>& index_ids, 140 const WebVector<WebIndexKeys>& index_keys) { 141 IndexedDBHostMsg_DatabaseSetIndexKeys_Params params; 142 params.ipc_database_id = ipc_database_id_; 143 params.transaction_id = transaction_id; 144 params.object_store_id = object_store_id; 145 params.primary_key = IndexedDBKeyBuilder::Build(primary_key); 146 147 DCHECK_EQ(index_ids.size(), index_keys.size()); 148 params.index_keys.resize(index_ids.size()); 149 for (size_t i = 0, len = index_ids.size(); i < len; ++i) { 150 params.index_keys[i].first = index_ids[i]; 151 params.index_keys[i].second.resize(index_keys[i].size()); 152 for (size_t j = 0; j < index_keys[i].size(); ++j) { 153 params.index_keys[i].second[j] = 154 IndexedDBKey(IndexedDBKeyBuilder::Build(index_keys[i][j])); 155 } 156 } 157 158 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseSetIndexKeys(params)); 159 } 160 161 void WebIDBDatabaseImpl::setIndexesReady( 162 long long transaction_id, 163 long long object_store_id, 164 const WebVector<long long>& web_index_ids) { 165 std::vector<int64> index_ids(web_index_ids.data(), 166 web_index_ids.data() + web_index_ids.size()); 167 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseSetIndexesReady( 168 ipc_database_id_, transaction_id, object_store_id, index_ids)); 169 } 170 171 void WebIDBDatabaseImpl::openCursor(long long transaction_id, 172 long long object_store_id, 173 long long index_id, 174 const WebIDBKeyRange& key_range, 175 WebIDBCursor::Direction direction, 176 bool key_only, 177 TaskType task_type, 178 WebIDBCallbacks* callbacks) { 179 IndexedDBDispatcher* dispatcher = 180 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 181 dispatcher->RequestIDBDatabaseOpenCursor( 182 ipc_database_id_, 183 transaction_id, 184 object_store_id, 185 index_id, 186 IndexedDBKeyRangeBuilder::Build(key_range), 187 direction, 188 key_only, 189 task_type, 190 callbacks); 191 } 192 193 void WebIDBDatabaseImpl::count(long long transaction_id, 194 long long object_store_id, 195 long long index_id, 196 const WebIDBKeyRange& key_range, 197 WebIDBCallbacks* callbacks) { 198 IndexedDBDispatcher* dispatcher = 199 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 200 dispatcher->RequestIDBDatabaseCount( 201 ipc_database_id_, 202 transaction_id, 203 object_store_id, 204 index_id, 205 IndexedDBKeyRangeBuilder::Build(key_range), 206 callbacks); 207 } 208 209 void WebIDBDatabaseImpl::deleteRange(long long transaction_id, 210 long long object_store_id, 211 const WebIDBKeyRange& key_range, 212 WebIDBCallbacks* callbacks) { 213 IndexedDBDispatcher* dispatcher = 214 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 215 dispatcher->RequestIDBDatabaseDeleteRange( 216 ipc_database_id_, 217 transaction_id, 218 object_store_id, 219 IndexedDBKeyRangeBuilder::Build(key_range), 220 callbacks); 221 } 222 223 void WebIDBDatabaseImpl::clear(long long transaction_id, 224 long long object_store_id, 225 WebIDBCallbacks* callbacks) { 226 IndexedDBDispatcher* dispatcher = 227 IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()); 228 dispatcher->RequestIDBDatabaseClear( 229 ipc_database_id_, transaction_id, object_store_id, callbacks); 230 } 231 232 void WebIDBDatabaseImpl::createIndex(long long transaction_id, 233 long long object_store_id, 234 long long index_id, 235 const WebString& name, 236 const WebIDBKeyPath& key_path, 237 bool unique, 238 bool multi_entry) { 239 IndexedDBHostMsg_DatabaseCreateIndex_Params params; 240 params.ipc_database_id = ipc_database_id_; 241 params.transaction_id = transaction_id; 242 params.object_store_id = object_store_id; 243 params.index_id = index_id; 244 params.name = name; 245 params.key_path = IndexedDBKeyPathBuilder::Build(key_path); 246 params.unique = unique; 247 params.multi_entry = multi_entry; 248 249 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseCreateIndex(params)); 250 } 251 252 void WebIDBDatabaseImpl::deleteIndex(long long transaction_id, 253 long long object_store_id, 254 long long index_id) { 255 thread_safe_sender_->Send(new IndexedDBHostMsg_DatabaseDeleteIndex( 256 ipc_database_id_, transaction_id, object_store_id, index_id)); 257 } 258 259 void WebIDBDatabaseImpl::abort(long long transaction_id) { 260 thread_safe_sender_->Send( 261 new IndexedDBHostMsg_DatabaseAbort(ipc_database_id_, transaction_id)); 262 } 263 264 void WebIDBDatabaseImpl::commit(long long transaction_id) { 265 thread_safe_sender_->Send( 266 new IndexedDBHostMsg_DatabaseCommit(ipc_database_id_, transaction_id)); 267 } 268 269 void WebIDBDatabaseImpl::ackReceivedBlobs(const WebVector<WebString>& uuids) { 270 DCHECK(uuids.size()); 271 std::vector<std::string> param(uuids.size()); 272 for (size_t i = 0; i < uuids.size(); ++i) 273 param[i] = uuids[i].latin1().data(); 274 thread_safe_sender_->Send(new IndexedDBHostMsg_AckReceivedBlobs(param)); 275 } 276 277 } // namespace content 278