In depth analysis of HTML5 indexeddb index database

Time:2021-11-29

introduce
Indexeddb is an HTML5 web database that allows HTML5 web applications to store data on the user browser side. Indexeddb is very powerful and useful for applications. It can store a large amount of data in web browsers such as chrome, ie and Firefox on the client. The following briefly introduces the basic concept of indexeddb.
 
What is indexeddb
Indexeddb, a new data store of HTML5, can store and operate data on the client, which can make applications load faster and respond better. Different from relational database, it has data tables and records. It affects the way we design and create applications. Indexeddb creates objects with data types and simple JavaScript persistent objects. Each object can have an index to effectively query and traverse the entire collection. This article provides you with a real-world example of how to use indexeddb in a web application.
 
start
We need to include the following pre code before execution

JavaScript CodeCopy contents to clipboard
  1. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;   
  2.     
  3. //prefixes of window.IDB objects   
  4. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;   
  5. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange   
  6.     
  7. if (!indexedDB) {   
  8. alert(“Your browser doesn’t support a stable version of IndexedDB.”)   
  9. }  

 
Open indexeddb
Before creating a database, we first need to create data for the database. Suppose we have the following user information:

JavaScript CodeCopy contents to clipboard
  1. var userData = [   
  2. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },   
  3. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }   
  4. ];  

Now we need to open our database with the open () method:

JavaScript CodeCopy contents to clipboard
  1. var db;   
  2. var request = indexedDB.open(“databaseName”, 1);   
  3.     
  4. request.onerror = function(e) {   
  5. console.log(“error: “, e);   
  6. };   
  7.     
  8. request.onsuccess = function(e) {   
  9. db = request.result;   
  10. console.log(“success: “+ db);   
  11. };   
  12. request.onupgradeneeded = function(e) {   
  13.     
  14. }  

As shown above, we have opened the database named “databasename” with the specified version number. The open () method has two parameters:
1. The first parameter is the database name. It will detect whether the database with the name “databasename” already exists. If it exists, open it, otherwise create a new database.
2. The second parameter is the version of the database, which is used for users to update the database structure.
 
Onsuccess processing
“Onsuccess” is triggered when a success event occurs. If all successful requests are processed here, we can save the request result by assigning it to the DB variable for later use.
 
Handler for onerror
“Onerror” is triggered when an error event occurs, if the process of opening the database fails.
 
Onupgraded handler
If you want to update the database (create, delete or modify the database), you must implement the onupgraded handler so that you can make any changes in the database. In the “on upgraded” handler, it is the only place where you can change the structure of the database.
 
To create and add data to a table:
Indexeddb uses object storage to store data, not through tables. Whenever a value is stored in the object store, it is associated with a key. It allows any object we create to store indexes. Indexes allow us to access values stored in the object store. The following code shows how to create an object store and insert pre prepared data:

JavaScript CodeCopy contents to clipboard
  1. request.onupgradeneeded = function(event) {   
  2. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});   
  3. for (var i in userData) {   
  4. objectStore.add(userData[i]);    
  5. }   
  6. }  

We use the createobjectstore () method to create an object store. This method accepts two parameters: – the name of the store and the parameter object. Here, we have an object store named “users” and define keypath, which is the attribute of object uniqueness. Here, we use “Id” as the keypath. This value is unique in the object store. We must ensure that the attribute of “Id” exists in each object in the object store. Once the object store is created, we can start adding data using the for loop.
 
To manually add data to a table:
We can manually add additional data to the database.

JavaScript CodeCopy contents to clipboard
  1. function Add() {   
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”)   
  3. .add({ id: “3”, name: “Gautam”, age: 30, email: “gautam[email protected]” });   
  4.     
  5. request.onsuccess = function(e) {   
  6. alert(“Gautam has been added to the database.”);   
  7. };   
  8.     
  9. request.onerror = function(e) {   
  10. alert(“Unable to add the information.”);    
  11. }   
  12.     
  13. }  

Before we do any CRUD operations (read, write, modify) in the database, we must use transactions. The transaction () method is used to specify the object storage we want to transact. The transaction () method accepts three parameters (the second and third are optional). The first is the list of object stores we want to process, the second specifies whether we want to read-only / read-write, and the third is version change.
 
Read data from table
The get () method is used to retrieve data from the object store. We have set the ID of the object as the keypath, so the get () method will find the object with the same ID value. The following code will return the object we named “bidurata”:

JavaScript CodeCopy contents to clipboard
  1. function Read() {   
  2. var objectStore = db.transaction([“users”]).objectStore(“users”);   
  3. var request = objectStore.get(“2”);   
  4. request.onerror = function(event) {   
  5. alert(“Unable to retrieve data from database!”);   
  6. };   
  7. request.onsuccess = function(event) {    
  8. if(request.result) {   
  9. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);   
  10. } else {   
  11. alert(“Bidulata couldn’t be found in your database!”);    
  12. }   
  13. };   
  14. }  

 
Read all data from table
The following method retrieves all data in the table. Here, we use cursors to retrieve all data in the object store:

JavaScript CodeCopy contents to clipboard
  1. function ReadAll() {   
  2. var objectStore = db.transaction(“users”).objectStore(“users”);    
  3. var req = objectStore.openCursor();   
  4. req.onsuccess = function(event) {   
  5. db.close();   
  6. var res = event.target.result;   
  7. if (res) {   
  8. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);   
  9. res.continue();   
  10. }   
  11. };   
  12. req.onerror = function (e) {   
  13. console.log(“Error Getting: “, e);   
  14. };    
  15. }  

The opencursor () is used to traverse multiple records in the database. Continue reading the next record in the continue() function.
Delete records in table
The following method deletes a record from an object.

JavaScript CodeCopy contents to clipboard
  1. function Remove() {    
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);   
  3. request.onsuccess = function(event) {   
  4. alert(“Tapas’s entry has been removed from your database.”);   
  5. };   
  6. }  

We will pass the keypath of the object as a parameter to the delete () method.
 
Final code
The following method deletes a record from the object source:

JavaScript CodeCopy contents to clipboard
  1. <!DOCTYPE html>  
  2. <head>  
  3. <meta http-equiv=“Content-Type” content=“text/html; charset=utf-8” />  
  4. <title>IndexedDB</title>  
  5. <script type=“text/javascript”>  
  6. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;   
  7.     
  8. //prefixes of window.IDB objects   
  9. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;   
  10. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange   
  11.     
  12. if (!indexedDB) {   
  13. alert(“Your browser doesn’t support a stable version of IndexedDB.”)   
  14. }   
  15. var customerData = [   
  16. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },   
  17. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }   
  18. ];   
  19. var db;   
  20. var request = indexedDB.open(“newDatabase”, 1);   
  21.     
  22. request.onerror = function(e) {   
  23. console.log(“error: “, e);   
  24. };   
  25.     
  26. request.onsuccess = function(e) {   
  27. db = request.result;   
  28. console.log(“success: “+ db);   
  29. };   
  30.     
  31. request.onupgradeneeded = function(event) {   
  32.     
  33. }   
  34. request.onupgradeneeded = function(event) {   
  35. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});   
  36. for (var i in userData) {   
  37. objectStore.add(userData[i]);    
  38. }   
  39. }   
  40. function Add() {   
  41. var request = db.transaction([“users”], “readwrite”)   
  42. .objectStore(“users”)   
  43. .add({ id: “3”, name: “Gautam”, age: 30, email: “[email protected]” });   
  44.     
  45. request.onsuccess = function(e) {   
  46. alert(“Gautam has been added to the database.”);   
  47. };   
  48.     
  49. request.onerror = function(e) {   
  50. alert(“Unable to add the information.”);    
  51. }   
  52.     
  53. }   
  54. function Read() {   
  55. var objectStore = db.transaction(“users”).objectStore(“users”);   
  56. var request = objectStore.get(“2”);   
  57. request.onerror = function(event) {   
  58. alert(“Unable to retrieve data from database!”);   
  59. };   
  60. request.onsuccess = function(event) {    
  61. if(request.result) {   
  62. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);   
  63. } else {   
  64. alert(“Bidulata couldn’t be found in your database!”);    
  65. }   
  66. };   
  67. }   
  68. function ReadAll() {   
  69. var objectStore = db.transaction(“users”).objectStore(“users”);    
  70. var req = objectStore.openCursor();   
  71. req.onsuccess = function(event) {   
  72. db.close();   
  73. var res = event.target.result;   
  74. if (res) {   
  75. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);   
  76. res.continue();   
  77. }   
  78. };   
  79. req.onerror = function (e) {   
  80. console.log(“Error Getting: “, e);   
  81. };    
  82. }   
  83. function Remove() {    
  84. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);   
  85. request.onsuccess = function(event) {   
  86. alert(“Tapas’s entry has been removed from your database.”);   
  87. };   
  88. }   
  89. </script>  
  90. </head>  
  91.     
  92. <body>  
  93. <button onclick=“Add()”>Add record</button>  
  94. <button onclick=“Remove()”>Delete record</button>  
  95. <button onclick=“Read()”>Retrieve single record</button>  
  96. <button onclick=“ReadAll()”>Retrieve all records</button>  
  97. </body>  
  98. </html>  

