X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=parser.js;h=6caf0a9f5a3f0dfdc4f153a5d8e4ffd54dba02df;hb=006d95a3942660083d2c957afea5338c2de8642d;hp=8a0932160a0a50f7f1b551242aed17dac2f9c30d;hpb=525c4d2aa73ae124da17a3c64a2ca44d13fcc49d;p=erdiag.git diff --git a/parser.js b/parser.js index 8a09321..6caf0a9 100644 --- a/parser.js +++ b/parser.js @@ -7,6 +7,7 @@ class ErDiags this.inheritances = []; this.associations = []; this.txt2json(description); + this.tables = []; // Cache SVG graphs returned by server (in addition to server cache = good perfs) this.mcdGraph = ""; this.mldGraph = ""; @@ -15,7 +16,7 @@ class ErDiags static get TYPES() { - // SQLite types without null (TODO: be more general) + // SQLite storage classes without null return ["integer","real","text","blob"]; } @@ -66,7 +67,7 @@ class ErDiags { case '[': // Entity = { name: { attributes, [weak] } } - let name = lines[start].match(/\w+/)[0]; + let name = lines[start].match(/[^\[\]"\s]+/)[0]; let entity = { attributes: this.parseAttributes(lines, start+1, end) }; if (lines[start].charAt(1) == '[') entity.weak = true; @@ -78,7 +79,7 @@ class ErDiags case '{': //association // Association = { [name], [attributes], [weak], entities: ArrayOf entity indices } let relationship = { }; - let nameRes = lines[start].match(/\w+/); + let nameRes = lines[start].match(/[^{}"\s]+/); if (nameRes !== null) relationship.name = nameRes[0]; if (lines[start].charAt(1) == '{') @@ -94,15 +95,20 @@ class ErDiags let attributes = []; for (let i=start; i { + if (mcdStyle == "compact") + mcdDot += "node [shape=plaintext];\n"; + _.shuffle(Object.keys(this.entities)).forEach( name => { if (mcdStyle == "bubble") { - mcdDot += name + '[shape=rectangle, label="' + name + '"'; + mcdDot += '"' + name + '" [shape=rectangle, label="' + name + '"'; if (this.entities[name].weak) mcdDot += ', peripheries=2'; mcdDot += '];\n'; if (!!this.entities[name].attributes) { - this.entities[name].attributes.forEach( a => { + _.shuffle(this.entities[name].attributes).forEach( a => { let label = (a.isKey ? '#' : '') + a.name; - mcdDot += name + '_' + a.name + '[shape=ellipse, label="' + label + '"];\n'; - mcdDot += name + '_' + a.name + ' -- ' + name + ';\n'; + let attrName = name + '_' + a.name; + mcdDot += '"' + attrName + '" [shape=ellipse, label="' + label + '"];\n'; + if (Math.random() < 0.5) + mcdDot += '"' + attrName + '" -- "' + name + '";\n'; + else + mcdDot += '"' + name + '" -- "' + attrName + '";\n'; }); } } else { - mcdDot += name + '[shape=plaintext, label=<'; + mcdDot += '"' + name + '" [label=<'; if (this.entities[name].weak) { mcdDot += '' + @@ -212,7 +226,7 @@ class ErDiags mcdDot += '\n'; if (!!this.entities[name].attributes) { - this.entities[name].attributes.forEach( a => { + _.shuffle(this.entities[name].attributes).forEach( a => { let label = (a.isKey ? '' : '') + a.name + (a.isKey ? '' : ''); mcdDot += '\n'; }); @@ -224,42 +238,55 @@ class ErDiags } }); // Inheritances: - this.inheritances.forEach( i => { - i.children.forEach( c => { - mcdDot += c + ':name -- ' + i.parent + ':name [len="1.00", dir="forward", arrowhead="vee", style="dashed"];\n'; + _.shuffle(this.inheritances).forEach( i => { + _.shuffle(i.children).forEach( c => { + if (Math.random() < 0.5) + mcdDot += '"' + c + '":name -- "' + i.parent; + else + mcdDot += '"' + i.parent + '":name -- "' + c; + mcdDot += '":name [dir="forward", arrowhead="vee", style="dashed"];\n'; }); }); // Relationships: let assoceCounter = 0; - this.associations.forEach( a => { + _.shuffle(this.associations).forEach( a => { let name = !!a.name && a.name.length > 0 ? a.name : '_assoce' + assoceCounter++; - mcdDot += name + '[shape="diamond", style="filled", color="lightgrey", label="' + (!!a.name ? a.name : '') + '"'; + mcdDot += '"' + name + '" [shape="diamond", style="filled", color="lightgrey", label="' + name + '"'; if (a.weak) mcdDot += ', peripheries=2'; mcdDot += '];\n'; - a.entities.forEach( e => { - mcdDot += e.name + ':name -- ' + name + '[len="1.00", label="' + ErDiags.CARDINAL[e.card] + '"];\n'; + _.shuffle(a.entities).forEach( e => { + if (Math.random() < 0.5) + mcdDot += '"' + e.name + '":name -- "' + name + '"'; + else + mcdDot += '"' + name + '" -- "' + e.name + '":name'; + mcdDot += '[label="' + ErDiags.CARDINAL[e.card] + '"];\n'; }); if (!!a.attributes) { - a.attributes.forEach( attr => { + _.shuffle(a.attributes).forEach( attr => { let label = (attr.isKey ? '#' : '') + attr.name; - mcdDot += name + '_' + attr.name + '[len="1.00", shape=ellipse, label="' + label + '"];\n'; - mcdDot += name + '_' + attr.name + ' -- ' + name + ';\n'; + mcdDot += '"' + name + '_' + attr.name + '" [shape=ellipse, label="' + label + '"];\n'; + let attrName = name + '_' + attr.name; + if (Math.random() < 0.5) + mcdDot += '"' + attrName + '" -- "' + name + '";\n'; + else + mcdDot += '"' + name + '" -- "' + attrName + '";\n'; }); } }); mcdDot += '}'; - //console.log(mcdDot); + console.log(mcdDot); ErDiags.AjaxGet(mcdDot, graphSvg => { this.mcdGraph = graphSvg; element.innerHTML = graphSvg; - }) + }); } // "Modèle logique des données" + // TODO: this one should draw links from foreign keys to keys (port=... in
' + name + '
' + label + '
) drawMld(id) { let element = document.getElementById(id); @@ -268,10 +295,30 @@ class ErDiags element.innerHTML = this.mcdGraph; return; } - //UNIMPLEMENTED - // TODO: analyze cardinalities (eat attributes, create new tables...) - // mldDot = ... + // Build dot graph input + let mldDot = 'graph {\n'; + // Nodes: + Object.keys(this.entities).forEach( name => { + //mld. ... --> devient table + // mldDot = ... + }); + // Relationships: + this.associations.forEach( a => { + a.entities.forEach( e => { // e.card e.name ... + // Pass 1 : entites deviennent tables + // Pass 2 : sur les assoces + // multi-arite : sub-loop si 0,1 ou 1,1 : aspiré comme attribut de l'association (phase 1) + // ensuite, que du 0,n ou 1,n : si == 1, OK une table + // si 2 ou + : n tables + 1 pour l'assoce, avec attrs clés étrangères + // clé étrangère NOT NULL si 1,1 + }); + }); // this.graphMld = ... + //console.log(mldDot); + ErDiags.AjaxGet(mldDot, graphSvg => { + this.mldGraph = graphSvg; + element.innerHTML = graphSvg; + }); } fillSql(id)