Ejemplo n.º 1
0
  private void buildContraints(Table table) {
    addConstraints(table.getAccessPatterns(), "AP", ACCESSPATTERN); // $NON-NLS-1$

    KeyRecord pk = table.getPrimaryKey();
    if (pk != null) {
      addConstraint("PK", PRIMARY_KEY, pk, true); // $NON-NLS-1$
    }

    addConstraints(table.getUniqueKeys(), UNIQUE, UNIQUE);
    addConstraints(table.getIndexes(), INDEX, INDEX);
    addConstraints(table.getFunctionBasedIndexes(), INDEX, INDEX);

    for (int i = 0; i < table.getForeignKeys().size(); i++) {
      ForeignKey key = table.getForeignKeys().get(i);
      addConstraint("FK" + i, FOREIGN_KEY, key, false); // $NON-NLS-1$
      append(SPACE).append(REFERENCES);
      if (key.getReferenceKey() != null) {
        if (key.getReferenceKey().getParent().getParent().equals(key.getParent().getParent())) {
          append(SPACE).append(new GroupSymbol(key.getReferenceKey().getParent().getName()));
        } else {
          append(SPACE).append(new GroupSymbol(key.getReferenceKey().getParent().getFullName()));
        }
      } else if (key.getReferenceTableName() != null) {
        append(SPACE).append(new GroupSymbol(key.getReferenceTableName()));
      }
      append(SPACE);
      addNames(key.getReferenceColumns());
      appendOptions(key);
    }
  }
  @Test
  public void testAssosiationWithReferentialContriant() throws Exception {
    ODataMetadataProcessor processor = new ODataMetadataProcessor();
    MetadataFactory mf =
        new MetadataFactory(
            "vdb",
            1,
            "northwind",
            SystemMetadata.getInstance().getRuntimeTypeMap(),
            new Properties(),
            null);

    CsdlEntityType g1Entity = entityType("g1");
    g1Entity.getProperties().add(createProperty("g2e2", EdmPrimitiveTypeKind.String));
    g1Entity.setKey(Arrays.asList(new CsdlPropertyRef().setName("g2e2")));
    CsdlEntityType g2Entity = entityType("g2");

    CsdlNavigationProperty navProperty = new CsdlNavigationProperty();
    navProperty.setName("one_2_one");
    navProperty.setType("namespace.g2");
    navProperty.setNullable(false);
    navProperty.setPartner("PartnerPath");
    navProperty.setReferentialConstraints(
        Arrays.asList(
            new CsdlReferentialConstraint().setProperty("g2e2").setReferencedProperty("e2")));

    g1Entity.setNavigationProperties(Arrays.asList(navProperty));

    CsdlEntitySet g1Set = createES("G1", "namespace.g1");
    CsdlEntitySet g2Set = createES("G2", "namespace.g2");

    CsdlNavigationPropertyBinding navBinding = new CsdlNavigationPropertyBinding();
    navBinding.setPath("one_2_one");
    navBinding.setTarget("G2");
    g1Set.setNavigationPropertyBindings(Arrays.asList(navBinding));

    XMLMetadata metadata = buildXmlMetadata(g1Entity, g1Set, g2Entity, g2Set);
    processor.getMetadata(mf, metadata);

    Table g1 = mf.getSchema().getTable("G1");
    Table g2 = mf.getSchema().getTable("G2");

    assertNotNull(g1);
    assertNotNull(g2);

    ForeignKey fk = g2.getForeignKeys().get(0);
    assertEquals("one_2_one", fk.getName());
    assertNotNull(fk.getColumnByName("e2"));
    assertEquals("g2e2", fk.getReferenceColumns().get(0));
  }
  private QueryCommand buildSubquery(Expression projected) {
    Criteria criteria = null;
    for (ForeignKey fk : this.childTable.getForeignKeys()) {
      if (fk.getPrimaryKey().getParent().equals(this.parent)) {
        List<String> refColumns = fk.getReferenceColumns();
        if (refColumns == null) {
          refColumns = ODataSQLBuilder.getColumnNames(childTable.getPrimaryKey().getColumns());
        }

        List<String> pkColumns =
            ODataSQLBuilder.getColumnNames(parent.getPrimaryKey().getColumns());
        List<Criteria> critList = new ArrayList<Criteria>();

        for (int i = 0; i < refColumns.size(); i++) {
          critList.add(
              new CompareCriteria(
                  new ElementSymbol(pkColumns.get(i), this.parentGroup),
                  CompareCriteria.EQ,
                  new ElementSymbol(refColumns.get(i), this.childGroup)));
        }

        criteria = critList.get(0);
        for (int i = 1; i < critList.size(); i++) {
          criteria = new CompoundCriteria(CompoundCriteria.AND, criteria, critList.get(i));
        }
      }
    }
    Select s1 = new Select();
    s1.addSymbol(projected);
    From f1 = new From();
    f1.addGroup(this.childGroup);
    Query q1 = new Query();
    q1.setSelect(s1);
    q1.setFrom(f1);
    q1.setCriteria(criteria);

    return q1;
  }
  private static void buildAssosiationSets(MetadataStore metadataStore, List<Builder> edmSchemas) {
    for (Schema schema : metadataStore.getSchemaList()) {

      EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName());
      EdmEntityContainer.Builder entityContainer =
          findEntityContainer(edmSchemas, schema.getName());
      List<EdmAssociationSet.Builder> assosiationSets = new ArrayList<EdmAssociationSet.Builder>();
      List<EdmAssociation.Builder> assosiations = new ArrayList<EdmAssociation.Builder>();

      for (Table table : schema.getTables().values()) {
        // build Associations
        for (ForeignKey fk : table.getForeignKeys()) {

          EdmEntitySet.Builder entitySet =
              findEntitySet(edmSchemas, schema.getName(), table.getName());
          EdmEntitySet.Builder refEntitySet =
              findEntitySet(edmSchemas, schema.getName(), fk.getReferenceTableName());
          EdmEntityType.Builder entityType =
              findEntityType(edmSchemas, schema.getName(), table.getName());
          EdmEntityType.Builder refEntityType =
              findEntityType(edmSchemas, schema.getName(), fk.getReferenceTableName());

          // check to see if fk is part of this table's pk, then it is 1 to 1 relation
          boolean onetoone = sameColumnSet(table.getPrimaryKey(), fk);

          // Build Association Ends
          EdmAssociationEnd.Builder endSelf =
              EdmAssociationEnd.newBuilder()
                  .setRole(table.getName())
                  .setType(entityType)
                  .setMultiplicity(onetoone ? EdmMultiplicity.ZERO_TO_ONE : EdmMultiplicity.MANY);

          EdmAssociationEnd.Builder endRef =
              EdmAssociationEnd.newBuilder()
                  .setRole(fk.getReferenceTableName())
                  .setType(refEntityType)
                  .setMultiplicity(EdmMultiplicity.ZERO_TO_ONE);

          // Build Association
          EdmAssociation.Builder association = EdmAssociation.newBuilder();
          association.setName(table.getName() + "_" + fk.getName());
          association.setEnds(endSelf, endRef);
          association.setNamespace(
              refEntityType
                  .getFullyQualifiedTypeName()
                  .substring(0, refEntityType.getFullyQualifiedTypeName().indexOf('.')));
          assosiations.add(association);

          // Build ReferentialConstraint
          if (fk.getReferenceColumns() != null) {
            EdmReferentialConstraint.Builder erc = EdmReferentialConstraint.newBuilder();
            erc.setPrincipalRole(fk.getReferenceTableName());
            erc.addPrincipalReferences(fk.getReferenceColumns());
            erc.setDependentRole(table.getName());
            erc.addDependentReferences(getColumnNames(fk.getColumns()));
            association.setRefConstraint(erc);
          }

          // Add EdmNavigationProperty to entity type
          EdmNavigationProperty.Builder nav =
              EdmNavigationProperty.newBuilder(fk.getReferenceTableName());
          nav.setRelationshipName(fk.getName());
          nav.setFromToName(table.getName(), fk.getReferenceTableName());
          nav.setRelationship(association);
          nav.setFromTo(endSelf, endRef);
          entityType.addNavigationProperties(nav);

          // Add EdmNavigationProperty to Reference entity type
          EdmNavigationProperty.Builder refNav = EdmNavigationProperty.newBuilder(table.getName());
          refNav.setRelationshipName(fk.getName());
          refNav.setFromToName(fk.getReferenceTableName(), table.getName());
          refNav.setRelationship(association);
          refNav.setFromTo(endRef, endSelf);
          refEntityType.addNavigationProperties(refNav);

          // build AssosiationSet
          EdmAssociationSet.Builder assosiationSet =
              EdmAssociationSet.newBuilder()
                  .setName(table.getName() + "_" + fk.getName())
                  .setAssociationName(fk.getName());

          // Build AssosiationSet Ends
          EdmAssociationSetEnd.Builder endOne =
              EdmAssociationSetEnd.newBuilder()
                  .setEntitySet(entitySet)
                  .setRoleName(table.getName())
                  .setRole(
                      EdmAssociationEnd.newBuilder()
                          .setType(entityType)
                          .setRole(entityType.getName()));

          EdmAssociationSetEnd.Builder endTwo =
              EdmAssociationSetEnd.newBuilder()
                  .setEntitySet(refEntitySet)
                  .setRoleName(fk.getReferenceTableName())
                  .setRole(
                      EdmAssociationEnd.newBuilder()
                          .setType(refEntityType)
                          .setRole(refEntityType.getName()));
          assosiationSet.setEnds(endOne, endTwo);

          assosiationSet.setAssociation(association);
          assosiationSets.add(assosiationSet);
        }
      }
      entityContainer.addAssociationSets(assosiationSets);
      odataSchema.addAssociations(assosiations);
    }
  }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());

        for (Table t : schema.getTables().values()) {
          if (t.isVirtual()) {
            if (t.isMaterialized() && t.getMaterializedTable() != null) {
              String matTableName = t.getMaterializedTable().getFullName();
              int index = matTableName.indexOf(Table.NAME_DELIM_CHAR);
              if (index == -1) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31088, matTableName, t.getFullName()));
              } else {
                String schemaName = matTableName.substring(0, index);
                Schema matSchema = store.getSchema(schemaName);
                if (matSchema == null) {
                  metadataValidator.log(
                      report,
                      model,
                      Messages.gs(
                          Messages.TEIID.TEIID31089, schemaName, matTableName, t.getFullName()));
                } else {
                  Table matTable = matSchema.getTable(matTableName.substring(index + 1));
                  if (matTable == null) {
                    metadataValidator.log(
                        report,
                        model,
                        Messages.gs(
                            Messages.TEIID.TEIID31090,
                            matTableName.substring(index + 1),
                            schemaName,
                            t.getFullName()));
                  } else {
                    t.setMaterializedTable(matTable);
                  }
                }
              }
            }
          }

          for (KeyRecord record : t.getAllKeys()) {
            if (record.getColumns() == null || record.getColumns().isEmpty()) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31149, t.getFullName(), record.getName()));
            }
          }

          List<ForeignKey> fks = t.getForeignKeys();
          if (fks == null || fks.isEmpty()) {
            continue;
          }

          for (ForeignKey fk : fks) {
            // Only applicable to older teiid releases than 8.9
            if (fk.getReferenceKey() != null
                && !metadataValidator.isTeiidOrGreater(Version.TEIID_8_9)) {
              // ensure derived fields are set
              fk.setReferenceKey(fk.getReferenceKey());
              continue;
            }

            String referenceTableName = fk.getReferenceTableName();
            Table referenceTable = null;
            if (fk.getReferenceKey() == null) {
              if (referenceTableName == null) {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31091, t.getFullName()));
                continue;
              }

              // TODO there is an ambiguity here because we don't properly track the name parts
              // so we have to first check for a table name that may contain .
              referenceTable = schema.getTable(referenceTableName);
            } else {
              referenceTableName = fk.getReferenceKey().getParent().getFullName();
            }

            String referenceSchemaName = schema.getName();
            int index = referenceTableName.indexOf(Table.NAME_DELIM_CHAR);
            if (referenceTable == null) {
              if (index != -1) {
                referenceSchemaName = referenceTableName.substring(0, index);
                Schema referenceSchema = store.getSchema(referenceSchemaName);
                if (referenceSchema == null) {
                  metadataValidator.log(
                      report,
                      model,
                      Messages.gs(Messages.TEIID.TEIID31093, referenceSchemaName, t.getFullName()));
                  continue;
                }
                referenceTable = referenceSchema.getTable(referenceTableName.substring(index + 1));
              }
              if (referenceTable == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(
                        Messages.TEIID.TEIID31092,
                        t.getFullName(),
                        referenceTableName.substring(index + 1),
                        referenceSchemaName));
                continue;
              }
            }

            KeyRecord uniqueKey = null;
            List<String> referenceColumns = fk.getReferenceColumns();
            if (fk.getReferenceKey() != null) {
              // index metadata logic sets the key prior to having the column names
              List<Column> cols = fk.getReferenceKey().getColumns();
              referenceColumns = new ArrayList<String>();
              for (Column col : cols) {
                referenceColumns.add(col.getName());
              }
            }
            if (referenceColumns == null || referenceColumns.isEmpty()) {
              if (referenceTable.getPrimaryKey() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(
                        Messages.TEIID.TEIID31094,
                        t.getFullName(),
                        referenceTableName.substring(index + 1),
                        referenceSchemaName));
              } else {
                uniqueKey = referenceTable.getPrimaryKey();
              }

            } else {
              for (KeyRecord record : referenceTable.getUniqueKeys()) {
                if (keyMatches(fk.getReferenceColumns(), record)) {
                  uniqueKey = record;
                  break;
                }
              }
              if (uniqueKey == null
                  && referenceTable.getPrimaryKey() != null
                  && keyMatches(fk.getReferenceColumns(), referenceTable.getPrimaryKey())) {
                uniqueKey = referenceTable.getPrimaryKey();
              }
            }
            if (uniqueKey == null) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(
                      Messages.TEIID.TEIID31095,
                      t.getFullName(),
                      referenceTableName.substring(index + 1),
                      referenceSchemaName,
                      fk.getReferenceColumns()));
            } else {
              fk.setReferenceKey(uniqueKey);
            }
          }
        }
      }
    }