minor fixes

This commit is contained in:
Ilya Kantor 2021-03-13 23:21:10 +03:00
parent 7ad529e27d
commit bbf60dd340

View file

@ -131,9 +131,7 @@ In order to organize that, the `versionchange` event triggers on the "outdated"
If we don't listen for the `versionchange` event and don't close the old connection, then the second, new connection won't be made. The `openRequest` object will emit the `blocked` event instead of `success`. So the second tab won't work.
Here's the code to correctly handle the parallel upgrade.
It installs an `onversionchange` handler after the database is opened, that closes the old connection:
Here's the code to correctly handle the parallel upgrade. It installs the `onversionchange` handler, that triggers if the current database connection becomes outdated (db version is updated elsewhere) and closes the connection.
```js
let openRequest = indexedDB.open("store", 2);
@ -164,14 +162,16 @@ openRequest.onblocked = function() {
*/!*
```
Here we do two things:
...In other words, here we do two things:
1. Add `db.onversionchange` listener after a successful opening, to be informed about a parallel update attempt.
2. Add `openRequest.onblocked` listener to handle the case when an old connection wasn't closed. This doesn't happen if we close it in `db.onversionchange`.
1. The `db.onversionchange` listener informs us about a parallel update attempt, if the current database version becomes outdated.
2. The `openRequest.onblocked` listener informs us about the opposite situation: there's a connection to an outdated version elsewhere, and it doesn't close, so the newer connection can't be made.
There are other variants. For example, we can take the time to close things gracefully in `db.onversionchange`, and prompt the visitor to save the data before the connection is closed. The new updating connection will be blocked immediately after `db.onversionchange` has finished without closing, and we can ask the visitor in the new tab to close other tabs for the update.
We can handle things more gracefully in `db.onversionchange`, prompt the visitor to save the data before the connection is closed and so on.
These update collisions happen rarely, but we should at least have some handling for them, e.g. `onblocked` handler, so that our script doesn't surprise the user by dying silently.
Or, an alternative approach would be to not close the database in `db.onversionchange`, but instead use the `onblocked` handler (in the new tab) to alert the visitor, tell him that the newer version can't be loaded until they close other tabs.
These update collisions happen rarely, but we should at least have some handling for them, at least `onblocked` handler, to prevent our script from dying silently.
## Object store
@ -475,24 +475,29 @@ request.onerror = function(event) {
};
```
## Searching by keys
## Searching
There are two main types of search in an object store:
1. By a key or a key range. That is: by `book.id` in our "books" storage.
2. By another object field, e.g. `book.price`.
First let's deal with the first type of search: by a key.
1. By a key value or a key range. In our "books" storage that would be a value or range of values of `book.id`.
2. By another object field, e.g. `book.price`. This required an additional data structure, named "index".
Searching methods support both exact keys and so-called "ranges" -- [IDBKeyRange](https://www.w3.org/TR/IndexedDB/#keyrange) objects that specify an acceptable "key range".
### By key
Ranges are created using following calls:
First let's deal with the first type of search: by key.
Searching methods support both exact key values and so-called "ranges of values" -- [IDBKeyRange](https://www.w3.org/TR/IndexedDB/#keyrange) objects that specify an acceptable "key range".
`IDBKeyRange` objects are created using following calls:
- `IDBKeyRange.lowerBound(lower, [open])` means: `≥lower` (or `>lower` if `open` is true)
- `IDBKeyRange.upperBound(upper, [open])` means: `≤upper` (or `<upper` if `open` is true)
- `IDBKeyRange.bound(lower, upper, [lowerOpen], [upperOpen])` means: between `lower` and `upper`. If the open flags is true, the corresponding key is not included in the range.
- `IDBKeyRange.only(key)` -- a range that consists of only one `key`, rarely used.
Searching methods accept a `query` argument that can be either an exact key or a key range:
We'll see practical examples of using them very soon.
To perform the actual search, there are following methods. They accept a `query` argument that can be either an exact key or a key range:
- `store.get(query)` -- search for the first value by a key or a range.
- `store.getAll([query], [count])` -- search for all values, limit by `count` if given.
@ -522,13 +527,12 @@ books.getAllKeys(IDBKeyRange.lowerBound('js', true))
```
```smart header="Object store is always sorted"
Object store sorts values by key internally.
An object store sorts values by key internally.
So requests that return many values always return them in sorted by key order.
```
## Searching by any field with an index
### By a field using an index
To search by other object fields, we need to create an additional data structure named "index".