Last active
January 18, 2017 10:32
-
-
Save joshontheweb/b17cf65cd1f6c4753f353badc119df17 to your computer and use it in GitHub Desktop.
tests adding large chunked blobs to indexeddb
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> | |
<body> | |
<div> | |
Starting Quota: | |
<span id="startingQuota"></span> | |
</div> | |
<div> | |
Blob Size: | |
<span id="blobSize"></span> | |
</div> | |
<h2>Save whole blob</h2> | |
<div> | |
Whole Blob Status: | |
<span id="wholeBlobStatus"></span> | |
</div> | |
<h2>Save chunked blob</h2> | |
<div> | |
Bytes Saved: | |
<span id="bytesSaved"></span> | |
</div> | |
<div> | |
Chunk Offset: | |
<span id="chunkOffset"></span> | |
</div> | |
<div> | |
Error: | |
<span id="error"></span> | |
</div> | |
<div> | |
Ending Quota: | |
<span id="endingQuota"></span> | |
</div> | |
<script> | |
var wholeBlobStatusEl = document.getElementById('wholeBlobStatus'); | |
var startingQuotaEl = document.getElementById('startingQuota'); | |
var bytesSavedEl = document.getElementById('bytesSaved'); | |
var chunkOffsetEl = document.getElementById('chunkOffset'); | |
var blobSizeEl = document.getElementById('blobSize'); | |
var errorEl = document.getElementById('error'); | |
var endingQuotaEl = document.getElementById('endingQuota'); | |
var blobSize = (Math.pow(1024, 2) * 300) // 300MB | |
var f32Length = blobSize / 4; | |
var blob = new Blob([new Float32Array(f32Length)]); | |
var chunkByteLength = (Math.pow(1024, 2) * .5) // 524k | |
var totalBytesSavedToStore = 0; | |
var dbName = 'testDb'; | |
var dbVersion = 1; | |
var storeName = 'testStore' | |
blobSizeEl.innerHTML = blob.size; | |
var db; | |
function initDb () { | |
var self = this; | |
return new Promise(function (resolve, reject) { | |
if (db) { | |
resolve(db); | |
} else { | |
var objectStores = [ | |
{name: storeName, indexes: [{name: 'byteOffset', unique: true}]}, | |
]; | |
console.log('Connecting to DB: ' + dbName + ' Store: ' + storeName); | |
var request = indexedDB.open(dbName, dbVersion); | |
request.onerror = function (e) { | |
errorEl.innerHTML = e.target.error; | |
console.log('Error: ', e); | |
reject(e); | |
}; | |
request.onblocked = function (e) { | |
errorEl.innerHTML = e.target.error; | |
console.log('Blocked: ', e); | |
reject(e); | |
} | |
request.onupgradeneeded = function (e) { | |
console.log('running open request onupgradeneeded'); | |
var db = e.target.result; | |
console.log(storeName, db.objectStoreNames); | |
objectStores.forEach(function (store) { | |
if (!db.objectStoreNames.contains(store.name)) { | |
var objectStore = db.createObjectStore(store.name, {autoIncrement: true}); | |
var indexes = store.indexes; | |
if (indexes){ | |
indexes.forEach(function (index) { | |
objectStore.createIndex(index.name, index.name, index.options); | |
}); | |
} | |
} | |
}); | |
}; | |
request.onsuccess = function (e) { | |
console.log('running open request onsuccess'); | |
db = e.target.result; | |
db.onerror = function (e) { | |
errorEl.innerHTML = e.target.error; | |
} | |
db.onversionchange = function (e) { | |
console.log('Version Change'); | |
var db = e.target | |
db.close(); | |
} | |
db.onblocked = function (e) { | |
console.log('blocked'); | |
} | |
resolve(db); | |
}; | |
} | |
}); | |
} | |
function add (data, cb) { | |
// insert *new* data only | |
try { | |
var transaction = db.transaction([storeName], "readwrite"); | |
var store = transaction.objectStore(storeName); | |
var request = store.add(data); | |
transaction.onabort = function (e) { | |
console.log('TRANSACTION ABORTED', e); | |
cb(e.target.error); | |
} | |
transaction.oncomplete = function (e) { | |
console.log(e); | |
if (cb) cb(null, e); | |
} | |
transaction.onerror = function (e) { | |
if (cb) cb(e.target.error); | |
} | |
} catch (err) { | |
if (cb) cb(err); | |
} | |
} | |
function saveToStore (blobChunk, cb) { | |
console.log('saveBlobToStore'); | |
var self = this; | |
initDb().then(function (db) { | |
var attrs = { | |
byteOffset: totalBytesSavedToStore, | |
byteLength: blobChunk.size, | |
totalByteLength: totalBytesSavedToStore + blobChunk.size, | |
blob: blobChunk | |
}; | |
add(attrs, function (err) { | |
if (err) { | |
errorEl.innerHTML = err; | |
console.error(err); | |
if (cb) cb(err); | |
} else { | |
totalBytesSavedToStore += attrs.byteLength; | |
if (cb) cb(null, totalBytesSavedToStore); | |
} | |
}); | |
}); | |
} | |
function saveChunk (start, byteLength, blob) { | |
var end = start + byteLength; | |
var blobChunk = blob.slice(start, end); | |
if (start < blob.size) { | |
saveToStore(blobChunk, function (err, totalBytesSaved) { | |
if (err) throw err; | |
bytesSavedEl.innerHTML = totalBytesSaved; | |
chunkOffsetEl.innerHTML = end; | |
console.log('Chunk Start Offset: ', end); | |
console.log('Blob size: ', blob.size); | |
saveChunk(end, byteLength, blob); | |
}); | |
} else { | |
errorEl.innerHTML = 'finished with no errors'; | |
navigator.webkitTemporaryStorage.queryUsageAndQuota(function (used, total) { | |
endingQuotaEl.innerHTML = JSON.stringify({total: total, used: used, free: total - used}); | |
}); | |
clearDatabase(); | |
} | |
} | |
function clearDatabase (cb) { | |
try { | |
var transaction = db.transaction([storeName], "readwrite"); | |
var store = transaction.objectStore(storeName); | |
var request = store.clear(); | |
transaction.oncomplete = function (e) { | |
if (cb) cb(); | |
} | |
transaction.onerror = function (e) { | |
if (cb) cb(e.target.error); | |
} | |
} catch (err) { | |
if (cb) cb(err); | |
} | |
} | |
navigator.webkitTemporaryStorage.queryUsageAndQuota(function (used, total) { | |
startingQuotaEl.innerHTML = JSON.stringify({total: total, used: used, free: total - used}); | |
}); | |
// save whole blob | |
saveToStore(blob, function (err, totalBytesSaved) { | |
wholeBlobStatusEl.innerHTML = 'Whole blob saved successfully: ' + totalBytesSaved; | |
// clean up | |
clearDatabase(function (err) { | |
if (err) { | |
errorEl.innerHTML = err; | |
console.log(err); | |
return; | |
} | |
totalBytesSavedToStore = 0; | |
// start saving chunked blob | |
saveChunk(0, chunkByteLength, blob); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment