/// <summary> /// Initializes a new instance of the <see cref="NullableSchema" /> class. /// </summary> /// <param name="nullableType">Type of the nullable.</param> /// <param name="attributes">The attributes.</param> /// <param name="valueSchema">The value type schema.</param> internal NullableSchema( Type nullableType, IDictionary<string, string> attributes, TypeSchema valueSchema) : base(nullableType, attributes) { this.valueSchema = valueSchema; }
public ODataAvroCollectionWriter(ODataAvroOutputContext outputContext, TypeSchema schema) { Debug.Assert(outputContext != null, "outputContext != null"); this.outputContext = outputContext; this.writerSchema = schema; collection = new List<object>(); }
private void WriteItemImplementation(object item) { if (this.writerSchema == null) { this.writerSchema = this.outputContext.AvroWriter.UpdateSchema(item, null, true); } collection.Add(item); }
/// <summary> /// Initializes a new instance of the <see cref="RecordField" /> class. /// </summary> /// <param name="namedEntityAttributes">The named entity attributes.</param> /// <param name="typeSchema">The type schema.</param> /// <param name="order">The order.</param> /// <param name="hasDefaultValue">Whether the field has a default value or not.</param> /// <param name="defaultValue">The default value.</param> /// <param name="info">The info.</param> /// <param name="position">The position of the field in the schema.</param> internal RecordField( NamedEntityAttributes namedEntityAttributes, TypeSchema typeSchema, SortOrder order, bool hasDefaultValue, object defaultValue, MemberInfo info, int position) : this(namedEntityAttributes, typeSchema, order, hasDefaultValue, defaultValue, info, position, new Dictionary<string, string>()) { }
/// <summary> /// Searches a schema for other schemas that can be used for code generation. /// </summary> /// <param name="schema">The schema.</param> /// <returns>A list of schemas that can be used for code generation.</returns> public static IEnumerable<TypeSchema> ResolveCodeGeneratingSchemas(TypeSchema schema) { if (schema == null) { throw new ArgumentNullException("schema"); } var result = new List<TypeSchema>(); GetSchemas(schema, result); return result; }
private byte[] ParseFixed(TypeSchema schema, string jsonObject) { var fixedSchema = (FixedSchema)schema; var result = ConvertToBytes(jsonObject); if (result.Length != fixedSchema.Size) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "'{0}' size does not match the size of fixed schema node.", jsonObject)); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="ArraySchema" /> class. /// </summary> /// <param name="item">The item.</param> /// <param name="runtimeType">Type of the runtime.</param> /// <param name="attributes">The attributes.</param> internal ArraySchema( TypeSchema item, Type runtimeType, Dictionary <string, string> attributes) : base(runtimeType, attributes) { if (item == null) { throw new ArgumentNullException("item"); } this.itemSchema = item; }
/// <summary> /// Initializes a new instance of the <see cref="ArraySchema" /> class. /// </summary> /// <param name="item">The item.</param> /// <param name="runtimeType">Type of the runtime.</param> /// <param name="attributes">The attributes.</param> internal ArraySchema( TypeSchema item, Type runtimeType, Dictionary<string, string> attributes) : base(runtimeType, attributes) { if (item == null) { throw new ArgumentNullException("item"); } this.itemSchema = item; }
private void AddRecordFields( IEnumerable <MemberSerializationInfo> members, Dictionary <string, NamedSchema> schemas, uint currentDepth, RecordSchema record) { int index = 0; foreach (MemberSerializationInfo info in members) { var property = info.MemberInfo as PropertyInfo; var field = info.MemberInfo as FieldInfo; Type memberType; if (property != null) { memberType = property.PropertyType; } else if (field != null) { memberType = field.FieldType; } else { throw new SerializationException( string.Format( CultureInfo.InvariantCulture, "Type member '{0}' is not supported.", info.MemberInfo.MemberType)); } TypeSchema fieldSchema = this.TryBuildUnionSchema(memberType, info.MemberInfo, schemas, currentDepth) ?? this.TryBuildFixedSchema(memberType, info.MemberInfo, record) ?? this.CreateSchema(info.Nullable, memberType, schemas, currentDepth + 1); var aliases = info .Aliases .Select(alias => alias.Contains(".") ? alias : record.Namespace + "." + alias) .ToList(); var recordField = new RecordField( new NamedEntityAttributes(new SchemaName(info.Name), aliases, info.Doc), fieldSchema, SortOrder.Ascending, false, null, info.MemberInfo, index++); record.AddField(recordField); } }
private AvroEnum ParseEnum(TypeSchema schema, string jsonObject) { var enumSchema = (EnumSchema)schema; if (!enumSchema.Symbols.Contains(jsonObject)) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "'{0}' is not a valid enum value.", jsonObject)); } return(new AvroEnum(schema) { Value = jsonObject }); }
/// <summary> /// Parses a JSON string according to given schema and returns the corresponding object. /// </summary> /// <param name="schema">The schema.</param> /// <param name="json">The JSON object.</param> /// <returns>The object.</returns> public object Parse(TypeSchema schema, string json) { if (this.parsersWithoutSchema.ContainsKey(schema.GetType())) { return(this.parsersWithoutSchema[schema.GetType()](json)); } if (this.parsersWithSchema.ContainsKey(schema.GetType())) { return(this.parsersWithSchema[schema.GetType()](schema, json)); } throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Unknown schema type '{0}'.", schema.GetType())); }
/// <summary> /// Creates the avro schema for the specified type. /// </summary> /// <param name="type">The type.</param> /// <param name="schemas">The schemas seen so far.</param> /// <param name="currentDepth">The current depth.</param> /// <returns> /// New instance of schema. /// </returns> /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when maximum depth of object graph is reached.</exception> private TypeSchema CreateNotNullableSchema(Type type, Dictionary<string, NamedSchema> schemas, uint currentDepth) { TypeSchema schema = TryBuildPrimitiveTypeSchema(type); if (schema != null) { return schema; } if ((type.GetTypeInfo().IsInterface || type.GetTypeInfo().IsAbstract) || this.HasApplicableKnownType(type)) { return this.BuildKnownTypeSchema(type, schemas, currentDepth); } return this.BuildComplexTypeSchema(type, schemas, currentDepth); }
/// <summary> /// Initializes a new instance of the <see cref="MapSchema" /> class. /// </summary> /// <param name="keySchema">The key schema.</param> /// <param name="valueSchema">The value schema.</param> /// <param name="runtimeType">Type of the runtime.</param> /// <param name="attributes">The attributes.</param> internal MapSchema( TypeSchema keySchema, TypeSchema valueSchema, Type runtimeType, Dictionary<string, string> attributes) : base(runtimeType, attributes) { if (keySchema == null) { throw new ArgumentNullException("keySchema"); } if (valueSchema == null) { throw new ArgumentNullException("valueSchema"); } this.valueSchema = valueSchema; this.keySchema = keySchema; }
/// <summary> /// Initializes a new instance of the <see cref="MapSchema" /> class. /// </summary> /// <param name="keySchema">The key schema.</param> /// <param name="valueSchema">The value schema.</param> /// <param name="runtimeType">Type of the runtime.</param> /// <param name="attributes">The attributes.</param> internal MapSchema( TypeSchema keySchema, TypeSchema valueSchema, Type runtimeType, Dictionary <string, string> attributes) : base(runtimeType, attributes) { if (keySchema == null) { throw new ArgumentNullException("keySchema"); } if (valueSchema == null) { throw new ArgumentNullException("valueSchema"); } this.valueSchema = valueSchema; this.keySchema = keySchema; }
private AvroRecord ParseRecord(TypeSchema schema, string jsonObject) { var recordSchema = (RecordSchema)schema; var result = new AvroRecord(recordSchema); var data = JsonConvert.DeserializeObject <Dictionary <string, JToken> >(jsonObject); foreach (var datum in data) { var matchedRecord = recordSchema.Fields.FirstOrDefault(field => field.Name == datum.Key); if (matchedRecord == null) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Could not set default value because JSON object contains fields that do not exist in the schema.")); } result[matchedRecord.Name] = this.Parse(matchedRecord.TypeSchema, datum.Value.ToString()); } return(result); }
/// <summary> /// Parses the record field. /// </summary> /// <param name="field">The field.</param> /// <param name="parent">The parent schema.</param> /// <param name="namedSchemas">The named schemas.</param> /// <param name="position">The position.</param> /// <returns> /// Schema internal representation. /// </returns> /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when <paramref name="field"/> is not valid or when sort order is not valid.</exception> private RecordField ParseRecordField(JObject field, NamedSchema parent, Dictionary <string, NamedSchema> namedSchemas, int position) { var name = field.RequiredProperty <string>(Token.Name); var doc = field.OptionalProperty <string>(Token.Doc); var order = field.OptionalProperty <string>(Token.Order); var aliases = this.GetAliases(field, parent.FullName); var fieldType = field[Token.Type]; if (fieldType == null) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Record field schema '{0}' has no type.", field)); } TypeSchema type = this.Parse(fieldType, parent, namedSchemas); object defaultValue = null; bool hasDefaultValue = field[Token.Default] != null; if (hasDefaultValue) { var objectParser = new JsonObjectParser(); defaultValue = objectParser.Parse(type, field[Token.Default].ToString()); } var orderValue = SortOrder.Ascending; if (!string.IsNullOrEmpty(order)) { if (!SortValue.ContainsKey(order.ToUpperInvariant())) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Invalid sort order of the field '{0}'.", order)); } orderValue = SortValue[order.ToUpperInvariant()]; } var fieldName = new SchemaName(name); var attributes = new NamedEntityAttributes(fieldName, aliases, doc); return(new RecordField(attributes, type, orderValue, hasDefaultValue, defaultValue, null, position)); }
/// <summary> /// Creates a <see cref="RecordField" /> instance. /// </summary> /// <param name="fieldName">The field name.</param> /// <param name="fieldType">The field type.</param> /// <returns>An instance of the <see cref="RecordField" />.</returns> public static RecordField CreateField(string fieldName, TypeSchema fieldType) { if (string.IsNullOrEmpty(fieldName)) { throw new ArgumentException("Field name is not allowed to be null or empty."); } if (fieldType == null) { throw new ArgumentNullException("fieldType"); } return(new RecordField( new NamedEntityAttributes(new SchemaName(fieldName), new List <string>(), string.Empty), fieldType, SortOrder.Ascending, false, null, null, -1)); }
/// <summary> /// Initializes a new instance of the <see cref="RecordField" /> class. /// </summary> /// <param name="namedEntityAttributes">The named entity attributes.</param> /// <param name="typeSchema">The type schema.</param> /// <param name="order">The order.</param> /// <param name="hasDefaultValue">Whether the field has a default value or not.</param> /// <param name="defaultValue">The default value.</param> /// <param name="info">The info.</param> /// <param name="position">The position of the field in the schema.</param> /// <param name="attributes">The attributes.</param> internal RecordField( NamedEntityAttributes namedEntityAttributes, TypeSchema typeSchema, SortOrder order, bool hasDefaultValue, object defaultValue, MemberInfo info, int position, Dictionary <string, string> attributes) : base(attributes) { this.namedEntityAttributes = namedEntityAttributes; this.typeSchema = typeSchema; this.order = order; this.hasDefaultValue = hasDefaultValue; this.defaultValue = defaultValue; this.info = info; this.position = position; this.ShouldBeSkipped = false; this.UseDefaultValue = false; }
/// <summary> /// Initializes a new instance of the <see cref="SurrogateSchema" /> class. /// </summary> /// <param name="originalType">Type of the original.</param> /// <param name="surrogateType">Type of the surrogate.</param> /// <param name="attributes">The attributes.</param> /// <param name="surrogateSchema">The surrogate schema.</param> internal SurrogateSchema( Type originalType, Type surrogateType, IDictionary <string, string> attributes, TypeSchema surrogateSchema) : base(originalType, attributes) { if (originalType == null) { throw new ArgumentNullException("originalType"); } if (surrogateType == null) { throw new ArgumentNullException("surrogateType"); } if (surrogateSchema == null) { throw new ArgumentNullException("surrogateSchema"); } this.surrogateType = surrogateType; this.surrogateSchema = surrogateSchema; }
/// <summary> /// according to avro spec http://avro.apache.org/docs/current/spec.html#Unions /// Unions may not contain more than one schema with the same type, except for the named types record, fixed and enum. /// For example, unions containing two array types or two map types are not permitted, but two types with different names are permitted /// </summary> /// <param name="existingSchema">the schema that's already processed.</param> /// <param name="typeSchema">the schema to check whether it's duplicate according to avro union spec.</param> /// <returns>true if existingSchema is same type as typeSchema according to avro spec on union</returns> internal static bool IsSameTypeAs(TypeSchema existingSchema, TypeSchema typeSchema) { // only add ArraySchema at most once based on above Avro spec for union var arraySchema = typeSchema as ArraySchema; var mapSchema = typeSchema as MapSchema; if (arraySchema != null) { // find previous array schema index with the same ItemSchema return(existingSchema is ArraySchema && IsSameTypeAs(((ArraySchema)existingSchema).ItemSchema, arraySchema.ItemSchema)); } if (mapSchema != null) { // find previous map schema index with the same ItemSchema return(existingSchema is MapSchema && IsSameTypeAs(((MapSchema)existingSchema).KeySchema, mapSchema.KeySchema) && IsSameTypeAs(((MapSchema)existingSchema).ValueSchema, mapSchema.ValueSchema)); } return(existingSchema.Type == typeSchema.Type); }
/// <summary> /// Initializes a new instance of the <see cref="SurrogateSchema" /> class. /// </summary> /// <param name="originalType">Type of the original.</param> /// <param name="surrogateType">Type of the surrogate.</param> /// <param name="attributes">The attributes.</param> /// <param name="surrogateSchema">The surrogate schema.</param> internal SurrogateSchema( Type originalType, Type surrogateType, IDictionary<string, string> attributes, TypeSchema surrogateSchema) : base(originalType, attributes) { if (originalType == null) { throw new ArgumentNullException("originalType"); } if (surrogateType == null) { throw new ArgumentNullException("surrogateType"); } if (surrogateSchema == null) { throw new ArgumentNullException("surrogateSchema"); } this.surrogateType = surrogateType; this.surrogateSchema = surrogateSchema; }
private void GenerateDefaultValue(TypeSchema typeSchema, object defaultValue) { if (typeSchema is IntSchema || typeSchema is LongSchema || typeSchema is BooleanSchema) { this.Write(this.ToStringHelper.ToStringWithCulture(defaultValue.ToString().ToLowerInvariant())); } else if(typeSchema is NullSchema) { this.Write("null"); } else if(typeSchema is StringSchema) { this.Write("\""); this.Write(this.ToStringHelper.ToStringWithCulture(defaultValue)); this.Write("\""); } else if(typeSchema is FloatSchema) { this.Write("(float)"); this.Write(this.ToStringHelper.ToStringWithCulture(((float) defaultValue).ToString(CultureInfo.InvariantCulture))); } else if(typeSchema is DoubleSchema) { this.Write(this.ToStringHelper.ToStringWithCulture(((double) defaultValue).ToString(CultureInfo.InvariantCulture))); } else if(typeSchema is BytesSchema || typeSchema is FixedSchema) { this.Write("new byte[] {"); var asArray = defaultValue as byte[]; for (int i = 0; i < asArray.Length; i++) { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(asArray[i].ToString(CultureInfo.InvariantCulture))); if(i < asArray.Length - 1){ this.Write(","); } } this.Write(" }"); } else if (typeSchema is EnumSchema) { var enumSchema = typeSchema as EnumSchema; this.Write(this.ToStringHelper.ToStringWithCulture(Utilities.Validate(string.Concat(Utilities.GetNamespace(this, enumSchema.Namespace), ".", enumSchema.Name)))); this.Write("."); this.Write(this.ToStringHelper.ToStringWithCulture((defaultValue as AvroEnum).Value)); } else if(typeSchema is UnionSchema) { GenerateDefaultValue((dynamic) (typeSchema as UnionSchema).Schemas[0], defaultValue); } else { this.Write("new "); GenerateType((dynamic)typeSchema, true, false, true); this.Write("{ "); if (typeSchema is ArraySchema) { var arrayDefaultValues = defaultValue as Array; for (int i = 0; i < arrayDefaultValues.Length; i++) { GenerateDefaultValue(((dynamic) typeSchema).ItemSchema, arrayDefaultValues.GetValue(i)); if(i < arrayDefaultValues.Length - 1){ this.Write(","); } this.Write(" "); } } else if (typeSchema is MapSchema) { var asDictionary = defaultValue as IDictionary<string, object>; int i = 0; foreach (var item in asDictionary) { this.Write("{ "); GenerateDefaultValue(((dynamic) typeSchema).KeySchema, item.Key); this.Write(", "); GenerateDefaultValue(((dynamic) typeSchema).ValueSchema, item.Value); this.Write(" }"); if (++i < asDictionary.Count) { this.Write(","); } } } else if (typeSchema is RecordSchema) { var fields = ((dynamic)defaultValue).Schema.Fields; for (int i = 0; i < fields.Count; i++) { this.Write(this.ToStringHelper.ToStringWithCulture(Utilities.Validate(fields[i].Name))); this.Write(" = "); GenerateDefaultValue((dynamic) fields[i].TypeSchema, ((dynamic)defaultValue)[fields[i].Name]); if(i < fields.Count - 1){ this.Write(","); } } } this.Write("}"); } }
internal SurrogateSchema(Type originalType, Type surrogateType, TypeSchema surrogateSchema) : this(originalType, surrogateType, new Dictionary <string, string>(), surrogateSchema) { }
/// <summary> /// Creates a <see cref="MapSchema" /> instance. /// </summary> /// <param name="valueSchema">The schema of the values.</param> /// <returns>An instance of the <see cref="MapSchema" />.</returns> public static MapSchema CreateMap(TypeSchema valueSchema) { return new MapSchema(new StringSchema(), valueSchema, typeof(Dictionary<,>)); }
/// <summary> /// Creates a <see cref="RecordField" /> instance. /// </summary> /// <param name="fieldName">The field name.</param> /// <param name="fieldType">The field type.</param> /// <param name="ns">The namespace.</param> /// <param name="aliases">The name aliases.</param> /// <param name="doc">The field documentation.</param> /// <param name="defaultValue">The field default value.</param> /// <param name="order">The field sorting order.</param> /// <returns>An instance of the <see cref="RecordField" />.</returns> public static RecordField CreateField(string fieldName, TypeSchema fieldType, string ns, IEnumerable<string> aliases, string doc, object defaultValue, SortOrder order) { return new RecordField( new NamedEntityAttributes(new SchemaName(fieldName, ns), aliases, doc), fieldType, order, defaultValue == null, defaultValue, null, -1); }
/// <summary> /// If writer's is a union, but reader's is not then /// if the reader's schema matches the selected writer's schema, it is recursively resolved against it. If they do not match, an error is signalled. /// </summary> /// <param name="w">The writer schema.</param> /// <param name="r">The reader schema.</param> /// <returns>True if match.</returns> private TypeSchema BuildCore(UnionSchema w, TypeSchema r) { var schemas = new List<TypeSchema>(); TypeSchema schemaToReplace = null; TypeSchema newSchema = null; foreach (var ws in w.Schemas) { newSchema = this.BuildDynamic(ws, r); if (newSchema != null) { schemaToReplace = ws; break; } } if (newSchema == null) { throw new SerializationException("Cannot match the union schema."); } foreach (var s in w.Schemas) { schemas.Add(s == schemaToReplace ? newSchema : s); } return new UnionSchema(schemas, newSchema.RuntimeType); }
private object ParseUnion(TypeSchema schema, string jsonObject) { var unionSchema = (UnionSchema)schema; return(this.Parse(unionSchema.Schemas[0], jsonObject)); }
/// <summary> /// Initializes a new instance of the <see cref="ArraySchema"/> class. /// </summary> /// <param name="item">The item.</param> /// <param name="runtimeType">Type of the runtime.</param> internal ArraySchema( TypeSchema item, Type runtimeType) : this(item, runtimeType, new Dictionary <string, string>()) { }
internal MapSchema(TypeSchema keySchema, TypeSchema valueSchema, Type runtimeType) : this(keySchema, valueSchema, runtimeType, new Dictionary <string, string>()) { }
internal SurrogateSchema(Type originalType, Type surrogateType, TypeSchema surrogateSchema) : this(originalType, surrogateType, new Dictionary<string, string>(), surrogateSchema) { }
private void GetKnownTypeSchemata(TypeSchema schema, ref List<TypeSchema> result) { while (true) { if (result.Any(s => s.ToString() == schema.ToString())) { return; } var mapSchema = schema as MapSchema; if (mapSchema != null) { result.Add(schema); schema = mapSchema.ValueSchema; continue; } var arraySchema = schema as ArraySchema; if (arraySchema != null) { result.Add(schema); schema = arraySchema.ItemSchema; continue; } break; } }
/// <summary> /// If reader's is a union, but writer's is not the first schema in the reader's union /// that matches the writer's schema is recursively resolved against it. If none match, an error is signalled. /// </summary> /// <param name="w">The writer schema.</param> /// <param name="r">The reader schema.</param> /// <returns>True if match.</returns> private TypeSchema BuildCore(TypeSchema w, UnionSchema r) { return(r.Schemas.Select(rs => this.BuildDynamic(w, rs)).SingleOrDefault(s => s != null)); }
public TypeSchema Build(TypeSchema w, TypeSchema r) { this.visited.Clear(); return(this.BuildDynamic(w, r)); }
/// <summary> /// Implements double dispatch. /// </summary> /// <param name="w">The writer schema.</param> /// <param name="r">The reader schema.</param> /// <returns>True if match.</returns> private TypeSchema BuildDynamic(TypeSchema w, TypeSchema r) { return(this.BuildCore((dynamic)w, (dynamic)r)); }
private static void GetSchemas(TypeSchema typeSchema, List<TypeSchema> result) { if (typeSchema == null) { throw new ArgumentNullException("typeSchema"); } if (result.Contains(typeSchema)) { return; } var arraySchema = typeSchema as ArraySchema; if (arraySchema != null) { GetSchemas(arraySchema.ItemSchema, result); return; } var mapSchema = typeSchema as MapSchema; if (mapSchema != null) { GetSchemas(mapSchema.ValueSchema, result); return; } var unionSchema = typeSchema as UnionSchema; if (unionSchema != null && unionSchema.IsNullable() == false) { foreach (var item in unionSchema.Schemas) { GetSchemas(item, result); } return; } var namedSchema = typeSchema as NamedSchema; if (namedSchema == null) { return; } if (typeSchema is FixedSchema == false) { result.Add(namedSchema); } var recordSchema = typeSchema as RecordSchema; if (recordSchema != null) { foreach (var field in recordSchema.Fields) { GetSchemas(field.TypeSchema, result); } } }
/// <summary> /// Initializes a new instance of the <see cref="RecordField" /> class. /// </summary> /// <param name="namedEntityAttributes">The named entity attributes.</param> /// <param name="typeSchema">The type schema.</param> /// <param name="order">The order.</param> /// <param name="hasDefaultValue">Whether the field has a default value or not.</param> /// <param name="defaultValue">The default value.</param> /// <param name="info">The info.</param> /// <param name="position">The position of the field in the schema.</param> /// <param name="attributes">The attributes.</param> internal RecordField( NamedEntityAttributes namedEntityAttributes, TypeSchema typeSchema, SortOrder order, bool hasDefaultValue, object defaultValue, MemberInfo info, int position, Dictionary<string, string> attributes) : base(attributes) { this.namedEntityAttributes = namedEntityAttributes; this.typeSchema = typeSchema; this.order = order; this.hasDefaultValue = hasDefaultValue; this.defaultValue = defaultValue; this.info = info; this.position = position; this.ShouldBeSkipped = false; this.UseDefaultValue = false; }
public static TypeSchema GetItemSchema(TypeSchema schema) { var unionSchema = schema as UnionSchema; if (unionSchema != null) { schema = unionSchema.Schemas.OfType<ArraySchema>().SingleOrDefault(); } var arraySchema = schema as ArraySchema; if (arraySchema != null) { return ((ArraySchema)AvroSerializer.CreateGeneric(arraySchema.ToString()).WriterSchema).ItemSchema; } throw new ApplicationException("Schema must be array schema"); }
/// <summary> /// Implements double dispatch. /// </summary> /// <param name="w">The writer schema.</param> /// <param name="r">The reader schema.</param> /// <returns>True if match.</returns> private TypeSchema BuildDynamic(TypeSchema w, TypeSchema r) { return this.BuildCore((dynamic)w, (dynamic)r); }
private TypeSchema BuildCore(TypeSchema w, NullableSchema r) { var schema = this.BuildDynamic(w, r.ValueSchema); return schema != null ? new NullableSchema(r.RuntimeType, schema) : null; }
/// <summary> /// Generates the array type schema. /// </summary> /// <param name="type">The type.</param> /// <param name="schemas">The schemas.</param> /// <param name="currentDepth">The current depth.</param> /// <returns> /// A new instance of schema. /// </returns> private TypeSchema BuildArrayTypeSchema(Type type, Dictionary<string, NamedSchema> schemas, uint currentDepth) { Type element = type.GetElementType(); TypeSchema elementSchema = this.CreateSchema(false, element, schemas, currentDepth + 1); return new ArraySchema(elementSchema, type); }
/// <summary> /// Initializes a new instance of the <see cref="ArraySchema"/> class. /// </summary> /// <param name="item">The item.</param> /// <param name="runtimeType">Type of the runtime.</param> internal ArraySchema( TypeSchema item, Type runtimeType) : this(item, runtimeType, new Dictionary<string, string>()) { }
/// <summary> /// according to avro spec http://avro.apache.org/docs/current/spec.html#Unions /// Unions may not contain more than one schema with the same type, except for the named types record, fixed and enum. /// For example, unions containing two array types or two map types are not permitted, but two types with different names are permitted /// </summary> /// <param name="existingSchema">the schema that's already processed.</param> /// <param name="typeSchema">the schema to check whether it's duplicate according to avro union spec.</param> /// <returns>true if existingSchema is same type as typeSchema according to avro spec on union</returns> internal static bool IsSameTypeAs(TypeSchema existingSchema, TypeSchema typeSchema) { // only add ArraySchema at most once based on above Avro spec for union var arraySchema = typeSchema as ArraySchema; var mapSchema = typeSchema as MapSchema; if (arraySchema != null) { // find previous array schema index with the same ItemSchema return existingSchema is ArraySchema && IsSameTypeAs(((ArraySchema) existingSchema).ItemSchema, arraySchema.ItemSchema); } if (mapSchema != null) { // find previous map schema index with the same ItemSchema return existingSchema is MapSchema && IsSameTypeAs(((MapSchema) existingSchema).KeySchema, mapSchema.KeySchema) && IsSameTypeAs(((MapSchema) existingSchema).ValueSchema, mapSchema.ValueSchema); } return existingSchema.Type == typeSchema.Type; }
/// <summary> /// If reader's is a union, but writer's is not the first schema in the reader's union /// that matches the writer's schema is recursively resolved against it. If none match, an error is signalled. /// </summary> /// <param name="w">The writer schema.</param> /// <param name="r">The reader schema.</param> /// <returns>True if match.</returns> private TypeSchema BuildCore(TypeSchema w, UnionSchema r) { return r.Schemas.Select(rs => this.BuildDynamic(w, rs)).SingleOrDefault(s => s != null); }
public TypeSchema Build(TypeSchema w, TypeSchema r) { this.visited.Clear(); return this.BuildDynamic(w, r); }
/// <summary> /// Creates a <see cref="ArraySchema" /> instance. /// </summary> /// <param name="itemSchema">The schema of the items.</param> /// <returns>An instance of the <see cref="ArraySchema" />.</returns> public static ArraySchema CreateArray(TypeSchema itemSchema) { return new ArraySchema(itemSchema, typeof(Array)); }
internal NullableSchema( Type nullableType, TypeSchema valueSchema) : this(nullableType, new Dictionary<string, string>(), valueSchema) { }
/// <summary> /// Creates a <see cref="RecordField" /> instance. /// </summary> /// <param name="fieldName">The field name.</param> /// <param name="fieldType">The field type.</param> /// <returns>An instance of the <see cref="RecordField" />.</returns> public static RecordField CreateField(string fieldName, TypeSchema fieldType) { if (string.IsNullOrEmpty(fieldName)) { throw new ArgumentException("Field name is not allowed to be null or empty."); } if (fieldType == null) { throw new ArgumentNullException("fieldType"); } return new RecordField( new NamedEntityAttributes(new SchemaName(fieldName), new List<string>(), string.Empty), fieldType, SortOrder.Ascending, false, null, null, -1); }
private TypeSchema BuildCore(TypeSchema w, SurrogateSchema r) { var schema = this.BuildDynamic(w, r.Surrogate); return schema != null ? new SurrogateSchema(r.RuntimeType, r.SurrogateType, r.Surrogate) : null; }
internal NullableSchema( Type nullableType, TypeSchema valueSchema) : this(nullableType, new Dictionary <string, string>(), valueSchema) { }
public static ArraySchema GetArraySchema(TypeSchema schema) { return Schema.CreateArray(schema); }
/// <summary> /// Creates a <see cref="ArraySchema" /> instance. /// </summary> /// <param name="itemSchema">The schema of the items.</param> /// <returns>An instance of the <see cref="ArraySchema" />.</returns> public static ArraySchema CreateArray(TypeSchema itemSchema) { return(new ArraySchema(itemSchema, typeof(Array))); }
internal MapSchema(TypeSchema keySchema, TypeSchema valueSchema, Type runtimeType) : this(keySchema, valueSchema, runtimeType, new Dictionary<string, string>()) { }
/// <summary> /// Creates a <see cref="MapSchema" /> instance. /// </summary> /// <param name="valueSchema">The schema of the values.</param> /// <returns>An instance of the <see cref="MapSchema" />.</returns> public static MapSchema CreateMap(TypeSchema valueSchema) { return(new MapSchema(new StringSchema(), valueSchema, typeof(Dictionary <,>))); }
internal void GenerateTypeAttributes(TypeSchema typeSchema) { var fixedSchema = typeSchema as FixedSchema; if(fixedSchema != null) { this.Write("\r\n [AvroFixed("); this.Write(this.ToStringHelper.ToStringWithCulture(fixedSchema.Size)); this.Write(", \""); this.Write(this.ToStringHelper.ToStringWithCulture(fixedSchema.Name)); this.Write("\", \""); this.Write(this.ToStringHelper.ToStringWithCulture(fixedSchema.Namespace)); this.Write("\")]"); } var unionSchema = typeSchema as UnionSchema; if(unionSchema == null) { return; } if (unionSchema.Schemas.Count == 2 && ((unionSchema.Schemas[0] is NullSchema && unionSchema.Schemas[1] is PrimitiveTypeSchema) || (unionSchema.Schemas[1] is NullSchema && unionSchema.Schemas[0] is PrimitiveTypeSchema))) { return; } else { if(unionSchema.Schemas.Any()) { this.Write("\r\n [AvroUnion("); for (int i = 0; i < unionSchema.Schemas.Count; i++) { if(unionSchema.Schemas[i] is NullSchema) { this.Write("typeof(AvroNull)"); } else { this.Write("typeof("); GenerateType(unionSchema.Schemas[i], false, true, false); this.Write(")"); } if(i < unionSchema.Schemas.Count - 1) { this.Write(", "); } } this.Write(")]"); } } }