| Differences between
and this patch
- a/Source/WebCore/ChangeLog +51 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2012-06-21  Alec Flett  <alecflett@chromium.org>
2
3
        IndexedDB: Implement spec behavior for multiEntry indexes with invalid/duplicate subkeys
4
        https://bugs.webkit.org/show_bug.cgi?id=86123
5
6
        Reviewed by Darin Fisher.
7
8
        Distinguish between an actual invalid IDBKey, and an array of
9
        possibly-invalid subkeys by making IDBKey::isValid() check subkeys
10
        if the type is an array.
11
12
        Introduce a new way to transform an IDBKey into a
13
        multiEntry-specific IDBKey, (IDBKey::createMultiEntryArray)
14
        throwing out duplicates and invalid keys. Use it when storing
15
        index entries for multiEntry indexes.
16
17
        No new tests: existing tests have been altered to include new behavior.
18
19
        * Modules/indexeddb/IDBCursor.cpp:
20
        (WebCore::IDBCursor::continueFunction):
21
        * Modules/indexeddb/IDBFactory.cpp:
22
        (WebCore::IDBFactory::cmp):
23
        * Modules/indexeddb/IDBIndex.cpp:
24
        (WebCore::IDBIndex::get):
25
        (WebCore::IDBIndex::getKey):
26
        * Modules/indexeddb/IDBKey.cpp:
27
        (WebCore::IDBKey::isValid):
28
        (WebCore):
29
        * Modules/indexeddb/IDBKey.h:
30
        (WebCore::IDBKey::createMultiEntryArray):
31
        (IDBKey):
32
        * Modules/indexeddb/IDBKeyRange.cpp:
33
        (WebCore::IDBKeyRange::only):
34
        (WebCore::IDBKeyRange::lowerBound):
35
        (WebCore::IDBKeyRange::upperBound):
36
        (WebCore::IDBKeyRange::bound):
37
        * Modules/indexeddb/IDBLevelDBBackingStore.cpp:
38
        (WebCore::IDBLevelDBBackingStore::putObjectStoreRecord):
39
        (WebCore::IDBLevelDBBackingStore::putIndexDataForRecord):
40
        * Modules/indexeddb/IDBLevelDBCoding.cpp:
41
        (WebCore::IDBLevelDBCoding::encodeIDBKey):
42
        * Modules/indexeddb/IDBObjectStore.cpp:
43
        (WebCore::IDBObjectStore::get):
44
        (WebCore::IDBObjectStore::add):
45
        (WebCore::IDBObjectStore::put):
46
        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
47
        (WebCore::IDBObjectStoreBackendImpl::putInternal):
48
        (WebCore):
49
        * bindings/v8/IDBBindingUtilities.cpp:
50
        (WebCore::createIDBKeyFromValue):
51
1
2012-06-21  Tim Horton  <timothy_horton@apple.com>
52
2012-06-21  Tim Horton  <timothy_horton@apple.com>
2
53
3
        SVGImageCache isn't invalidated for <img> on dynamic page scale changes
54
        SVGImageCache isn't invalidated for <img> on dynamic page scale changes
- a/Source/WebKit/chromium/ChangeLog +16 lines
Lines 1-3 a/Source/WebKit/chromium/ChangeLog_sec1
1
2012-06-21  Alec Flett  <alecflett@chromium.org>
2
3
        IndexedDB: Implement spec behavior for multiEntry indexes with invalid/duplicate subkeys
4
        https://bugs.webkit.org/show_bug.cgi?id=86123
5
6
        Reviewed by Darin Fisher.
7
8
        Add matching isValid() to WebIDBKey to match the one in IDBKey.
9
10
        * public/WebIDBKey.h:
11
        * src/WebIDBKey.cpp:
12
        (WebKit::WebIDBKey::isValid):
13
        (WebKit):
14
        * src/WebIDBKeyRange.cpp:
15
        (WebKit::WebIDBKeyRange::assign):
16
1
2012-06-21  Min Qin  <qinmin@chromium.org>
17
2012-06-21  Min Qin  <qinmin@chromium.org>
2
18
3
        remove ENABLE_FULLSCREEN_MEDIA_CONTROL flag
