#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
+#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
#include "content/common/indexed_db/indexed_db_key.h"
// TODO(ericu): Move this down into the member section of this file. I'm
// leaving it here for this CL as it's easier to see the diffs in place.
-WARN_UNUSED_RESULT bool IndexedDBBackingStore::SetUpMetadata() {
+WARN_UNUSED_RESULT leveldb::Status IndexedDBBackingStore::SetUpMetadata() {
const uint32 latest_known_data_version =
blink::kSerializedScriptValueVersion;
const std::string schema_version_key = SchemaVersionKey::Encode();
GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
if (!s.ok()) {
INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return s;
}
if (!found) {
// Initialize new backing store.
// leftover from a partially-purged previous generation of data.
if (!base::DeleteFile(blob_path_, true)) {
INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return IOErrorStatus();
}
} else {
// Upgrade old backing store.
s = GetInt(transaction.get(), it->Key(), &database_id, &found);
if (!s.ok()) {
INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return s;
}
if (!found) {
INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return InternalInconsistencyStatus();
}
std::string int_version_key = DatabaseMetaDataKey::Encode(
database_id, DatabaseMetaDataKey::USER_INT_VERSION);
db_schema_version = 3;
if (!base::DeleteFile(blob_path_, true)) {
INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return IOErrorStatus();
}
}
}
if (!s.ok()) {
INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return s;
}
// All new values will be written using this serialization version.
s = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
if (!s.ok()) {
INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return s;
}
if (!found) {
INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
+ return InternalInconsistencyStatus();
}
if (db_data_version < latest_known_data_version) {
db_data_version = latest_known_data_version;
DCHECK_EQ(db_data_version, latest_known_data_version);
s = transaction->Commit();
- if (!s.ok()) {
+ if (!s.ok())
INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
- return false;
- }
- return true;
+ return s;
}
template <typename DBOrTransaction>
bool found = false;
leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found);
if (!s.ok()) {
- INTERNAL_READ_ERROR_UNTESTED(READ_BLOB_JOURNAL);
+ INTERNAL_READ_ERROR(READ_BLOB_JOURNAL);
return s;
}
journal->clear();
return leveldb::Status::OK();
StringPiece slice(data);
if (!DecodeBlobJournal(&slice, journal)) {
- INTERNAL_READ_ERROR_UNTESTED(DECODE_BLOB_JOURNAL);
+ INTERNAL_CONSISTENCY_ERROR_UNTESTED(DECODE_BLOB_JOURNAL);
s = InternalInconsistencyStatus();
}
return s;
net::URLRequestContext* request_context,
scoped_ptr<LevelDBDatabase> db,
scoped_ptr<LevelDBComparator> comparator,
- base::TaskRunner* task_runner)
+ base::SequencedTaskRunner* task_runner)
: indexed_db_factory_(indexed_db_factory),
origin_url_(origin_url),
blob_path_(blob_path),
blink::WebIDBDataLoss* data_loss,
std::string* data_loss_message,
bool* disk_full,
- base::TaskRunner* task_runner,
- bool clean_journal) {
+ base::SequencedTaskRunner* task_runner,
+ bool clean_journal,
+ leveldb::Status* status) {
*data_loss = blink::WebIDBDataLossNone;
DefaultLevelDBFactory leveldb_factory;
return IndexedDBBackingStore::Open(indexed_db_factory,
disk_full,
&leveldb_factory,
task_runner,
- clean_journal);
+ clean_journal,
+ status);
}
static std::string OriginToCustomHistogramSuffix(const GURL& origin_url) {
bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base,
const GURL& origin_url,
- std::string& message) {
+ std::string* message) {
const base::FilePath info_path =
path_base.Append(ComputeCorruptionFileName(origin_url));
if (val && val->GetType() == base::Value::TYPE_DICTIONARY) {
base::DictionaryValue* dict_val =
static_cast<base::DictionaryValue*>(val.get());
- success = dict_val->GetString("message", &message);
+ success = dict_val->GetString("message", message);
}
}
file.Close();
std::string* data_loss_message,
bool* is_disk_full,
LevelDBFactory* leveldb_factory,
- base::TaskRunner* task_runner,
- bool clean_journal) {
+ base::SequencedTaskRunner* task_runner,
+ bool clean_journal,
+ leveldb::Status* status) {
IDB_TRACE("IndexedDBBackingStore::Open");
DCHECK(!path_base.empty());
*data_loss = blink::WebIDBDataLossNone;
*data_loss_message = "";
*is_disk_full = false;
+ *status = leveldb::Status::OK();
+
scoped_ptr<LevelDBComparator> comparator(new Comparator());
if (!base::IsStringASCII(path_base.AsUTF8Unsafe())) {
origin_url);
}
if (!base::CreateDirectory(path_base)) {
- LOG(ERROR) << "Unable to create IndexedDB database path "
- << path_base.AsUTF8Unsafe();
+ *status =
+ leveldb::Status::IOError("Unable to create IndexedDB database path");
+ LOG(ERROR) << status->ToString() << ": \"" << path_base.AsUTF8Unsafe()
+ << "\"";
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY,
origin_url);
return scoped_refptr<IndexedDBBackingStore>();
path_base.Append(ComputeBlobPath(origin_url));
if (IsPathTooLong(file_path)) {
+ *status = leveldb::Status::IOError("File path too long");
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG,
origin_url);
return scoped_refptr<IndexedDBBackingStore>();
}
scoped_ptr<LevelDBDatabase> db;
- leveldb::Status status = leveldb_factory->OpenLevelDB(
+ *status = leveldb_factory->OpenLevelDB(
file_path, comparator.get(), &db, is_disk_full);
- DCHECK(!db == !status.ok());
- if (!status.ok()) {
- if (leveldb_env::IndicatesDiskFull(status)) {
+ DCHECK(!db == !status->ok());
+ if (!status->ok()) {
+ if (leveldb_env::IndicatesDiskFull(*status)) {
*is_disk_full = true;
- } else if (leveldb_env::IsCorruption(status)) {
+ } else if (leveldb_env::IsCorruption(*status)) {
*data_loss = blink::WebIDBDataLossTotal;
- *data_loss_message = leveldb_env::GetCorruptionMessage(status);
+ *data_loss_message = leveldb_env::GetCorruptionMessage(*status);
}
}
bool is_schema_known = false;
if (db) {
std::string corruption_message;
- if (ReadCorruptionInfo(path_base, origin_url, corruption_message)) {
+ if (ReadCorruptionInfo(path_base, origin_url, &corruption_message)) {
LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) "
"database.";
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
}
}
- DCHECK(status.ok() || !is_schema_known || leveldb_env::IsIOError(status) ||
- leveldb_env::IsCorruption(status));
+ DCHECK(status->ok() || !is_schema_known || leveldb_env::IsIOError(*status) ||
+ leveldb_env::IsCorruption(*status));
if (db) {
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin_url);
- } else if (leveldb_env::IsIOError(status)) {
+ } else if (leveldb_env::IsIOError(*status)) {
LOG(ERROR) << "Unable to open backing store, not trying to recover - "
- << status.ToString();
+ << status->ToString();
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, origin_url);
return scoped_refptr<IndexedDBBackingStore>();
} else {
- DCHECK(!is_schema_known || leveldb_env::IsCorruption(status));
+ DCHECK(!is_schema_known || leveldb_env::IsCorruption(*status));
LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup";
- status = leveldb_factory->DestroyLevelDB(file_path);
- if (!status.ok()) {
+ *status = leveldb_factory->DestroyLevelDB(file_path);
+ if (!status->ok()) {
LOG(ERROR) << "IndexedDB backing store cleanup failed";
HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED,
origin_url);
request_context,
db.Pass(),
comparator.Pass(),
- task_runner);
+ task_runner,
+ status);
if (clean_journal && backing_store &&
!backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()).ok()) {
// static
scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
const GURL& origin_url,
- base::TaskRunner* task_runner) {
+ base::SequencedTaskRunner* task_runner,
+ leveldb::Status* status) {
DefaultLevelDBFactory leveldb_factory;
return IndexedDBBackingStore::OpenInMemory(
- origin_url, &leveldb_factory, task_runner);
+ origin_url, &leveldb_factory, task_runner, status);
}
// static
scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
const GURL& origin_url,
LevelDBFactory* leveldb_factory,
- base::TaskRunner* task_runner) {
+ base::SequencedTaskRunner* task_runner,
+ leveldb::Status* status) {
IDB_TRACE("IndexedDBBackingStore::OpenInMemory");
scoped_ptr<LevelDBComparator> comparator(new Comparator());
NULL /* request_context */,
db.Pass(),
comparator.Pass(),
- task_runner);
+ task_runner,
+ status);
}
// static
net::URLRequestContext* request_context,
scoped_ptr<LevelDBDatabase> db,
scoped_ptr<LevelDBComparator> comparator,
- base::TaskRunner* task_runner) {
+ base::SequencedTaskRunner* task_runner,
+ leveldb::Status* status) {
// TODO(jsbell): Handle comparator name changes.
scoped_refptr<IndexedDBBackingStore> backing_store(
new IndexedDBBackingStore(indexed_db_factory,
db.Pass(),
comparator.Pass(),
task_runner));
- if (!backing_store->SetUpMetadata())
+ *status = backing_store->SetUpMetadata();
+ if (!status->ok())
return scoped_refptr<IndexedDBBackingStore>();
return backing_store;
for (*s = it->Seek(start_key);
s->ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
*s = it->Next()) {
+ // Decode database name (in iterator key).
StringPiece slice(it->Key());
DatabaseNameKey database_name_key;
if (!DatabaseNameKey::Decode(&slice, &database_name_key) ||
INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
continue;
}
- found_names.push_back(database_name_key.database_name());
+
+ // Decode database id (in iterator value).
+ int64 database_id = 0;
+ StringPiece valueSlice(it->Value());
+ if (!DecodeVarInt(&valueSlice, &database_id) || !valueSlice.empty()) {
+ INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
+ continue;
+ }
+
+ // Look up version by id.
+ bool found = false;
+ int64 database_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
+ *s = GetVarInt(db_.get(),
+ DatabaseMetaDataKey::Encode(
+ database_id, DatabaseMetaDataKey::USER_INT_VERSION),
+ &database_version,
+ &found);
+ if (!s->ok() || !found) {
+ INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES);
+ continue;
+ }
+
+ // Ignore stale metadata from failed initial opens.
+ if (database_version != IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)
+ found_names.push_back(database_name_key.database_name());
}
if (!s->ok())
- INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES);
+ INTERNAL_READ_ERROR(GET_DATABASE_NAMES);
return found_names;
}
const base::string16& version,
int64 int_version,
int64* row_id) {
+ // TODO(jsbell): Don't persist metadata if open fails. http://crbug.com/395472
scoped_refptr<LevelDBTransaction> transaction =
IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
- IndexedDBValue& value,
+ IndexedDBValue* value,
ScopedVector<webkit_blob::BlobDataHandle>* handles,
RecordIdentifier* record_identifier) {
IDB_TRACE("IndexedDBBackingStore::PutRecord");
std::string v;
EncodeVarInt(version, &v);
- v.append(value.bits);
+ v.append(value->bits);
leveldb_transaction->Put(object_store_data_key, &v);
s = transaction->PutBlobInfoIfNeeded(database_id,
object_store_id,
object_store_data_key,
- &value.blob_info,
+ &value->blob_info,
handles);
if (!s.ok())
return s;
database_id,
object_store_id,
key_range,
- indexed_db::CURSOR_NEXT,
+ blink::WebIDBCursorDirectionNext,
&s);
if (!s.ok())
return s;
database_id,
object_store_id,
key_range,
- indexed_db::CURSOR_PREV,
+ blink::WebIDBCursorDirectionPrev,
&s);
if (!s.ok())
ChainedBlobWriterImpl(
int64 database_id,
IndexedDBBackingStore* backing_store,
- WriteDescriptorVec& blobs,
+ WriteDescriptorVec* blobs,
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback)
: waiting_for_callback_(false),
database_id_(database_id),
backing_store_(backing_store),
callback_(callback),
aborted_(false) {
- blobs_.swap(blobs);
+ blobs_.swap(*blobs);
iter_ = blobs_.begin();
backing_store->task_runner()->PostTask(
FROM_HERE, base::Bind(&ChainedBlobWriterImpl::WriteNextFile, this));
};
class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
- public base::RefCounted<LocalWriteClosure> {
+ public base::RefCountedThreadSafe<LocalWriteClosure> {
public:
LocalWriteClosure(IndexedDBBackingStore::Transaction::ChainedBlobWriter*
chained_blob_writer,
- base::TaskRunner* task_runner)
+ base::SequencedTaskRunner* task_runner)
: chained_blob_writer_(chained_blob_writer),
task_runner_(task_runner),
bytes_written_(0) {}
}
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&LocalWriteClosure::callBlobCallbackOnIDBTaskRunner,
- this,
- write_status == FileWriterDelegate::SUCCESS_COMPLETED));
+ base::Bind(&IndexedDBBackingStore::Transaction::ChainedBlobWriter::
+ ReportWriteCompletion,
+ chained_blob_writer_,
+ write_status == FileWriterDelegate::SUCCESS_COMPLETED,
+ bytes_written_));
}
void writeBlobToFileOnIOThread(const FilePath& file_path,
}
private:
- virtual ~LocalWriteClosure() {}
- friend class base::RefCounted<LocalWriteClosure>;
-
- void callBlobCallbackOnIDBTaskRunner(bool succeeded) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- chained_blob_writer_->ReportWriteCompletion(succeeded, bytes_written_);
+ virtual ~LocalWriteClosure() {
+ // Make sure the last reference to a ChainedBlobWriter is released (and
+ // deleted) on the IDB thread since it owns a transaction which has thread
+ // affinity.
+ IndexedDBBackingStore::Transaction::ChainedBlobWriter* raw_tmp =
+ chained_blob_writer_.get();
+ raw_tmp->AddRef();
+ chained_blob_writer_ = NULL;
+ task_runner_->ReleaseSoon(FROM_HERE, raw_tmp);
}
+ friend class base::RefCountedThreadSafe<LocalWriteClosure>;
- IndexedDBBackingStore::Transaction::ChainedBlobWriter* chained_blob_writer_;
- base::TaskRunner* task_runner_;
+ scoped_refptr<IndexedDBBackingStore::Transaction::ChainedBlobWriter>
+ chained_blob_writer_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
int64 bytes_written_;
DISALLOW_COPY_AND_ASSIGN(LocalWriteClosure);
static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction,
const std::string& target,
std::string* found_key,
- leveldb::Status& s) {
+ leveldb::Status* s) {
scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
- s = it->Seek(target);
- if (!s.ok())
+ *s = it->Seek(target);
+ if (!s->ok())
return false;
if (!it->IsValid()) {
- s = it->SeekToLast();
- if (!s.ok() || !it->IsValid())
+ *s = it->SeekToLast();
+ if (!s->ok() || !it->IsValid())
return false;
}
while (CompareIndexKeys(it->Key(), target) > 0) {
- s = it->Prev();
- if (!s.ok() || !it->IsValid())
+ *s = it->Prev();
+ if (!s->ok() || !it->IsValid())
return false;
}
*found_key = it->Key().as_string();
// There can be several index keys that compare equal. We want the last one.
- s = it->Next();
- } while (s.ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target));
+ *s = it->Next();
+ } while (s->ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target));
return true;
}
// TODO(alecflett): avoid a copy here?
IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey();
- bool first_iteration = true;
-
// When iterating with PrevNoDuplicate, spec requires that the
// value we yield for each key is the first duplicate in forwards
// order.
IndexedDBKey last_duplicate_key;
bool forward = cursor_options_.forward;
+ bool first_iteration_forward = forward;
+ bool flipped = false;
for (;;) {
if (next_state == SEEK) {
// TODO(jsbell): Optimize seeking for reverse cursors as well.
- if (first_iteration && key && forward) {
+ if (first_iteration_forward && key) {
+ first_iteration_forward = false;
std::string leveldb_key;
if (primary_key) {
leveldb_key = EncodeKey(*key, *primary_key);
leveldb_key = EncodeKey(*key);
}
*s = iterator_->Seek(leveldb_key);
- first_iteration = false;
} else if (forward) {
*s = iterator_->Next();
} else {
// We need to walk forward because we hit the end of
// the data.
forward = true;
+ flipped = true;
continue;
}
// We need to walk forward because now we're beyond the
// bounds defined by the cursor.
forward = true;
+ flipped = true;
continue;
}
if (primary_key && current_key_->Equals(*key) &&
this->primary_key().IsLessThan(*primary_key))
continue;
- if (current_key_->IsLessThan(*key))
+ if (!flipped && current_key_->IsLessThan(*key))
continue;
} else {
if (primary_key && key->Equals(*current_key_) &&
// between key ranges.
if (!last_duplicate_key.Equals(*current_key_)) {
forward = true;
+ flipped = true;
continue;
}
int64 database_id,
int64 object_store_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
cursor_options->database_id = database_id;
cursor_options->object_store_id = object_store_id;
bool lower_bound = range.lower().IsValid();
bool upper_bound = range.upper().IsValid();
cursor_options->forward =
- (direction == indexed_db::CURSOR_NEXT_NO_DUPLICATE ||
- direction == indexed_db::CURSOR_NEXT);
- cursor_options->unique = (direction == indexed_db::CURSOR_NEXT_NO_DUPLICATE ||
- direction == indexed_db::CURSOR_PREV_NO_DUPLICATE);
+ (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
+ direction == blink::WebIDBCursorDirectionNext);
+ cursor_options->unique =
+ (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
+ direction == blink::WebIDBCursorDirectionPrevNoDuplicate);
if (!lower_bound) {
cursor_options->low_key =
if (!FindGreatestKeyLessThanOrEqual(transaction,
cursor_options->high_key,
&cursor_options->high_key,
- s))
+ &s))
return false;
cursor_options->high_open = false;
}
std::string found_high_key;
// TODO(cmumford): Handle this error (crbug.com/363397)
if (!FindGreatestKeyLessThanOrEqual(
- transaction, cursor_options->high_key, &found_high_key, s))
+ transaction, cursor_options->high_key, &found_high_key, &s))
return false;
// If the target key should not be included, but we end up with a smaller
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
DCHECK(transaction);
if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
bool lower_bound = range.lower().IsValid();
bool upper_bound = range.upper().IsValid();
cursor_options->forward =
- (direction == indexed_db::CURSOR_NEXT_NO_DUPLICATE ||
- direction == indexed_db::CURSOR_NEXT);
- cursor_options->unique = (direction == indexed_db::CURSOR_NEXT_NO_DUPLICATE ||
- direction == indexed_db::CURSOR_PREV_NO_DUPLICATE);
+ (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
+ direction == blink::WebIDBCursorDirectionNext);
+ cursor_options->unique =
+ (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
+ direction == blink::WebIDBCursorDirectionPrevNoDuplicate);
if (!lower_bound) {
cursor_options->low_key =
if (!FindGreatestKeyLessThanOrEqual(transaction,
cursor_options->high_key,
&cursor_options->high_key,
- s))
+ &s))
return false;
cursor_options->high_open = false;
}
// Seek to the *last* key in the set of non-unique keys
// TODO(cmumford): Handle this error (crbug.com/363397)
if (!FindGreatestKeyLessThanOrEqual(
- transaction, cursor_options->high_key, &found_high_key, s))
+ transaction, cursor_options->high_key, &found_high_key, &s))
return false;
// If the target key should not be included, but we end up with a smaller
int64 database_id,
int64 object_store_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor");
*s = leveldb::Status::OK();
int64 database_id,
int64 object_store_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
*s = leveldb::Status::OK();
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
*s = leveldb::Status::OK();
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& range,
- indexed_db::CursorDirection direction,
+ blink::WebIDBCursorDirection direction,
leveldb::Status* s) {
IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
LevelDBTransaction* leveldb_transaction = transaction->transaction();
s = backing_store_->CleanUpBlobJournal(BlobJournalKey::Encode());
if (!s.ok()) {
- INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
+ INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD);
transaction_ = NULL;
return s;
}
if (new_files_to_write.size()) {
// This kicks off the writes of the new blobs, if any.
// This call will zero out new_blob_entries and new_files_to_write.
- WriteNewBlobs(new_blob_entries, new_files_to_write, callback);
+ WriteNewBlobs(&new_blob_entries, &new_files_to_write, callback);
// Remove the add journal, if any; once the blobs are written, and we
// commit, this will do the cleanup.
ClearBlobJournal(transaction_.get(), BlobJournalKey::Encode());
}
}
if (!s.ok())
- INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
+ INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD);
else if (blobs_to_remove_.size())
s = backing_store_->CleanUpBlobJournal(BlobJournalKey::Encode());
};
void IndexedDBBackingStore::Transaction::WriteNewBlobs(
- BlobEntryKeyValuePairVec& new_blob_entries,
- WriteDescriptorVec& new_files_to_write,
+ BlobEntryKeyValuePairVec* new_blob_entries,
+ WriteDescriptorVec* new_files_to_write,
scoped_refptr<BlobWriteCallback> callback) {
- DCHECK_GT(new_files_to_write.size(), 0UL);
+ DCHECK_GT(new_files_to_write->size(), 0UL);
DCHECK_GT(database_id_, 0);
BlobEntryKeyValuePairVec::iterator blob_entry_iter;
- for (blob_entry_iter = new_blob_entries.begin();
- blob_entry_iter != new_blob_entries.end();
+ for (blob_entry_iter = new_blob_entries->begin();
+ blob_entry_iter != new_blob_entries->end();
++blob_entry_iter) {
// Add the new blob-table entry for each blob to the main transaction, or
// remove any entry that may exist if there's no new one.
void IndexedDBBackingStore::Transaction::Rollback() {
IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
- DCHECK(transaction_.get());
if (chained_blob_writer_) {
chained_blob_writer_->Abort();
chained_blob_writer_ = NULL;
}
+ if (transaction_.get() == NULL)
+ return;
transaction_->Rollback();
transaction_ = NULL;
}