private static void buildFunctionImports(MetadataStore metadataStore, List<Builder> edmSchemas) { for (Schema schema : metadataStore.getSchemaList()) { EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName()); EdmEntityContainer.Builder entityContainer = findEntityContainer(edmSchemas, schema.getName()); // procedures for (Procedure proc : schema.getProcedures().values()) { EdmFunctionImport.Builder edmProcedure = EdmFunctionImport.newBuilder(); edmProcedure.setName(proc.getName()); String httpMethod = "POST"; for (ProcedureParameter pp : proc.getParameters()) { if (pp.getName().equals("return")) { httpMethod = "GET"; edmProcedure.setReturnType( ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName())); continue; } EdmFunctionParameter.Builder param = EdmFunctionParameter.newBuilder(); param.setName(pp.getName()); param.setType(ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName())); if (pp.getType() == ProcedureParameter.Type.In) { param.setMode(Mode.In); } else if (pp.getType() == ProcedureParameter.Type.InOut) { param.setMode(Mode.InOut); } else if (pp.getType() == ProcedureParameter.Type.Out) { param.setMode(Mode.Out); } param.setNullable(pp.getNullType() == NullType.Nullable); edmProcedure.addParameters(param); } // add a complex type for return resultset. ColumnSet<Procedure> returnColumns = proc.getResultSet(); if (returnColumns != null) { httpMethod = "GET"; EdmComplexType.Builder complexType = EdmComplexType.newBuilder(); complexType.setName(proc.getName() + "_" + returnColumns.getName()); complexType.setNamespace(schema.getName()); for (Column c : returnColumns.getColumns()) { EdmProperty.Builder property = EdmProperty.newBuilder(c.getName()) .setType(ODataTypeManager.odataType(c.getDatatype().getRuntimeTypeName())) .setNullable(c.getNullType() == NullType.Nullable); if (c.getDatatype() .getRuntimeTypeName() .equals(DataTypeManager.DefaultDataTypes.STRING)) { property .setFixedLength(c.isFixedLength()) .setMaxLength(c.getLength()) .setUnicode(true); } complexType.addProperties(property); } odataSchema.addComplexTypes(complexType); edmProcedure.setIsCollection(true); edmProcedure.setReturnType( EdmCollectionType.newBuilder() .setCollectionType(complexType) .setKind(CollectionKind.Collection)); } edmProcedure.setHttpMethod(httpMethod); entityContainer.addFunctionImports(edmProcedure); } } }
@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.isPhysical() && !model.isSource()) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31075, t.getFullName(), model.getName())); } } Set<String> names = new HashSet<String>(); for (Procedure p : schema.getProcedures().values()) { boolean hasReturn = false; names.clear(); for (int i = 0; i < p.getParameters().size(); i++) { ProcedureParameter param = p.getParameters().get(i); if (param.isVarArg() && param != p.getParameters().get(p.getParameters().size() - 1)) { // check that the rest of the parameters are optional // this accommodates variadic multi-source procedures // effective this and the resolving logic ensure that you can used named parameters // for everything, // or call the vararg procedure as normal if (isTeiidOrGreater(Version.TEIID_8_10)) { for (int j = i + 1; j < p.getParameters().size(); j++) { ProcedureParameter param1 = p.getParameters().get(j); if ((param1.getType() == Type.In || param1.getType() == Type.InOut) && (param1.isVarArg() || (param1.getNullType() != NullType.Nullable && param1.getDefaultValue() == null))) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName())); } } } else { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName())); } } if (param.getType() == ProcedureParameter.Type.ReturnValue) { if (hasReturn) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31107, p.getFullName())); } hasReturn = true; } else if (p.isFunction() && param.getType() != ProcedureParameter.Type.In && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31165, p.getFullName(), param.getFullName())); } if (!names.add(param.getName())) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31106, p.getFullName(), param.getFullName())); } } if (!p.isVirtual() && !model.isSource()) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31077, p.getFullName(), model.getName())); } if (p.isFunction() && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) { if (!hasReturn) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31166, p.getFullName())); } if (p.isVirtual() && p.getQueryPlan() == null) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31167, p.getFullName())); } } } for (FunctionMethod func : schema.getFunctions().values()) { for (FunctionParameter param : func.getInputParameters()) { if (param.isVarArg() && param != func.getInputParameters().get(func.getInputParameterCount() - 1)) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31112, func.getFullName())); } } if (func.getPushdown().equals(FunctionMethod.PushDown.MUST_PUSHDOWN) && !model.isSource()) { metadataValidator.log( report, model, Messages.gs(Messages.TEIID.TEIID31078, func.getFullName(), model.getName())); } } } }