{"id":1906,"date":"2017-10-31T14:14:29","date_gmt":"2017-10-31T14:14:29","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=1906"},"modified":"2021-01-23T16:30:15","modified_gmt":"2021-01-23T16:30:15","slug":"javascript-database-designer-with-sql-generator","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/javascript-database-designer-with-sql-generator\/","title":{"rendered":"JavaScript Database Designer with SQL Generator"},"content":{"rendered":"<p>We are going to use the <a title=\"JS Flowchart Library\" href=\"https:\/\/mindfusion.dev\/javascript-diagram.html\">JS flowchart library<\/a> as a database design tool. We will create DB tables, add rows, connect the tables and generate SQL statements that would create the tables.<\/p>\n<p>Here is a screenshot of the application:<\/p>\n<div id=\"attachment_1913\" style=\"width: 892px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/10\/javascript-database-designer.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1913\" class=\"size-full wp-image-1913\" src=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/10\/javascript-database-designer.png\" alt=\"Database Designer Application with SQL Generator\" width=\"882\" height=\"981\" srcset=\"https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/10\/javascript-database-designer.png 882w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/10\/javascript-database-designer-270x300.png 270w, https:\/\/mindfusion.dev\/blog\/wp-content\/uploads\/2017\/10\/javascript-database-designer-768x854.png 768w\" sizes=\"auto, (max-width: 882px) 100vw, 882px\" \/><\/a><p id=\"caption-attachment-1913\" class=\"wp-caption-text\">Database Designer Application with SQL Generator<\/p><\/div>\n<p><strong>I. Project Setup<\/strong><\/p>\n<p>We need two JavaScript libraries for the flowchart:<\/p>\n<ul>\n<li>MindFusion.Common.js<\/li>\n<li>MindFusion.Diagramming.js<\/li>\n<\/ul>\n<p>We copy them in the work folder of the project, where we will put the HTML and the JavaScript code behind. Then we create an HTML file and name it DBDesign.html. There we will reference the two JavaScript libraries:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">a<\/span> <span class=\"attribute-name\">href<\/span>=\"<a class=\"attribute-value\" href=\"view-source:http:\/\/mindfusion.common.js\/\">http:\/\/MindFusion.Common.js<\/a>\"&gt;http:\/\/MindFusion.Common.js&lt;\/<span class=\"end-tag\">a<\/span>&gt;\n<span id=\"line257\"><\/span>&lt;<span class=\"start-tag\">a<\/span> <span class=\"attribute-name\">href<\/span>=\"<a class=\"attribute-value\" href=\"view-source:http:\/\/mindfusion.diagramming.js\/\">http:\/\/MindFusion.Diagramming.js<\/a>\"&gt;http:\/\/MindFusion.Diagramming.js&lt;\/<span class=\"end-tag\">a<\/span>&gt;<\/pre>\n<p>We reference those two libraries at the end of the HTML file, just before the closing tag. This way we are sure that the majority of the browsers will load the scripts correct.<\/p>\n<p>We need an <a title=\"HTML 5 Canvas\" href=\"https:\/\/www.w3schools.com\/html\/html5_canvas.asp\">HTML 5 Canvas element<\/a> for the diagram to draw itself onto and we create one inside a &lt;div&gt; tag:<\/p>\n<p>&lt;div style=&#8221;position: absolute; width: 100%; height: 100%; overflow: auto;&#8221;&gt;<br \/>&lt;canvas id=&#8221;diagram&#8221; width=&#8221;2100&#8243; height=&#8221;2100&#8243;&gt;<br \/>This page requires a browser that supports HTML 5 Canvas element.<br \/>&lt;\/canvas&gt;<br \/>&lt;\/div&gt;<\/p>\n<p>It\u2019s important to set and id for the Canvas element, that\u2019s how we will get it in the JavaScript code behind file.<\/p>\n<p>We create the JS file to be used by this project as DBDesign.js and we place it in the same directory as the two other JS files. We add a reference to it in the HTML page:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">a<\/span> <span class=\"attribute-name\">href<\/span>=\"<a class=\"attribute-value\" href=\"view-source:http:\/\/dbdesign.js\/\">http:\/\/DBDesign.js<\/a>\"&gt;http:\/\/DBDesign.js&lt;\/<span class=\"end-tag\">a<\/span>&gt;<\/pre>\n<p><strong>II. UI Controls<\/strong><\/p>\n<p>The DBDesigner has a line of controls at the bottoms that provide menus \u2013 add\/edit\/delete row, create\/delete\/rename table and a button for connection info. We create them as buttons:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">div<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">controls<\/a>\" <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">height: 150px<\/a>\" <span class=\"attribute-name\">left:<\/span>=\"\" <span class=\"attribute-name\">0;<\/span>=\"\" <span class=\"attribute-name\">right:<\/span>=\"\" <span class=\"attribute-name error\" title=\"Quote in attribute name. Probable cause: Matching quote missing somewhere earlier.\">401px;\"<\/span>=\"\"&gt;\n<span id=\"line273\"><\/span>   &lt;<span class=\"start-tag\">input<\/span> <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">button<\/a>\" <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">btnAddRow<\/a>\" <span class=\"attribute-name\">value<\/span>=\"<a class=\"attribute-value\">Add row<\/a>\" <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">margin-left: 5px; margin-bottom: 2px;<\/a>\"&gt;\n<span id=\"line274\"><\/span>   &lt;<span class=\"start-tag\">input<\/span> <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">button<\/a>\" <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">btnEditRow<\/a>\" <span class=\"attribute-name\">value<\/span>=\"<a class=\"attribute-value\">Edit row<\/a>\" <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">margin-left: 5px; margin-bottom: 2px;<\/a>\"&gt;\n<span id=\"line275\"><\/span>   &lt;<span class=\"start-tag\">input<\/span> <span class=\"attribute-name\">type<\/span>=\"<a class=\"attribute-value\">button<\/a>\" <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">btnDeleteRow<\/a>\" <span class=\"attribute-name\">value<\/span>=\"<a class=\"attribute-value\">Delete row<\/a>\" <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">margin-left: 5px; margin-bottom: 2px;<\/a>\"&gt;\n<span id=\"line276\"><\/span>\u2026..\n<span id=\"line277\"><\/span>&lt;\/<span class=\"end-tag\">div<\/span>&gt;<\/pre>\n<p>We add a textarea for the generated SQL and we close the div:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">textarea<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">generatedSql<\/a>\" <span class=\"attribute-name\">style<\/span>=\"<a class=\"attribute-value\">height: 120px;width: 100%<\/a>\"&gt;&lt;\/<span class=\"end-tag\">textarea<\/span>&gt;<\/pre>\n<p>When the user presses one of those buttons we show a dialog. The dialogs are forms. Here is the form that renames a table:<\/p>\n<pre id=\"line1\">&lt;<span class=\"start-tag\">div<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">renameTable-dialog<\/a>\" <span class=\"attribute-name\">title<\/span>=\"<a class=\"attribute-value\">Rename Table<\/a>\"&gt;\n<span id=\"line285\"><\/span>  &lt;<span class=\"start-tag\">form<\/span>&gt;\n<span id=\"line286\"><\/span>\n<span id=\"line287\"><\/span>&lt;<span class=\"start-tag\">fieldset<\/span>&gt;\n<span id=\"line288\"><\/span>  \t &lt;<span class=\"start-tag\">label<\/span> <span class=\"attribute-name\">for<\/span>=\"<a class=\"attribute-value\">renameTableCaption<\/a>\"&gt;Table name&lt;\/<span class=\"end-tag\">label<\/span>&gt;\n<span id=\"line289\"><\/span>&lt;\/<span class=\"end-tag\">fieldset<\/span>&gt;\n<span id=\"line290\"><\/span>\n<span id=\"line291\"><\/span>\t&lt;\/<span class=\"end-tag\">form<\/span>&gt;\n<span id=\"line292\"><\/span>&lt;\/<span class=\"end-tag\">div<\/span>&gt;<\/pre>\n<p><strong>III. General Diagram Settings<\/strong><\/p>\n<p>Let\u2019s start coding the JavaScript methods for the DBDesign application. We use the document.ready method to initialize the <a title=\"Diagram class\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_Diagram_Members_0.htm\">Diagram:<\/a><\/p>\n<pre>var Diagram = MindFusion.Diagramming.Diagram;\n\nvar diagram;\n\n$(document).ready(function () {\n   \/\/ create a Diagram component that wraps the \"diagram\" canvas\n   diagram = MindFusion.AbstractionLayer.createControl(Diagram, null, null, null, $(\"#diagram\")[0]);\n\u2026\u2026\u2026.\n\n});\n<\/pre>\n<p>\u00a0<\/p>\n<p>We use the id of the diagram Canvas that we set in the web page and now create the diagram control. Once we have it we set some properties to it:<\/p>\n<pre>\/\/ set some Diagram properties.\ndiagram.setBehavior(Behavior.LinkTables);\ndiagram.setAllowSelfLoops(false);\ndiagram.setBackBrush('#F0F0F0');\ndiagram.setLinkHeadShape('Triangle');\ndiagram.setLinkHeadShapeSize(4);\ndiagram.getSelection().allowMultipleSelection = false;\n<\/pre>\n<p>\u00a0<\/p>\n<p>We change the default <a title=\"setBehavior method\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?M_MindFusion_Diagramming_Diagram_setBehavior_1_Behavior.htm\">Behavior<\/a> of the diagram control to <a title=\"Behavior enumeration\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_Behavior_0.htm\">\u201cLinkTables\u201d,<\/a> which means users would be able to connect table rows. We stop users from creating self loops on tables and add some styling: the back brush is set to light gray, <a title=\"setLinkHeadShape method\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?M_MindFusion_Diagramming_Diagram_setLinkHeadShape_1_Shape.htm\">the head shape of links<\/a> is \u2018Triangle\u2019 and we forbid the users to select multiple objects.<\/p>\n<p>The styling of the diagram is done through <a title=\"Theme class\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/Cindex.htm?C_T_MindFusion_Diagramming_Theme_Members_0.htm\">themes.<\/a> We create a theme and add to it a style for the table nodes:<\/p>\n<pre>\/\/ set the Diagram style.\nvar theme = new Theme();\n\nvar tableNodeStyle = new Style();\ntableNodeStyle.setBrush({ type: 'LinearGradientBrush', color1: 'rgb(224, 233, 233)', color2: 'rgb(102, 154, 204)', angle: 30 });\ntableNodeStyle.setTextColor({ type: 'SolidBrush', color: 'rgb(45, 57, 86)' });\ntableNodeStyle.setStroke('rgb(192, 192, 192)');\n<\/pre>\n<p>\u00a0<\/p>\n<p>The tableNodeStyle sets the brush, text color and stroke for the tables. Let\u2019s tell the theme object that this is the style for table nodes:<\/p>\n<pre>theme.styles['std:TableNode'] = tableNodeStyle;\n<\/pre>\n<p>And let\u2019s tell the diagram control that it has a theme:<\/p>\n<pre>diagram.setTheme(theme);\n<\/pre>\n<p>\u00a0<\/p>\n<p>Link styling is done in the same way and you can find the code in the *.zip file that is available for download.<\/p>\n<p><strong>IV. Events<\/strong><\/p>\n<p>Handling events is the most important part of this application. We have events raised by the diagram elements and we have events that are raised by the JavaScript buttons. Let\u2019s start with the js buttons. When the web page is loaded there is a single button active from the row of buttons available at the bottom of the page \u2013 \u201cCreate table\u201d. In the document.ready() method we wire the button with an event:<\/p>\n<pre>$('#btnCreateTable').button().click(function (event) { createTable(); });\n<\/pre>\n<p>\u00a0<\/p>\n<p>This event calls the createTable method that generates a <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_TableNode_Members_0.htm\">TableNode<\/a> instance:<\/p>\n<pre>function createTable() {\n\t\/\/ create a new table with the specified extent\n\tvar table = diagram.getFactory().createTableNode(\n\t\t\t\t15 + tableCount * 3, 15 + tableCount * 4, 50, 60);\n\ttable.setText(\"Table\" + tableCount++);\n\ttable.redimTable(2, 0);\n\ttable.setScrollable(true);\n\ttable.setConnectionStyle(ConnectionStyle.Rows);\n\n\t\/\/ set the first column to resize with the table\n\ttable.getColumn(0).columnStyle = ColumnStyle.AutoWidth;\n\n\tgenerateSQL();\n}\n<\/pre>\n<p>\u00a0<\/p>\n<p>The createTableNode method accepts as arguments the x and y coordinates of the new <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_TableNode_Members_0.htm\">TableNode<\/a> and its width and height. We create initially the table with two columns and no rows. By default the tables can be scrolled and the links connect table rows.<\/p>\n<p>The generateSQL method is a simple one \u2013 it just creates an SQL table. You can expand the sample with more complicated SQL statements but in our case we just create a table with the columns that were set to the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?CC_T_MindFusion_Diagramming_TableNode_Members_0.htm\">TableNode<\/a>:<\/p>\n<pre>function generateSQL() {\n   var text = '';\n\n   \/\/ enumerate all tables in the current diagram\n   ArrayList.forEach(diagram.nodes, function (table) {\n   text += \"CREATE TABLE \" + table.getText() + \"\\r\\n(\";\n\n   \/\/ enumerate all rows of a table\n   for (var r = 0; r &lt; table.cells.rows; ++r) {\n   \/\/ get text of cells in current row\n   text += \"\\t\" + table.getCell(0, r).getText() + \" \" + table.getCell(1, r).getText();\n   if (r &lt; table.cells.rows - 1)\n\t text += \",\\r\\n\";\n   }\n\ttext += \"\\r\\n);\\r\\n\\r\\n\";\n   });\n\n  $('#generatedSql')[0].innerHTML = text;\n}\n<\/pre>\n<p>When the SQL text is generated we assign it to <a title=\"HTML Textarea Tag\" href=\"https:\/\/www.w3schools.com\/tags\/tag_textarea.asp\">the textarea<\/a> instance that we created.<\/p>\n<p><strong>V. Diagram Events<\/strong><\/p>\n<p>Here we will talk about the events fired by the diagram control. Once a table is created the users can double click on it to create new rows, edit or delete existing rows. This happens when we handle the <a title=\"nodeDoubleClicked Event\" href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/jsdiagram\/index.htm?F_MindFusion_Diagramming_Events_nodeDoubleClicked.htm\">nodeDoubleClicked<\/a> event:<\/p>\n<pre>diagram.addEventListener(Events.nodeDoubleClicked, function (sender, args) {\n\tif (tblClicked != args.getNode()) {\n\t\ttblClicked = args.getNode();\n\t}\n\u2026.\n\n});\n<\/pre>\n<p>\u00a0<\/p>\n<p>Here we identify the table that is clicked and then we have to decide which dialogue to show:<\/p>\n<pre>if (tblClicked) {\n\t\tvar cellClicked = tblClicked.cellFromPoint(args.getMousePosition());\n\t\tif (cellClicked) {\n\t\t\trowClicked = cellClicked.row;\n\t\t\teditRowOpen();\n\t\t}\n\t\telse if (tblClicked.hitTestManipulators(args.getMousePosition()) == null) {\n\t\tif (args.getMousePosition().y &lt;= tblClicked.getBounds().y + tblClicked.getCaptionHeight())\n\t\t\trenameTableOpen();\n\t\t\telse\n\t\t\taddRowOpen();\n\t\t    }\n\t\t}\n\n<\/pre>\n<p>\u00a0<\/p>\n<p>If an existing cell is clicked we open the editRow form. If the caption of the table was clicked we open the form for rename of a table. If none of those, we open the form that adds a new row.<\/p>\n<p>Let\u2019s look how the addRow dialogue opens:<\/p>\n<pre>function addRowOpen() {\n  var table = tblClicked || diagram.getActiveItem();\n\n  if (!table || !AbstractionLayer.isInstanceOfType(TableNode, table))\n\treturn;\n\n   addRowDialog.dialog(\"open\");\n}\n<\/pre>\n<p>\u00a0<\/p>\n<p>the method calls the dialog method of addRowDialog. At the beginning of the js file we have declared a variable:<\/p>\n<pre>var addRowDialog = null\n<\/pre>\n<p>\u00a0<\/p>\n<p>Then we create the addRowDialog object:<\/p>\n<pre>addRowDialog = $(\"#addRow-dialog\").dialog({\n\t\tautoOpen: false,\n\t\tresizable: false,\n\t\theight: 'auto',\n\t\twidth: 250,\n\t\tmodal: false,\n\t\tbuttons: {\n\t\t\t\"OK\": addRow,\n\t\t\tCancel: function () {\n\t\t\t\taddRowDialog.dialog(\"close\");\n\t\t\t}\n\t\t},\n\t\tclose: function () {\n\t\t\taddRowType.val(\"NUMBER\");\n\t\t\taddRowType.selectmenu(\"refresh\");\n\t\t\taddRowForm[0].reset();\n\t\t}\n\t});\n\taddRowForm = addRowDialog.find(\"form\").on(\"submit\", function (event) {\n\t\tevent.preventDefault();\n\t\taddRow();\n\t});\n\n<\/pre>\n<p>\u00a0<\/p>\n<p>Here we create the dialog that has auto height, width of 250 and two buttons: OK and Cancel. The Cancel button closes the dialog. When the user has pressed OK the form is submitted and the addRow method is called.<\/p>\n<p>The form that shows is defined in the HTML page and looks like that:<\/p>\n<pre id=\"line1\"><span class=\"start-tag\">div<\/span> <span class=\"attribute-name\">id<\/span>=\"<a class=\"attribute-value\">addRow-dialog<\/a>\" <span class=\"attribute-name\">title<\/span>=\"<a class=\"attribute-value\">New Field<\/a>\"&gt;\n<span id=\"line446\"><\/span>\t\t&lt;<span class=\"start-tag\">form<\/span>&gt;\n<span id=\"line447\"><\/span>\n<span id=\"line448\"><\/span>&lt;<span class=\"start-tag\">fieldset<\/span>&gt;\n<span id=\"line449\"><\/span>\t\t\t&lt;<span class=\"start-tag\">label<\/span> <span class=\"attribute-name\">for<\/span>=\"<a class=\"attribute-value\">addRow-fieldName<\/a>\"&gt;\n<span id=\"line450\"><\/span>\t\t\t\tField name&lt;\/<span class=\"end-tag\">label<\/span>&gt;\n<span id=\"line451\"><\/span>\t\t\t\n<span id=\"line452\"><\/span>\t\t\t&lt;<span class=\"start-tag\">label<\/span> <span class=\"attribute-name\">for<\/span>=\"<a class=\"attribute-value\">addRow-fieldType<\/a>\"&gt;\n<span id=\"line453\"><\/span>\t\t\t\tField type&lt;\/<span class=\"end-tag\">label<\/span>&gt;\n<span id=\"line454\"><\/span>\t\t\t\n<span id=\"line455\"><\/span>\t\t\t\tNUMBER\n<span id=\"line456\"><\/span>\t\t\t\tCHAR(32)\n<span id=\"line457\"><\/span>\t\t\t\tDATE\n<span id=\"line458\"><\/span>\t\t\t\tVARCHAR\n<span id=\"line459\"><\/span>\t\t\t\tBLOB\n<span id=\"line460\"><\/span>\t\t\t\n<span id=\"line461\"><\/span>&lt;\/<span class=\"end-tag\">fieldset<\/span>&gt;\n<span id=\"line462\"><\/span>\n<span id=\"line463\"><\/span>\t\t&lt;\/<span class=\"end-tag\">form<\/span>&gt;\n<span id=\"line464\"><\/span>&lt;\/<span class=\"end-tag\">div<\/span>&gt;<\/pre>\n<p>The addRow method gets the clicked table and gets the two cells at the last row. It gets the text that was chosen in the dialog and assigns it to the cells. Then the dialog is closed and the SQL is generated once again.<\/p>\n<pre>function addRow() {\n\tvar table = tblClicked || diagram.getActiveItem();\n\n\tif (!table || !AbstractionLayer.isInstanceOfType(TableNode, table))\n\t\treturn;\n\n\ttable.addRow();\n\n\tvar lastRow = table.cells.rows - 1;\n\n\t\/\/ use the cell indexer to access cells by their column and row\n\ttable.getCell(0, lastRow).setText(addRowName[0].value);\n\ttable.getCell(1, lastRow).setText(addRowType[0].value);\n\n\t\/\/ close the dialog\n\taddRowDialog.dialog(\"close\");\n\n\t\/\/ refresh SQL definition\n\tgenerateSQL();\n}\n<\/pre>\n<p>\u00a0<\/p>\n<p>And that\u2019s the end for this tutorial. You can download the sample together with the necessary JavaScript libraries from this link:<\/p>\n<p align=\"center\"><a title=\"Download JavaScript DB Designer Application\" href=\"https:\/\/mindfusion.dev\/samples\/javascript\/diagram\/DBDesign.zip\">Download the JavaScript Database Designer Application<\/a><\/p>\n<p>Find out more about MindFusion JavaScript Diagram Library at <a title=\"JS flowchart\" href=\"https:\/\/mindfusion.dev\/javascript-diagram.html\">https:\/\/mindfusion.dev\/javascript-diagram.html<\/a><\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are going to use the JS flowchart library as a database design tool. We will create DB tables, add rows, connect the tables and generate SQL statements that would create the tables. Here is a screenshot of the application: &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/javascript-database-designer-with-sql-generator\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"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,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[95,74],"tags":[490,488,473,492,491,489],"class_list":["post-1906","post","type-post","status-publish","format-standard","hentry","category-diagramming-2","category-sample-code","tag-db-designer-javascript","tag-javascript-database-designer","tag-javascript-diagram","tag-js-database-design","tag-js-flowchart","tag-sql-table-generator"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-uK","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=1906"}],"version-history":[{"count":9,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1906\/revisions"}],"predecessor-version":[{"id":2640,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/1906\/revisions\/2640"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=1906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=1906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=1906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}