javascript - IndexedDB: Can you manually initiate a version change transaction? -
i writing chrome extension utilizes indexeddb
store information client side in idbobjectstore
within idbdatabase
.
the nature of data such need users able modify object store @ whim. (add new objects modify existing ones etc.) accomplishing through settings page , fine , dandy far.
the caveat comes when want release new version of (default) object store. if didn't care overwriting users' data, handle onupgradeneeded
event same way handle when fired in reaction fresh install. like:
var request = window.indexeddb.open(db_name, current_db_version); request.onupgradeneeded = upgrade; function upgrade(event){ var db = event.target.result; var objectstore = db.createobjectstore("domains", {keypath: "id", autoincrement: true}); objectstore.createindex("domain", "domain", {multientry: true }); for(var i=0; i<tags.length; i++){ objectstore.add(tags[i]); console.log("added " + tags[i]["domain"] + " idbobjectstore 'domains' in idbdatabase 'tags' (format)"); } }
...but care.
so, doing placing conditional inside of upgrade(event)
function checks truthyness of event.oldversion
(its 0 on fresh install). if value greater 0, open new tab contains options page user can pick , choose objects wants update.
now tricky part: once page closes need send message background page contains necessary upgrade information. normally, receive message in listener , perform update, utilizing provided information. however, idbdatabase.createobjectstore()
throws invalidstateerror
if:
the method [is] not called versionchange transaction callback.
when @ spec idbdatabase.transaction(storenames, mode)
, in mode
parameter description, says:
versionchange
mode can't specified here.
so, seems me need trigger onupgradeneeded
event, need pass event handler additional parameter, besides event itself, contains information can use decide how perform upgrade.
i don't know how go doing though.
can offer me insight?
you getting invalidstateerror
because may not calling idbdatabase.createobjectstore()
onupgradeneeded
event handler. in case of idb, object store creation , manipulation has happen inside of onupgradeneeded
event handler or after onupgradeneeded
triggered.
if understood requirement correctly not want override user's existing object store in conditions, , want pass information in onupgradeneeded
event handler tell whether create afresh object store or modification on top of existing object store.
my recommendation - have 2 global array variables db_schema_drop_queries
, db_schema_create_queries
can prepare drop , create data before opening database using window.indexeddb.open(db_name, current_db_version);
then have code below (i giving heads up), when want 1. create afresh database first drop existing data stores database , create new (which means populate both db_schema_drop_queries
, db_schema_create_queries
). 2. add 1 more object store prepare db_schema_create_queries
3. modify existing object store prepare both db_schema_drop_queries
, db_schema_create_queries
particular object store
basically trying achieve making things dynamic instead of hard-coding data store creation db.createobjectstore("domains", {keypath: "id", autoincrement: true});
. rid of maintaining version records.
var dropquerieslength = db_schema_drop_queries.length; for(var =0; < dropquerieslength; i++){ try{ db_handler.deleteobjectstore(db_schema_drop_queries[i].name); } catch(e){ } } for(var =0; < db_schema_create_queries.length; i++){ var objectstore = null; if(db_schema_create_queries[i].primarykeycol != null && db_schema_create_queries[i].primarykeycol != undefined){ objectstore = db_handler.createobjectstore(db_schema_create_queries[i].name, { keypath: db_schema_create_queries[i].primarykeycol}); } }
Comments
Post a Comment