Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: content/browser/indexed_db/indexed_db_database.cc

Issue 198223002: Added IndexedDBPendingConnection to group up a bunch of parameters that get (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge out Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_database.h" 5 #include "content/browser/indexed_db/indexed_db_database.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <set> 8 #include <set>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "content/browser/indexed_db/indexed_db_connection.h" 16 #include "content/browser/indexed_db/indexed_db_connection.h"
17 #include "content/browser/indexed_db/indexed_db_cursor.h" 17 #include "content/browser/indexed_db/indexed_db_cursor.h"
18 #include "content/browser/indexed_db/indexed_db_factory.h" 18 #include "content/browser/indexed_db/indexed_db_factory.h"
19 #include "content/browser/indexed_db/indexed_db_index_writer.h" 19 #include "content/browser/indexed_db/indexed_db_index_writer.h"
20 #include "content/browser/indexed_db/indexed_db_pending_connection.h"
20 #include "content/browser/indexed_db/indexed_db_tracing.h" 21 #include "content/browser/indexed_db/indexed_db_tracing.h"
21 #include "content/browser/indexed_db/indexed_db_transaction.h" 22 #include "content/browser/indexed_db/indexed_db_transaction.h"
22 #include "content/common/indexed_db/indexed_db_key_path.h" 23 #include "content/common/indexed_db/indexed_db_key_path.h"
23 #include "content/common/indexed_db/indexed_db_key_range.h" 24 #include "content/common/indexed_db/indexed_db_key_range.h"
24 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" 25 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
25 26
26 using base::ASCIIToUTF16; 27 using base::ASCIIToUTF16;
27 using base::Int64ToString16; 28 using base::Int64ToString16;
28 using blink::WebIDBKeyTypeNumber; 29 using blink::WebIDBKeyTypeNumber;
29 30
30 namespace content { 31 namespace content {
31 32
32 // PendingOpenCall has a scoped_refptr<IndexedDBDatabaseCallbacks> because it
33 // isn't a connection yet.
34 class IndexedDBDatabase::PendingOpenCall {
35 public:
36 PendingOpenCall(scoped_refptr<IndexedDBCallbacks> callbacks,
37 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
38 int64 transaction_id,
39 int64 version)
40 : callbacks_(callbacks),
41 database_callbacks_(database_callbacks),
42 version_(version),
43 transaction_id_(transaction_id) {}
44 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
45 scoped_refptr<IndexedDBDatabaseCallbacks> const database_callbacks() {
46 return database_callbacks_;
47 }
48 int64 version() const { return version_; }
49 int64 transaction_id() const { return transaction_id_; }
50
51 private:
52 scoped_refptr<IndexedDBCallbacks> callbacks_;
53 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_;
54 int64 version_;
55 const int64 transaction_id_;
56 };
57
58 // PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the 33 // PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the
59 // in-progress connection. 34 // in-progress connection.
60 class IndexedDBDatabase::PendingUpgradeCall { 35 class IndexedDBDatabase::PendingUpgradeCall {
61 public: 36 public:
62 PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, 37 PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks,
63 scoped_ptr<IndexedDBConnection> connection, 38 scoped_ptr<IndexedDBConnection> connection,
64 int64 transaction_id, 39 int64 transaction_id,
65 int64 version) 40 int64 version)
66 : callbacks_(callbacks), 41 : callbacks_(callbacks),
67 connection_(connection.Pass()), 42 connection_(connection.Pass()),
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 return backing_store_->CreateIDBDatabaseMetaData( 177 return backing_store_->CreateIDBDatabaseMetaData(
203 metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id); 178 metadata_.name, metadata_.version, metadata_.int_version, &metadata_.id);
204 } 179 }
205 180
206 IndexedDBDatabase::~IndexedDBDatabase() { 181 IndexedDBDatabase::~IndexedDBDatabase() {
207 DCHECK(transactions_.empty()); 182 DCHECK(transactions_.empty());
208 DCHECK(pending_open_calls_.empty()); 183 DCHECK(pending_open_calls_.empty());
209 DCHECK(pending_delete_calls_.empty()); 184 DCHECK(pending_delete_calls_.empty());
210 } 185 }
211 186
187 scoped_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection(
188 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
189 int child_process_id) {
190 scoped_ptr<IndexedDBConnection> connection(
191 new IndexedDBConnection(this, database_callbacks));
192 connections_.insert(connection.get());
193 /* TODO(ericu): Grant child process permissions here so that the connection
194 * can create Blobs.
195 */
196 return connection.Pass();
197 }
198
212 IndexedDBTransaction* IndexedDBDatabase::GetTransaction( 199 IndexedDBTransaction* IndexedDBDatabase::GetTransaction(
213 int64 transaction_id) const { 200 int64 transaction_id) const {
214 TransactionMap::const_iterator trans_iterator = 201 TransactionMap::const_iterator trans_iterator =
215 transactions_.find(transaction_id); 202 transactions_.find(transaction_id);
216 if (trans_iterator == transactions_.end()) 203 if (trans_iterator == transactions_.end())
217 return NULL; 204 return NULL;
218 return trans_iterator->second; 205 return trans_iterator->second;
219 } 206 }
220 207
221 bool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const { 208 bool IndexedDBDatabase::ValidateObjectStoreId(int64 object_store_id) const {
(...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 } 1328 }
1342 // delete_database_final should never re-queue calls. 1329 // delete_database_final should never re-queue calls.
1343 DCHECK(pending_delete_calls_.empty()); 1330 DCHECK(pending_delete_calls_.empty());
1344 // Fall through when complete, as pending opens may be unblocked. 1331 // Fall through when complete, as pending opens may be unblocked.
1345 } 1332 }
1346 1333
1347 if (!IsOpenConnectionBlocked()) { 1334 if (!IsOpenConnectionBlocked()) {
1348 PendingOpenCallList pending_open_calls; 1335 PendingOpenCallList pending_open_calls;
1349 pending_open_calls_.swap(pending_open_calls); 1336 pending_open_calls_.swap(pending_open_calls);
1350 while (!pending_open_calls.empty()) { 1337 while (!pending_open_calls.empty()) {
1351 scoped_ptr<PendingOpenCall> pending_open_call(pending_open_calls.front()); 1338 OpenConnection(pending_open_calls.front());
1352 pending_open_calls.pop_front(); 1339 pending_open_calls.pop_front();
1353 OpenConnection(pending_open_call->callbacks(),
1354 pending_open_call->database_callbacks(),
1355 pending_open_call->transaction_id(),
1356 pending_open_call->version());
1357 } 1340 }
1358 } 1341 }
1359 } 1342 }
1360 1343
1361 void IndexedDBDatabase::CreateTransaction( 1344 void IndexedDBDatabase::CreateTransaction(
1362 int64 transaction_id, 1345 int64 transaction_id,
1363 IndexedDBConnection* connection, 1346 IndexedDBConnection* connection,
1364 const std::vector<int64>& object_store_ids, 1347 const std::vector<int64>& object_store_ids,
1365 uint16 mode) { 1348 uint16 mode) {
1366 1349
(...skipping 17 matching lines...) Expand all
1384 transactions_[transaction->id()] = transaction; 1367 transactions_[transaction->id()] = transaction;
1385 } 1368 }
1386 1369
1387 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { 1370 bool IndexedDBDatabase::IsOpenConnectionBlocked() const {
1388 return !pending_delete_calls_.empty() || 1371 return !pending_delete_calls_.empty() ||
1389 transaction_coordinator_.IsRunningVersionChangeTransaction() || 1372 transaction_coordinator_.IsRunningVersionChangeTransaction() ||
1390 pending_run_version_change_transaction_call_; 1373 pending_run_version_change_transaction_call_;
1391 } 1374 }
1392 1375
1393 void IndexedDBDatabase::OpenConnection( 1376 void IndexedDBDatabase::OpenConnection(
1394 scoped_refptr<IndexedDBCallbacks> callbacks, 1377 const IndexedDBPendingConnection& connection) {
1395 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
1396 int64 transaction_id,
1397 int64 version) {
1398 DCHECK(backing_store_); 1378 DCHECK(backing_store_);
1399 1379
1400 // TODO(jsbell): Should have a priority queue so that higher version 1380 // TODO(jsbell): Should have a priority queue so that higher version
1401 // requests are processed first. http://crbug.com/225850 1381 // requests are processed first. http://crbug.com/225850
1402 if (IsOpenConnectionBlocked()) { 1382 if (IsOpenConnectionBlocked()) {
1403 // The backing store only detects data loss when it is first opened. The 1383 // The backing store only detects data loss when it is first opened. The
1404 // presence of existing connections means we didn't even check for data loss 1384 // presence of existing connections means we didn't even check for data loss
1405 // so there'd better not be any. 1385 // so there'd better not be any.
1406 DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); 1386 DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss());
1407 pending_open_calls_.push_back(new PendingOpenCall( 1387 pending_open_calls_.push_back(connection);
1408 callbacks, database_callbacks, transaction_id, version));
1409 return; 1388 return;
1410 } 1389 }
1411 1390
1412 if (metadata_.id == kInvalidId) { 1391 if (metadata_.id == kInvalidId) {
1413 // The database was deleted then immediately re-opened; OpenInternal() 1392 // The database was deleted then immediately re-opened; OpenInternal()
1414 // recreates it in the backing store. 1393 // recreates it in the backing store.
1415 if (OpenInternal().ok()) { 1394 if (OpenInternal().ok()) {
1416 DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, 1395 DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION,
1417 metadata_.int_version); 1396 metadata_.int_version);
1418 } else { 1397 } else {
1419 base::string16 message; 1398 base::string16 message;
1420 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1399 if (connection.version == IndexedDBDatabaseMetadata::NO_INT_VERSION) {
1421 message = ASCIIToUTF16( 1400 message = ASCIIToUTF16(
1422 "Internal error opening database with no version specified."); 1401 "Internal error opening database with no version specified.");
1423 } else { 1402 } else {
1424 message = 1403 message =
1425 ASCIIToUTF16("Internal error opening database with version ") + 1404 ASCIIToUTF16("Internal error opening database with version ") +
1426 Int64ToString16(version); 1405 Int64ToString16(connection.version);
1427 } 1406 }
1428 callbacks->OnError(IndexedDBDatabaseError( 1407 connection.callbacks->OnError(IndexedDBDatabaseError(
1429 blink::WebIDBDatabaseExceptionUnknownError, message)); 1408 blink::WebIDBDatabaseExceptionUnknownError, message));
1430 return; 1409 return;
1431 } 1410 }
1432 } 1411 }
1433 1412
1434 // We infer that the database didn't exist from its lack of either type of 1413 // We infer that the database didn't exist from its lack of either type of
1435 // version. 1414 // version.
1436 bool is_new_database = 1415 bool is_new_database =
1437 metadata_.version == kNoStringVersion && 1416 metadata_.version == kNoStringVersion &&
1438 metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; 1417 metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION;
1439 1418
1440 scoped_ptr<IndexedDBConnection> connection( 1419 if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) {
1441 new IndexedDBConnection(this, database_callbacks));
1442
1443 if (version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) {
1444 // For unit tests only - skip upgrade steps. Calling from script with 1420 // For unit tests only - skip upgrade steps. Calling from script with
1445 // DEFAULT_INT_VERSION throws exception. 1421 // DEFAULT_INT_VERSION throws exception.
1446 // TODO(jsbell): DCHECK that not in unit tests. 1422 // TODO(jsbell): DCHECK that not in unit tests.
1447 DCHECK(is_new_database); 1423 DCHECK(is_new_database);
1448 connections_.insert(connection.get()); 1424 connection.callbacks->OnSuccess(
1449 callbacks->OnSuccess(connection.Pass(), this->metadata()); 1425 CreateConnection(connection.database_callbacks,
1426 connection.child_process_id),
1427 this->metadata());
1450 return; 1428 return;
1451 } 1429 }
1452 1430
1453 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { 1431 // We may need to change the version.
1432 int64 local_version = connection.version;
1433 if (local_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) {
1454 if (!is_new_database) { 1434 if (!is_new_database) {
1455 connections_.insert(connection.get()); 1435 connection.callbacks->OnSuccess(
1456 callbacks->OnSuccess(connection.Pass(), this->metadata()); 1436 CreateConnection(connection.database_callbacks,
1437 connection.child_process_id),
1438 this->metadata());
1457 return; 1439 return;
1458 } 1440 }
1459 // Spec says: If no version is specified and no database exists, set 1441 // Spec says: If no version is specified and no database exists, set
1460 // database version to 1. 1442 // database version to 1.
1461 version = 1; 1443 local_version = 1;
1462 } 1444 }
1463 1445
1464 if (version > metadata_.int_version) { 1446 if (local_version > metadata_.int_version) {
1465 connections_.insert(connection.get()); 1447 RunVersionChangeTransaction(connection.callbacks,
1466 RunVersionChangeTransaction( 1448 CreateConnection(connection.database_callbacks,
1467 callbacks, connection.Pass(), transaction_id, version); 1449 connection.child_process_id),
1450 connection.transaction_id,
1451 local_version);
1468 return; 1452 return;
1469 } 1453 }
1470 if (version < metadata_.int_version) { 1454 if (local_version < metadata_.int_version) {
1471 callbacks->OnError(IndexedDBDatabaseError( 1455 connection.callbacks->OnError(IndexedDBDatabaseError(
1472 blink::WebIDBDatabaseExceptionVersionError, 1456 blink::WebIDBDatabaseExceptionVersionError,
1473 ASCIIToUTF16("The requested version (") + Int64ToString16(version) + 1457 ASCIIToUTF16("The requested version (") +
1458 Int64ToString16(local_version) +
1474 ASCIIToUTF16(") is less than the existing version (") + 1459 ASCIIToUTF16(") is less than the existing version (") +
1475 Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); 1460 Int64ToString16(metadata_.int_version) + ASCIIToUTF16(").")));
1476 return; 1461 return;
1477 } 1462 }
1478 DCHECK_EQ(version, metadata_.int_version); 1463 DCHECK_EQ(local_version, metadata_.int_version);
1479 connections_.insert(connection.get()); 1464 connection.callbacks->OnSuccess(
1480 callbacks->OnSuccess(connection.Pass(), this->metadata()); 1465 CreateConnection(connection.database_callbacks,
1466 connection.child_process_id),
1467 this->metadata());
1481 } 1468 }
1482 1469
1483 void IndexedDBDatabase::RunVersionChangeTransaction( 1470 void IndexedDBDatabase::RunVersionChangeTransaction(
1484 scoped_refptr<IndexedDBCallbacks> callbacks, 1471 scoped_refptr<IndexedDBCallbacks> callbacks,
1485 scoped_ptr<IndexedDBConnection> connection, 1472 scoped_ptr<IndexedDBConnection> connection,
1486 int64 transaction_id, 1473 int64 transaction_id,
1487 int64 requested_version) { 1474 int64 requested_version) {
1488 1475
1489 DCHECK(callbacks); 1476 DCHECK(callbacks);
1490 DCHECK(connections_.count(connection.get())); 1477 DCHECK(connections_.count(connection.get()));
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 const base::string16& previous_version, 1654 const base::string16& previous_version,
1668 int64 previous_int_version, 1655 int64 previous_int_version,
1669 IndexedDBTransaction* transaction) { 1656 IndexedDBTransaction* transaction) {
1670 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1657 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
1671 DCHECK(!transaction); 1658 DCHECK(!transaction);
1672 metadata_.version = previous_version; 1659 metadata_.version = previous_version;
1673 metadata_.int_version = previous_int_version; 1660 metadata_.int_version = previous_int_version;
1674 } 1661 }
1675 1662
1676 } // namespace content 1663 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_database.h ('k') | content/browser/indexed_db/indexed_db_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698