зеркало из https://github.com/mozilla/gecko-dev.git
Bug 871846 - Handle locale aware indexes. r=janv
This commit is contained in:
Родитель
0e18f3afbd
Коммит
9a1f803114
|
@ -2688,11 +2688,13 @@ BackgroundCursorChild::HandleResponse(const IndexCursorResponse& aResponse)
|
|||
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()),
|
||||
Move(response.sortKey()),
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.sortKey()),
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
mCursor = newCursor;
|
||||
|
@ -2718,10 +2720,13 @@ BackgroundCursorChild::HandleResponse(const IndexKeyCursorResponse& aResponse)
|
|||
nsRefPtr<IDBCursor> newCursor;
|
||||
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()), Move(response.objectKey()));
|
||||
mCursor->Reset(Move(response.key()),
|
||||
Move(response.sortKey()),
|
||||
Move(response.objectKey()));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.sortKey()),
|
||||
Move(response.objectKey()));
|
||||
mCursor = newCursor;
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ struct FullIndexMetadata
|
|||
|
||||
public:
|
||||
FullIndexMetadata()
|
||||
: mCommonMetadata(0, nsString(), KeyPath(0), false, false)
|
||||
: mCommonMetadata(0, nsString(), KeyPath(0), nsCString(), false, false, false)
|
||||
, mDeleted(false)
|
||||
{
|
||||
// This can happen either on the QuotaManager IO thread or on a
|
||||
|
@ -5438,6 +5438,11 @@ protected:
|
|||
BindKeyRangeToStatement(const SerializedKeyRange& aKeyRange,
|
||||
mozIStorageStatement* aStatement);
|
||||
|
||||
static nsresult
|
||||
BindKeyRangeToStatement(const SerializedKeyRange& aKeyRange,
|
||||
mozIStorageStatement* aStatement,
|
||||
const nsCString& aLocale);
|
||||
|
||||
static void
|
||||
AppendConditionClause(const nsACString& aColumnName,
|
||||
const nsACString& aArgName,
|
||||
|
@ -7708,10 +7713,12 @@ private:
|
|||
|
||||
nsCString mContinueQuery;
|
||||
nsCString mContinueToQuery;
|
||||
nsCString mLocale;
|
||||
|
||||
Key mKey;
|
||||
Key mObjectKey;
|
||||
Key mRangeKey;
|
||||
Key mSortKey;
|
||||
|
||||
CursorOpBase* mCurrentlyRunningOp;
|
||||
|
||||
|
@ -7764,6 +7771,11 @@ private:
|
|||
|
||||
virtual bool
|
||||
RecvContinue(const CursorRequestParams& aParams, const Key& key) override;
|
||||
|
||||
bool
|
||||
IsLocaleAware() const {
|
||||
return !mLocale.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
class Cursor::CursorOpBase
|
||||
|
@ -14668,6 +14680,10 @@ Cursor::Cursor(TransactionBase* aTransaction,
|
|||
MOZ_ASSERT(mBackgroundParent);
|
||||
}
|
||||
|
||||
if (aIndexMetadata) {
|
||||
mLocale = aIndexMetadata->mCommonMetadata.locale();
|
||||
}
|
||||
|
||||
static_assert(OpenCursorParams::T__None == 0 &&
|
||||
OpenCursorParams::T__Last == 4,
|
||||
"Lots of code here assumes only four types of cursors!");
|
||||
|
@ -14713,6 +14729,8 @@ Cursor::VerifyRequestParams(const CursorRequestParams& aParams) const
|
|||
return false;
|
||||
}
|
||||
|
||||
const Key& sortKey = IsLocaleAware() ? mSortKey : mKey;
|
||||
|
||||
switch (aParams.type()) {
|
||||
case CursorRequestParams::TContinueParams: {
|
||||
const Key& key = aParams.get_ContinueParams().key();
|
||||
|
@ -14720,7 +14738,7 @@ Cursor::VerifyRequestParams(const CursorRequestParams& aParams) const
|
|||
switch (mDirection) {
|
||||
case IDBCursor::NEXT:
|
||||
case IDBCursor::NEXT_UNIQUE:
|
||||
if (NS_WARN_IF(key <= mKey)) {
|
||||
if (NS_WARN_IF(key <= sortKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
@ -14728,7 +14746,7 @@ Cursor::VerifyRequestParams(const CursorRequestParams& aParams) const
|
|||
|
||||
case IDBCursor::PREV:
|
||||
case IDBCursor::PREV_UNIQUE:
|
||||
if (NS_WARN_IF(key >= mKey)) {
|
||||
if (NS_WARN_IF(key >= sortKey)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
@ -17479,24 +17497,21 @@ DatabaseOperationBase::BindKeyRangeToStatement(
|
|||
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||
MOZ_ASSERT(aStatement);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
|
||||
|
||||
if (aKeyRange.isOnly()) {
|
||||
return aKeyRange.lower().BindToStatement(aStatement, lowerKey);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!aKeyRange.lower().IsUnset()) {
|
||||
rv = aKeyRange.lower().BindToStatement(aStatement, lowerKey);
|
||||
rv = aKeyRange.lower().BindToStatement(aStatement, NS_LITERAL_CSTRING("lower_key"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (aKeyRange.isOnly()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!aKeyRange.upper().IsUnset()) {
|
||||
rv = aKeyRange.upper().BindToStatement(aStatement,
|
||||
NS_LITERAL_CSTRING("upper_key"));
|
||||
rv = aKeyRange.upper().BindToStatement(aStatement, NS_LITERAL_CSTRING("upper_key"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -17505,6 +17520,56 @@ DatabaseOperationBase::BindKeyRangeToStatement(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DatabaseOperationBase::BindKeyRangeToStatement(
|
||||
const SerializedKeyRange& aKeyRange,
|
||||
mozIStorageStatement* aStatement,
|
||||
const nsCString& aLocale)
|
||||
{
|
||||
#ifndef ENABLE_INTL_API
|
||||
return BindKeyRangeToStatement(aKeyRange, aStatement);
|
||||
#else
|
||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||
MOZ_ASSERT(aStatement);
|
||||
MOZ_ASSERT(!aLocale.IsEmpty());
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!aKeyRange.lower().IsUnset()) {
|
||||
Key lower;
|
||||
rv = aKeyRange.lower().ToLocaleBasedKey(lower, aLocale);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = lower.BindToStatement(aStatement, NS_LITERAL_CSTRING("lower_key"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (aKeyRange.isOnly()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!aKeyRange.upper().IsUnset()) {
|
||||
Key upper;
|
||||
rv = aKeyRange.upper().ToLocaleBasedKey(upper, aLocale);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = upper.BindToStatement(aStatement, NS_LITERAL_CSTRING("upper_key"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
DatabaseOperationBase::AppendConditionClause(const nsACString& aColumnName,
|
||||
|
@ -17632,13 +17697,15 @@ DatabaseOperationBase::IndexDataValuesFromUpdateInfos(
|
|||
const IndexUpdateInfo& updateInfo = aUpdateInfos[idxIndex];
|
||||
const int64_t& indexId = updateInfo.indexId();
|
||||
const Key& key = updateInfo.value();
|
||||
const Key& sortKey = updateInfo.localizedValue();
|
||||
|
||||
bool unique;
|
||||
MOZ_ALWAYS_TRUE(aUniqueIndexTable.Get(indexId, &unique));
|
||||
|
||||
IndexDataValue idv(indexId, unique, key, sortKey);
|
||||
|
||||
MOZ_ALWAYS_TRUE(
|
||||
aIndexValues.InsertElementSorted(IndexDataValue(indexId, unique, key),
|
||||
fallible));
|
||||
aIndexValues.InsertElementSorted(idv, fallible));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -22242,6 +22309,7 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
|
|||
metadata.keyPath(),
|
||||
metadata.unique(),
|
||||
metadata.multiEntry(),
|
||||
metadata.locale(),
|
||||
mCx,
|
||||
clone,
|
||||
updateInfos);
|
||||
|
@ -22325,7 +22393,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
|
|||
MOZ_ALWAYS_TRUE(
|
||||
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
|
||||
metadata.unique(),
|
||||
info.value()),
|
||||
info.value(),
|
||||
info.localizedValue()),
|
||||
fallible));
|
||||
}
|
||||
|
||||
|
@ -22362,7 +22431,8 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues,
|
|||
MOZ_ALWAYS_TRUE(
|
||||
indexValues.InsertElementSorted(IndexDataValue(metadata.id(),
|
||||
metadata.unique(),
|
||||
info.value()),
|
||||
info.value(),
|
||||
info.localizedValue()),
|
||||
fallible));
|
||||
}
|
||||
}
|
||||
|
@ -24750,9 +24820,23 @@ OpenOp::GetRangeKeyInfo(bool aLowerBound, Key* aKey, bool* aOpen)
|
|||
if (range.isOnly()) {
|
||||
*aKey = range.lower();
|
||||
*aOpen = false;
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (mCursor->IsLocaleAware()) {
|
||||
range.lower().ToLocaleBasedKey(*aKey, mCursor->mLocale);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
*aKey = aLowerBound ? range.lower() : range.upper();
|
||||
*aOpen = aLowerBound ? range.lowerOpen() : range.upperOpen();
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (mCursor->IsLocaleAware()) {
|
||||
if (aLowerBound) {
|
||||
range.lower().ToLocaleBasedKey(*aKey, mCursor->mLocale);
|
||||
} else {
|
||||
range.upper().ToLocaleBasedKey(*aKey, mCursor->mLocale);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
*aOpen = false;
|
||||
|
@ -25663,8 +25747,14 @@ ContinueOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
NS_NAMED_LITERAL_CSTRING(rangeKeyName, "range_key");
|
||||
NS_NAMED_LITERAL_CSTRING(objectKeyName, "object_key");
|
||||
|
||||
const Key& currentKey =
|
||||
hasContinueKey ? mParams.get_ContinueParams().key() : mCursor->mKey;
|
||||
const bool localeAware = mCursor->IsLocaleAware();
|
||||
|
||||
Key& currentKey = mCursor->mKey;
|
||||
if (hasContinueKey) {
|
||||
currentKey = mParams.get_ContinueParams().key();
|
||||
} else if (localeAware) {
|
||||
currentKey = mCursor->mSortKey;
|
||||
}
|
||||
|
||||
const bool usingRangeKey = !mCursor->mRangeKey.IsUnset();
|
||||
|
||||
|
|
|
@ -904,12 +904,17 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
const KeyPath& aKeyPath,
|
||||
bool aUnique,
|
||||
bool aMultiEntry,
|
||||
const nsCString& aLocale,
|
||||
JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
#ifdef ENABLE_INTL_API
|
||||
const bool localeAware = !aLocale.IsEmpty();
|
||||
#endif
|
||||
|
||||
if (!aMultiEntry) {
|
||||
Key key;
|
||||
rv = aKeyPath.ExtractKey(aCx, aVal, key);
|
||||
|
@ -926,6 +931,14 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
|
||||
updateInfo->indexId() = aIndexID;
|
||||
updateInfo->value() = key;
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (localeAware) {
|
||||
rv = key.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -960,6 +973,14 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
|
||||
updateInfo->indexId() = aIndexID;
|
||||
updateInfo->value() = value;
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (localeAware) {
|
||||
rv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -973,6 +994,14 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
|
||||
updateInfo->indexId() = aIndexID;
|
||||
updateInfo->value() = value;
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (localeAware) {
|
||||
rv = value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1126,8 +1155,9 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
const IndexMetadata& metadata = indexes[idxIndex];
|
||||
|
||||
rv = AppendIndexUpdateInfo(metadata.id(), metadata.keyPath(),
|
||||
metadata.unique(), metadata.multiEntry(), aCx,
|
||||
aValue, aUpdateInfoArray);
|
||||
metadata.unique(), metadata.multiEntry(),
|
||||
metadata.locale(), aCx, aValue,
|
||||
aUpdateInfoArray);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1780,10 +1810,24 @@ IDBObjectStore::CreateIndexInternal(
|
|||
const IndexMetadata* oldMetadataElements =
|
||||
indexes.IsEmpty() ? nullptr : indexes.Elements();
|
||||
|
||||
// With this setup we only validate the passed in locale name by the time we
|
||||
// get to encoding Keys. Maybe we should do it here right away and error out.
|
||||
|
||||
// Valid locale names are always ASCII as per BCP-47.
|
||||
nsCString locale = NS_LossyConvertUTF16toASCII(aOptionalParameters.mLocale);
|
||||
bool autoLocale = locale.EqualsASCII("auto");
|
||||
#ifdef ENABLE_INTL_API
|
||||
if (autoLocale) {
|
||||
locale = IndexedDatabaseManager::GetLocale();
|
||||
}
|
||||
#endif
|
||||
|
||||
IndexMetadata* metadata = indexes.AppendElement(
|
||||
IndexMetadata(transaction->NextIndexId(), nsString(aName), aKeyPath,
|
||||
locale,
|
||||
aOptionalParameters.mUnique,
|
||||
aOptionalParameters.mMultiEntry));
|
||||
aOptionalParameters.mMultiEntry,
|
||||
autoLocale));
|
||||
|
||||
if (oldMetadataElements &&
|
||||
oldMetadataElements != indexes.Elements()) {
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
const KeyPath& aKeyPath,
|
||||
bool aUnique,
|
||||
bool aMultiEntry,
|
||||
const nsCString& aLocale,
|
||||
JSContext* aCx,
|
||||
JS::Handle<JS::Value> aObject,
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
||||
|
|
|
@ -56,6 +56,7 @@ struct IndexUpdateInfo
|
|||
{
|
||||
int64_t indexId;
|
||||
Key value;
|
||||
Key localizedValue;
|
||||
};
|
||||
|
||||
union OptionalKeyRange
|
||||
|
|
Загрузка…
Ссылка в новой задаче