Last active
December 5, 2019 21:29
-
-
Save SupaFuzz/ee2d141110f1235d4bcc86e38e84b143 to your computer and use it in GitHub Desktop.
IndexedDB vanilla basic CRUD operations
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
<!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