Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
## 4.0.0

* Breaking API change (minor)/Feature: `delStore` will no longer throw upon
being called with a store not present (in case one wishes to delete a store
which is still existing but was not added by idb-schema). (If `delStore`
does throw later (or if there is any other upgrade error), the error
can now be caught by `callback` or `open`/`upgrade`.)
* API change: During upgrades, stores and indexes slated for deletion will
be deleted before those slated for creation (allowing one to rebuild a
store or index--bearing in mind that rebuilding a store will not preserve
its data)
* Fix: Allow stores, indexes, and store `keyPath`s to be an empty string
* Fix: Allow `autoIncrement` with non-empty string `keyPath`s but disallow
arrays and empty string
* Fix: Throw proper exceptions (as would be thrown if sent to IndexedDB at
run-time)
* Feature: Allow `delStore` to pass in name not present within schema (in
case added previously).
* Feature: Add `open` and `upgrade` methods to allow a sequence of upgrades
which can support promises returned by `addCallback` callbacks (and a
`flushIncomplete` method for flushing storage pertaining to incomplete
upgrades)
* Feature: Add `addEarlyCallback` to allow use of `idb-schema` methods
within these synchronous callbacks
* Feature: Support `errBack` argument to `callback`
* Feature: Support object store argument supplied to `getStore`
* Feature: `version(number)` will now allow inputting versions out of order,
but the getter will continue to get the highest version. To get the current
rather than highest version, the method `lastEnteredVersion()` has been
added.

## 3.2.1 / 2015-11-29

* remove `component-clone` as deps,
Expand Down
151 changes: 147 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ schema.stores()

## API

### schema.callback()
### schema.callback([errBack])

Generate `onupgradeneeded` callback.

