Basically, if you have objectStores 'students' with an index 'name' and 'schools' with an index 'city', and you query the 'name' index on 'students' with no range specified (or WITH a range - it doesnt matter), you will get a cursor that iterates a mix of student names and cities. Each onsuccess callback from the cursor will have a key that sometimes is a student name and sometimes a city. The value though is always a student and some students are shown multiple times - one time with the name key and another time with a city key.
Last active
September 22, 2016 22:33
-
-
Save dfahlander/a7a0608513d527742c5a09e3c95dd343 to your computer and use it in GitHub Desktop.
Repro of IndexedDB bug in Safari10 (webkit bug #158833)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<script> | |
const log = txt => document.writeln(`${txt}<br/>`); | |
log("Deleting db"); | |
indexedDB.deleteDatabase("db").onsuccess = ()=> { | |
log("db deleted"); | |
let req = indexedDB.open("db", 1); | |
req.onupgradeneeded = e => { | |
log ("Creating db"); | |
let db = req.transaction.db; | |
let schools = db.createObjectStore('schools', { keyPath: 'id', autoIncrement: true }); | |
schools.createIndex ('city', 'city'); | |
schools.add({name: 'Stockholm University', city: 'Stockholm'}); | |
schools.add({name: 'Uppsala University', city: 'Uppsala'}); | |
schools.add({name: 'Chalmers', city: 'Gothenburg'}); | |
let students = db.createObjectStore('students', { keyPath: 'id', autoIncrement: true }); | |
students.createIndex ('name', 'name'); | |
students.add({name: 'Adam Anderson'}); | |
students.add({name: 'Bertil Bengtson'}); | |
} | |
req.onsuccess = ()=> { | |
let db = req.result; | |
let tx = db.transaction(['schools', 'students'], 'readonly'); | |
dump(tx.objectStore('schools'), ()=> { | |
dump(tx.objectStore('schools').index('city'), ()=> { | |
dump(tx.objectStore('students'), ()=>{ | |
dump(tx.objectStore('students').index('name'), ()=>{ | |
log("Done."); | |
}) | |
}); | |
}); | |
}); | |
} | |
} | |
function dump (idx, done) { | |
log (idx instanceof IDBObjectStore ? | |
`Enumerating ObjectStore '${idx.name}' by primary key` : | |
`Enumerating index '${idx.name}' on '${idx.objectStore.name}'`); | |
idx.openCursor().onsuccess = e => { | |
let cursor = e.target.result; | |
if (cursor) { | |
log(`key: ${cursor.key}, primaryKey: ${cursor.primaryKey}, value: ${JSON.stringify(cursor.value)}`); | |
cursor.continue(); | |
} else { | |
done(); | |
} | |
} | |
} | |
</script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
db deleted | |
Creating db | |
Enumerating ObjectStore 'schools' by primary key | |
key: 1, primaryKey: 1, value: {"name":"Stockholm University","city":"Stockholm","id":1} | |
key: 2, primaryKey: 2, value: {"name":"Uppsala University","city":"Uppsala","id":2} | |
key: 3, primaryKey: 3, value: {"name":"Chalmers","city":"Gothenburg","id":3} | |
Enumerating index 'city' on 'schools' | |
key: Gothenburg, primaryKey: 3, value: {"name":"Chalmers","city":"Gothenburg","id":3} | |
key: Stockholm, primaryKey: 1, value: {"name":"Stockholm University","city":"Stockholm","id":1} | |
key: Uppsala, primaryKey: 2, value: {"name":"Uppsala University","city":"Uppsala","id":2} | |
Enumerating ObjectStore 'students' by primary key | |
key: 1, primaryKey: 1, value: {"name":"Adam Anderson","id":1} | |
key: 2, primaryKey: 2, value: {"name":"Bertil Bengtson","id":2} | |
Enumerating index 'name' on 'students' | |
key: Adam Anderson, primaryKey: 1, value: {"name":"Adam Anderson","id":1} | |
key: Bertil Bengtson, primaryKey: 2, value: {"name":"Bertil Bengtson","id":2} | |
Done. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
db deleted | |
Creating db | |
Enumerating ObjectStore 'schools' by primary key | |
key: 1, primaryKey: 1, value: {"name":"Stockholm University","city":"Stockholm","id":1} | |
key: 2, primaryKey: 2, value: {"name":"Uppsala University","city":"Uppsala","id":2} | |
key: 3, primaryKey: 3, value: {"name":"Chalmers","city":"Gothenburg","id":3} | |
Enumerating index 'city' on 'schools' | |
key: Adam Anderson, primaryKey: 1, value: {"name":"Stockholm University","city":"Stockholm","id":1} | |
key: Bertil Bengtson, primaryKey: 2, value: {"name":"Uppsala University","city":"Uppsala","id":2} | |
key: Gothenburg, primaryKey: 3, value: {"name":"Chalmers","city":"Gothenburg","id":3} | |
key: Stockholm, primaryKey: 1, value: {"name":"Stockholm University","city":"Stockholm","id":1} | |
key: Uppsala, primaryKey: 2, value: {"name":"Uppsala University","city":"Uppsala","id":2} | |
Enumerating ObjectStore 'students' by primary key | |
key: 1, primaryKey: 1, value: {"name":"Adam Anderson","id":1} | |
key: 2, primaryKey: 2, value: {"name":"Bertil Bengtson","id":2} | |
Enumerating index 'name' on 'students' | |
key: Adam Anderson, primaryKey: 1, value: {"name":"Adam Anderson","id":1} | |
key: Bertil Bengtson, primaryKey: 2, value: {"name":"Bertil Bengtson","id":2} | |
key: Stockholm, primaryKey: 1, value: {"name":"Adam Anderson","id":1} | |
key: Uppsala, primaryKey: 2, value: {"name":"Bertil Bengtson","id":2} | |
Done. |
Update : bug was fixed today by Bradley Eidson at Apple. Thanks! :-)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tested with Safari 10.0 (12602.1.38.2) on browserstack.com.
As you can see, on Safari 10, IDBIndex.openCursor() will iterate the mix of keys in the index itself and other indexes on other stores.
The diff's first unexpected output is at line 8, where a city was expected, but it is iterating a key from another store.