lock

Localstorage does not have lock function. In order to realize the front-end data sharing and need the lock function, you need to use other storage methods, such as indexeddb. Indeddb uses the transaction processing mechanism, which is actually the lock function.
To do this test, you need to simply encapsulate the operation of indexeddb, because the connection of indexeddb is troublesome, and both test pages need to be used

JavaScript CodeCopy contents to clipboard
  1. //db.js   
  2. //Encapsulate transaction operations
  3. IDBDatabase.prototype.doTransaction=function(f){   
  4.   f(this.transaction([“Obj”],”readwrite”).objectStore(“Obj”));   
  5. };   
  6. / / connect to database, call main function after success.
  7. (function(){   
  8. //Open database
  9.   var cn=indexedDB.open(“TestDB”,1);   
  10. //Create data object
  11.   cn.onupgradeneeded=function(e){   
  12.     e.target.result.createObjectStore(“Obj”);   
  13.   };   
  14. //Database connection succeeded
  15.   cn.onsuccess=function(e){   
  16.     main(e.target.result);   
  17.   };   
  18. })();   
  19. Then there are two test pages
  20. <script src=“db.js”></script>  
  21. <script>  
  22. //a.html   
  23. function main(e){   
  24.   (function callee(){   
  25. //Start a transaction
  26.     e.doTransaction(function(e){   
  27. e.put(1,”test”);  // Set the value of test to 1
  28. e.put(2,”test”);  // Set the value of test to 2
  29.     });   
  30.     setTimeout(callee);   
  31.   })();   
  32. };   
  33. </script>  
  34. <script src=“db.js”></script>  
  35. <script>  
  36. //b.html   
  37. function main(e){   
  38.   (function callee(){   
  39. //Start a transaction
  40.     e.doTransaction(function(e){   
  41. //Get the value of test
  42.       e.get(“test”).onsuccess=function(e){   
  43.         console.log(e.target.result);   
  44.       };   
  45.     });   
  46.     setTimeout(callee);   
  47.   })();   
  48. };   
  49. </script>  

Replace localstorage with indexeddb transaction processing. But the results are different

During the test, there may be no immediate output in b.html, because indexeddb is busy processing a.html, and b.html transactions are lost in the transaction queue. But in any case, the output will not be the value of 1. Because the minimum processing unit of indexeddb is transaction, not expression as localstorage. In this way, just put the things that need to be processed between lock and unlock into a transaction. In addition, the browser’s support for indexeddb is not as good as localstorage, so browser compatibility must be considered when using it.

Recommended Today

On the mutation mechanism of Clickhouse (with source code analysis)

Recently studied a bit of CH code.I found an interesting word, mutation.The word Google has the meaning of mutation, but more relevant articles translate this as “revision”. The previous article analyzed background_ pool_ Size parameter.This parameter is related to the background asynchronous worker pool merge.The asynchronous merge and mutation work in Clickhouse kernel is completed […]