Skip to content

Instantly share code, notes, and snippets.

@SupaFuzz
Last active December 5, 2019 21:29
Show Gist options
  • Save SupaFuzz/ee2d141110f1235d4bcc86e38e84b143 to your computer and use it in GitHub Desktop.
Save SupaFuzz/ee2d141110f1235d4bcc86e38e84b143 to your computer and use it in GitHub Desktop.
IndexedDB vanilla basic CRUD operations
<!DOCTYPE html>
<html lang="en">
<!--
This illustrates the basic tricks you need to get your CRUD-on with
indexedDB. There is a helluva lot more to it but if you basically
are at the point I am, and it's all like "I need a version of
localStorage that can hold a couple hundred MBs" ... these'll be the
code nuggets you need to get that done.
mighty helpful stuff links:
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
https://gist.github.com/JamesMessinger/a0d6389a5d0e3a24814b
- Amy ❤️ <amy@hicox.com> 12/05/19
-->
<head>
<meta charset="utf-8" />
<style type="text/css">
body {
background-color: #FFFFFF;
font-size: 12px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
}
.btn {
padding: .5em;
background-color: #FEBE7E;
color: #57385C;
border: 1px solid #57385C;
border-radius: .5em;
display: inline-block;
text-decoration: none;
margin: .5em;
font-weight: bolder;
}
.btn:hover, .btn:active {
color: #FEBE7E;
border: 1px solid #FEBE7E;
background-color: #57385C;
cursor: pointer;
}
</style>
<script type="text/javascript">
// quickie for logging onscreen
function logIt(msg, elName){
if (! elName){ elName = "log"; }
document.getElementById(elName).insertAdjacentHTML('beforeend', `<li>${msg}</li>`);
}
// dummy data
window.testData = {
users: [
{id: 'scoob', first: 'Scooby', middle: 'D', last: 'Doo'},
{id: 'shaggy', first: 'Shaggy', middle: 'R', last: 'Rogeers'},
{id: 'sbsqrpnts', first: 'Sponge', middle: 'B', last: 'Squarepants'},
{id: 'sqdwrd', first: 'Squidward', middle: 'J', last: 'Tentacles'},
{id: 'krabbs', first: 'Eugene', middle: 'C', last: 'Krabbs'},
{id: 'ssqrl', first: 'Sandy', middle: 'X', last: 'Squirrel'}
],
places: [
{id: 'BBTM', name: 'Bikini Bottom'},
{id: 'RBTM', name: 'Rock Bottom'},
{id: 'MMCH', name: 'Mystery Machine'},
{id: 'GSKL', name: 'Castle Greyskull'}
]
};
// execute on DOM loaded
document.addEventListener("DOMContentLoaded", function(evt){
logIt("document loaded");
/* this function fires when you click the start button */
document.getElementById("btn_Start").addEventListener("click", function(evt){
logIt(`starting db test ...<br><ul id="dbSubtest"><ul>`);
if (! window.indexedDB){
logIt("indexedDB is not supported on this browser", "dbSubtest");
return(false);
}
logIt("indexedDB is supported!", "dbSubtest");
/*
open the db
if it's new or changed, lay in the "table" definitions (onupgradeneeded)
*/
let openRequest = window.indexedDB.open("charDB", 3);
// fires when you first try to open a DB at a given value of version
openRequest.onupgradeneeded = function(evt){
logIt("setting up db ...", "dbSubtest");
let db = evt.target.result;
// just blow away the tables if we've already got em LOL. brutal.
Object.keys(window.testData).forEach(function(storeName){
if (Array.from(db.objectStoreNames).indexOf(storeName) >= 0){ db.deleteObjectStore(storeName); }
db.createObjectStore(storeName, {keyPath: "id"});
});
}
// fires when you've mounted the DB
openRequest.onsuccess = function(evt){
/*
objectStoreNames returns a DOMStringList
which is a list of strings.
but not an array. not even an itterable object.
Array.from is apparently the way to cast whatever that crap is into an array.
I dunno. javascript, yo.
*/
logIt(`database is open, checking objectStores ...<ul id="storeList"></ul>`, "dbSubtest");
Array.from(evt.target.result.objectStoreNames).forEach(function(storeName){
evt.target.result.transaction(storeName, "readonly").objectStore(storeName).count().onsuccess = function(e){
logIt(`[${storeName}]: ${e.target.result}`, "storeList");
}
});
document.getElementById("buttons").insertAdjacentHTML('beforeend', `<span id="btn_Insert" class="btn">insert data</span>`);
document.getElementById("btn_Insert").addEventListener('click', function(){ insertTest(evt.target.result); });
} // end on opendb success
}); // end on test button click
}); // end DOMContentLoaded
// promisify the put so we can Promise.all that async rat's nest ...
function insert(transHandle, storeName, object){
return(new Promise(function(resolve, reject){
let req = transHandle.objectStore(storeName).put(object);
req.onsuccess = function(){ resolve(true); }
req.onerror = function(e){ reject(e); }
}));
}
// this fires when you click the "insert data" button
function insertTest(dbHandle){
let trans = dbHandle.transaction(Array.from(dbHandle.objectStoreNames), "readwrite");
let pk = [];
Object.keys(window.testData).forEach(function(storeName){
window.testData[storeName].forEach(function(obj){
pk.push(insert(trans, storeName, obj));
});
});
Promise.all(pk).then(function(){
logIt("insert complete");
document.getElementById("buttons").insertAdjacentHTML('beforeend', `<span id="btn_Show" class="btn">show data</span>`);
document.getElementById("btn_Show").addEventListener('click', function(){ showTest(dbHandle); });
});
}
// promisify the getAll
function get(transHandle, storeName){
return(new Promise(function(resolve, reject){
let req = transHandle.objectStore(storeName).getAll();
req.onsuccess = function(evt){ resolve(evt.target.result); }
req.onerror = function(e){ reject(e); }
}));
}
// show me the data
function showTest(dbHandle){
logIt(`read test ...<ul id="readTest"></ul>`);
let trans = dbHandle.transaction(Array.from(dbHandle.objectStoreNames), "readonly");
Object.keys(window.testData).forEach(async function(storeName){
data = await get(trans, storeName);
logIt(`${storeName} <ul id="${storeName}_list"></ul>`, "readTest");
data.forEach(function(row){
let tmpStr = '';
Object.keys(row).forEach(function(fName){ tmpStr += ` [${fName}]: ${row[fName]}`});
logIt(`${tmpStr}`, `${storeName}_list`);
});
});
}
</script>
</head>
<body>
<div id="buttons">
<span id="btn_Start" class="btn">start</span>
</div>
<ul id="log"></ul>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment