From c9a83d42b8f1512d33c9cc214c7cff3e51b93baf Mon Sep 17 00:00:00 2001 From: Bob Garner Date: Thu, 22 Aug 2024 05:35:46 +0900 Subject: [PATCH] Fixes issue where having multiple relationships to the same entity was a problem. (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also added support for using “self” for template argument instead of having to repeat the container entity name. --- .../java/org/entityc/compiler/ASTVisitor.java | 6 +++- .../model/entity/MTEntityTemplate.java | 33 ++++++++++++++----- .../compiler/model/entity/MTRelationship.java | 3 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/entityc/compiler/ASTVisitor.java b/src/main/java/org/entityc/compiler/ASTVisitor.java index 776cb52..188a43b 100644 --- a/src/main/java/org/entityc/compiler/ASTVisitor.java +++ b/src/main/java/org/entityc/compiler/ASTVisitor.java @@ -1372,7 +1372,11 @@ public MTRelationship visitRelationshipStatement(EntityLanguageParser.Relationsh instantiation = new MTEntityTemplateInstantiation(ctx.relationshipTemplateAs(), ctx.relationshipTemplateAs().id().getText()); for (EntityLanguageParser.RelationshipTemplateArgContext argContext : ctx.relationshipTemplateAs().relationshipTemplateArg()) { - instantiation.addTemplateArgEntityName(argContext.id().getText(), argContext.UNIQUE() != null); + String argEntityName = argContext.id().getText(); + if (argEntityName.equals("self")) { + argEntityName = fromEntityName; + } + instantiation.addTemplateArgEntityName(argEntityName, argContext.UNIQUE() != null); } } toEntityName = ctx.id(0).getText(); diff --git a/src/main/java/org/entityc/compiler/model/entity/MTEntityTemplate.java b/src/main/java/org/entityc/compiler/model/entity/MTEntityTemplate.java index fb76ed9..ad4b744 100644 --- a/src/main/java/org/entityc/compiler/model/entity/MTEntityTemplate.java +++ b/src/main/java/org/entityc/compiler/model/entity/MTEntityTemplate.java @@ -44,6 +44,7 @@ public MTEntityTemplate(ParserRuleContext ctx, MTModule module, String name, Lis } public MTEntity makeEntity(MTEntity parentEntity, String asEntityName, MTEntityTemplateInstantiation instantiation, MTSpace space) { + List templateArgEntityNames = instantiation.getTemplateArgEntityNames(); MTEntity entity = new MTEntity(instantiation.getParserRuleContext(), parentEntity.getModule(), asEntityName); @@ -62,30 +63,44 @@ public MTEntity makeEntity(MTEntity parentEntity, String asEntityName, MTEntityT } entity.primaryKey = copiedPrimaryKey; - // Map the template arguments to the entity names in the instantiation - Map argToEntityName = new HashMap<>(); + // Map the template argument names (e.g., ) to the entity names + // in the instantiation (e.g., ) + Map templateArgToEntityName = new HashMap<>(); if (templateArgs.size() != templateArgEntityNames.size()) { ECLog.logFatal(this, "The number of arguments of the template do not match that of its instantiation."); } for (int i = 0; i < templateArgs.size(); i++) { - argToEntityName.put(templateArgs.get(i), templateArgEntityNames.get(i)); + templateArgToEntityName.put(templateArgs.get(i), templateArgEntityNames.get(i)); } + // Copy the attributes for (MTAttribute attribute : this.getAttributes()) { entity.addAttribute(MTAttribute.Copy(attribute, entity)); } - Map argToRelationship = new HashMap<>(); + Map templateArgToRelationship = new HashMap<>(); MTRelationship parentRelationship = null; - // copy the relationships, substituting template variable with instantiated entity + ArrayList sameToEntityRelationships = new ArrayList<>(); + + for (MTRelationship relationship : this.relationships) { + if (this.hasRelationshipToEntityNamed(relationship.getTo().getEntityName())) { + sameToEntityRelationships.add(relationship); + } + } + + // + // Copy the relationships + // -- substituting template argument with instantiated entity name + // for (MTRelationship relationship : this.relationships) { // look for template arguments that need to be resolved. String templateArgName = relationship.getTo().getEntityName(); - String mappedEntityName = argToEntityName.get(templateArgName); + String mappedEntityName = templateArgToEntityName.get(templateArgName); if (mappedEntityName != null) { + String relationshipName = relationship.getName() + mappedEntityName; MTRelationship resolvedRelationship = new MTRelationship(instantiation.getParserRuleContext(), - ECStringUtil.Uncapitalize(mappedEntityName), + relationshipName, entity.getName(), relationship.getTo().getPlurality(), mappedEntityName, @@ -95,7 +110,7 @@ public MTEntity makeEntity(MTEntity parentEntity, String asEntityName, MTEntityT relationship.getToEntityIdName(), templateArgName); entity.addRelationship(resolvedRelationship); - argToRelationship.put(relationship.getTo().getEntityName(), resolvedRelationship); + templateArgToRelationship.put(templateArgName, resolvedRelationship); if (relationship.isParent() && !relationship.isOptional()) { parentRelationship = resolvedRelationship; } @@ -125,7 +140,7 @@ public MTEntity makeEntity(MTEntity parentEntity, String asEntityName, MTEntityT if (unique) { MTUniqueness uniqueness = new MTUniqueness(instantiation.getParserRuleContext(), parentRelationship); - MTRelationship relationship = argToRelationship.get(templateArg); + MTRelationship relationship = templateArgToRelationship.get(templateArg); if (relationship != null) { uniqueness.setRelationship(relationship); entity.addUniqueness(uniqueness); diff --git a/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java b/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java index 23e99cd..d60ce30 100644 --- a/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java +++ b/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java @@ -282,7 +282,7 @@ public boolean resolveReferences(MTSpace space, int pass) { return false; } - // find a list of possble relationships between entities + // find a list of possible relationships between entities boolean anotherPass = this.to.resolveReferences(space, pass); if (anotherPass) { if (pass > 7) { @@ -327,6 +327,7 @@ public boolean resolveReferences(MTSpace space, int pass) { for (MTRelationship fromRelationship : possibleFromRelationships) { if (found) { duplicates = true; + // TODO: Maybe this is because two tables are used for two relationships... ECLog.logWarning(fromRelationship, "Found duplicate relationship matches between " + from.getEntity().getName() + "." + this.getName() + " and " + to.getEntity().getName() + "."