Expand All @@ -70,6 +70,92 @@ req.onsuccess = (e) => {
}
```

Note that this callback will not support `addCallback` callbacks if they rely
on promises and run transactions (since `upgradeneeded`'s transaction will
expire). You can instead use `schema.open` or `schema.upgrade`.

`callback` takes an optional `errBack` function which is passed an error
object (upon encountering any errors during the upgrade) as well as the
`upgradeneeded` event.

```js
const schema = new Schema().version(1).delStore('nonexistentStore')
open(dbName, schema.version(), schema.callback(function errBack(err /* , e */) {
throw new Error('Bad upgrade')
})).catch((err) => {
console.log(err.message) // 'Bad upgrade'
})
```

If no `errBack` is provided, the error responsible will be thrown and can
be caught by the consuming code.

### schema.open(dbName, [version])

With `schema.open`, in addition to getting upgrades applied (including
callbacks added by `addCallback` and even including promise-based callbacks
which utilize transactions), you can use the `db` result opened at the
latest version:

```js
schema.open('myDb', 3).then((db) => {
// Use db
})
```

However, unlike `callback()`, when `schema.open` is used, the callbacks
added by `addCallback` cannot handle operations such as adding stores
or indexes (though these operations can be executed with the other
methods of idb-schema anyways) though those added by `addEarlyCallback`
can be.

Besides conducting an upgrade, `schema.open` uses the `open` of
[idb-factory](https://github.com/treojs/idb-factory) behind the scenes, so
one can also catch errors and benefit from its fixing of browser quirks.

If a version is not supplied, the latest version available within the schema
will be used.

If you only wish to upgrade and do not wish to keep a connection open, use
`schema.upgrade`. If you wish to manage opening a connection yourself (and are
not using promises within `addCallback` callbacks), you can use
`schema.callback`.

Despite allowing for promise-based callbacks utilizing transactions, due to
[current limitations in IndexedDB](https://github.com/w3c/IndexedDB/issues/42),
we cannot get a transaction which encompasses both the store/index changes
and the store content changes, so it will not be possible to rollback the
entire version upgrade if the store/index changes transaction succeeds while
the store content change transaction fails. However, upon such a condition
idb-schema will set a `localStorage` property to disallow subsequent attempts
on `schema.open` or `schema.upgrade` to succeed until either the storage
property is manually flushed by the `flushIncomplete()` method or if the
`retry` method on the error object is invoked to return a Promise which will
reattempt to execute the failed callback and the rest of the upgrades and
which will resolve according to whether this next attempt was successful or
not.

### schema.upgrade(dbName, [version], [keepOpen=false])

Equivalent to `schema.open` but without keeping a connection open
(unless `keepOpen` is set to `true`):

```js
schema.upgrade('myDb', 3).then(() => {
// No database result is available for upgrades. Use `schema.open` if you
// wish to keep a connection to the latest version open
// for non-upgrade related transactions
})
```

### schema.flushIncomplete(dbName)

If there was an incomplete upgrade, this method will flush the local storage
used to signal to `schema.open`/`schema.upgrade` that they should not yet allow
opening until the upgrade is complete. This method should normally not be used
as it is important to ensure an upgrade occurs like a complete transaction, and
flushing will interfere with this.

### schema.stores()

Get JSON representation of database schema.
Expand Down Expand Up @@ -122,8 +208,16 @@ Get JSON representation of database schema.

### schema.version([number])

Get current version or set new version to `number` and reset current store.
Use it to separate migrations on time.
Gets the highest version or sets the new version to `number` and resets
the current store. Use it to separate migrations by time.

Note that `schema.version(number)` can now be used to add versions out of
order, but `schema.version()` will always return the highest version number.

### schema.lastEnteredVersion()

This gets the most recently entered version number. This should only
be needed by classes extending `idb-schema`.

### schema.addStore(name, [opts])

Expand All @@ -137,11 +231,26 @@ Options:

Delete store by `name`.

Note that if a non-existent store is provided, this method will
not immediately throw (since it is possible one may wish to use this
for deleting stores added prior to using `idb-schema`). You will be
able to catch the errors, however:

```js
const schema = new Schema().version(1).delStore('nonexistentStore')
return open(dbName, schema.version(), schema.callback()).catch((err) => {
console.log(err.name) // 'NotFoundError'
})
```

### schema.getStore(name)

Switch current store.
Use it to make operations with indexes.

This can be the name of a store, or it can also be an actual IndexedDB
store object.

### schema.addIndex(name, field, [opts])

Create index with `name` and to `field` (or array of fields).
Expand All @@ -154,9 +263,33 @@ Options:

Delete index by `name` from current store.

### schema.addEarlyCallback(cb)

Adds a `cb` to be executed at the beginning of the `upgradeneeded` event
and passed the event object. This will, out of necessity, run synchronously,
so promises cannot safely be used therein (whether used in `schema.callback`
or `schema.open`/`schema.upgrade`).

However, due to their early execution, such callbacks are, unlike
`addCallback` callbacks used with `schema.open`/`schema.upgrade`,
able to use methods such as `addStore`.

```js
const schema = new Schema()
.addStore('users', { increment: true, keyPath: 'id' })
.addIndex('byName', 'name')
.addEarlyCallback((e) => {
schema.addIndex('byId', 'id')
})
```

### schema.addCallback(cb)

Add `cb` to be executed at the end of the `upgradeneeded` event.
Adds a `cb` to be executed at the end of the `upgradeneeded` event
(if `schema.callback()` is used) or, at the beginning of the `success`
event (if `schema.open` and `schema.upgrade` are used). If `callback`
is used, the callback will be passed the `upgradeneeded` event. If
the other two methods are used, the db result will be passed instead.

```js
new Schema()
Expand All @@ -169,6 +302,16 @@ new Schema()
})
```

Note that if you wish to use promises within such callbacks and make
transactions within them, your `addCallback` callback should return
a promise chain and then use `schema.open` or `schema.upgrade` because
these methods, unlike `schema.callback`, will cause the callbacks
to be executed safely within the more persistent `onsuccess` event (and the
callback will be passed the database result instead of the `upgradeneeded`
event). If you do not need promises, you will have the option of using
`schema.callback` in addition to `schema.open` or `schema.upgrade` (or
you can use `addEarlyCallback`).

### schema.clone()

Return a deep clone of current schema.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
],
"scripts": {
"prepublish": "babel src --out-dir lib",
"test": "eslint src/ test/ && browserify-test -t babelify && SAUCE_USERNAME=idb-schema zuul --tunnel-host http://treojs.com --no-coverage -- test/index.js",
"test:local": "eslint src/ test/ && browserify-test -t babelify",
"test": "npm run test:local && SAUCE_USERNAME=idb-schema zuul --tunnel-host http://treojs.com --no-coverage -- test/index.js",
"development": "browserify-test -t babelify --watch"
},
"dependencies": {
Expand All @@ -30,14 +31,14 @@
"babel-core": "6.1.18",
"babel-eslint": "^5.0.0-beta4",
"babel-plugin-add-module-exports": "^0.1.1",
"babel-polyfill": "^6.7.4",
"babel-preset-es2015": "^6.1.18",
"babelify": "^7.2.0",
"browserify-test": "^2.1.2",
"chai": "^3.4.1",
"es6-promise": "^3.0.2",
"eslint": "^1.10.2",
"eslint-config-airbnb": "^1.0.2",
"idb-factory": "^1.0.0",
"idb-request": "^3.0.0",
"indexeddbshim": "^2.2.1",
"lodash": "^3.10.1",
Expand Down
Loading