public static InternalSchemaDefinition Create(Type userType, SchemaDefinition userSchemaDefinition) { Contracts.AssertValue(userType); Contracts.AssertValueOrNull(userSchemaDefinition); if (userSchemaDefinition == null) { userSchemaDefinition = SchemaDefinition.Create(userType); } Column[] dstCols = new Column[userSchemaDefinition.Count]; for (int i = 0; i < userSchemaDefinition.Count; ++i) { var col = userSchemaDefinition[i]; if (col.MemberName == null) { throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Null field name detected in schema definition"); } bool isVector; DataKind kind; MemberInfo memberInfo = null; if (!col.IsComputed) { memberInfo = userType.GetField(col.MemberName); if (memberInfo == null) { memberInfo = userType.GetProperty(col.MemberName); } if (memberInfo == null) { throw Contracts.ExceptParam(nameof(userSchemaDefinition), "No field or property with name '{0}' found in type '{1}'", col.MemberName, userType.FullName); } //Clause to handle the field that may be used to expose the cursor channel. //This field does not need a column. if ((memberInfo is FieldInfo && (memberInfo as FieldInfo).FieldType == typeof(IChannel)) || (memberInfo is PropertyInfo && (memberInfo as PropertyInfo).PropertyType == typeof(IChannel))) { continue; } GetVectorAndKind(memberInfo, out isVector, out kind); } else { var parameterType = col.ReturnType; if (parameterType == null) { throw Contracts.ExceptParam(nameof(userSchemaDefinition), "No return parameter found in computed column."); } GetVectorAndKind(parameterType, "returnType", out isVector, out kind); } // Infer the column name. var colName = string.IsNullOrEmpty(col.ColumnName) ? col.MemberName : col.ColumnName; // REVIEW: Because order is defined, we allow duplicate column names, since producing an IDataView // with duplicate column names is completely legal. Possible objection is that we should make it less // convenient to produce "hidden" columns, since this may not be of practical use to users. ColumnType colType; if (col.ColumnType == null) { // Infer a type as best we can. PrimitiveType itemType = PrimitiveType.FromKind(kind); colType = isVector ? new VectorType(itemType) : (ColumnType)itemType; } else { // Make sure that the types are compatible with the declared type, including // whether it is a vector type. VectorType columnVectorType = col.ColumnType as VectorType; if (isVector != (columnVectorType != null)) { throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Column '{0}' is supposed to be {1}, but type of associated field '{2}' is {3}", colName, columnVectorType != null ? "vector" : "scalar", col.MemberName, isVector ? "vector" : "scalar"); } ColumnType itemType = columnVectorType?.ItemType ?? col.ColumnType; if (kind != itemType.RawKind) { throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Column '{0}' is supposed to have item kind {1}, but associated field has kind {2}", colName, itemType.RawKind, kind); } colType = col.ColumnType; } dstCols[i] = col.IsComputed ? new Column(colName, colType, col.Generator, col.Metadata) : new Column(colName, colType, memberInfo, col.Metadata); } return(new InternalSchemaDefinition(dstCols)); }
/// <summary> /// Creates a column with slot names from arrays. The added column will be re-interpreted as a buffer. /// </summary> public void AddColumn <T>(string name, ValueGetter <VBuffer <ReadOnlyMemory <char> > > getNames, PrimitiveType itemType, params T[][] values) { _host.CheckValue(getNames, nameof(getNames)); _host.CheckParam(itemType != null && itemType.RawType == typeof(T), nameof(itemType)); CheckLength(name, values); var col = new ArrayToVBufferColumn <T>(itemType, values); _columns.Add(col); _getSlotNames.Add(name, getNames); _names.Add(name); }
/// <summary> /// Add key values metadata. /// </summary> /// <typeparam name="TValue">The value type of key values.</typeparam> /// <param name="builder">The MetadataBuilder to which to add the key values.</param> /// <param name="size">The size of key values vector.</param> /// <param name="valueType">The value type of key values. Its raw type must match <typeparamref name="TValue"/>.</param> /// <param name="getter">The getter delegate for the key values.</param> public static void AddKeyValues <TValue>(this MetadataBuilder builder, int size, PrimitiveType valueType, ValueGetter <VBuffer <TValue> > getter) => builder.Add(MetadataUtils.Kinds.KeyValues, new VectorType(valueType, size), getter);
public AssignmentColumn(PrimitiveType type, T[] values) : base(type, values) { }