mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1404276 - Support IDB key extraction with autoincremented primary key. r=dom-storage-reviewers,janv
This patch is originally authored by Bevis Tseng. Differential Revision: https://phabricator.services.mozilla.com/D204361
This commit is contained in:
parent
65be157489
commit
17acc6cd4d
@ -3637,7 +3637,7 @@ class ObjectStoreAddOrPutRequestOp final : public NormalTransactionOp {
|
||||
};
|
||||
class SCInputStream;
|
||||
|
||||
const ObjectStoreAddPutParams mParams;
|
||||
ObjectStoreAddPutParams mParams;
|
||||
Maybe<UniqueIndexTable> mUniqueIndexTable;
|
||||
|
||||
// This must be non-const so that we can update the mNextAutoIncrementId field
|
||||
@ -6453,9 +6453,9 @@ class DeserializeIndexValueHelper final : public Runnable {
|
||||
value.setUndefined();
|
||||
|
||||
ErrorResult rv;
|
||||
IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mMultiEntry,
|
||||
mLocale, jsapi.cx(), value,
|
||||
&mUpdateInfoArray, &rv);
|
||||
IDBObjectStore::AppendIndexUpdateInfo(
|
||||
mIndexID, mKeyPath, mMultiEntry, &mUpdateInfoArray,
|
||||
/* aAutoIncrementedObjectStoreKeyPath */ VoidString(), &rv);
|
||||
return rv.Failed() ? rv.StealNSResult() : NS_OK;
|
||||
}
|
||||
#endif
|
||||
@ -6493,9 +6493,9 @@ class DeserializeIndexValueHelper final : public Runnable {
|
||||
[this](const nsresult rv) { OperationCompleted(rv); });
|
||||
|
||||
ErrorResult errorResult;
|
||||
IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mMultiEntry,
|
||||
mLocale, cx, value, &mUpdateInfoArray,
|
||||
&errorResult);
|
||||
IDBObjectStore::AppendIndexUpdateInfo(
|
||||
mIndexID, mKeyPath, mMultiEntry, mLocale, cx, value, &mUpdateInfoArray,
|
||||
/* aAutoIncrementedObjectStoreKeyPath */ VoidString(), &errorResult);
|
||||
QM_TRY(OkIf(!errorResult.Failed()), NS_OK,
|
||||
([this, &errorResult](const NotOk) {
|
||||
OperationCompleted(errorResult.StealNSResult());
|
||||
@ -18653,6 +18653,11 @@ nsresult ObjectStoreAddOrPutRequestOp::DoDatabaseWork(
|
||||
}
|
||||
|
||||
QM_TRY(key.SetFromInteger(autoIncrementNum));
|
||||
|
||||
// Update index keys if primary key is preserved in child.
|
||||
for (auto& updateInfo : mParams.indexUpdateInfos()) {
|
||||
updateInfo.value().MaybeUpdateAutoIncrementKey(autoIncrementNum);
|
||||
}
|
||||
} else if (key.IsFloat()) {
|
||||
double numericKey = key.ToFloat();
|
||||
numericKey = std::min(numericKey, double(1LL << 53));
|
||||
|
@ -410,13 +410,20 @@ RefPtr<IDBObjectStore> IDBObjectStore::Create(
|
||||
void IDBObjectStore::AppendIndexUpdateInfo(
|
||||
const int64_t aIndexID, const KeyPath& aKeyPath, const bool aMultiEntry,
|
||||
const nsCString& aLocale, JSContext* const aCx, JS::Handle<JS::Value> aVal,
|
||||
nsTArray<IndexUpdateInfo>* const aUpdateInfoArray, ErrorResult* const aRv) {
|
||||
nsTArray<IndexUpdateInfo>* const aUpdateInfoArray,
|
||||
const VoidOrObjectStoreKeyPathString& aAutoIncrementedObjectStoreKeyPath,
|
||||
ErrorResult* const aRv) {
|
||||
// This precondition holds when `aVal` is the result of a structured clone.
|
||||
js::AutoAssertNoContentJS noContentJS(aCx);
|
||||
|
||||
static_assert(std::is_same_v<IDBObjectStore::VoidOrObjectStoreKeyPathString,
|
||||
KeyPath::VoidOrObjectStoreKeyPathString>,
|
||||
"Inconsistent types");
|
||||
|
||||
if (!aMultiEntry) {
|
||||
Key key;
|
||||
*aRv = aKeyPath.ExtractKey(aCx, aVal, key);
|
||||
*aRv =
|
||||
aKeyPath.ExtractKey(aCx, aVal, key, aAutoIncrementedObjectStoreKeyPath);
|
||||
|
||||
// If an index's keyPath doesn't match an object, we ignore that object.
|
||||
if (aRv->ErrorCodeIs(NS_ERROR_DOM_INDEXEDDB_DATA_ERR) || key.IsUnset()) {
|
||||
@ -625,6 +632,21 @@ void IDBObjectStore::GetAddInfo(JSContext* aCx, ValueWrapper& aValueWrapper,
|
||||
const nsTArray<IndexMetadata>& indexes = mSpec->indexes();
|
||||
const uint32_t idxCount = indexes.Length();
|
||||
|
||||
const auto& autoIncrementedObjectStoreKeyPath =
|
||||
[this]() -> const nsAString& {
|
||||
if (AutoIncrement() && GetKeyPath().IsValid()) {
|
||||
// By https://w3c.github.io/IndexedDB/#database-interface ,
|
||||
// createObjectStore algorithm, step 8, neither arrays nor empty paths
|
||||
// are allowed for autoincremented object stores.
|
||||
// See also KeyPath::IsAllowedForObjectStore.
|
||||
MOZ_ASSERT(GetKeyPath().IsString());
|
||||
MOZ_ASSERT(!GetKeyPath().IsEmpty());
|
||||
return GetKeyPath().mStrings[0];
|
||||
}
|
||||
|
||||
return VoidString();
|
||||
}();
|
||||
|
||||
aUpdateInfoArray.SetCapacity(idxCount); // Pretty good estimate
|
||||
|
||||
for (uint32_t idxIndex = 0; idxIndex < idxCount; idxIndex++) {
|
||||
@ -632,7 +654,8 @@ void IDBObjectStore::GetAddInfo(JSContext* aCx, ValueWrapper& aValueWrapper,
|
||||
|
||||
AppendIndexUpdateInfo(metadata.id(), metadata.keyPath(),
|
||||
metadata.multiEntry(), metadata.locale(), aCx,
|
||||
aValueWrapper.Value(), &aUpdateInfoArray, &aRv);
|
||||
aValueWrapper.Value(), &aUpdateInfoArray,
|
||||
autoIncrementedObjectStoreKeyPath, &aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ class IDBObjectStore final : public nsISupports, public nsWrapperCache {
|
||||
using KeyPath = indexedDB::KeyPath;
|
||||
using ObjectStoreSpec = indexedDB::ObjectStoreSpec;
|
||||
using StructuredCloneReadInfoChild = indexedDB::StructuredCloneReadInfoChild;
|
||||
using VoidOrObjectStoreKeyPathString = nsAString;
|
||||
|
||||
// For AddOrPut() and DeleteInternal().
|
||||
// TODO Consider removing this, and making the functions public?
|
||||
@ -98,11 +99,12 @@ class IDBObjectStore final : public nsISupports, public nsWrapperCache {
|
||||
[[nodiscard]] static RefPtr<IDBObjectStore> Create(
|
||||
SafeRefPtr<IDBTransaction> aTransaction, ObjectStoreSpec& aSpec);
|
||||
|
||||
static void AppendIndexUpdateInfo(int64_t aIndexID, const KeyPath& aKeyPath,
|
||||
bool aMultiEntry, const nsCString& aLocale,
|
||||
JSContext* aCx, JS::Handle<JS::Value> aVal,
|
||||
nsTArray<IndexUpdateInfo>* aUpdateInfoArray,
|
||||
ErrorResult* aRv);
|
||||
static void AppendIndexUpdateInfo(
|
||||
int64_t aIndexID, const KeyPath& aKeyPath, bool aMultiEntry,
|
||||
const nsCString& aLocale, JSContext* aCx, JS::Handle<JS::Value> aVal,
|
||||
nsTArray<IndexUpdateInfo>* aUpdateInfoArray,
|
||||
const VoidOrObjectStoreKeyPathString& aAutoIncrementedObjectStoreKeyPath,
|
||||
ErrorResult* aRv);
|
||||
|
||||
static void ClearCloneReadInfo(
|
||||
indexedDB::StructuredCloneReadInfoChild& aReadInfo);
|
||||
|
@ -560,6 +560,51 @@ Result<Ok, nsresult> Key::EncodeString(const Span<const T> aInput,
|
||||
#define KEY_MAXIMUM_BUFFER_LENGTH \
|
||||
::mozilla::detail::nsTStringLengthStorage<char>::kMax
|
||||
|
||||
void Key::ReserveAutoIncrementKey(bool aFirstOfArray) {
|
||||
// Allocate memory for the new size
|
||||
uint32_t oldLen = mBuffer.Length();
|
||||
char* buffer;
|
||||
if (!mBuffer.GetMutableData(&buffer, oldLen + 1 + sizeof(double))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remember the offset of the buffer to be updated later.
|
||||
mAutoIncrementKeyOffsets.AppendElement(oldLen + 1);
|
||||
|
||||
// Fill the type.
|
||||
buffer += oldLen;
|
||||
*(buffer++) = aFirstOfArray ? (eMaxType + eFloat) : eFloat;
|
||||
|
||||
// Fill up with 0xFF to reserve the buffer in fixed size because the encoded
|
||||
// string could be trimmed if ended with padding zeros.
|
||||
mozilla::BigEndian::writeUint64(buffer, UINT64_MAX);
|
||||
}
|
||||
|
||||
void Key::MaybeUpdateAutoIncrementKey(int64_t aKey) {
|
||||
if (mAutoIncrementKeyOffsets.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t offset : mAutoIncrementKeyOffsets) {
|
||||
char* buffer;
|
||||
MOZ_ALWAYS_TRUE(mBuffer.GetMutableData(&buffer));
|
||||
buffer += offset;
|
||||
WriteDoubleToUint64(buffer, double(aKey));
|
||||
}
|
||||
|
||||
TrimBuffer();
|
||||
}
|
||||
|
||||
void Key::WriteDoubleToUint64(char* aBuffer, double aValue) {
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
uint64_t bits = BitwiseCast<uint64_t>(aValue);
|
||||
const uint64_t signbit = FloatingPoint<double>::kSignBit;
|
||||
uint64_t number = bits & signbit ? (-bits) : (bits | signbit);
|
||||
|
||||
mozilla::BigEndian::writeUint64(aBuffer, number);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Result<Ok, nsresult> Key::EncodeAsString(const Span<const T> aInput,
|
||||
uint8_t aType) {
|
||||
@ -797,13 +842,8 @@ Result<Ok, nsresult> Key::EncodeNumber(double aFloat, uint8_t aType) {
|
||||
|
||||
*(buffer++) = aType;
|
||||
|
||||
uint64_t bits = BitwiseCast<uint64_t>(aFloat);
|
||||
// Note: The subtraction from 0 below is necessary to fix
|
||||
// MSVC build warning C4146 (negating an unsigned value).
|
||||
const uint64_t signbit = FloatingPoint<double>::kSignBit;
|
||||
uint64_t number = bits & signbit ? (0 - bits) : (bits | signbit);
|
||||
WriteDoubleToUint64(buffer, aFloat);
|
||||
|
||||
mozilla::BigEndian::writeUint64(buffer, number);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ class Key {
|
||||
friend struct IPC::ParamTraits<Key>;
|
||||
|
||||
nsCString mBuffer;
|
||||
CopyableTArray<uint32_t> mAutoIncrementKeyOffsets;
|
||||
|
||||
public:
|
||||
enum {
|
||||
@ -86,7 +87,10 @@ class Key {
|
||||
return Compare(mBuffer, aOther.mBuffer) >= 0;
|
||||
}
|
||||
|
||||
void Unset() { mBuffer.SetIsVoid(true); }
|
||||
void Unset() {
|
||||
mBuffer.SetIsVoid(true);
|
||||
mAutoIncrementKeyOffsets.Clear();
|
||||
}
|
||||
|
||||
bool IsUnset() const { return mBuffer.IsVoid(); }
|
||||
|
||||
@ -174,6 +178,10 @@ class Key {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ReserveAutoIncrementKey(bool aFirstOfArray);
|
||||
|
||||
void MaybeUpdateAutoIncrementKey(int64_t aKey);
|
||||
|
||||
private:
|
||||
class MOZ_STACK_CLASS ArrayValueEncoder;
|
||||
|
||||
@ -273,6 +281,8 @@ class Key {
|
||||
|
||||
template <typename T>
|
||||
nsresult SetFromSource(T* aSource, uint32_t aIndex);
|
||||
|
||||
void WriteDoubleToUint64(char* aBuffer, double aValue);
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom::indexedDB
|
||||
|
@ -329,8 +329,9 @@ bool KeyPath::AppendStringWithValidation(const nsAString& aString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue,
|
||||
Key& aKey) const {
|
||||
nsresult KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey,
|
||||
const VoidOrObjectStoreKeyPathString&
|
||||
aAutoIncrementedObjectStoreKeyPath) const {
|
||||
uint32_t len = mStrings.Length();
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
|
||||
@ -341,6 +342,17 @@ nsresult KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue,
|
||||
GetJSValFromKeyPathString(aCx, aValue, mStrings[i], value.address(),
|
||||
DoNotCreateProperties, nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (!aAutoIncrementedObjectStoreKeyPath.IsVoid() &&
|
||||
mStrings[i].Equals(aAutoIncrementedObjectStoreKeyPath)) {
|
||||
// We are extracting index keys of an object to be added if
|
||||
// object store key path for a string key is provided.
|
||||
// Because the autoIncrement primary key is part of
|
||||
// this index key but is not defined in |aValue|, so we reserve
|
||||
// the space here to update the key later in parent.
|
||||
aKey.ReserveAutoIncrementKey(IsArray() && i == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ class KeyPath {
|
||||
KeyPath() : mType(KeyPathType::NonExistent) { MOZ_COUNT_CTOR(KeyPath); }
|
||||
|
||||
public:
|
||||
using VoidOrObjectStoreKeyPathString = nsAString;
|
||||
|
||||
enum class KeyPathType { NonExistent, String, Array, EndGuard };
|
||||
|
||||
void SetType(KeyPathType aType);
|
||||
@ -76,7 +78,10 @@ class KeyPath {
|
||||
static Result<KeyPath, nsresult> Parse(
|
||||
const Nullable<OwningStringOrStringSequence>& aValue);
|
||||
|
||||
nsresult ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const;
|
||||
nsresult ExtractKey(
|
||||
JSContext* aCx, const JS::Value& aValue, Key& aKey,
|
||||
const VoidOrObjectStoreKeyPathString& aAutoIncrementedObjectStoreKeyPath =
|
||||
VoidString()) const;
|
||||
|
||||
nsresult ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
|
||||
JS::Value* aOutVal) const;
|
||||
|
@ -31,10 +31,12 @@ struct ParamTraits<mozilla::dom::indexedDB::Key> {
|
||||
|
||||
static void Write(MessageWriter* aWriter, const paramType& aParam) {
|
||||
WriteParam(aWriter, aParam.mBuffer);
|
||||
WriteParam(aWriter, aParam.mAutoIncrementKeyOffsets);
|
||||
}
|
||||
|
||||
static bool Read(MessageReader* aReader, paramType* aResult) {
|
||||
return ReadParam(aReader, &aResult->mBuffer);
|
||||
return ReadParam(aReader, &aResult->mBuffer) &&
|
||||
ReadParam(aReader, &aResult->mAutoIncrementKeyOffsets);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
[idbobjectstore_createIndex15-autoincrement.htm]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Auto-Increment Primary Key]
|
||||
expected: FAIL
|
||||
|
||||
[Auto-Increment Primary Key - invalid key values elsewhere]
|
||||
expected: FAIL
|
@ -1,48 +0,0 @@
|
||||
[reading-autoincrement-indexes-cursors.any.serviceworker.html]
|
||||
[IDBIndex.openCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[reading-autoincrement-indexes-cursors.any.worker.html]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [OK, TIMEOUT]
|
||||
[IDBIndex.openCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [FAIL, TIMEOUT]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
[IDBIndex.openCursor() iterates over an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
|
||||
[reading-autoincrement-indexes-cursors.any.sharedworker.html]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [OK, TIMEOUT]
|
||||
[IDBIndex.openCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and (os == "win") and not debug: [PASS, TIMEOUT]
|
||||
|
||||
|
||||
[reading-autoincrement-indexes-cursors.any.html]
|
||||
[IDBIndex.openCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.openKeyCursor() iterates over an index on the autoincrement key]
|
||||
expected: FAIL
|
@ -1,117 +0,0 @@
|
||||
[reading-autoincrement-indexes.any.serviceworker.html]
|
||||
expected:
|
||||
if (os == "win") and not debug: [OK, TIMEOUT]
|
||||
[IDBIndex.getAll() for an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.getAllKeys() for an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.get() for an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.getAllKeys() returns correct result for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, TIMEOUT]
|
||||
|
||||
[IDBIndex.get() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
|
||||
[reading-autoincrement-indexes.any.html]
|
||||
expected:
|
||||
if (os == "win") and not debug: [OK, TIMEOUT]
|
||||
[IDBIndex.getAll() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, TIMEOUT]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.getAllKeys() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, NOTRUN]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.get() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, NOTRUN]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.getAll() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [PASS, TIMEOUT]
|
||||
if (os == "win") and not debug and (processor == "x86"): [PASS, TIMEOUT, NOTRUN]
|
||||
|
||||
[IDBIndex.get() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
[IDBIndex.getAllKeys() returns correct result for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
|
||||
[reading-autoincrement-indexes.any.sharedworker.html]
|
||||
expected:
|
||||
if (os == "win") and not debug: [OK, TIMEOUT]
|
||||
[IDBIndex.getAll() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, TIMEOUT]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.getAllKeys() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, NOTRUN]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.get() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [FAIL, TIMEOUT]
|
||||
if (os == "win") and not debug and (processor == "x86"): [FAIL, NOTRUN]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.getAll() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
[IDBIndex.get() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
[IDBIndex.getAllKeys() returns correct result for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug: [PASS, NOTRUN]
|
||||
|
||||
|
||||
[reading-autoincrement-indexes.any.worker.html]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [OK, TIMEOUT]
|
||||
if (os == "win") and not debug and (processor == "x86"): [TIMEOUT, OK]
|
||||
[IDBIndex.getAll() for an index on the autoincrement key]
|
||||
expected: FAIL
|
||||
|
||||
[IDBIndex.getAllKeys() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [FAIL, TIMEOUT]
|
||||
FAIL
|
||||
|
||||
[IDBIndex.get() for an index on the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [FAIL, NOTRUN]
|
||||
if (os == "win") and not debug and (processor == "x86"): TIMEOUT
|
||||
FAIL
|
||||
|
||||
[IDBIndex.get() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [PASS, NOTRUN]
|
||||
if (os == "win") and not debug and (processor == "x86"): [NOTRUN, PASS]
|
||||
|
||||
[IDBIndex.getAllKeys() returns correct result for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [PASS, NOTRUN]
|
||||
if (os == "win") and not debug and (processor == "x86"): [NOTRUN, PASS, TIMEOUT]
|
||||
|
||||
[IDBIndex.getAll() for an index not covering the autoincrement key]
|
||||
expected:
|
||||
if (os == "win") and not debug and (processor == "x86_64"): [PASS, NOTRUN]
|
||||
if (os == "win") and not debug and (processor == "x86"): NOTRUN
|
Loading…
Reference in New Issue
Block a user