private void AddSchemaColumn(string outputColumn, string sourceColumn, NodeSchema schema, INodeSchema sourceSchema) { if (!sourceSchema.ContainsColumn(sourceColumn, out var normalized)) { return; } var mapped = $"{Alias}.{outputColumn}"; schema.Schema[mapped] = sourceSchema.Schema[normalized]; if (normalized == sourceSchema.PrimaryKey) { schema.PrimaryKey = mapped; } if (!schema.Aliases.TryGetValue(outputColumn, out var aliases)) { aliases = new List <string>(); schema.Aliases[outputColumn] = aliases; } aliases.Add(mapped); var sorted = sourceSchema.SortOrder.Contains(sourceColumn, StringComparer.OrdinalIgnoreCase); if (sorted) { schema.SortOrder.Add(outputColumn); } }
private void AddSchemaAttribute(NodeSchema schema, string fullName, string simpleName, Type type, AttributeMetadata attrMetadata) { // Add the logical attribute AddSchemaAttribute(schema, fullName, simpleName, type); if (attrMetadata.IsPrimaryId == true) { _primaryKeyColumns[fullName] = attrMetadata.EntityLogicalName; } if (FetchXml.aggregate) { return; } // Add standard virtual attributes if (attrMetadata is EnumAttributeMetadata || attrMetadata is BooleanAttributeMetadata) { AddSchemaAttribute(schema, fullName + "name", attrMetadata.LogicalName + "name", typeof(SqlString)); } if (attrMetadata is LookupAttributeMetadata lookup) { AddSchemaAttribute(schema, fullName + "name", attrMetadata.LogicalName + "name", typeof(SqlString)); if (lookup.Targets?.Length > 1 && lookup.AttributeType != AttributeTypeCode.PartyList) { AddSchemaAttribute(schema, fullName + "type", attrMetadata.LogicalName + "type", typeof(SqlString)); } } }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { if (!dataSources.TryGetValue(DataSource, out var dataSource)) { throw new NotSupportedQueryFragmentException("Missing datasource " + DataSource); } var fetchXmlString = FetchXmlString; if (_lastSchema != null && Alias == _lastSchemaAlias && fetchXmlString == _lastSchemaFetchXml) { return(_lastSchema); } _primaryKeyColumns = new Dictionary <string, string>(); var schema = new NodeSchema(); // Add each attribute from the main entity and recurse into link entities var entity = FetchXml.Items.OfType <FetchEntityType>().Single(); var meta = dataSource.Metadata[entity.name]; if (!FetchXml.aggregate) { schema.PrimaryKey = $"{Alias}.{meta.PrimaryIdAttribute}"; } AddSchemaAttributes(schema, dataSource.Metadata, entity.name, Alias, entity.Items); _lastSchema = schema; _lastSchemaFetchXml = fetchXmlString; _lastSchemaAlias = Alias; return(schema); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { // Map the base names to the alias names var sourceSchema = Source.GetSchema(dataSources, parameterTypes); var schema = new NodeSchema(); foreach (var col in ColumnSet) { if (col.AllColumns) { foreach (var sourceCol in sourceSchema.Schema) { if (col.SourceColumn != null && !sourceCol.Key.StartsWith(col.SourceColumn + ".")) { continue; } var simpleName = sourceCol.Key.Split('.').Last(); var outputName = $"{Alias}.{simpleName}"; AddSchemaColumn(simpleName, sourceCol.Key, schema, sourceSchema); } } else { AddSchemaColumn(col.OutputColumn, col.SourceColumn, schema, sourceSchema); } } return(schema); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = new NodeSchema(); var sourceSchema = Sources[0].GetSchema(dataSources, parameterTypes); foreach (var col in ColumnSet) { schema.Schema[col.OutputColumn] = sourceSchema.Schema[col.SourceColumns[0]]; } return(schema); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { // Copy the source schema and add in the additional computed columns var sourceSchema = Source.GetSchema(dataSources, parameterTypes); var schema = new NodeSchema(sourceSchema); foreach (var calc in Columns) { schema.Schema[calc.Key] = calc.Value.GetType(sourceSchema, null, parameterTypes); } return(schema); }
/// <summary> /// Gets the records to perform the DML operation on /// </summary> /// <param name="org">The <see cref="IOrganizationService"/> to use to get the data</param> /// <param name="metadata">The <see cref="IAttributeMetadataCache"/> to use to get metadata</param> /// <param name="options"><see cref="IQueryExecutionOptions"/> to indicate how the query can be executed</param> /// <param name="parameterTypes">A mapping of parameter names to their related types</param> /// <param name="parameterValues">A mapping of parameter names to their current values</param> /// <param name="schema">The schema of the data source</param> /// <returns>The entities to perform the DML operation on</returns> protected List <Entity> GetDmlSourceEntities(IDictionary <string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary <string, Type> parameterTypes, IDictionary <string, object> parameterValues, out INodeSchema schema) { List <Entity> entities; if (Source is IDataExecutionPlanNode dataSource) { schema = dataSource.GetSchema(dataSources, parameterTypes); entities = dataSource.Execute(dataSources, options, parameterTypes, parameterValues).ToList(); } else if (Source is IDataSetExecutionPlanNode dataSetSource) { var dataTable = dataSetSource.Execute(dataSources, options, parameterTypes, parameterValues); // Store the values under the column index as well as name for compatibility with INSERT ... SELECT ... schema = new NodeSchema(); for (var i = 0; i < dataTable.Columns.Count; i++) { var col = dataTable.Columns[i]; ((NodeSchema)schema).Schema[col.ColumnName] = col.DataType; ((NodeSchema)schema).Schema[i.ToString()] = col.DataType; } entities = dataTable.Rows .Cast <DataRow>() .Select(row => { var entity = new Entity(); for (var i = 0; i < dataTable.Columns.Count; i++) { entity[dataTable.Columns[i].ColumnName] = row[i]; entity[i.ToString()] = row[i]; } return(entity); }) .ToList(); } else { throw new QueryExecutionException("Unexpected data source") { Node = this }; } return(entities); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var sourceSchema = Source.GetSchema(dataSources, parameterTypes); var schema = new NodeSchema(); foreach (var group in GroupBy) { var colName = group.GetColumnName(); sourceSchema.ContainsColumn(colName, out var normalized); schema.Schema[normalized] = sourceSchema.Schema[normalized]; foreach (var alias in sourceSchema.Aliases.Where(a => a.Value.Contains(normalized))) { if (!schema.Aliases.TryGetValue(alias.Key, out var aliases)) { aliases = new List <string>(); schema.Aliases[alias.Key] = aliases; } aliases.Add(normalized); } if (GroupBy.Count == 1) { schema.PrimaryKey = normalized; } } foreach (var aggregate in Aggregates) { Type aggregateType; switch (aggregate.Value.AggregateType) { case AggregateType.Count: case AggregateType.CountStar: aggregateType = typeof(SqlInt32); break; default: aggregateType = aggregate.Value.SqlExpression.GetType(sourceSchema, null, parameterTypes); break; } schema.Schema[aggregate.Key] = aggregateType; } return(schema); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = Source.GetSchema(dataSources, parameterTypes); // If this is a distinct list of one column we know the values in that column will be unique if (Columns.Count == 1) { schema = new NodeSchema(schema) { PrimaryKey = Columns[0] } } ; return(schema); }
protected virtual INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes, bool includeSemiJoin) { var outerSchema = LeftSource.GetSchema(dataSources, parameterTypes); var innerSchema = GetRightSchema(dataSources, parameterTypes); var schema = new NodeSchema(); if (JoinType == QualifiedJoinType.LeftOuter && SemiJoin) { schema.PrimaryKey = outerSchema.PrimaryKey; } foreach (var subSchema in new[] { outerSchema, innerSchema }) { // Semi-join does not include data from the right source if (SemiJoin && subSchema == innerSchema && !includeSemiJoin) { continue; } foreach (var column in subSchema.Schema) { schema.Schema[column.Key] = column.Value; } foreach (var alias in subSchema.Aliases) { if (!schema.Aliases.TryGetValue(alias.Key, out var aliasDetails)) { aliasDetails = new List <string>(); schema.Aliases[alias.Key] = aliasDetails; } schema.Aliases[alias.Key].AddRange(alias.Value); } } foreach (var definedValue in DefinedValues) { schema.Schema[definedValue.Key] = innerSchema.Schema[definedValue.Value]; } return(schema); }
private void AddSchemaAttribute(NodeSchema schema, string fullName, string simpleName, Type type) { schema.Schema[fullName] = type; if (simpleName == null) { return; } if (!schema.Aliases.TryGetValue(simpleName, out var simpleColumnNameAliases)) { simpleColumnNameAliases = new List <string>(); schema.Aliases[simpleName] = simpleColumnNameAliases; } if (!simpleColumnNameAliases.Contains(fullName)) { simpleColumnNameAliases.Add(fullName); } }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = new NodeSchema(); foreach (var prop in _optionsetProps.Values) { schema.Schema[$"{Alias}.{prop.Name}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.Name, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.Name] = aliases; } aliases.Add($"{Alias}.{prop.Name}"); } schema.PrimaryKey = $"{Alias}.{nameof(OptionSetMetadataBase.MetadataId)}"; return(schema); }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = new NodeSchema(Source.GetSchema(dataSources, parameterTypes)); schema.SortOrder.Clear(); foreach (var sort in Sorts) { if (!(sort.Expression is ColumnReferenceExpression col)) { return(schema); } if (!schema.ContainsColumn(col.GetColumnName(), out var colName)) { return(schema); } schema.SortOrder.Add(colName); } return(schema); }
private void AddSchemaAttributes(NodeSchema schema, IAttributeMetadataCache metadata, string entityName, string alias, object[] items) { if (items == null && !ReturnFullSchema) { return; } var meta = metadata[entityName]; if (ReturnFullSchema) { foreach (var attrMetadata in meta.Attributes) { if (attrMetadata.IsValidForRead == false) { continue; } if (attrMetadata.AttributeOf != null) { continue; } var fullName = $"{alias}.{attrMetadata.LogicalName}"; var attrType = attrMetadata.GetAttributeSqlType(); AddSchemaAttribute(schema, fullName, attrMetadata.LogicalName, attrType, attrMetadata); } } if (items != null) { foreach (var attribute in items.OfType <FetchAttributeType>()) { var attrMetadata = meta.Attributes.Single(a => a.LogicalName == attribute.name); var attrType = attrMetadata.GetAttributeSqlType(); if (attribute.aggregateSpecified && (attribute.aggregate == Engine.FetchXml.AggregateType.count || attribute.aggregate == Engine.FetchXml.AggregateType.countcolumn) || attribute.dategroupingSpecified) { attrType = typeof(SqlInt32); } string fullName; string attrAlias; if (!String.IsNullOrEmpty(attribute.alias)) { if (!FetchXml.aggregate || attribute.groupbySpecified && attribute.groupby == FetchBoolType.@true) { fullName = $"{alias}.{attribute.alias}"; attrAlias = attribute.alias; } else { fullName = attribute.alias; attrAlias = null; } } else { fullName = $"{alias}.{attribute.name}"; attrAlias = attribute.name; } AddSchemaAttribute(schema, fullName, attrAlias, attrType, attrMetadata); } if (items.OfType <allattributes>().Any()) { foreach (var attrMetadata in meta.Attributes) { if (attrMetadata.IsValidForRead == false) { continue; } if (attrMetadata.AttributeOf != null) { continue; } var attrType = attrMetadata.GetAttributeSqlType(); var attrName = attrMetadata.LogicalName; var fullName = $"{alias}.{attrName}"; AddSchemaAttribute(schema, fullName, attrName, attrType, attrMetadata); } } foreach (var sort in items.OfType <FetchOrderType>()) { string fullName; string attributeName; if (!String.IsNullOrEmpty(sort.alias)) { var attribute = items.OfType <FetchAttributeType>().SingleOrDefault(a => a.alias.Equals(sort.alias, StringComparison.OrdinalIgnoreCase)); if (!FetchXml.aggregate || attribute != null && attribute.groupbySpecified && attribute.groupby == FetchBoolType.@true) { fullName = $"{alias}.{attribute.alias}"; } else { fullName = attribute.alias; } attributeName = attribute.name; } else { fullName = $"{alias}.{sort.attribute}"; attributeName = sort.attribute; } // Sorts applied to lookup or enum fields are actually performed on the associated ___name virtual attribute var attrMeta = meta.Attributes.SingleOrDefault(a => a.LogicalName.Equals(attributeName, StringComparison.OrdinalIgnoreCase)); if (attrMeta is LookupAttributeMetadata || attrMeta is EnumAttributeMetadata || attrMeta is BooleanAttributeMetadata) { fullName += "name"; } schema.SortOrder.Add(fullName); } foreach (var linkEntity in items.OfType <FetchLinkEntityType>()) { if (linkEntity.SemiJoin) { continue; } if (schema.PrimaryKey != null) { var childMeta = metadata[linkEntity.name]; if (linkEntity.from != childMeta.PrimaryIdAttribute) { if (linkEntity.linktype == "inner") { schema.PrimaryKey = $"{linkEntity.alias}.{childMeta.PrimaryIdAttribute}"; } else { schema.PrimaryKey = null; } } } AddSchemaAttributes(schema, metadata, linkEntity.name, linkEntity.alias, linkEntity.Items); } } }
public override INodeSchema GetSchema(IDictionary <string, DataSource> dataSources, IDictionary <string, Type> parameterTypes) { var schema = new NodeSchema(); var childCount = 0; if (MetadataSource.HasFlag(MetadataSource.Entity)) { var entityProps = (IEnumerable <MetadataProperty>)_entityProps.Values; if (Query.Properties != null) { entityProps = entityProps.Where(p => Query.Properties.AllProperties || Query.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in entityProps) { schema.Schema[$"{EntityAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{EntityAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{EntityAlias}.{nameof(EntityMetadata.MetadataId)}"; } if (MetadataSource.HasFlag(MetadataSource.Attribute)) { var attributeProps = (IEnumerable <AttributeProperty>)_attributeProps.Values; if (Query.AttributeQuery?.Properties != null) { attributeProps = attributeProps.Where(p => Query.AttributeQuery.Properties.AllProperties || Query.AttributeQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in attributeProps) { schema.Schema[$"{AttributeAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{AttributeAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{AttributeAlias}.{nameof(AttributeMetadata.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.OneToManyRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_oneToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{OneToManyRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{OneToManyRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{OneToManyRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.ManyToOneRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_oneToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{ManyToOneRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{ManyToOneRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{ManyToOneRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (MetadataSource.HasFlag(MetadataSource.ManyToManyRelationship)) { var relationshipProps = (IEnumerable <MetadataProperty>)_manyToManyRelationshipProps.Values; if (Query.RelationshipQuery?.Properties != null) { relationshipProps = relationshipProps.Where(p => Query.RelationshipQuery.Properties.AllProperties || Query.RelationshipQuery.Properties.PropertyNames.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)); } foreach (var prop in relationshipProps) { schema.Schema[$"{ManyToManyRelationshipAlias}.{prop.SqlName}"] = prop.Type; if (!schema.Aliases.TryGetValue(prop.SqlName, out var aliases)) { aliases = new List <string>(); schema.Aliases[prop.SqlName] = aliases; } aliases.Add($"{ManyToManyRelationshipAlias}.{prop.SqlName}"); } schema.PrimaryKey = $"{ManyToManyRelationshipAlias}.{nameof(RelationshipMetadataBase.MetadataId)}"; childCount++; } if (childCount > 1) { schema.PrimaryKey = null; } return(schema); }