| OLD | NEW |
| 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 <vector> | 8 #include <vector> |
| 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/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 15 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 16 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 16 #include "content/browser/indexed_db/indexed_db_cursor.h" | 17 #include "content/browser/indexed_db/indexed_db_cursor.h" |
| 17 #include "content/browser/indexed_db/indexed_db_factory.h" | 18 #include "content/browser/indexed_db/indexed_db_factory.h" |
| 18 #include "content/browser/indexed_db/indexed_db_index_writer.h" | 19 #include "content/browser/indexed_db/indexed_db_index_writer.h" |
| 19 #include "content/browser/indexed_db/indexed_db_tracing.h" | 20 #include "content/browser/indexed_db/indexed_db_tracing.h" |
| 20 #include "content/browser/indexed_db/indexed_db_transaction.h" | 21 #include "content/browser/indexed_db/indexed_db_transaction.h" |
| 21 #include "content/common/indexed_db/indexed_db_key_path.h" | 22 #include "content/common/indexed_db/indexed_db_key_path.h" |
| 22 #include "content/common/indexed_db/indexed_db_key_range.h" | 23 #include "content/common/indexed_db/indexed_db_key_range.h" |
| 23 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
| 24 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" | 25 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" |
| 25 | 26 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 52 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; | 53 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; |
| 53 | 54 |
| 54 private: | 55 private: |
| 55 const scoped_refptr<IndexedDBBackingStore> backing_store_; | 56 const scoped_refptr<IndexedDBBackingStore> backing_store_; |
| 56 const IndexedDBObjectStoreMetadata object_store_metadata_; | 57 const IndexedDBObjectStoreMetadata object_store_metadata_; |
| 57 }; | 58 }; |
| 58 | 59 |
| 59 class IndexedDBDatabase::VersionChangeOperation | 60 class IndexedDBDatabase::VersionChangeOperation |
| 60 : public IndexedDBTransaction::Operation { | 61 : public IndexedDBTransaction::Operation { |
| 61 public: | 62 public: |
| 62 VersionChangeOperation( | 63 VersionChangeOperation(scoped_refptr<IndexedDBDatabase> database, |
| 63 scoped_refptr<IndexedDBDatabase> database, | 64 int64 transaction_id, |
| 64 int64 transaction_id, | 65 int64 version, |
| 65 int64 version, | 66 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 66 scoped_refptr<IndexedDBCallbacks> callbacks, | 67 scoped_ptr<IndexedDBConnection> connection, |
| 67 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 68 WebKit::WebIDBCallbacks::DataLoss data_loss) |
| 68 WebKit::WebIDBCallbacks::DataLoss data_loss) | |
| 69 : database_(database), | 69 : database_(database), |
| 70 transaction_id_(transaction_id), | 70 transaction_id_(transaction_id), |
| 71 version_(version), | 71 version_(version), |
| 72 callbacks_(callbacks), | 72 callbacks_(callbacks), |
| 73 database_callbacks_(database_callbacks), | 73 connection_(connection.Pass()), |
| 74 data_loss_(data_loss) {} | 74 data_loss_(data_loss) {} |
| 75 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; | 75 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; |
| 76 | 76 |
| 77 private: | 77 private: |
| 78 scoped_refptr<IndexedDBDatabase> database_; | 78 scoped_refptr<IndexedDBDatabase> database_; |
| 79 int64 transaction_id_; | 79 int64 transaction_id_; |
| 80 int64 version_; | 80 int64 version_; |
| 81 scoped_refptr<IndexedDBCallbacks> callbacks_; | 81 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 82 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_; | 82 scoped_ptr<IndexedDBConnection> connection_; |
| 83 WebKit::WebIDBCallbacks::DataLoss data_loss_; | 83 WebKit::WebIDBCallbacks::DataLoss data_loss_; |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 class CreateObjectStoreAbortOperation : public IndexedDBTransaction::Operation { | 86 class CreateObjectStoreAbortOperation : public IndexedDBTransaction::Operation { |
| 87 public: | 87 public: |
| 88 CreateObjectStoreAbortOperation(scoped_refptr<IndexedDBDatabase> database, | 88 CreateObjectStoreAbortOperation(scoped_refptr<IndexedDBDatabase> database, |
| 89 int64 object_store_id) | 89 int64 object_store_id) |
| 90 : database_(database), object_store_id_(object_store_id) {} | 90 : database_(database), object_store_id_(object_store_id) {} |
| 91 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; | 91 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; |
| 92 | 92 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 callbacks_(callbacks) {} | 361 callbacks_(callbacks) {} |
| 362 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; | 362 virtual void Perform(IndexedDBTransaction* transaction) OVERRIDE; |
| 363 | 363 |
| 364 private: | 364 private: |
| 365 const scoped_refptr<IndexedDBBackingStore> backing_store_; | 365 const scoped_refptr<IndexedDBBackingStore> backing_store_; |
| 366 const int64 database_id_; | 366 const int64 database_id_; |
| 367 const int64 object_store_id_; | 367 const int64 object_store_id_; |
| 368 const scoped_refptr<IndexedDBCallbacks> callbacks_; | 368 const scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 369 }; | 369 }; |
| 370 | 370 |
| 371 // PendingOpenCall has a scoped_refptr<IndexedDBDatabaseCallbacks> because it |
| 372 // isn't a connection yet. |
| 371 class IndexedDBDatabase::PendingOpenCall { | 373 class IndexedDBDatabase::PendingOpenCall { |
| 372 public: | 374 public: |
| 373 PendingOpenCall(scoped_refptr<IndexedDBCallbacks> callbacks, | 375 PendingOpenCall(scoped_refptr<IndexedDBCallbacks> callbacks, |
| 374 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 376 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 375 int64 transaction_id, | 377 int64 transaction_id, |
| 376 int64 version) | 378 int64 version) |
| 377 : callbacks_(callbacks), | 379 : callbacks_(callbacks), |
| 378 database_callbacks_(database_callbacks), | 380 database_callbacks_(database_callbacks), |
| 379 version_(version), | 381 version_(version), |
| 380 transaction_id_(transaction_id) {} | 382 transaction_id_(transaction_id) {} |
| 381 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } | 383 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } |
| 382 scoped_refptr<IndexedDBDatabaseCallbacks> DatabaseCallbacks() { | 384 scoped_refptr<IndexedDBDatabaseCallbacks> DatabaseCallbacks() { |
| 383 return database_callbacks_; | 385 return database_callbacks_; |
| 384 } | 386 } |
| 385 int64 Version() { return version_; } | 387 int64 Version() { return version_; } |
| 386 int64 TransactionId() const { return transaction_id_; } | 388 int64 TransactionId() const { return transaction_id_; } |
| 387 | 389 |
| 388 private: | 390 private: |
| 389 scoped_refptr<IndexedDBCallbacks> callbacks_; | 391 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 390 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_; | 392 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks_; |
| 391 int64 version_; | 393 int64 version_; |
| 392 const int64 transaction_id_; | 394 const int64 transaction_id_; |
| 393 }; | 395 }; |
| 394 | 396 |
| 397 // PendingUpgradeCall has a scoped_ptr<IndexedDBConnection> because it owns the |
| 398 // in-progress connection. |
| 399 class IndexedDBDatabase::PendingUpgradeCall { |
| 400 public: |
| 401 PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, |
| 402 scoped_ptr<IndexedDBConnection> connection, |
| 403 int64 transaction_id, |
| 404 int64 version) |
| 405 : callbacks_(callbacks), |
| 406 connection_(connection.Pass()), |
| 407 version_(version), |
| 408 transaction_id_(transaction_id) {} |
| 409 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } |
| 410 scoped_ptr<IndexedDBConnection> Connection() { return connection_.Pass(); } |
| 411 int64 Version() { return version_; } |
| 412 int64 TransactionId() const { return transaction_id_; } |
| 413 |
| 414 private: |
| 415 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 416 scoped_ptr<IndexedDBConnection> connection_; |
| 417 int64 version_; |
| 418 const int64 transaction_id_; |
| 419 }; |
| 420 |
| 421 // PendingSuccessCall has a IndexedDBConnection* because the connection is now |
| 422 // owned elsewhere, but we need to cancel the success call if that connection |
| 423 // closes before it is sent. |
| 424 class IndexedDBDatabase::PendingSuccessCall { |
| 425 public: |
| 426 PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks, |
| 427 IndexedDBConnection* connection, |
| 428 int64 transaction_id, |
| 429 int64 version) |
| 430 : callbacks_(callbacks), |
| 431 connection_(connection), |
| 432 version_(version), |
| 433 transaction_id_(transaction_id) {} |
| 434 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } |
| 435 IndexedDBConnection* Connection() { return connection_; } |
| 436 int64 Version() { return version_; } |
| 437 int64 TransactionId() const { return transaction_id_; } |
| 438 |
| 439 private: |
| 440 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 441 IndexedDBConnection* connection_; |
| 442 int64 version_; |
| 443 const int64 transaction_id_; |
| 444 }; |
| 445 |
| 395 class IndexedDBDatabase::PendingDeleteCall { | 446 class IndexedDBDatabase::PendingDeleteCall { |
| 396 public: | 447 public: |
| 397 explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) | 448 explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) |
| 398 : callbacks_(callbacks) {} | 449 : callbacks_(callbacks) {} |
| 399 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } | 450 scoped_refptr<IndexedDBCallbacks> Callbacks() { return callbacks_; } |
| 400 | 451 |
| 401 private: | 452 private: |
| 402 scoped_refptr<IndexedDBCallbacks> callbacks_; | 453 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 403 }; | 454 }; |
| 404 | 455 |
| (...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 database_->metadata_.int_version)) { | 1433 database_->metadata_.int_version)) { |
| 1383 IndexedDBDatabaseError error( | 1434 IndexedDBDatabaseError error( |
| 1384 WebKit::WebIDBDatabaseExceptionUnknownError, | 1435 WebKit::WebIDBDatabaseExceptionUnknownError, |
| 1385 ASCIIToUTF16("Internal error writing data to stable storage when " | 1436 ASCIIToUTF16("Internal error writing data to stable storage when " |
| 1386 "updating version.")); | 1437 "updating version.")); |
| 1387 callbacks_->OnError(error); | 1438 callbacks_->OnError(error); |
| 1388 transaction->Abort(error); | 1439 transaction->Abort(error); |
| 1389 return; | 1440 return; |
| 1390 } | 1441 } |
| 1391 DCHECK(!database_->pending_second_half_open_); | 1442 DCHECK(!database_->pending_second_half_open_); |
| 1392 database_->pending_second_half_open_.reset(new PendingOpenCall( | 1443 |
| 1393 callbacks_, database_callbacks_, transaction_id_, version_)); | 1444 database_->pending_second_half_open_.reset(new PendingSuccessCall( |
| 1445 callbacks_, connection_.get(), transaction_id_, version_)); |
| 1394 callbacks_->OnUpgradeNeeded( | 1446 callbacks_->OnUpgradeNeeded( |
| 1395 old_version, database_, database_->metadata(), data_loss_); | 1447 old_version, connection_.Pass(), database_->metadata(), data_loss_); |
| 1396 } | 1448 } |
| 1397 | 1449 |
| 1398 void IndexedDBDatabase::TransactionStarted(IndexedDBTransaction* transaction) { | 1450 void IndexedDBDatabase::TransactionStarted(IndexedDBTransaction* transaction) { |
| 1399 | 1451 |
| 1400 if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { | 1452 if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { |
| 1401 DCHECK(!running_version_change_transaction_); | 1453 DCHECK(!running_version_change_transaction_); |
| 1402 running_version_change_transaction_ = transaction; | 1454 running_version_change_transaction_ = transaction; |
| 1403 } | 1455 } |
| 1404 } | 1456 } |
| 1405 | 1457 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1428 } | 1480 } |
| 1429 } | 1481 } |
| 1430 | 1482 |
| 1431 void IndexedDBDatabase::TransactionFinishedAndCompleteFired( | 1483 void IndexedDBDatabase::TransactionFinishedAndCompleteFired( |
| 1432 IndexedDBTransaction* transaction) { | 1484 IndexedDBTransaction* transaction) { |
| 1433 if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { | 1485 if (transaction->mode() == indexed_db::TRANSACTION_VERSION_CHANGE) { |
| 1434 DCHECK(pending_second_half_open_); | 1486 DCHECK(pending_second_half_open_); |
| 1435 if (pending_second_half_open_) { | 1487 if (pending_second_half_open_) { |
| 1436 DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version); | 1488 DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version); |
| 1437 DCHECK(metadata_.id != kInvalidId); | 1489 DCHECK(metadata_.id != kInvalidId); |
| 1438 pending_second_half_open_->Callbacks()->OnSuccess(this, this->metadata()); | 1490 |
| 1491 // Connection was already minted for OnUpgradeNeeded callback. |
| 1492 scoped_ptr<IndexedDBConnection> connection; |
| 1493 |
| 1494 pending_second_half_open_->Callbacks()->OnSuccess( |
| 1495 connection.Pass(), this->metadata()); |
| 1439 pending_second_half_open_.reset(); | 1496 pending_second_half_open_.reset(); |
| 1440 } | 1497 } |
| 1441 ProcessPendingCalls(); | 1498 ProcessPendingCalls(); |
| 1442 } | 1499 } |
| 1443 } | 1500 } |
| 1444 | 1501 |
| 1445 size_t IndexedDBDatabase::ConnectionCount() const { | 1502 size_t IndexedDBDatabase::ConnectionCount() const { |
| 1446 // This does not include pending open calls, as those should not block version | 1503 // This does not include pending open calls, as those should not block version |
| 1447 // changes and deletes. | 1504 // changes and deletes. |
| 1448 return database_callbacks_set_.size(); | 1505 return connections_.size(); |
| 1449 } | 1506 } |
| 1450 | 1507 |
| 1451 void IndexedDBDatabase::ProcessPendingCalls() { | 1508 void IndexedDBDatabase::ProcessPendingCalls() { |
| 1452 if (pending_second_half_open_) { | |
| 1453 DCHECK_EQ(pending_second_half_open_->Version(), metadata_.int_version); | |
| 1454 DCHECK(metadata_.id != kInvalidId); | |
| 1455 scoped_ptr<PendingOpenCall> pending_call = pending_second_half_open_.Pass(); | |
| 1456 pending_call->Callbacks()->OnSuccess(this, this->metadata()); | |
| 1457 // Fall through when complete, as pending opens may be unblocked. | |
| 1458 } | |
| 1459 | |
| 1460 if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { | 1509 if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { |
| 1461 DCHECK(pending_run_version_change_transaction_call_->Version() > | 1510 DCHECK(pending_run_version_change_transaction_call_->Version() > |
| 1462 metadata_.int_version); | 1511 metadata_.int_version); |
| 1463 scoped_ptr<PendingOpenCall> pending_call = | 1512 scoped_ptr<PendingUpgradeCall> pending_call = |
| 1464 pending_run_version_change_transaction_call_.Pass(); | 1513 pending_run_version_change_transaction_call_.Pass(); |
| 1465 RunVersionChangeTransactionFinal(pending_call->Callbacks(), | 1514 RunVersionChangeTransactionFinal(pending_call->Callbacks(), |
| 1466 pending_call->DatabaseCallbacks(), | 1515 pending_call->Connection(), |
| 1467 pending_call->TransactionId(), | 1516 pending_call->TransactionId(), |
| 1468 pending_call->Version()); | 1517 pending_call->Version()); |
| 1469 DCHECK_EQ(static_cast<size_t>(1), ConnectionCount()); | 1518 DCHECK_EQ(static_cast<size_t>(1), ConnectionCount()); |
| 1470 // Fall through would be a no-op, since transaction must complete | 1519 // Fall through would be a no-op, since transaction must complete |
| 1471 // asynchronously. | 1520 // asynchronously. |
| 1472 DCHECK(IsDeleteDatabaseBlocked()); | 1521 DCHECK(IsDeleteDatabaseBlocked()); |
| 1473 DCHECK(IsOpenConnectionBlocked()); | 1522 DCHECK(IsOpenConnectionBlocked()); |
| 1474 return; | 1523 return; |
| 1475 } | 1524 } |
| 1476 | 1525 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1499 OpenConnection(pending_open_call->Callbacks(), | 1548 OpenConnection(pending_open_call->Callbacks(), |
| 1500 pending_open_call->DatabaseCallbacks(), | 1549 pending_open_call->DatabaseCallbacks(), |
| 1501 pending_open_call->TransactionId(), | 1550 pending_open_call->TransactionId(), |
| 1502 pending_open_call->Version()); | 1551 pending_open_call->Version()); |
| 1503 } | 1552 } |
| 1504 } | 1553 } |
| 1505 } | 1554 } |
| 1506 | 1555 |
| 1507 void IndexedDBDatabase::CreateTransaction( | 1556 void IndexedDBDatabase::CreateTransaction( |
| 1508 int64 transaction_id, | 1557 int64 transaction_id, |
| 1509 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, | 1558 IndexedDBConnection* connection, |
| 1510 const std::vector<int64>& object_store_ids, | 1559 const std::vector<int64>& object_store_ids, |
| 1511 uint16 mode) { | 1560 uint16 mode) { |
| 1512 | 1561 |
| 1513 DCHECK(database_callbacks_set_.has(callbacks)); | 1562 DCHECK(connections_.has(connection)); |
| 1514 | 1563 |
| 1515 scoped_refptr<IndexedDBTransaction> transaction = | 1564 scoped_refptr<IndexedDBTransaction> transaction = |
| 1516 IndexedDBTransaction::Create( | 1565 IndexedDBTransaction::Create( |
| 1517 transaction_id, | 1566 transaction_id, |
| 1518 callbacks, | 1567 connection->callbacks(), |
| 1519 object_store_ids, | 1568 object_store_ids, |
| 1520 static_cast<indexed_db::TransactionMode>(mode), | 1569 static_cast<indexed_db::TransactionMode>(mode), |
| 1521 this); | 1570 this); |
| 1522 DCHECK(transactions_.find(transaction_id) == transactions_.end()); | 1571 DCHECK(transactions_.find(transaction_id) == transactions_.end()); |
| 1523 transactions_[transaction_id] = transaction.get(); | 1572 transactions_[transaction_id] = transaction.get(); |
| 1524 } | 1573 } |
| 1525 | 1574 |
| 1526 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1575 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
| 1527 return !pending_delete_calls_.empty() || | 1576 return !pending_delete_calls_.empty() || |
| 1528 running_version_change_transaction_ || | 1577 running_version_change_transaction_ || |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1557 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); | 1606 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); |
| 1558 pending_open_calls_.push_back(new PendingOpenCall( | 1607 pending_open_calls_.push_back(new PendingOpenCall( |
| 1559 callbacks, database_callbacks, transaction_id, version)); | 1608 callbacks, database_callbacks, transaction_id, version)); |
| 1560 return; | 1609 return; |
| 1561 } | 1610 } |
| 1562 | 1611 |
| 1563 if (metadata_.id == kInvalidId) { | 1612 if (metadata_.id == kInvalidId) { |
| 1564 // The database was deleted then immediately re-opened; OpenInternal() | 1613 // The database was deleted then immediately re-opened; OpenInternal() |
| 1565 // recreates it in the backing store. | 1614 // recreates it in the backing store. |
| 1566 if (OpenInternal()) { | 1615 if (OpenInternal()) { |
| 1567 DCHECK_EQ(metadata_.int_version, | 1616 DCHECK_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, |
| 1568 IndexedDBDatabaseMetadata::NO_INT_VERSION); | 1617 metadata_.int_version); |
| 1569 } else { | 1618 } else { |
| 1570 string16 message; | 1619 string16 message; |
| 1571 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) | 1620 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) |
| 1572 message = ASCIIToUTF16( | 1621 message = ASCIIToUTF16( |
| 1573 "Internal error opening database with no version specified."); | 1622 "Internal error opening database with no version specified."); |
| 1574 else | 1623 else |
| 1575 message = | 1624 message = |
| 1576 ASCIIToUTF16("Internal error opening database with version ") + | 1625 ASCIIToUTF16("Internal error opening database with version ") + |
| 1577 Int64ToString16(version); | 1626 Int64ToString16(version); |
| 1578 callbacks->OnError(IndexedDBDatabaseError( | 1627 callbacks->OnError(IndexedDBDatabaseError( |
| 1579 WebKit::WebIDBDatabaseExceptionUnknownError, message)); | 1628 WebKit::WebIDBDatabaseExceptionUnknownError, message)); |
| 1580 return; | 1629 return; |
| 1581 } | 1630 } |
| 1582 } | 1631 } |
| 1583 | 1632 |
| 1584 // We infer that the database didn't exist from its lack of either type of | 1633 // We infer that the database didn't exist from its lack of either type of |
| 1585 // version. | 1634 // version. |
| 1586 bool is_new_database = | 1635 bool is_new_database = |
| 1587 metadata_.version == kNoStringVersion && | 1636 metadata_.version == kNoStringVersion && |
| 1588 metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; | 1637 metadata_.int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION; |
| 1589 | 1638 |
| 1639 scoped_ptr<IndexedDBConnection> connection( |
| 1640 new IndexedDBConnection(this, database_callbacks)); |
| 1641 |
| 1590 if (version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { | 1642 if (version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) { |
| 1591 // For unit tests only - skip upgrade steps. Calling from script with | 1643 // For unit tests only - skip upgrade steps. Calling from script with |
| 1592 // DEFAULT_INT_VERSION throws exception. | 1644 // DEFAULT_INT_VERSION throws exception. |
| 1593 // TODO(jsbell): DCHECK that not in unit tests. | 1645 // TODO(jsbell): DCHECK that not in unit tests. |
| 1594 DCHECK(is_new_database); | 1646 DCHECK(is_new_database); |
| 1595 database_callbacks_set_.insert(database_callbacks); | 1647 connections_.insert(connection.get()); |
| 1596 callbacks->OnSuccess(this, this->metadata()); | 1648 callbacks->OnSuccess(connection.Pass(), this->metadata()); |
| 1597 return; | 1649 return; |
| 1598 } | 1650 } |
| 1599 | 1651 |
| 1600 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { | 1652 if (version == IndexedDBDatabaseMetadata::NO_INT_VERSION) { |
| 1601 if (!is_new_database) { | 1653 if (!is_new_database) { |
| 1602 database_callbacks_set_.insert(database_callbacks); | 1654 connections_.insert(connection.get()); |
| 1603 callbacks->OnSuccess(this, this->metadata()); | 1655 callbacks->OnSuccess(connection.Pass(), this->metadata()); |
| 1604 return; | 1656 return; |
| 1605 } | 1657 } |
| 1606 // Spec says: If no version is specified and no database exists, set | 1658 // Spec says: If no version is specified and no database exists, set |
| 1607 // database version to 1. | 1659 // database version to 1. |
| 1608 version = 1; | 1660 version = 1; |
| 1609 } | 1661 } |
| 1610 | 1662 |
| 1611 if (version > metadata_.int_version) { | 1663 if (version > metadata_.int_version) { |
| 1612 database_callbacks_set_.insert(database_callbacks); | 1664 connections_.insert(connection.get()); |
| 1613 RunVersionChangeTransaction( | 1665 RunVersionChangeTransaction( |
| 1614 callbacks, database_callbacks, transaction_id, version, data_loss); | 1666 callbacks, connection.Pass(), transaction_id, version, data_loss); |
| 1615 return; | 1667 return; |
| 1616 } | 1668 } |
| 1617 if (version < metadata_.int_version) { | 1669 if (version < metadata_.int_version) { |
| 1618 callbacks->OnError(IndexedDBDatabaseError( | 1670 callbacks->OnError(IndexedDBDatabaseError( |
| 1619 WebKit::WebIDBDatabaseExceptionVersionError, | 1671 WebKit::WebIDBDatabaseExceptionVersionError, |
| 1620 ASCIIToUTF16("The requested version (") + Int64ToString16(version) + | 1672 ASCIIToUTF16("The requested version (") + Int64ToString16(version) + |
| 1621 ASCIIToUTF16(") is less than the existing version (") + | 1673 ASCIIToUTF16(") is less than the existing version (") + |
| 1622 Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); | 1674 Int64ToString16(metadata_.int_version) + ASCIIToUTF16(")."))); |
| 1623 return; | 1675 return; |
| 1624 } | 1676 } |
| 1625 DCHECK_EQ(version, metadata_.int_version); | 1677 DCHECK_EQ(version, metadata_.int_version); |
| 1626 database_callbacks_set_.insert(database_callbacks); | 1678 connections_.insert(connection.get()); |
| 1627 callbacks->OnSuccess(this, this->metadata()); | 1679 callbacks->OnSuccess(connection.Pass(), this->metadata()); |
| 1628 } | 1680 } |
| 1629 | 1681 |
| 1630 void IndexedDBDatabase::RunVersionChangeTransaction( | 1682 void IndexedDBDatabase::RunVersionChangeTransaction( |
| 1631 scoped_refptr<IndexedDBCallbacks> callbacks, | 1683 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1632 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 1684 scoped_ptr<IndexedDBConnection> connection, |
| 1633 int64 transaction_id, | 1685 int64 transaction_id, |
| 1634 int64 requested_version, | 1686 int64 requested_version, |
| 1635 WebKit::WebIDBCallbacks::DataLoss data_loss) { | 1687 WebKit::WebIDBCallbacks::DataLoss data_loss) { |
| 1636 | 1688 |
| 1637 DCHECK(callbacks.get()); | 1689 DCHECK(callbacks.get()); |
| 1638 DCHECK(database_callbacks_set_.has(database_callbacks)); | 1690 DCHECK(connections_.has(connection.get())); |
| 1639 if (ConnectionCount() > 1) { | 1691 if (ConnectionCount() > 1) { |
| 1640 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); | 1692 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); |
| 1641 // Front end ensures the event is not fired at connections that have | 1693 // Front end ensures the event is not fired at connections that have |
| 1642 // close_pending set. | 1694 // close_pending set. |
| 1643 for (DatabaseCallbacksSet::const_iterator it = | 1695 for (ConnectionSet::const_iterator it = connections_.begin(); |
| 1644 database_callbacks_set_.begin(); | 1696 it != connections_.end(); |
| 1645 it != database_callbacks_set_.end(); | |
| 1646 ++it) { | 1697 ++it) { |
| 1647 if (it->get() != database_callbacks.get()) | 1698 if (*it != connection.get()) { |
| 1648 (*it)->OnVersionChange(metadata_.int_version, requested_version); | 1699 (*it)->callbacks()->OnVersionChange( |
| 1700 metadata_.int_version, requested_version); |
| 1701 } |
| 1649 } | 1702 } |
| 1650 // TODO(jsbell): Remove the call to OnBlocked and instead wait | 1703 // TODO(jsbell): Remove the call to OnBlocked and instead wait |
| 1651 // until the frontend tells us that all the "versionchange" events | 1704 // until the frontend tells us that all the "versionchange" events |
| 1652 // have been delivered. http://crbug.com/100123 | 1705 // have been delivered. http://crbug.com/100123 |
| 1653 callbacks->OnBlocked(metadata_.int_version); | 1706 callbacks->OnBlocked(metadata_.int_version); |
| 1654 | 1707 |
| 1655 DCHECK(!pending_run_version_change_transaction_call_); | 1708 DCHECK(!pending_run_version_change_transaction_call_); |
| 1656 pending_run_version_change_transaction_call_.reset(new PendingOpenCall( | 1709 pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall( |
| 1657 callbacks, database_callbacks, transaction_id, requested_version)); | 1710 callbacks, connection.Pass(), transaction_id, requested_version)); |
| 1658 return; | 1711 return; |
| 1659 } | 1712 } |
| 1660 RunVersionChangeTransactionFinal(callbacks, | 1713 RunVersionChangeTransactionFinal(callbacks, |
| 1661 database_callbacks, | 1714 connection.Pass(), |
| 1662 transaction_id, | 1715 transaction_id, |
| 1663 requested_version, | 1716 requested_version, |
| 1664 data_loss); | 1717 data_loss); |
| 1665 } | 1718 } |
| 1666 | 1719 |
| 1667 void IndexedDBDatabase::RunVersionChangeTransactionFinal( | 1720 void IndexedDBDatabase::RunVersionChangeTransactionFinal( |
| 1668 scoped_refptr<IndexedDBCallbacks> callbacks, | 1721 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1669 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 1722 scoped_ptr<IndexedDBConnection> connection, |
| 1670 int64 transaction_id, | 1723 int64 transaction_id, |
| 1671 int64 requested_version) { | 1724 int64 requested_version) { |
| 1672 const WebKit::WebIDBCallbacks::DataLoss kDataLoss = | 1725 const WebKit::WebIDBCallbacks::DataLoss kDataLoss = |
| 1673 WebKit::WebIDBCallbacks::DataLossNone; | 1726 WebKit::WebIDBCallbacks::DataLossNone; |
| 1674 RunVersionChangeTransactionFinal(callbacks, | 1727 RunVersionChangeTransactionFinal(callbacks, |
| 1675 database_callbacks, | 1728 connection.Pass(), |
| 1676 transaction_id, | 1729 transaction_id, |
| 1677 requested_version, | 1730 requested_version, |
| 1678 kDataLoss); | 1731 kDataLoss); |
| 1679 } | 1732 } |
| 1680 | 1733 |
| 1681 void IndexedDBDatabase::RunVersionChangeTransactionFinal( | 1734 void IndexedDBDatabase::RunVersionChangeTransactionFinal( |
| 1682 scoped_refptr<IndexedDBCallbacks> callbacks, | 1735 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1683 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 1736 scoped_ptr<IndexedDBConnection> connection, |
| 1684 int64 transaction_id, | 1737 int64 transaction_id, |
| 1685 int64 requested_version, | 1738 int64 requested_version, |
| 1686 WebKit::WebIDBCallbacks::DataLoss data_loss) { | 1739 WebKit::WebIDBCallbacks::DataLoss data_loss) { |
| 1687 | 1740 |
| 1688 std::vector<int64> object_store_ids; | 1741 std::vector<int64> object_store_ids; |
| 1689 CreateTransaction(transaction_id, | 1742 CreateTransaction(transaction_id, |
| 1690 database_callbacks, | 1743 connection.get(), |
| 1691 object_store_ids, | 1744 object_store_ids, |
| 1692 indexed_db::TRANSACTION_VERSION_CHANGE); | 1745 indexed_db::TRANSACTION_VERSION_CHANGE); |
| 1693 scoped_refptr<IndexedDBTransaction> transaction = | 1746 scoped_refptr<IndexedDBTransaction> transaction = |
| 1694 transactions_[transaction_id]; | 1747 transactions_[transaction_id]; |
| 1695 | 1748 |
| 1696 transaction->ScheduleTask( | 1749 transaction->ScheduleTask( |
| 1697 new VersionChangeOperation(this, | 1750 new VersionChangeOperation(this, |
| 1698 transaction_id, | 1751 transaction_id, |
| 1699 requested_version, | 1752 requested_version, |
| 1700 callbacks, | 1753 callbacks, |
| 1701 database_callbacks, | 1754 connection.Pass(), |
| 1702 data_loss), | 1755 data_loss), |
| 1703 new VersionChangeAbortOperation( | 1756 new VersionChangeAbortOperation( |
| 1704 this, metadata_.version, metadata_.int_version)); | 1757 this, metadata_.version, metadata_.int_version)); |
| 1705 | 1758 |
| 1706 DCHECK(!pending_second_half_open_); | 1759 DCHECK(!pending_second_half_open_); |
| 1707 } | 1760 } |
| 1708 | 1761 |
| 1709 void IndexedDBDatabase::DeleteDatabase( | 1762 void IndexedDBDatabase::DeleteDatabase( |
| 1710 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1763 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1711 | 1764 |
| 1712 if (IsDeleteDatabaseBlocked()) { | 1765 if (IsDeleteDatabaseBlocked()) { |
| 1713 for (DatabaseCallbacksSet::const_iterator it = | 1766 for (ConnectionSet::const_iterator it = connections_.begin(); |
| 1714 database_callbacks_set_.begin(); | 1767 it != connections_.end(); |
| 1715 it != database_callbacks_set_.end(); | |
| 1716 ++it) { | 1768 ++it) { |
| 1717 // Front end ensures the event is not fired at connections that have | 1769 // Front end ensures the event is not fired at connections that have |
| 1718 // close_pending set. | 1770 // close_pending set. |
| 1719 (*it)->OnVersionChange(metadata_.int_version, | 1771 (*it)->callbacks()->OnVersionChange( |
| 1720 IndexedDBDatabaseMetadata::NO_INT_VERSION); | 1772 metadata_.int_version, IndexedDBDatabaseMetadata::NO_INT_VERSION); |
| 1721 } | 1773 } |
| 1722 // TODO(jsbell): Only fire OnBlocked if there are open | 1774 // TODO(jsbell): Only fire OnBlocked if there are open |
| 1723 // connections after the VersionChangeEvents are received, not | 1775 // connections after the VersionChangeEvents are received, not |
| 1724 // just set up to fire. http://crbug.com/100123 | 1776 // just set up to fire. http://crbug.com/100123 |
| 1725 callbacks->OnBlocked(metadata_.int_version); | 1777 callbacks->OnBlocked(metadata_.int_version); |
| 1726 pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); | 1778 pending_delete_calls_.push_back(new PendingDeleteCall(callbacks)); |
| 1727 return; | 1779 return; |
| 1728 } | 1780 } |
| 1729 DeleteDatabaseFinal(callbacks); | 1781 DeleteDatabaseFinal(callbacks); |
| 1730 } | 1782 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1743 "Internal error deleting database.")); | 1795 "Internal error deleting database.")); |
| 1744 return; | 1796 return; |
| 1745 } | 1797 } |
| 1746 metadata_.version = kNoStringVersion; | 1798 metadata_.version = kNoStringVersion; |
| 1747 metadata_.id = kInvalidId; | 1799 metadata_.id = kInvalidId; |
| 1748 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; | 1800 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; |
| 1749 metadata_.object_stores.clear(); | 1801 metadata_.object_stores.clear(); |
| 1750 callbacks->OnSuccess(); | 1802 callbacks->OnSuccess(); |
| 1751 } | 1803 } |
| 1752 | 1804 |
| 1753 void IndexedDBDatabase::Close( | 1805 void IndexedDBDatabase::Close(IndexedDBConnection* connection) { |
| 1754 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks) { | 1806 DCHECK(connections_.has(connection)); |
| 1755 DCHECK(callbacks.get()); | |
| 1756 DCHECK(database_callbacks_set_.has(callbacks)); | |
| 1757 | 1807 |
| 1758 // Close outstanding transactions from the closing connection. This | 1808 // Close outstanding transactions from the closing connection. This |
| 1759 // can not happen if the close is requested by the connection itself | 1809 // can not happen if the close is requested by the connection itself |
| 1760 // as the front-end defers the close until all transactions are | 1810 // as the front-end defers the close until all transactions are |
| 1761 // complete, so something unusual has happened e.g. unexpected | 1811 // complete, so something unusual has happened e.g. unexpected |
| 1762 // process termination. | 1812 // process termination. |
| 1763 { | 1813 { |
| 1764 TransactionMap transactions(transactions_); | 1814 TransactionMap transactions(transactions_); |
| 1765 for (TransactionMap::const_iterator it = transactions.begin(), | 1815 for (TransactionMap::const_iterator it = transactions.begin(), |
| 1766 end = transactions.end(); | 1816 end = transactions.end(); |
| 1767 it != end; | 1817 it != end; |
| 1768 ++it) { | 1818 ++it) { |
| 1769 if (it->second->connection() == callbacks.get()) | 1819 if (it->second->connection() == connection->callbacks()) |
| 1770 it->second->Abort( | 1820 it->second->Abort( |
| 1771 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, | 1821 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, |
| 1772 "Connection is closing.")); | 1822 "Connection is closing.")); |
| 1773 } | 1823 } |
| 1774 } | 1824 } |
| 1775 | 1825 |
| 1776 database_callbacks_set_.erase(callbacks); | 1826 connections_.erase(connection); |
| 1777 if (pending_second_half_open_ && | 1827 if (pending_second_half_open_ && |
| 1778 pending_second_half_open_->DatabaseCallbacks().get() == callbacks.get()) { | 1828 pending_second_half_open_->Connection() == connection) { |
| 1779 pending_second_half_open_->Callbacks()->OnError( | 1829 pending_second_half_open_->Callbacks()->OnError( |
| 1780 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, | 1830 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, |
| 1781 "The connection was closed.")); | 1831 "The connection was closed.")); |
| 1782 pending_second_half_open_.reset(); | 1832 pending_second_half_open_.reset(); |
| 1783 } | 1833 } |
| 1784 | 1834 |
| 1785 // process_pending_calls allows the inspector to process a pending open call | 1835 // process_pending_calls allows the inspector to process a pending open call |
| 1786 // and call close, reentering IndexedDBDatabase::close. Then the | 1836 // and call close, reentering IndexedDBDatabase::close. Then the |
| 1787 // backend would be removed both by the inspector closing its connection, and | 1837 // backend would be removed both by the inspector closing its connection, and |
| 1788 // by the connection that first called close. | 1838 // by the connection that first called close. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 | 1873 |
| 1824 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( | 1874 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( |
| 1825 IndexedDBTransaction* transaction) { | 1875 IndexedDBTransaction* transaction) { |
| 1826 IDB_TRACE("VersionChangeAbortOperation"); | 1876 IDB_TRACE("VersionChangeAbortOperation"); |
| 1827 DCHECK(!transaction); | 1877 DCHECK(!transaction); |
| 1828 database_->metadata_.version = previous_version_; | 1878 database_->metadata_.version = previous_version_; |
| 1829 database_->metadata_.int_version = previous_int_version_; | 1879 database_->metadata_.int_version = previous_int_version_; |
| 1830 } | 1880 } |
| 1831 | 1881 |
| 1832 } // namespace content | 1882 } // namespace content |
| OLD | NEW |