From 7a80e6db5860033f0a922d54cc0ba3e950f4f268 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 2 Feb 2018 23:54:36 +0100
Subject: [PATCH] Improve cardinality, detect duplicated fields after creating
 tables

---
 README.md |  6 ++++++
 parser.js | 37 +++++++++++++++++++++++++++----------
 2 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index f4e75d1..ef279e6 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,12 @@ Cardinality dictionary:
 
 Special cardinalities are also available to indicate relative identification: `?R` and `1R`.
 
+And, in case of a self-relationship, symbols '>' and '<' can indicate the sense, as in
+
+	{manage}
+	Users *>
+	Users 1<
+
 To mark a weak entity, just surround its name by extra-brackets
 
 	[[WeakEntity]]
diff --git a/parser.js b/parser.js
index 6d028fd..6d43d4f 100644
--- a/parser.js
+++ b/parser.js
@@ -15,16 +15,17 @@ class ErDiags
 		this.sqlText = "";
 	}
 
-	static get CARDINAL()
+	static CARDINAL(symbol)
 	{
-		return {
-			"*": "0,n",
-			"+": "1,n",
-			"?": "0,1",
-			"1": "1,1",
-			"?R": "(0,1)",
-			"1R": "(1,1)",
-		};
+		let res = { "*": "0,n", "+": "1,n", "?": "0,1", "1": "1,1" } [ symbol[0] ];
+		if (symbol.length >= 2)
+		{
+			if (symbol[1] == 'R')
+				res = '(' + res + ')';
+			else if (['>','<'].includes(symbol[1]))
+				res += symbol[1];
+		}
+		return res;
 	}
 
 	///////////////////////////////
@@ -243,6 +244,22 @@ class ErDiags
 						});
 					});
 				});
+				// Check for duplicates (in case of self-relationship), rename if needed
+				newTable.fields.forEach( (f,i) => {
+					const idx = newTable.fields.findIndex( item => { return item.name == f.name; });
+					if (idx < i)
+					{
+						// Current field is a duplicate
+						let suffix = 2;
+						let newName = f.name + suffix;
+						while (newTable.fields.findIndex( item => { return item.name == newName; }) >= 0)
+						{
+							suffix++;
+							newName = f.name + suffix;
+						}
+						f.name = newName;
+					}
+				});
 				// Add relationship potential own attributes
 				(a.attributes || [ ]).forEach( attr => {
 					newTable.fields.push({
@@ -392,7 +409,7 @@ class ErDiags
 					mcdDot += '"' + e.name + '":name -- "' + name + '"';
 				else
 					mcdDot += '"' + name + '" -- "' + e.name + '":name';
-				mcdDot += '[label="' + ErDiags.CARDINAL[e.card] + '"];\n';
+				mcdDot += '[label="' + ErDiags.CARDINAL(e.card) + '"];\n';
 			});
 		});
 		mcdDot += '}';
-- 
2.44.0