Skip to content

Commit

Permalink
Fixes issue where having multiple relationships to the same entity wa…
Browse files Browse the repository at this point in the history
…s a problem. (#25)

Also added support for using “self” for template argument instead of having to repeat the container entity name.
  • Loading branch information
bobgarner authored Aug 21, 2024
1 parent 7df3e7f commit c9a83d4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
6 changes: 5 additions & 1 deletion src/main/java/org/entityc/compiler/ASTVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> templateArgEntityNames = instantiation.getTemplateArgEntityNames();
MTEntity entity = new MTEntity(instantiation.getParserRuleContext(),
parentEntity.getModule(), asEntityName);
Expand All @@ -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<String, String> argToEntityName = new HashMap<>();
// Map the template argument names (e.g., <A, B>) to the entity names
// in the instantiation (e.g., <MyEntity, OtherEntity>)
Map<String, String> 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<String, MTRelationship> argToRelationship = new HashMap<>();
Map<String, MTRelationship> templateArgToRelationship = new HashMap<>();

MTRelationship parentRelationship = null;
// copy the relationships, substituting template variable with instantiated entity
ArrayList<MTRelationship> 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,
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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() + "."
Expand Down

0 comments on commit c9a83d4

Please sign in to comment.