{"id":748,"date":"2014-11-29T22:26:44","date_gmt":"2014-11-29T16:56:44","guid":{"rendered":"http:\/\/codeforgeek.com\/?p=748"},"modified":"2021-06-20T06:05:35","modified_gmt":"2021-06-20T00:35:35","slug":"sync-app-mysql-indexeddb","status":"publish","type":"post","link":"https:\/\/codeforgeek.com\/sync-app-mysql-indexeddb\/","title":{"rendered":"Synchronization between mysql and IndexedDB"},"content":{"rendered":"<p>IndexedDB is powerful api for web application developers. In last tutorial I mentioned the basics about IndexedDB and about how to perform SQL transaction in it. Check out the <a title=\"IndexedDB : Database in browser\" href=\"https:\/\/codeforgeek.com\/indexeddb-tutorial\/\" target=\"_blank\" rel=\"noopener\">IndexedDB <\/a>tutorial before moving ahead.<\/p>\n<p>In this tutorial i am going to show you one demo application which i named <strong>&#8220;Synker&#8221;&nbsp;<\/strong>which basically sync the data between MySQL and IndexedDB.<br \/>\n<center><a class=\"button-rounded button-flat-caution wplightbox\" href=\"http:\/\/www.youtube.com\/embed\/aTn90IQgh8I\" title=\"Synker demo\" data-width=\"640\" data-height=\"360\" target=\"_blank\" rel=\"noopener\"><i class=\"fa fa-code\"><\/i>LIVE DEMO<\/a> <a class=\"button-rounded button-flat\" href=\"https:\/\/codeload.github.com\/codeforgeek\/Synker\/zip\/master\" target=\"_blank\" rel=\"noopener\"><i class=\"fa fa-github\"><\/i>DOWNLOAD<\/a><\/center><\/p>\n<h3>Motivation behind Synker:<\/h3>\n<p>This app is not for production payload or not created for any commercial purpose so there is room for bug and feature enhancement.<\/p>\n<p>I was amazed by the IndexedDB api and wanted to put it some real world use. Hope this piece of code helps you to understand the use of IndexedDB.<\/p>\n<h3>How Synker works:<\/h3>\n<p>Basic working is like this, when our client is not able to connect to <a href=\"https:\/\/codeforgeek.com\/eventemitter-node-js\/\" title=\"EventEmitter module in Node.js\" target=\"_blank\" rel=\"noopener\">Node <\/a>server we assume that either internet connection is down or something happened at client end. <\/p>\n<p>In order to keep the user working we will store data in IndexedDB and as soon as our connection is up with Server whole data will be updated to MySQL as well as to IndexedDB in order to keep the data consistent.<\/p>\n<p>I used simple HTML textarea which let user type something and in 5 seconds or so Synker will sync the content present in the textarea to MySQL or IndexedDB depending upon the connection to web server.<\/p>\n<h3>Database design:<\/h3>\n<p>Our database is in MySQL. Create database named <strong>&#8220;synker&#8221;<\/strong> using <strong>PhpMyadmin<\/strong> or command line whichever suits you best and execute following command to create our table.<br \/>\n<code lang=\"sql\"><br \/>\ncreate table content<br \/>\n(<br \/>\n    user_id int(100) PRIMARY KEY AUTO_INCREMENT,<br \/>\n    content TEXT<br \/>\n);<br \/>\n<\/code><\/p>\n<h3>Directory structure:<\/h3>\n<p><code><br \/>\n--node_module<br \/>\n             | -- mysql<br \/>\n             | -- express<br \/>\n--views<br \/>\n             | --index.html<br \/>\n--Server.js<br \/>\n--package.json<br \/>\n<\/code><\/p>\n<h3>Synker &#8211; Code :<\/h3>\n<div class=\"file_name\"><strong>package.json<\/strong><\/div>\n<p><code lang=\"javascript\"><br \/>\n{<br \/>\n  \"name\": \"Synker\",<br \/>\n  \"version\": \"0.1.1\",<br \/>\n  \"dependencies\": {<br \/>\n    \"express\": \"~4.10.1\",<br \/>\n    \"mysql\": \"~2.5.2\",<br \/>\n    \"ejs\": \"~1.0.0\"<br \/>\n  }<br \/>\n}<br \/>\n<\/code><br \/>\ninstall the dependencies by typing <code>npm install<\/code><br \/>\nThis is <strong>node.js&nbsp;<\/strong>script which basically does the job of syncing. It contains API which we call  according to connection scenario.<\/p>\n<div class=\"file_name\"><strong>Server.js<\/strong><\/div>\n<p><code lang=\"javascript\"><br \/>\nvar express=require(\"express\");<br \/>\nvar mysql=require(\"mysql\");<br \/>\nvar app=express();<\/p>\n<p>var connection = mysql.createConnection({<br \/>\n  host     : 'localhost',<br \/>\n  user     : 'root',<br \/>\n  password : '',<br \/>\n  database : 'synker'<br \/>\n});<\/p>\n<p>connection.connect();<\/p>\n<p>app.set('views',__dirname + '\/view');<br \/>\napp.use(express.static(__dirname + '\/js'));<br \/>\napp.set('view engine', 'ejs');<br \/>\napp.engine('html', require('ejs').renderFile);<\/p>\n<p>app.get('\/',function(req,res){<br \/>\n        res.render('index.html');<br \/>\n});<\/p>\n<p>app.get('\/get_from_db',function(req,res){<br \/>\n        connection.query(\"SELECT * from content\",function(err,rows){<br \/>\n          res.json(rows[0]);<br \/>\n        });<br \/>\n});<\/p>\n<p>app.get('\/ping',function(req,res){<br \/>\n        res.json({\"alive\":\"yes\"});<br \/>\n});<\/p>\n<p>app.get('\/update',function(req,res){<br \/>\n        var content=req.query.data;<br \/>\n        \/*Check if there is any row else put one row for all time*\/<br \/>\n        connection.query(\"SELECT * from content\",function(err,rows,field){<br \/>\n            if(rows.length===0)<br \/>\n              {<br \/>\n                \/*add one row*\/<br \/>\n                connection.query(\"INSERT into content(user_id,content) VALUES (1,'')\",function(err,rows){<br \/>\n                    if(err)<br \/>\n                      {<br \/>\n                        console.log(err);<br \/>\n                        res.json({\"error\":\"1\"});<br \/>\n                      }<br \/>\n                      else<br \/>\n                        {<br \/>\n                          res.json({\"yes\":\"1\"});<br \/>\n                        }<br \/>\n                });<br \/>\n              }<br \/>\n            else<br \/>\n              {<br \/>\n                \/*Sync exisiting data*\/<br \/>\n                connection.query(\"UPDATE content set content='\"+content+\"' where user_id=1\",function(err,rows){<br \/>\n                    if(err)<br \/>\n                      {<br \/>\n                        console.log(err);<br \/>\n                        res.json({\"error\":\"1\"});<br \/>\n                      }<br \/>\n                    else<br \/>\n                      {<br \/>\n                        res.json({\"yes\":\"1\"});<br \/>\n                      }<br \/>\n                });<br \/>\n              }<br \/>\n        });<br \/>\n});<\/p>\n<p>app.listen(3000,function(){<\/p>\n<p>    console.log(\"I am live at PORT 3000.\");<\/p>\n<p>});<br \/>\n<\/code><br \/>\nLike i said we are using simple textarea with no fancy css, so here is the html i am using.<\/p>\n<div class=\"file_name\"><strong>index.html<\/strong><\/strong><\/div>\n<p><code lang=\"html\"><\/p>\n<div id=\"container\">\n      <textarea rows=\"20\" cols=\"120\" id=\"my_container\"><\/textarea><\/p>\n<p>      <input type=\"button\" id=\"save\" value=\"Save\"><\/input><\/p>\n<p>      <span id=\"message\"><\/span>\n<\/div>\n<p><\/code><br \/>\nHere is JavaScript code which is responsible for following things.<\/p>\n<ul>\n<li>Create IndexedDB in browser if not present.<\/li>\n<li>Update the IndexedDB with latest data present in MySQL.<\/li>\n<li>Retrieve data from IndexedDB in case user is offline.<\/li>\n<\/ul>\n<div class=\"file_name\"><strong>index.html : IndexedDB JavaScript code (important) <\/strong><\/div>\n<p><code lang=\"javascript\"><br \/>\n  <script type=\"text\/javascript\">\n          var request = indexedDB.open(\"synker\");\n          var db;\n          request.onupgradeneeded = function() {\n          \/\/ The database did not previously exist, so create object stores and indexes.\n          db = request.result;\n          var store = db.createObjectStore(\"notes\", {keyPath: \"ID\"});\n          var ourindex = store.createIndex(\"content\",\"user_content\");\n        };\n        request.onsuccess = function() {\n          db = request.result;\n        };\n        function addData(data)\n        {\n            var tx = db.transaction(\"notes\", \"readwrite\");\n            var store = tx.objectStore(\"notes\");\n            store.put({content: data, ID:1});\n        }\n        function addinsql(data)\n        {\n          $.get(\"\/update?data=\"+data,function(data){\n            if(data.yes==1)\n              {\n                alert(\"data updated\");\n              }\n            else\n              {\n                alert(\"error\");\n              }\n          });\n        }\n        function check_alive(){\n            var a;\n            $.ajax({\n                    url: '\/ping',\n                    type: 'GET',\n                    async: false,\n                    success: function(data){\n                          \/\/Ready for MySQL insertion.\n                          console.log(\"MySQL is UP\");\n                          a=0;\n                    },\n                    error: function(data) {\n                            \/\/Go in the indexDB\n                            a=1;\n                    }\n            });\n            return a;\n        }\n        function getalldata()\n        {\n                  var all_content;\n                  var self=this;\n                  var tx = db.transaction(\"notes\", \"readonly\");\n                  var store = tx.objectStore(\"notes\");\n                  var request = store.openCursor();\n                  request.onsuccess = function() {\n                    var cursor = request.result;\n                    if (cursor) {\n                      self.all_content=cursor.value.content;\n                      cursor.continue();\n                    }\n                  };\n              return self.all_content;\n        }\n  <\/script><br \/>\n<\/code><\/p>\n<div class=\"file_name\"><strong>index.html : jQuery code (to handle Request\/Response to Server)<\/strong><\/div>\n<p><code lang=\"javascript\"><br \/>\n <script>\n  $(document).ready(function(){\n        $(\"#message\").empty().html(\"<b>We are good ! Keep writing.<\/b>\").css(\"color\",\"green\");\n        $.get(\"\/get_from_db\",function(data){\n          $(\"#my_container\").val(data.content);\n        });\n        setInterval(function(){\n                if(check_alive()==0)\n                  {\n                    $(\"#message\").empty().html(\"<b>We are good ! Keep writing.<\/b>\").css(\"color\",\"green\");\n                    \/\/get all data from indexDB and update it in MySQL.\n                    $(\"#message\").empty().html(\"<b>Syncing...<\/b>\").css(\"color\",\"green\");\n                    var c2=getalldata();\n                    console.log(c2);\n                    $.get('\/update?data='+c2,function(data){\n                        if(data.error==1)\n                          {\n                            console.log(\"Some issue.\");\n                          }\n                          else\n                            {\n                              $(\"#message\").empty().html(\"<b>We are good ! Keep writing.<\/b>\").css(\"color\",\"green\");\n                            }\n                    });\n                  }\n                else\n                  {\n                    $(\"#message\").empty().html(\"<b>Connection lost ! keep writing. We will deal with it.<\/b>\").css(\"color\",\"red\");\n                  }\n          }, 10000);\n        $(\"#save\").click(function(){\n          var content=$(\"#my_container\").val();\n          var control=check_alive();\n          if(control==0)\n            {\n              console.log(\"Put data in Mysql\");\n              addinsql(content);\n              addData(content);\n            }\n          else\n            {\n              console.log(\"Putting in indexDB.\");\n              addData(content);\n            }\n        });\n  });\n  <\/script><br \/>\n<\/code><\/p>\n<h3>How to run:<\/h3>\n<p>I hope you have XAMPP or WAMP server, turn on MySQL and keep it up. Switch to folder where our code present and type <code>node Server.js<\/code> to run it. Visit <strong>localhost:3000&nbsp;<\/strong>to view the app.<br \/>\n<figure id=\"attachment_906\" aria-describedby=\"caption-attachment-906\" style=\"width: 879px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image1.png\"><img decoding=\"async\" src=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image1.png\" alt=\"Server is up ! Start typing,\" width=\"879\" height=\"651\" class=\"size-full wp-image-906\" srcset=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image1.png 879w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image1-768x569.png 768w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image1-300x222.png 300w\" sizes=\"(max-width: 879px) 100vw, 879px\" \/><\/a><figcaption id=\"caption-attachment-906\" class=\"wp-caption-text\">Server is up ! Start typing,<\/figcaption><\/figure><br \/>\nNow while using the app stop Node server and see the error message on client page. Just keep typing and after a minute or so start node server again. Within 5 seconds your data will be updated to MySQL engine.<br \/>\n<figure id=\"attachment_907\" aria-describedby=\"caption-attachment-907\" style=\"width: 879px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image2.png\"><img decoding=\"async\" src=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image2.png\" alt=\"Turn off the server and restart again.\" width=\"879\" height=\"685\" class=\"size-full wp-image-907\" srcset=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image2.png 879w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image2-768x598.png 768w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image2-300x234.png 300w\" sizes=\"(max-width: 879px) 100vw, 879px\" \/><\/a><figcaption id=\"caption-attachment-907\" class=\"wp-caption-text\">Turn off the server and restart again.<\/figcaption><\/figure><br \/>\nNow to validate whether we have consistent data in MySQL and IndexedDB let&#8217;s open and see both of them. View my screenshot for reference.<br \/>\n<a href=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image3.png\"><img decoding=\"async\" src=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image3.png\" alt=\"image3\" width=\"991\" height=\"570\" class=\"alignnone size-full wp-image-908\" srcset=\"https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image3.png 991w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image3-768x442.png 768w, https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/image3-300x173.png 300w\" sizes=\"(max-width: 991px) 100vw, 991px\" \/><\/a><\/p>\n<h4>Conclusion:<\/h4>\n<p>Synker is designed to demonstrate uses of IndexedDB. I am not saying this is correct use or this is what you should use. All i am saying is that you can do something like this with IndexedDB api.<\/p>\n<h4>Further reading:<\/h4>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/IndexedDB_API\" target=\"_blank\" rel=\"noopener\">Official MDN doc about IndexedDB is awesome ! Give it a shot.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>IndexedDB is powerful api for web application developers. In last tutorial I mentioned the basics about IndexedDB and about how to perform SQL transaction in it. Check out the IndexedDB tutorial before moving ahead. In this tutorial i am going to show you one demo application which i named &#8220;Synker&#8221;&nbsp;which basically sync the data between [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":916,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_surecart_dashboard_logo_width":"180px","_surecart_dashboard_show_logo":true,"_surecart_dashboard_navigation_orders":true,"_surecart_dashboard_navigation_invoices":true,"_surecart_dashboard_navigation_subscriptions":true,"_surecart_dashboard_navigation_downloads":true,"_surecart_dashboard_navigation_billing":true,"_surecart_dashboard_navigation_account":true,"_uag_custom_page_level_css":"","footnotes":""},"categories":[9,14,18],"tags":[],"class_list":["post-748","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-js","category-nodejs","category-tutorial"],"blocksy_meta":[],"uagb_featured_image_src":{"full":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21.png",800,212,false],"thumbnail":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21-150x150.png",150,150,true],"medium":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21-300x80.png",300,80,true],"medium_large":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21-768x204.png",768,204,true],"large":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21.png",800,212,false],"1536x1536":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21.png",800,212,false],"2048x2048":["https:\/\/codeforgeek.com\/wp-content\/uploads\/2014\/11\/banner21.png",800,212,false]},"uagb_author_info":{"display_name":"Shahid","author_link":"https:\/\/codeforgeek.com\/author\/shahid\/"},"uagb_comment_info":0,"uagb_excerpt":"IndexedDB is powerful api for web application developers. In last tutorial I mentioned the basics about IndexedDB and about how to perform SQL transaction in it. Check out the IndexedDB tutorial before moving ahead. In this tutorial i am going to show you one demo application which i named &#8220;Synker&#8221;&nbsp;which basically sync the data between&hellip;","_links":{"self":[{"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/posts\/748","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/comments?post=748"}],"version-history":[{"count":0,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/posts\/748\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/media\/916"}],"wp:attachment":[{"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/media?parent=748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/categories?post=748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeforgeek.com\/wp-json\/wp\/v2\/tags?post=748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}