19
        remove ENABLE_FULLSCREEN_MEDIA_CONTROL flag
- a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp -1 / +1 lines
Lines 183-189 void IDBCursor::advance(unsigned long count, ExceptionCode& ec) a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp_sec1
183
void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
183
void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionCode& ec)
184
{
184
{
185
    IDB_TRACE("IDBCursor::continue");
185
    IDB_TRACE("IDBCursor::continue");
186
    if (key && (key->type() == IDBKey::InvalidType)) {
186
    if (key && !key->isValid()) {
187
        ec = IDBDatabaseException::DATA_ERR;
187
        ec = IDBDatabaseException::DATA_ERR;
188
        return;
188
        return;
189
    }
189
    }
- a/Source/WebCore/Modules/indexeddb/IDBFactory.cpp -1 / +1 lines
Lines 133-139 short IDBFactory::cmp(PassRefPtr<IDBKey> first, PassRefPtr<IDBKey> second, Excep a/Source/WebCore/Modules/indexeddb/IDBFactory.cpp_sec1
133
    ASSERT(first);
133
    ASSERT(first);
134
    ASSERT(second);
134
    ASSERT(second);
135
135
136
    if (first->type() == IDBKey::InvalidType || second->type() == IDBKey::InvalidType) {
136
    if (!first->isValid() || !second->isValid()) {
137
        ec = IDBDatabaseException::DATA_ERR;
137
        ec = IDBDatabaseException::DATA_ERR;
138
        return 0;
138
        return 0;
139
    }    
139
    }    
- a/Source/WebCore/Modules/indexeddb/IDBKey.cpp +15 lines
Lines 40-45 IDBKey::~IDBKey() a/Source/WebCore/Modules/indexeddb/IDBKey.cpp_sec1
40
{
40
{
41
}
41
}
42
42
43
bool IDBKey::isValid() const
44
{
45
    if (m_type == InvalidType)
46
        return false;
47
48
    if (m_type == ArrayType) {
49
        for (size_t i = 0; i < m_array.size(); i++) {
50
            if (!m_array[i]->isValid())
51
                return false;
52
        }
53
    }
54
55
    return true;
56
}
57
43
int IDBKey::compare(const IDBKey* other) const
58
int IDBKey::compare(const IDBKey* other) const
44
{
59
{
45
    ASSERT(other);
60
    ASSERT(other);
- a/Source/WebCore/Modules/indexeddb/IDBKey.h -1 / +27 lines
Lines 73-78 public: a/Source/WebCore/Modules/indexeddb/IDBKey.h_sec1
73
        return idbKey.release();
73
        return idbKey.release();
74
    }
74
    }
75
75
76
    static PassRefPtr<IDBKey> createMultiEntryArray(const KeyArray& array)
77
    {
78
        RefPtr<IDBKey> idbKey = adoptRef(new IDBKey());
79
        idbKey->m_type = ArrayType;
80
        KeyArray& result = idbKey->m_array;
81
82
        for (size_t i = 0; i < array.size(); i++) {
83
            if (!array[i]->isValid())
84
                continue;
85
86
            bool skip = false;
87
            for (size_t j = 0; j < result.size(); j++) {
88
                if (array[i]->isEqual(result[j].get())) {
89
                    skip = true;
90
                    break;
91
                }
92
            }
93
            if (!skip) {
94
                result.append(array[i]);
95
                idbKey->m_sizeEstimate += array[i]->m_sizeEstimate;
96
            }
97
        }
98
        ASSERT(idbKey->isValid());
99
        return idbKey.release();
100
    }
101
76
    static PassRefPtr<IDBKey> createArray(const KeyArray& array)
102
    static PassRefPtr<IDBKey> createArray(const KeyArray& array)
77
    {
103
    {
78
        RefPtr<IDBKey> idbKey = adoptRef(new IDBKey());
104
        RefPtr<IDBKey> idbKey = adoptRef(new IDBKey());
Lines 98-104 public: a/Source/WebCore/Modules/indexeddb/IDBKey.h_sec2
98
    };
124
    };
99
125
100
    Type type() const { return m_type; }
126
    Type type() const { return m_type; }
101
    bool isValid() const { return m_type != InvalidType; }
127
    bool isValid() const;
102
128
103
    const KeyArray& array() const
129
    const KeyArray& array() const
104
    {
130
    {
- a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp +2 lines
Lines 587-592 static int64_t getNewVersionNumber(LevelDBTransaction* transaction, int64_t data a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp_sec1
587
587
588
bool IDBLevelDBBackingStore::putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, ObjectStoreRecordIdentifier* recordIdentifier)
588
bool IDBLevelDBBackingStore::putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, ObjectStoreRecordIdentifier* recordIdentifier)
589
{
589
{
590
    ASSERT(key.isValid());
590
    ASSERT(m_currentTransaction);
591
    ASSERT(m_currentTransaction);
591
    int64_t version = getNewVersionNumber(m_currentTransaction.get(), databaseId, objectStoreId);
592
    int64_t version = getNewVersionNumber(m_currentTransaction.get(), databaseId, objectStoreId);
592
    const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
593
    const Vector<char> objectStoredataKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
Lines 869-874 void IDBLevelDBBackingStore::deleteIndex(int64_t databaseId, int64_t objectStore a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp_sec2
869
870
870
bool IDBLevelDBBackingStore::putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, const ObjectStoreRecordIdentifier* recordIdentifier)
871
bool IDBLevelDBBackingStore::putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, const ObjectStoreRecordIdentifier* recordIdentifier)
871
{
872
{
873
    ASSERT(key.isValid());
872
    ASSERT(indexId >= kMinimumIndexId);
874
    ASSERT(indexId >= kMinimumIndexId);
873
    const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier);
875
    const LevelDBRecordIdentifier* levelDBRecordIdentifier = static_cast<const LevelDBRecordIdentifier*>(recordIdentifier);
874
876
- a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp +1 lines
Lines 387-392 Vector<char> encodeIDBKey(const IDBKey& key) a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp_sec1
387
void encodeIDBKey(const IDBKey& key, Vector<char>& into)
387
void encodeIDBKey(const IDBKey& key, Vector<char>& into)
388
{
388
{
389
    size_t previousSize = into.size();
389
    size_t previousSize = into.size();
390
    ASSERT(key.isValid());
390
    switch (key.type()) {
391
    switch (key.type()) {
391
    case IDBKey::InvalidType:
392
    case IDBKey::InvalidType:
392
    case IDBKey::MinType:
393
    case IDBKey::MinType:
- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp -2 / +2 lines
Lines 126-132 PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, Pass a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp_sec1
126
        return 0;
126
        return 0;
127
    }
127
    }
128
128
129
    if (key && (key->type() == IDBKey::InvalidType)) {
129
    if (key && !key->isValid()) {
130
        ec = IDBDatabaseException::DATA_ERR;
130
        ec = IDBDatabaseException::DATA_ERR;
131
        return 0;
131
        return 0;
132
    }
132
    }
Lines 159-165 PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, Pass a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp_sec2
159
        return 0;
159
        return 0;
160
    }
160
    }
161
161
162
    if (key && (key->type() == IDBKey::InvalidType)) {
162
    if (key && !key->isValid()) {
163
        ec = IDBDatabaseException::DATA_ERR;
163
        ec = IDBDatabaseException::DATA_ERR;
164
        return 0;
164
        return 0;
165
    }
165
    }
- a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp -2 / +7 lines
Lines 264-269 void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp_sec1
264
        const RefPtr<IDBIndexBackendImpl>& index = it->second;
264
        const RefPtr<IDBIndexBackendImpl>& index = it->second;
265
265
266
        RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
266
        RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
267
        if (indexKey && index->multiEntry() && indexKey->type() == IDBKey::ArrayType)
268
            indexKey = IDBKey::createMultiEntryArray(indexKey->array());
269
267
        if (!indexKey || !indexKey->isValid()) {
270
        if (!indexKey || !indexKey->isValid()) {
268
            // Null/invalid keys not added to index; null entry keeps iterator/vector indexes consistent.
271
            // Null/invalid keys not added to index; null entry keeps iterator/vector indexes consistent.
269
            indexKey.clear();
272
            indexKey.clear();
Lines 279-285 void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp_sec2
279
        }
282
        }
280
283
281
        if (index->multiEntry() && indexKey->type() == IDBKey::ArrayType) {
284
        if (index->multiEntry() && indexKey->type() == IDBKey::ArrayType) {
282
           for (size_t j = 0; j < indexKey->array().size(); ++j) {
285
            for (size_t j = 0; j < indexKey->array().size(); ++j) {
283
                if (!index->addingKeyAllowed(indexKey->array()[j].get(), key.get())) {
286
                if (!index->addingKeyAllowed(indexKey->array()[j].get(), key.get())) {
284
                    objectStore->resetAutoIncrementKeyCache();
287
                    objectStore->resetAutoIncrementKeyCache();
285
                    callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements."));
288
                    callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements."));
Lines 426-433 public: a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp_sec3
426
        } else {
429
        } else {
427
            ASSERT(m_index->multiEntry());
430
            ASSERT(m_index->multiEntry());
428
            ASSERT(indexKey->type() == IDBKey::ArrayType);
431
            ASSERT(indexKey->type() == IDBKey::ArrayType);
432
433
            indexKey = IDBKey::createMultiEntryArray(indexKey->array());
429
            for (size_t i = 0; i < indexKey->array().size(); ++i) {
434
            for (size_t i = 0; i < indexKey->array().size(); ++i) {
430
                if (!m_index->addingKeyAllowed(indexKey.get()))
435
                if (!m_index->addingKeyAllowed(indexKey->array()[i].get()))
431
                    return false;
436
                    return false;
432
                if (!m_backingStore.putIndexDataForRecord(m_databaseId, m_objectStoreId, m_index->id(), *indexKey->array()[i], recordIdentifier))
437
                if (!m_backingStore.putIndexDataForRecord(m_databaseId, m_objectStoreId, m_index->id(), *indexKey->array()[i], recordIdentifier))
433
                    return false;
438
                    return false;
- a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp -2 / +3 lines
Lines 65-72 static PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value, Vec a/Source/WebCore/bindings/v8/IDBBindingUtilities.cpp_sec1
65
            v8::Local<v8::Value> item = array->Get(v8::Int32::New(i));
65
            v8::Local<v8::Value> item = array->Get(v8::Int32::New(i));
66
            RefPtr<IDBKey> subkey = createIDBKeyFromValue(item, stack);
66
            RefPtr<IDBKey> subkey = createIDBKeyFromValue(item, stack);
67
            if (!subkey)
67
            if (!subkey)
68
                return 0;
68
                subkeys.append(IDBKey::createInvalid());
69
            subkeys.append(subkey);
69
            else
70
                subkeys.append(subkey);
70
        }
71
        }
71
72
72
        stack.removeLast();
73
        stack.removeLast();
- a/Source/WebKit/chromium/public/WebIDBKey.h +1 lines
Lines 79-84 public: a/Source/WebKit/chromium/public/WebIDBKey.h_sec1
79
    };
79
    };
80
80
81
    WEBKIT_EXPORT Type type() const;
81
    WEBKIT_EXPORT Type type() const;
82
    WEBKIT_EXPORT bool isValid() const;
82
    WEBKIT_EXPORT WebVector<WebIDBKey> array() const; // Only valid for ArrayType.
83
    WEBKIT_EXPORT WebVector<WebIDBKey> array() const; // Only valid for ArrayType.
83
    WEBKIT_EXPORT WebString string() const; // Only valid for StringType.
84
    WEBKIT_EXPORT WebString string() const; // Only valid for StringType.
84
    WEBKIT_EXPORT double date() const; // Only valid for DateType.
85
    WEBKIT_EXPORT double date() const; // Only valid for DateType.
- a/Source/WebKit/chromium/src/WebIDBKey.cpp +11 lines
Lines 120-125 static PassRefPtr<IDBKey> convertFromWebIDBKeyArray(const WebVector<WebIDBKey>& a/Source/WebKit/chromium/src/WebIDBKey.cpp_sec1
120
            keys.append(IDBKey::createNumber(array[i].number()));
120
            keys.append(IDBKey::createNumber(array[i].number()));
121
            break;
121
            break;
122
        case WebIDBKey::InvalidType:
122
        case WebIDBKey::InvalidType:
123
            keys.append(IDBKey::createInvalid());
124
            break;
123
        case WebIDBKey::NullType:
125
        case WebIDBKey::NullType:
124
            ASSERT_NOT_REACHED();
126
            ASSERT_NOT_REACHED();
125
            break;
127
            break;
Lines 149-154 static void convertToWebIDBKeyArray(const IDBKey::KeyArray& array, WebVector<Web a/Source/WebKit/chromium/src/WebIDBKey.cpp_sec2
149
            keys[i] = WebIDBKey::createNumber(key->number());
151
            keys[i] = WebIDBKey::createNumber(key->number());
150
            break;
152
            break;
151
        case IDBKey::InvalidType:
153
        case IDBKey::InvalidType:
154
            keys[i] = WebIDBKey::createInvalid();
155
            break;
152
        case IDBKey::MinType:
156
        case IDBKey::MinType:
153
            ASSERT_NOT_REACHED();
157
            ASSERT_NOT_REACHED();
154
            break;
158
            break;
Lines 199-204 WebIDBKey::Type WebIDBKey::type() const a/Source/WebKit/chromium/src/WebIDBKey.cpp_sec3
199
    return Type(m_private->type());
203
    return Type(m_private->type());
200
}
204
}
201
205
206
bool WebIDBKey::isValid() const
207
{
208
    if (!m_private.get())
209
        return false;
210
    return m_private->isValid();
211
}
212
202
WebVector<WebIDBKey> WebIDBKey::array() const
213
WebVector<WebIDBKey> WebIDBKey::array() const
203
{
214
{
204
    WebVector<WebIDBKey> keys;
215
    WebVector<WebIDBKey> keys;
- a/Source/WebKit/chromium/src/WebIDBKeyRange.cpp -1 / +1 lines
Lines 43-49 void WebIDBKeyRange::assign(const WebIDBKeyRange& other) a/Source/WebKit/chromium/src/WebIDBKeyRange.cpp_sec1
43
43
44
void WebIDBKeyRange::assign(const WebIDBKey& lower, const WebIDBKey& upper, bool lowerOpen, bool upperOpen)
44
void WebIDBKeyRange::assign(const WebIDBKey& lower, const WebIDBKey& upper, bool lowerOpen, bool upperOpen)
45
{
45
{
46
    if (lower.type() == WebIDBKey::InvalidType && upper.type() == WebIDBKey::InvalidType)
46
    if (!lower.isValid() && !upper.isValid())
47
        m_private = 0;
47
        m_private = 0;
48
    else
48
    else
49
        m_private = IDBKeyRange::create(lower, upper, lowerOpen ? IDBKeyRange::LowerBoundOpen : IDBKeyRange::LowerBoundClosed, upperOpen ? IDBKeyRange::UpperBoundOpen : IDBKeyRange::UpperBoundClosed);
49
        m_private = IDBKeyRange::create(lower, upper, lowerOpen ? IDBKeyRange::LowerBoundOpen : IDBKeyRange::LowerBoundClosed, upperOpen ? IDBKeyRange::UpperBoundOpen : IDBKeyRange::UpperBoundClosed);
- a/LayoutTests/ChangeLog +17 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2012-06-21  Alec Flett  <alecflett@chromium.org>
2
3
        IndexedDB: Implement spec behavior for multiEntry indexes with invalid/duplicate subkeys
4
        https://bugs.webkit.org/show_bug.cgi?id=86123
5
6
        Reviewed by Darin Fisher.
7
8
        * storage/indexeddb/index-multientry-expected.txt:
9
        * storage/indexeddb/resources/index-multientry.js:
10
        (addData):
11
        (verifyIndexes.request.onsuccess):
12
        (verifyIndexes):
13
        (verifyUniqueConstraint.request.onsuccess.request.onsuccess.request.onerror):
14
        (verifyUniqueConstraint.request.onsuccess.request.onsuccess):
15
        (verifyUniqueConstraint.request.onsuccess):
16
        (verifyUniqueConstraint):
17
1
2012-06-21  Tim Horton  <timothy_horton@apple.com>
18
2012-06-21  Tim Horton  <timothy_horton@apple.com>
2
19
3
        SVGImageCache isn't invalidated for <img> on dynamic page scale changes
20
        SVGImageCache isn't invalidated for <img> on dynamic page scale changes
- a/LayoutTests/storage/indexeddb/index-multientry-expected.txt -1 / +51 lines
Lines 25-30 transaction.objectStore('store').put({x: [7, 8, 9], y: 'a'}, 'foo') a/LayoutTests/storage/indexeddb/index-multientry-expected.txt_sec1
25
Now overwrite them with what we're expecting
25
Now overwrite them with what we're expecting
26
transaction.objectStore('store').put({x: [1, 2, 3], y: 'a'}, 'foo')
26
transaction.objectStore('store').put({x: [1, 2, 3], y: 'a'}, 'foo')
27
transaction.objectStore('store').put({x: [4, 5, 6], y: 'b'}, 'bar')
27
transaction.objectStore('store').put({x: [4, 5, 6], y: 'b'}, 'bar')
28
transaction.objectStore('store').put({x: [7, 7, 8, 7], y: 'c'}, 'baz')
29
transaction.objectStore('store').put({x: [null, 9, 9], y: 'd'}, 'bloop')
28
30
29
Verifying index: index
31
Verifying index: index
30
transaction = db.transaction(['store'], 'readonly')
32
transaction = db.transaction(['store'], 'readonly')
Lines 34-64 PASS ex is non-null. a/LayoutTests/storage/indexeddb/index-multientry-expected.txt_sec2
34
PASS cursor.key is 1
36
PASS cursor.key is 1
35
PASS cursor.primaryKey is "foo"
37
PASS cursor.primaryKey is "foo"
36
PASS cursor.value.y is "a"
38
PASS cursor.value.y is "a"
39
cursor.continue()
37
cursor = event.target.result
40
cursor = event.target.result
38
PASS ex is non-null.
41
PASS ex is non-null.
39
PASS cursor.key is 2
42
PASS cursor.key is 2
40
PASS cursor.primaryKey is "foo"
43
PASS cursor.primaryKey is "foo"
41
PASS cursor.value.y is "a"
44
PASS cursor.value.y is "a"
45
cursor.continue()
42
cursor = event.target.result
46
cursor = event.target.result
43
PASS ex is non-null.
47
PASS ex is non-null.
44
PASS cursor.key is 3
48
PASS cursor.key is 3
45
PASS cursor.primaryKey is "foo"
49
PASS cursor.primaryKey is "foo"
46
PASS cursor.value.y is "a"
50
PASS cursor.value.y is "a"
51
cursor.continue()
47
cursor = event.target.result
52
cursor = event.target.result
48
PASS ex is non-null.
53
PASS ex is non-null.
49
PASS cursor.key is 4
54
PASS cursor.key is 4
50
PASS cursor.primaryKey is "bar"
55
PASS cursor.primaryKey is "bar"
51
PASS cursor.value.y is "b"
56
PASS cursor.value.y is "b"
57
cursor.continue()
52
cursor = event.target.result
58
cursor = event.target.result
53
PASS ex is non-null.
59
PASS ex is non-null.
54
PASS cursor.key is 5
60
PASS cursor.key is 5
55
PASS cursor.primaryKey is "bar"
61
PASS cursor.primaryKey is "bar"
56
PASS cursor.value.y is "b"
62
PASS cursor.value.y is "b"
63
cursor.continue()
57
cursor = event.target.result
64
cursor = event.target.result
58
PASS ex is non-null.
65
PASS ex is non-null.
59
PASS cursor.key is 6
66
PASS cursor.key is 6
60
PASS cursor.primaryKey is "bar"
67
PASS cursor.primaryKey is "bar"
61
PASS cursor.value.y is "b"
68
PASS cursor.value.y is "b"
69
cursor.continue()
70
cursor = event.target.result
71
PASS ex is non-null.
72
PASS cursor.key is 7
73
PASS cursor.primaryKey is "baz"
74
PASS cursor.value.y is "c"
75
cursor.continue()
76
cursor = event.target.result
77
PASS ex is non-null.
78
PASS cursor.key is 8
79
PASS cursor.primaryKey is "baz"
80
PASS cursor.value.y is "c"
81
cursor.continue()
82
cursor = event.target.result
83
PASS ex is non-null.
84
PASS cursor.key is 9
85
PASS cursor.primaryKey is "bloop"
86
PASS cursor.value.y is "d"
87
cursor.continue()
62
cursor = event.target.result
88
cursor = event.target.result
63
PASS expected.length is 0
89
PASS expected.length is 0
64
90
Lines 71-77 transaction.objectStore('store-unique').put({x: [1, 2, 7], y: 'a'}, 'foo') a/LayoutTests/storage/indexeddb/index-multientry-expected.txt_sec3
71
success!
97
success!
72
This should fail the uniqueness constraint on the index, and fail:
98
This should fail the uniqueness constraint on the index, and fail:
73
transaction.objectStore('store-unique').put({x: [5, 2], y: 'c'}, 'should fail')
99
transaction.objectStore('store-unique').put({x: [5, 2], y: 'c'}, 'should fail')
74
Request failed, as expected
100
Request failed, as expected (DataError)
75
Transaction aborted as expected
101
Transaction aborted as expected
76
102
77
Create an index on a populated store
103
Create an index on a populated store
Lines 89-119 PASS ex is non-null. a/LayoutTests/storage/indexeddb/index-multientry-expected.txt_sec4
89
PASS cursor.key is 1
115
PASS cursor.key is 1
90
PASS cursor.primaryKey is "foo"
116
PASS cursor.primaryKey is "foo"
91
PASS cursor.value.y is "a"
117
PASS cursor.value.y is "a"
118
cursor.continue()
92
cursor = event.target.result
119
cursor = event.target.result
93
PASS ex is non-null.
120
PASS ex is non-null.
94
PASS cursor.key is 2
121
PASS cursor.key is 2
95
PASS cursor.primaryKey is "foo"
122
PASS cursor.primaryKey is "foo"
96
PASS cursor.value.y is "a"
123
PASS cursor.value.y is "a"
124
cursor.continue()
97
cursor = event.target.result
125
cursor = event.target.result
98
PASS ex is non-null.
126
PASS ex is non-null.
99
PASS cursor.key is 3
127
PASS cursor.key is 3
100
PASS cursor.primaryKey is "foo"
128
PASS cursor.primaryKey is "foo"
101
PASS cursor.value.y is "a"
129
PASS cursor.value.y is "a"
130
cursor.continue()
102
cursor = event.target.result
131
cursor = event.target.result
103
PASS ex is non-null.
132
PASS ex is non-null.
104
PASS cursor.key is 4
133
PASS cursor.key is 4
105
PASS cursor.primaryKey is "bar"
134
PASS cursor.primaryKey is "bar"
106
PASS cursor.value.y is "b"
135
PASS cursor.value.y is "b"
136
cursor.continue()
107
cursor = event.target.result
137
cursor = event.target.result
108
PASS ex is non-null.
138
PASS ex is non-null.
109
PASS cursor.key is 5
139
PASS cursor.key is 5
110
PASS cursor.primaryKey is "bar"
140
PASS cursor.primaryKey is "bar"
111
PASS cursor.value.y is "b"
141
PASS cursor.value.y is "b"
142
cursor.continue()
112
cursor = event.target.result
143
cursor = event.target.result
113
PASS ex is non-null.
144
PASS ex is non-null.
114
PASS cursor.key is 6
145
PASS cursor.key is 6
115
PASS cursor.primaryKey is "bar"
146
PASS cursor.primaryKey is "bar"
116
PASS cursor.value.y is "b"
147
PASS cursor.value.y is "b"
148
cursor.continue()
149
cursor = event.target.result
150
PASS ex is non-null.
151
PASS cursor.key is 7
152
PASS cursor.primaryKey is "baz"
153
PASS cursor.value.y is "c"
154
cursor.continue()
155
cursor = event.target.result
156
PASS ex is non-null.
157
PASS cursor.key is 8
158
PASS cursor.primaryKey is "baz"
159
PASS cursor.value.y is "c"
160
cursor.continue()
161
cursor = event.target.result
162
PASS ex is non-null.
163
PASS cursor.key is 9
164
PASS cursor.primaryKey is "bloop"
165
PASS cursor.value.y is "d"
166
cursor.continue()
117
cursor = event.target.result
167
cursor = event.target.result
118
PASS expected.length is 0
168
PASS expected.length is 0
119
PASS successfullyParsed is true
169
PASS successfullyParsed is true
- a/LayoutTests/storage/indexeddb/resources/index-multientry.js -2 / +9 lines
Lines 54-59 function addData() a/LayoutTests/storage/indexeddb/resources/index-multientry.js_sec1
54
    request.onerror = unexpectedErrorCallback;
54
    request.onerror = unexpectedErrorCallback;
55
    request = evalAndLog("transaction.objectStore('store').put({x: [4, 5, 6], y: 'b'}, 'bar')");
55
    request = evalAndLog("transaction.objectStore('store').put({x: [4, 5, 6], y: 'b'}, 'bar')");
56
    request.onerror = unexpectedErrorCallback;
56
    request.onerror = unexpectedErrorCallback;
57
    request = evalAndLog("transaction.objectStore('store').put({x: [7, 7, 8, 7], y: 'c'}, 'baz')");
58
    request.onerror = unexpectedErrorCallback;
59
    request = evalAndLog("transaction.objectStore('store').put({x: [null, 9, 9], y: 'd'}, 'bloop')");
60
    request.onerror = unexpectedErrorCallback;
57
}
61
}
58
62
59
function verifyIndexes(indexName, callback)
63
function verifyIndexes(indexName, callback)
Lines 71-76 function verifyIndexes(indexName, callback) a/LayoutTests/storage/indexeddb/resources/index-multientry.js_sec2
71
        { key: 4, primaryKey: 'bar', y: 'b' },
75
        { key: 4, primaryKey: 'bar', y: 'b' },
72
        { key: 5, primaryKey: 'bar', y: 'b' },
76
        { key: 5, primaryKey: 'bar', y: 'b' },
73
        { key: 6, primaryKey: 'bar', y: 'b' },
77
        { key: 6, primaryKey: 'bar', y: 'b' },
78
        { key: 7, primaryKey: 'baz', y: 'c' },
79
        { key: 8, primaryKey: 'baz', y: 'c' },
80
        { key: 9, primaryKey: 'bloop', y: 'd' },
74
    ];
81
    ];
75
82
76
    var request = evalAndLog("transaction.objectStore('store').index('" + indexName + "').openCursor()");
83
    var request = evalAndLog("transaction.objectStore('store').index('" + indexName + "').openCursor()");
Lines 83-89 function verifyIndexes(indexName, callback) a/LayoutTests/storage/indexeddb/resources/index-multientry.js_sec3
83
            shouldBe("cursor.key", String(ex.key));
90
            shouldBe("cursor.key", String(ex.key));
84
            shouldBeEqualToString("cursor.primaryKey", ex.primaryKey);
91
            shouldBeEqualToString("cursor.primaryKey", ex.primaryKey);
85
            shouldBeEqualToString("cursor.value.y", ex.y);
92
            shouldBeEqualToString("cursor.value.y", ex.y);
86
            cursor.continue();
93
            evalAndLog("cursor.continue()");
87
        } else {
94
        } else {
88
            shouldBe("expected.length", "0");
95
            shouldBe("expected.length", "0");
89
        }
96
        }
Lines 113-119 function verifyUniqueConstraint() a/LayoutTests/storage/indexeddb/resources/index-multientry.js_sec4
113
            debug("This should fail the uniqueness constraint on the index, and fail:");
120
            debug("This should fail the uniqueness constraint on the index, and fail:");
114
            request = evalAndLog("transaction.objectStore('store-unique').put({x: [5, 2], y: 'c'}, 'should fail')");
121
            request = evalAndLog("transaction.objectStore('store-unique').put({x: [5, 2], y: 'c'}, 'should fail')");
115
            request.onsuccess = unexpectedSuccessCallback;
122
            request.onsuccess = unexpectedSuccessCallback;
116
            request.onerror = function() { debug("Request failed, as expected"); };
123
            request.onerror = function() { debug("Request failed, as expected (" + request.error.name + ")"); };
117
        };
124
        };
118
    };
125
    };
119
}
126
}

Return to Bug 86123