зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1149815 - Don't assume that index creation always succeeds, r=janv.
This commit is contained in:
Родитель
dbe52fd678
Коммит
778f5ee935
|
@ -5343,11 +5343,10 @@ protected:
|
|||
const Key& aObjectStoreKey,
|
||||
const FallibleTArray<IndexDataValue>& aIndexValues);
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool
|
||||
static nsresult
|
||||
ObjectStoreHasIndexes(DatabaseConnection* aConnection,
|
||||
const int64_t aObjectStoreId);
|
||||
#endif
|
||||
const int64_t aObjectStoreId,
|
||||
bool* aHasIndexes);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
|
@ -6941,7 +6940,6 @@ class DeleteObjectStoreOp final
|
|||
|
||||
const nsRefPtr<FullObjectStoreMetadata> mMetadata;
|
||||
const bool mIsLastObjectStore;
|
||||
const bool mObjectStoreHasIndexes;
|
||||
|
||||
private:
|
||||
// Only created by VersionChangeTransaction.
|
||||
|
@ -6951,7 +6949,6 @@ private:
|
|||
: VersionChangeTransactionOp(aTransaction)
|
||||
, mMetadata(aMetadata)
|
||||
, mIsLastObjectStore(aIsLastObjectStore)
|
||||
, mObjectStoreHasIndexes(aMetadata->HasLiveIndexes())
|
||||
{
|
||||
MOZ_ASSERT(aMetadata->mCommonMetadata.id());
|
||||
}
|
||||
|
@ -7138,6 +7135,15 @@ protected:
|
|||
~NormalTransactionOp()
|
||||
{ }
|
||||
|
||||
// An overload of DatabaseOperationBase's function that can avoid doing extra
|
||||
// work on non-versionchange transactions.
|
||||
static nsresult
|
||||
ObjectStoreHasIndexes(NormalTransactionOp* aOp,
|
||||
DatabaseConnection* aConnection,
|
||||
const int64_t aObjectStoreId,
|
||||
const bool aMayHaveIndexes,
|
||||
bool* aHasIndexes);
|
||||
|
||||
// Subclasses use this override to set the IPDL response value.
|
||||
virtual void
|
||||
GetResponse(RequestResponse& aResponse) = 0;
|
||||
|
@ -7179,7 +7185,7 @@ class ObjectStoreAddOrPutRequestOp final
|
|||
const nsCString mOrigin;
|
||||
const PersistenceType mPersistenceType;
|
||||
const bool mOverwrite;
|
||||
const bool mObjectStoreHasIndexes;
|
||||
const bool mObjectStoreMayHaveIndexes;
|
||||
|
||||
private:
|
||||
// Only created by TransactionBase.
|
||||
|
@ -7297,7 +7303,7 @@ class ObjectStoreDeleteRequestOp final
|
|||
|
||||
const ObjectStoreDeleteParams mParams;
|
||||
ObjectStoreDeleteResponse mResponse;
|
||||
const bool mObjectStoreHasIndexes;
|
||||
const bool mObjectStoreMayHaveIndexes;
|
||||
|
||||
private:
|
||||
ObjectStoreDeleteRequestOp(TransactionBase* aTransaction,
|
||||
|
@ -7323,7 +7329,7 @@ class ObjectStoreClearRequestOp final
|
|||
|
||||
const ObjectStoreClearParams mParams;
|
||||
ObjectStoreClearResponse mResponse;
|
||||
const bool mObjectStoreHasIndexes;
|
||||
const bool mObjectStoreMayHaveIndexes;
|
||||
|
||||
private:
|
||||
ObjectStoreClearRequestOp(TransactionBase* aTransaction,
|
||||
|
@ -18063,8 +18069,16 @@ DatabaseOperationBase::DeleteObjectStoreDataTableRowsWithIndexes(
|
|||
MOZ_ASSERT(aConnection);
|
||||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(aObjectStoreId);
|
||||
MOZ_ASSERT(ObjectStoreHasIndexes(aConnection, aObjectStoreId),
|
||||
"Don't use this slow method if there are no indexes!");
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
bool hasIndexes = false;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(
|
||||
ObjectStoreHasIndexes(aConnection, aObjectStoreId, &hasIndexes)));
|
||||
MOZ_ASSERT(hasIndexes,
|
||||
"Don't use this slow method if there are no indexes!");
|
||||
}
|
||||
#endif
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"DatabaseOperationBase::"
|
||||
|
@ -18272,38 +18286,45 @@ DatabaseOperationBase::UpdateIndexValues(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
// static
|
||||
bool
|
||||
nsresult
|
||||
DatabaseOperationBase::ObjectStoreHasIndexes(DatabaseConnection* aConnection,
|
||||
const int64_t aObjectStoreId)
|
||||
const int64_t aObjectStoreId,
|
||||
bool* aHasIndexes)
|
||||
{
|
||||
MOZ_ASSERT(aConnection);
|
||||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(aObjectStoreId);
|
||||
MOZ_ASSERT(aHasIndexes);
|
||||
|
||||
DatabaseConnection::CachedStatement stmt;
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id "
|
||||
"FROM object_store_index "
|
||||
"WHERE object_store_id = :object_store_id;"),
|
||||
&stmt)));
|
||||
nsresult rv = aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id "
|
||||
"FROM object_store_index "
|
||||
"WHERE object_store_id = :object_store_id "
|
||||
"LIMIT 1;"),
|
||||
&stmt);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
stmt->BindInt64ByName(NS_LITERAL_CSTRING("object_store_id"),
|
||||
aObjectStoreId)));
|
||||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("object_store_id"),
|
||||
aObjectStoreId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool hasResult;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)));
|
||||
rv = stmt->ExecuteStep(&hasResult);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return hasResult;
|
||||
*aHasIndexes = hasResult;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(DatabaseOperationBase,
|
||||
nsRunnable,
|
||||
mozIStorageProgressHandler)
|
||||
|
@ -21635,11 +21656,6 @@ DeleteObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
foundThisObjectStore && !foundOtherObjectStore);
|
||||
MOZ_ASSERT_IF(!mIsLastObjectStore,
|
||||
foundThisObjectStore && foundOtherObjectStore);
|
||||
|
||||
// Make sure |hasIndexes| is telling the truth.
|
||||
MOZ_ASSERT(mObjectStoreHasIndexes ==
|
||||
ObjectStoreHasIndexes(aConnection,
|
||||
mMetadata->mCommonMetadata.id()));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -21712,7 +21728,15 @@ DeleteObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
return rv;
|
||||
}
|
||||
} else {
|
||||
if (mObjectStoreHasIndexes) {
|
||||
bool hasIndexes;
|
||||
rv = ObjectStoreHasIndexes(aConnection,
|
||||
mMetadata->mCommonMetadata.id(),
|
||||
&hasIndexes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (hasIndexes) {
|
||||
rv = DeleteObjectStoreDataTableRowsWithIndexes(
|
||||
aConnection,
|
||||
mMetadata->mCommonMetadata.id(),
|
||||
|
@ -22790,6 +22814,48 @@ DeleteIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
NormalTransactionOp::ObjectStoreHasIndexes(NormalTransactionOp* aOp,
|
||||
DatabaseConnection* aConnection,
|
||||
const int64_t aObjectStoreId,
|
||||
const bool aMayHaveIndexes,
|
||||
bool* aHasIndexes)
|
||||
{
|
||||
MOZ_ASSERT(aOp);
|
||||
MOZ_ASSERT(aConnection);
|
||||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(aObjectStoreId);
|
||||
MOZ_ASSERT(aHasIndexes);
|
||||
|
||||
bool hasIndexes;
|
||||
if (aOp->Transaction()->GetMode() == IDBTransaction::VERSION_CHANGE &&
|
||||
aMayHaveIndexes) {
|
||||
// If this is a version change transaction then mObjectStoreMayHaveIndexes
|
||||
// could be wrong (e.g. if a unique index failed to be created due to a
|
||||
// constraint error). We have to check on this thread by asking the database
|
||||
// directly.
|
||||
nsresult rv =
|
||||
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
|
||||
aObjectStoreId,
|
||||
&hasIndexes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(NS_SUCCEEDED(
|
||||
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
|
||||
aObjectStoreId,
|
||||
&hasIndexes)));
|
||||
MOZ_ASSERT(aMayHaveIndexes == hasIndexes);
|
||||
|
||||
hasIndexes = aMayHaveIndexes;
|
||||
}
|
||||
|
||||
*aHasIndexes = hasIndexes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NormalTransactionOp::SendSuccessResult()
|
||||
{
|
||||
|
@ -22866,7 +22932,7 @@ ObjectStoreAddOrPutRequestOp::ObjectStoreAddOrPutRequestOp(
|
|||
, mOrigin(aTransaction->GetDatabase()->Origin())
|
||||
, mPersistenceType(aTransaction->GetDatabase()->Type())
|
||||
, mOverwrite(aParams.type() == RequestParams::TObjectStorePutParams)
|
||||
, mObjectStoreHasIndexes(false)
|
||||
, mObjectStoreMayHaveIndexes(false)
|
||||
{
|
||||
MOZ_ASSERT(aParams.type() == RequestParams::TObjectStoreAddParams ||
|
||||
aParams.type() == RequestParams::TObjectStorePutParams);
|
||||
|
@ -22875,7 +22941,7 @@ ObjectStoreAddOrPutRequestOp::ObjectStoreAddOrPutRequestOp(
|
|||
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
|
||||
MOZ_ASSERT(mMetadata);
|
||||
|
||||
const_cast<bool&>(mObjectStoreHasIndexes) = mMetadata->HasLiveIndexes();
|
||||
const_cast<bool&>(mObjectStoreMayHaveIndexes) = mMetadata->HasLiveIndexes();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -22886,7 +22952,18 @@ ObjectStoreAddOrPutRequestOp::RemoveOldIndexDataValues(
|
|||
MOZ_ASSERT(aConnection);
|
||||
MOZ_ASSERT(mOverwrite);
|
||||
MOZ_ASSERT(!mResponse.IsUnset());
|
||||
MOZ_ASSERT(mObjectStoreHasIndexes);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
bool hasIndexes = false;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(
|
||||
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
|
||||
mParams.objectStoreId(),
|
||||
&hasIndexes)));
|
||||
MOZ_ASSERT(hasIndexes,
|
||||
"Don't use this slow method if there are no indexes!");
|
||||
}
|
||||
#endif
|
||||
|
||||
DatabaseConnection::CachedStatement indexValuesStmt;
|
||||
nsresult rv = aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
|
||||
|
@ -23098,8 +23175,6 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(aConnection->GetStorageConnection());
|
||||
MOZ_ASSERT_IF(mFileManager, !mStoredFileInfos.IsEmpty());
|
||||
MOZ_ASSERT(mObjectStoreHasIndexes ==
|
||||
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"ObjectStoreAddOrPutRequestOp::DoDatabaseWork",
|
||||
|
@ -23115,6 +23190,16 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool objectStoreHasIndexes;
|
||||
rv = ObjectStoreHasIndexes(this,
|
||||
aConnection,
|
||||
mParams.objectStoreId(),
|
||||
mObjectStoreMayHaveIndexes,
|
||||
&objectStoreHasIndexes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// This will be the final key we use.
|
||||
Key& key = mResponse;
|
||||
key = mParams.key();
|
||||
|
@ -23125,7 +23210,7 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
|
||||
// First delete old index_data_values if we're overwriting something and we
|
||||
// have indexes.
|
||||
if (mOverwrite && !keyUnset && mObjectStoreHasIndexes) {
|
||||
if (mOverwrite && !keyUnset && objectStoreHasIndexes) {
|
||||
rv = RemoveOldIndexDataValues(aConnection);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
|
@ -23779,7 +23864,7 @@ ObjectStoreDeleteRequestOp::ObjectStoreDeleteRequestOp(
|
|||
const ObjectStoreDeleteParams& aParams)
|
||||
: NormalTransactionOp(aTransaction)
|
||||
, mParams(aParams)
|
||||
, mObjectStoreHasIndexes(false)
|
||||
, mObjectStoreMayHaveIndexes(false)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aTransaction);
|
||||
|
@ -23788,7 +23873,7 @@ ObjectStoreDeleteRequestOp::ObjectStoreDeleteRequestOp(
|
|||
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
|
||||
MOZ_ASSERT(metadata);
|
||||
|
||||
const_cast<bool&>(mObjectStoreHasIndexes) = metadata->HasLiveIndexes();
|
||||
const_cast<bool&>(mObjectStoreMayHaveIndexes) = metadata->HasLiveIndexes();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -23796,9 +23881,6 @@ ObjectStoreDeleteRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
{
|
||||
MOZ_ASSERT(aConnection);
|
||||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(mObjectStoreHasIndexes ==
|
||||
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"ObjectStoreDeleteRequestOp::DoDatabaseWork",
|
||||
js::ProfileEntry::Category::STORAGE);
|
||||
|
@ -23809,7 +23891,17 @@ ObjectStoreDeleteRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (mObjectStoreHasIndexes) {
|
||||
bool objectStoreHasIndexes;
|
||||
rv = ObjectStoreHasIndexes(this,
|
||||
aConnection,
|
||||
mParams.objectStoreId(),
|
||||
mObjectStoreMayHaveIndexes,
|
||||
&objectStoreHasIndexes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (objectStoreHasIndexes) {
|
||||
rv = DeleteObjectStoreDataTableRowsWithIndexes(aConnection,
|
||||
mParams.objectStoreId(),
|
||||
mParams.keyRange());
|
||||
|
@ -23864,7 +23956,7 @@ ObjectStoreClearRequestOp::ObjectStoreClearRequestOp(
|
|||
const ObjectStoreClearParams& aParams)
|
||||
: NormalTransactionOp(aTransaction)
|
||||
, mParams(aParams)
|
||||
, mObjectStoreHasIndexes(false)
|
||||
, mObjectStoreMayHaveIndexes(false)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aTransaction);
|
||||
|
@ -23873,7 +23965,7 @@ ObjectStoreClearRequestOp::ObjectStoreClearRequestOp(
|
|||
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
|
||||
MOZ_ASSERT(metadata);
|
||||
|
||||
const_cast<bool&>(mObjectStoreHasIndexes) = metadata->HasLiveIndexes();
|
||||
const_cast<bool&>(mObjectStoreMayHaveIndexes) = metadata->HasLiveIndexes();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -23881,8 +23973,6 @@ ObjectStoreClearRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
{
|
||||
MOZ_ASSERT(aConnection);
|
||||
aConnection->AssertIsOnConnectionThread();
|
||||
MOZ_ASSERT(mObjectStoreHasIndexes ==
|
||||
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"ObjectStoreClearRequestOp::DoDatabaseWork",
|
||||
|
@ -23894,7 +23984,17 @@ ObjectStoreClearRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (mObjectStoreHasIndexes) {
|
||||
bool objectStoreHasIndexes;
|
||||
rv = ObjectStoreHasIndexes(this,
|
||||
aConnection,
|
||||
mParams.objectStoreId(),
|
||||
mObjectStoreMayHaveIndexes,
|
||||
&objectStoreHasIndexes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (objectStoreHasIndexes) {
|
||||
rv = DeleteObjectStoreDataTableRowsWithIndexes(aConnection,
|
||||
mParams.objectStoreId(),
|
||||
void_t());
|
||||
|
|
Загрузка…
Ссылка в новой задаче