Home | History | Annotate | Download | only in indexed_db
      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