{"id":3736,"date":"2014-02-20T13:25:58","date_gmt":"2014-02-20T07:55:58","guid":{"rendered":"http:\/\/JitendraZaa.com\/blog\/?p=3736"},"modified":"2014-02-20T13:25:58","modified_gmt":"2014-02-20T07:55:58","slug":"indexeddb-client-side-database","status":"publish","type":"post","link":"https:\/\/www.jitendrazaa.com\/blog\/others\/tips\/indexeddb-client-side-database\/","title":{"rendered":"IndexedDB &#8211; Client Side Database"},"content":{"rendered":"<p style=\"text-align: justify;\">One of many features of HTML5 is capability to store data on client machine with the help of &#8220;<a title=\"Indexed Database API - Local Database\" href=\"http:\/\/www.w3.org\/TR\/IndexedDB\/\">Indexed Database API<\/a>&#8220;. Using this technique web developers can add offline capabilities to their application. Currently almost every modern browser supports &#8220;IndexedDB&#8221;.<\/p>\n<p style=\"text-align: justify;\">Unlike traditional RDBMS, IndexedDB doesn&#8217;t have table or columns which supports SQL. In RDBMS, it is very hard to change structure of table once schema is decided. IndexedDB actually stores object which can be of any type. Store Object in IndexedDB and process inside Javascript, it is that simple. Every object needs to have unique Index which makes it accessing faster and efficient. Before IndexedDB, we had &#8220;<a title=\"Web SQL Database\" href=\"http:\/\/www.w3.org\/TR\/webdatabase\/\">Web SQL Database<\/a>&#8220;. However W3C announced that it is depreciated, still few browsers continues support for Web SQL.<\/p>\n<p>Lets start with Example on Indexed DB :<\/p>\n<p style=\"text-align: justify;\">Very first step in IndexedDB is opening database. Below Code Sample will explain the process.<\/p>\n<p><!--more--><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/\/Open Database\n        offline.indexedDB.open = function() {\n            var version = 1.0;\n\n            \/\/Open &quot;todos&quot; database, which will be used throughout App\n            var request = indexedDB.open(&quot;todos&quot;, version);\n\n            \/\/ We can only create Object stores in a versionchange transaction.\n            request.onupgradeneeded = function(e) {\n                var db = e.target.result;\n\n                \/\/ A versionchange transaction is started automatically.\n                e.target.transaction.onerror = offline.indexedDB.onerror;\n\n                if(db.objectStoreNames.contains(&quot;todo&quot;)) {\n                  db.deleteObjectStore(&quot;todo&quot;);\n                }\n\n                var store = db.createObjectStore(&quot;todo&quot;,\n                  {keyPath: &quot;timeStamp&quot;});\n            };\n\n            request.onsuccess = function(e) {\n                \/\/Code on Success\n            };\n\n            request.onerror = function(e) {\n                \/\/Code on Error\n            };\n\n    }; \/\/End Open\n<\/pre>\n<p style=\"text-align: justify;\">In above code sample, we have opened IndexedDb database named &#8220;todos&#8221;. You can give any name to your database. For ease of code maintenance, I am using namespace &#8220;offline&#8221;. All methods and necessary information are encapsulated in this namespace.<\/p>\n<p>open() method of IndexedDB returns &#8220;IDBRequest&#8221; object. If have defined three methods on this.<\/p>\n<ol>\n<li>onerrr()<\/li>\n<li>onsuccess()<\/li>\n<li>onupgradeneeded()<\/li>\n<\/ol>\n<p>As name suggests, onsuccess and onerror method will be called if we are able to open IndexedDB connection successfully or not.<\/p>\n<p style=\"text-align: justify;\">Most important method is &#8220;<em>onupgradeneeded<\/em>&#8220;. If the open request is successful and database&#8217;s version is higher than existing database&#8217;s version, then our <em>onupgradeneeded<\/em> callback is executed. In this callback, a &#8220;versionchange&#8221; transaction will be started automatically.<\/p>\n<p style=\"text-align: justify;\">The <em>onupgradeneeded<\/em> callback is the only place in our code that we can alter the structure of the database. In it we can create and delete Object Stores and build and remove indexes. If we want to alter the structure of the database again, it is necessary to upgrade database&#8217;s version.<\/p>\n<p>Also, Object Stores are created with a call to <em>createObjectStore<\/em>().<\/p>\n<p style=\"text-align: justify;\"><strong>What is ObjectStore in IndexedDB ?<\/strong><br \/>\nData is stored in object stores, which are collections of JavaScript objects whose attributes contain individual values.<\/p>\n<p style=\"text-align: justify;\">Each JavaScript object, sometimes called a record, in an object store has a common attribute called a key path; the value of this attribute is called a key value (or key). Key values uniquely identify individual records within an object store.<\/p>\n<p style=\"text-align: justify;\"><strong>Adding Record in IndexedDB<\/strong><br \/>\nIf everything is fine in above code and we are successfully able to open connection to database then we can add record by simply calling &#8220;put&#8221; method. This method also returns &#8220;request&#8221; object where we can define success and error callback.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\noffline.indexedDB.addTodo = function(todoText) {\n      var db = offline.indexedDB.db;\n      var trans = db.transaction(&#x5B;&quot;todo&quot;], &quot;readwrite&quot;);\n\n      \/\/Get Object Store\n      var store = trans.objectStore(&quot;todo&quot;);\n\n      \/\/Add Object into Database\n      var request = store.put({\n        &quot;text&quot;: todoText,\n        &quot;timeStamp&quot; : new Date().getTime()\n      });\n\n      request.onsuccess = function(e) {\n        \/\/ Do operation if request success\n      };\n\n      request.onerror = offline.indexedDB.onerror;\n\n    }; \/\/End addTodo\n<\/pre>\n<p>In above code we have defined &#8220;read-write&#8221; <em>transaction<\/em>.<\/p>\n<p style=\"text-align: justify;\">A <em>transaction<\/em> manages the context of operations and is used to maintain the integrity of database activities. For example, you can create object stores only in the context of a version change transaction. If a transaction is aborted, all operations within the transaction are canceled.<\/p>\n<p style=\"text-align: justify;\"><strong>Deleting record from IndexedDB<\/strong><br \/>\nRecord can be deleted from Indexed DB by calling <em>delete(id)<\/em> method. This method excepts key which identifies record uniquely.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\noffline.indexedDB.deleteTodo = function(id) {\n      var db = offline.indexedDB.db;\n      var trans = db.transaction(&#x5B;&quot;todo&quot;], &quot;readwrite&quot;);\n      var store = trans.objectStore(&quot;todo&quot;);\n\n      var request = store.delete(id);\n\n      request.onsuccess = function(e) {\n        \/\/ Code on Success\n      };\n\n      request.onerror = offline.indexedDB.onerror;\n    };\n<\/pre>\n<p><strong>Complete code :<\/strong><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n&lt;html&gt;\n&lt;head&gt;\n&lt;title&gt;Getting started with IndexedDB &lt;\/title&gt;\n&lt;script src=&quot;http:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.9.1\/jquery.min.js&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;div id=&quot;todoItems&quot;&gt;\n    &lt;!-- Data will be loaded here --&gt;\n    &lt;ul&gt; &lt;li&gt; sds &lt;\/li&gt; &lt;\/ul&gt;\n&lt;\/div&gt;\n\n&lt;input type=&quot;text&quot; id=&quot;todo&quot; name=&quot;todo&quot; placeholder=&quot;Add To do Item here&quot; style=&quot;width: 200px;&quot; \/&gt;\n&lt;input type=&quot;submit&quot; value=&quot;Add Todo Item&quot; onclick=&quot;addTodo(); return false;&quot; \/&gt;\n\n&lt;script&gt;\n    \/\/Get DOM Elements in variable with JQuery\n    $todoItems = $(&quot;#todoItems&quot;).find(&quot;ul&quot;);\n    $todo = $(&quot;#todo&quot;);\n\n    \/\/offline is namespace, so that all our code is encapsulated\n    var offline = {};\n    offline.indexedDB = {};\n\n    offline.indexedDB.db = null;\n\n        \/\/Open Database\n        offline.indexedDB.open = function() {\n            var version = 1;\n\n            \/\/Open &quot;todos&quot; database, which will be used throughout App\n            var request = indexedDB.open(&quot;todos&quot;, version);\n\n            \/\/ We can only create Object stores in a versionchange transaction.\n            request.onupgradeneeded = function(e) {\n                var db = e.target.result;\n\n                \/\/ A versionchange transaction is started automatically.\n                e.target.transaction.onerror = offline.indexedDB.onerror;\n\n                if(db.objectStoreNames.contains(&quot;todo&quot;)) {\n                  db.deleteObjectStore(&quot;todo&quot;);\n                }\n\n                var store = db.createObjectStore(&quot;todo&quot;,\n                  {keyPath: &quot;timeStamp&quot;});\n            };\n\n            request.onsuccess = function(e) {\n                offline.indexedDB.db = e.target.result;\n                offline.indexedDB.getAllTodoItems();\n            };\n\n            request.onerror = offline.indexedDB.onerror;\n\n    }; \/\/End Open\n\n    \/\/define error method\n    offline.indexedDB.onerror = function(err) {\n        \/\/write error on Javascript Console\n        console.log(e.value);\n    } ; \/\/onerror\n\n    offline.indexedDB.addTodo = function(todoText) {\n      var db = offline.indexedDB.db;\n      var trans = db.transaction(&#x5B;&quot;todo&quot;], &quot;readwrite&quot;);\n      var store = trans.objectStore(&quot;todo&quot;);\n      var request = store.put({\n        &quot;text&quot;: todoText,\n        &quot;timeStamp&quot; : new Date().getTime()\n      });\n\n      request.onsuccess = function(e) {\n        \/\/ Re-render all the todo's\n        offline.indexedDB.getAllTodoItems();\n      };\n\n      request.onerror = offline.indexedDB.onerror;\n\n    }; \/\/End addTodo\n\n    offline.indexedDB.getAllTodoItems = function() {\n      $todoItems.html(&quot;&quot;);\n\n      var db = offline.indexedDB.db;\n      var trans = db.transaction(&#x5B;&quot;todo&quot;], &quot;readwrite&quot;);\n      var store = trans.objectStore(&quot;todo&quot;);\n\n      \/\/ Get everything in the store;\n      var keyRange = IDBKeyRange.lowerBound(0);\n      var cursorRequest = store.openCursor(keyRange);\n\n      cursorRequest.onsuccess = function(e) {\n        var result = e.target.result;\n\n        if(result == null || result == false)\n          return;\n\n        renderTodo(result.value);\n        result.continue();\n      };\n\n      cursorRequest.onerror = offline.indexedDB.onerror;\n    };\/\/GetAllTodo\n\n    function renderTodo(row) {\n\n       var $li = $(&quot;&lt;li&gt;&lt;span&gt;&lt;\/span&gt;&lt;a&gt;&lt;\/a&gt;&lt;\/li&gt;&quot;);\n       $todoItems.append($li);\n\n       $(&quot;span&quot;,$li).html(row.text);\n       $(&quot;a&quot;,$li).attr(&quot;href&quot;, &quot;#&quot;);\n       $(&quot;a&quot;,$li).html(&quot;- Del&quot;);\n\n       $(&quot;a&quot;,$li).click(function(e) {\n          offline.indexedDB.deleteTodo(row.timeStamp);\n        });\n\n    }\n\n    offline.indexedDB.deleteTodo = function(id) {\n      var db = offline.indexedDB.db;\n      var trans = db.transaction(&#x5B;&quot;todo&quot;], &quot;readwrite&quot;);\n      var store = trans.objectStore(&quot;todo&quot;);\n\n      var request = store.delete(id);\n\n      request.onsuccess = function(e) {\n        \/\/ Refresh the screen\n        offline.indexedDB.getAllTodoItems();\n      };\n\n      request.onerror = offline.indexedDB.onerror;\n    };\n\n    function init() {\n      \/\/ open displays the data previously saved\n      offline.indexedDB.open();\n    }\n\n    function addTodo() {\n      offline.indexedDB.addTodo($todo.val());\n      $todo.val('');\n    }\n\n    \/\/Start Application\n    init();\n&lt;\/script&gt;\n\n<\/pre>\n<p><strong>Output :<\/strong><\/p>\n<figure id=\"attachment_3740\" aria-describedby=\"caption-attachment-3740\" style=\"width: 345px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2014\/02\/HTML5-IndexedDB-Demo.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3740\" alt=\"HTML5 IndexedDB Demo\" src=\"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2014\/02\/HTML5-IndexedDB-Demo.png?resize=345%2C134&#038;ssl=1\" width=\"345\" height=\"134\" \/><\/a><figcaption id=\"caption-attachment-3740\" class=\"wp-caption-text\">HTML5 IndexedDB Demo<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>One of many features of HTML5 is capability to store data on client machine with the help of &#8220;Indexed Database API&#8220;. Using this technique web developers can add offline capabilities to their application. Currently almost every modern browser supports &#8220;IndexedDB&#8221;. Unlike traditional RDBMS, IndexedDB doesn&#8217;t have table or columns which supports SQL. In RDBMS, it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"jz_research_post":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[26,17],"tags":[114,118,217],"class_list":["post-3736","post","type-post","status-publish","format-standard","hentry","category-web","category-tips","tag-html-5","tag-indexeddb","tag-web-sql-database"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1396,"url":"https:\/\/www.jitendrazaa.com\/blog\/microsoft\/what-is-odbc-and-oledb-interview-question\/","url_meta":{"origin":3736,"position":0},"title":"What is ODBC and OLEDB &#8211; Interview Question","author":"Jitendra","date":"December 5, 2010","format":false,"excerpt":"This articles explains in detail description of ODBC and OLEDB component of Microsoft and its Usage","rel":"","context":"In &quot;c#&quot;","block_context":{"text":"c#","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/microsoft\/csharp\/"},"img":{"alt_text":"How ODBC Works","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2010\/12\/How-ODBC-Works.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3460,"url":"https:\/\/www.jitendrazaa.com\/blog\/java\/hibernate\/introduction-hibernate\/","url_meta":{"origin":3736,"position":1},"title":"Introduction to Hibernate","author":"Jitendra","date":"October 1, 2013","format":false,"excerpt":"Post by - Subhash Bhajankar What is the problem that hibernate is trying to solve? \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Let's take an example of simple class that you have in your application. Referring Image 1, we have Employee object in our java class which has six fields. In our running\u2026","rel":"","context":"In &quot;Hibernate&quot;","block_context":{"text":"Hibernate","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/java\/hibernate\/"},"img":{"alt_text":"Necessity of Hibernate ","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2013\/10\/problem.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2013\/10\/problem.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2013\/10\/problem.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1385,"url":"https:\/\/www.jitendrazaa.com\/blog\/sql\/sqlserver\/difference-in-ado-and-ado-net\/","url_meta":{"origin":3736,"position":2},"title":"Difference in ADO and ADO.Net &#8211; Interview Question","author":"Jitendra","date":"December 5, 2010","format":false,"excerpt":"Basic comparison between ADO and ADO.Net component in .Net Framework","rel":"","context":"In &quot;c#&quot;","block_context":{"text":"c#","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/microsoft\/csharp\/"},"img":{"alt_text":"ADO.Net","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2010\/12\/ADO.Net_.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":5828,"url":"https:\/\/www.jitendrazaa.com\/blog\/sql\/sqlserver\/sql-server-search-complete-database-for-value\/","url_meta":{"origin":3736,"position":3},"title":"SQL Server \u2013 Search complete database for value","author":"Jitendra","date":"November 26, 2016","format":false,"excerpt":"Search complete Database in SQL Server for some value","rel":"","context":"In &quot;SQL Server&quot;","block_context":{"text":"SQL Server","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/sql\/sqlserver\/"},"img":{"alt_text":"SQL Server search database for value","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/11\/SQL-Server-search-database-for-value.png?fit=1108%2C429&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/11\/SQL-Server-search-database-for-value.png?fit=1108%2C429&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/11\/SQL-Server-search-database-for-value.png?fit=1108%2C429&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/11\/SQL-Server-search-database-for-value.png?fit=1108%2C429&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/11\/SQL-Server-search-database-for-value.png?fit=1108%2C429&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":5873,"url":"https:\/\/www.jitendrazaa.com\/blog\/sql\/sqlserver\/export-documents-saved-as-blob-binary-from-sql-server\/","url_meta":{"origin":3736,"position":4},"title":"Export Documents saved as Blob \/ Binary from SQL Server","author":"Jitendra","date":"December 24, 2016","format":false,"excerpt":"T-SQL Scripts to Export Blob or Binary data stored in SQL Server","rel":"","context":"In &quot;SQL Server&quot;","block_context":{"text":"SQL Server","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/sql\/sqlserver\/"},"img":{"alt_text":"SQL Server Export Blob as File","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/SQL-Server-Export-Blob.gif?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/SQL-Server-Export-Blob.gif?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/SQL-Server-Export-Blob.gif?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/SQL-Server-Export-Blob.gif?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1359,"url":"https:\/\/www.jitendrazaa.com\/blog\/sql\/sqlserverintegrationservices\/etl-dts-and-ssis-introduction\/","url_meta":{"origin":3736,"position":5},"title":"ETL , DTS and SSIS Introduction","author":"Jitendra","date":"December 4, 2010","format":false,"excerpt":"Introduction to ETL Services, Data transformation services, SQL Server Integration Services, Advantages of SSIS over DTS, New features of SSIS 2008","rel":"","context":"In &quot;SSIS&quot;","block_context":{"text":"SSIS","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/sql\/sqlserverintegrationservices\/"},"img":{"alt_text":"What is ETL Extraction Transformation Loading","src":"https:\/\/i0.wp.com\/jitendrazaa.com\/blog\/wp-content\/uploads\/2010\/12\/What-is-ETL-Extraction-Transformation-Loading.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/3736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/comments?post=3736"}],"version-history":[{"count":0,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/3736\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/media?parent=3736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/categories?post=3736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/tags?post=3736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}