/// <inheritdoc/> public override void ValidateSchema(LogicalSchema schema) { if (Schema.Type.Long != schema.BaseSchema.Tag) { throw new AvroTypeException("'timestamp-micros' can only be used with an underlying long type"); } }
/// <summary> /// Applies 'decimal' logical type validation for a given logical schema. /// </summary> /// <param name="schema">The schema to be validated.</param> public override void ValidateSchema(LogicalSchema schema) { if (Schema.Type.Bytes != schema.BaseSchema.Tag && Schema.Type.Fixed != schema.BaseSchema.Tag) { throw new AvroTypeException("'decimal' can only be used with an underlying bytes or fixed type"); } }
/// <summary> /// Applies 'time-millis' logical type validation for a given logical schema. /// </summary> /// <param name="schema">The schema to be validated.</param> public override void ValidateSchema(LogicalSchema schema) { if (Schema.Type.Int != schema.BaseSchema.Tag) { throw new AvroTypeException("'time-millis' can only be used with an underlying int type"); } }
/// <inheritdoc /> public override void ValidateSchema(LogicalSchema schema) { if (Schema.Type.String != schema.BaseSchema.Tag) { throw new AvroTypeException("'uuid' can only be used with an underlying string type"); } }
/// <summary> /// Converts a logical value to an instance of its base type. /// </summary> /// <param name="logicalValue">The logical value to convert.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> /// <returns>An object representing the encoded value of the base type.</returns> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var val = (decimal)logicalValue; var buffer = new byte[16]; var valBits = decimal.GetBits(val); buffer[0] = (byte)valBits[0]; buffer[1] = (byte)(valBits[0] >> 8); buffer[2] = (byte)(valBits[0] >> 16); buffer[3] = (byte)(valBits[0] >> 24); buffer[4] = (byte)valBits[1]; buffer[5] = (byte)(valBits[1] >> 8); buffer[6] = (byte)(valBits[1] >> 16); buffer[7] = (byte)(valBits[1] >> 24); buffer[8] = (byte)valBits[2]; buffer[9] = (byte)(valBits[2] >> 8); buffer[10] = (byte)(valBits[2] >> 16); buffer[11] = (byte)(valBits[2] >> 24); buffer[12] = (byte)valBits[3]; buffer[13] = (byte)(valBits[3] >> 8); buffer[14] = (byte)(valBits[3] >> 16); buffer[15] = (byte)(valBits[3] >> 24); return(Schema.Type.Bytes == schema.BaseSchema.Tag ? (object)buffer : (object)new GenericFixed((FixedSchema)schema.BaseSchema, buffer)); }
/// <inheritdoc/> public override void ValidateSchema(LogicalSchema schema) { if (Schema.Type.Bytes != schema.BaseSchema.Tag && Schema.Type.Fixed != schema.BaseSchema.Tag) { throw new AvroTypeException("'decimal' can only be used with an underlying bytes or fixed type"); } var precisionVal = schema.GetProperty("precision"); if (string.IsNullOrEmpty(precisionVal)) { throw new AvroTypeException("'decimal' requires a 'precision' property"); } var precision = int.Parse(precisionVal, CultureInfo.CurrentCulture); if (precision <= 0) { throw new AvroTypeException("'decimal' requires a 'precision' property that is greater than zero"); } var scale = GetScalePropertyValueFromSchema(schema); if (scale < 0 || scale > precision) { throw new AvroTypeException("'decimal' requires a 'scale' property that is zero or less than or equal to 'precision'"); } }
/// <inheritdoc/> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { var buffer = Schema.Type.Bytes == schema.BaseSchema.Tag ? (byte[])baseValue : ((GenericFixed)baseValue).Value; Array.Reverse(buffer); return(new AvroDecimal(new BigInteger(buffer), GetScalePropertyValueFromSchema(schema))); }
/// <summary> /// Converts a logical TimeMillisecond to an integer representing the number of milliseconds after midnight. /// </summary> /// <param name="logicalValue">The logical time to convert.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var time = (TimeSpan)logicalValue; if (time > _maxTime) { throw new ArgumentOutOfRangeException("logicalValue", "A 'time-millis' value can only have the range '00:00:00' to '23:59:59'."); } return((int)(time - UnixEpocDateTime.TimeOfDay).TotalMilliseconds); }
/// <inheritdoc/> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var time = (TimeSpan)logicalValue; if (time >= _exclusiveUpperBound) { throw new ArgumentOutOfRangeException(nameof(logicalValue), "A 'time-micros' value can only have the range '00:00:00' to '23:59:59'."); } return((time - UnixEpochDateTime.TimeOfDay).Ticks / _ticksPerMicrosecond); }
public void TestLogicalPrimitive(string s, string baseType, string logicalType) { Schema sc = Schema.Parse(s); Assert.AreEqual(Schema.Type.Logical, sc.Tag); LogicalSchema logsc = sc as LogicalSchema; Assert.AreEqual(baseType, logsc.BaseSchema.Name); Assert.AreEqual(logicalType, logsc.LogicalType.Name); testEquality(s, sc); testToString(sc); }
/// <summary> /// Converts a base value to an instance of the logical type. /// </summary> /// <param name="baseValue">The base value to convert.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> /// <returns>An object representing the encoded value of the logical type.</returns> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { var buffer = Schema.Type.Bytes == schema.BaseSchema.Tag ? (byte[])baseValue : ((GenericFixed)baseValue).Value; var valBits = new int[4]; valBits[0] = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); valBits[1] = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24); valBits[2] = buffer[8] | (buffer[9] << 8) | (buffer[10] << 16) | (buffer[11] << 24); valBits[3] = buffer[12] | (buffer[13] << 8) | (buffer[14] << 16) | (buffer[15] << 24); return(new decimal(valBits)); }
/// <inheritdoc/> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var decimalValue = (AvroDecimal)logicalValue; var logicalScale = GetScalePropertyValueFromSchema(schema); var scale = decimalValue.Scale; if (scale != logicalScale) { throw new ArgumentOutOfRangeException(nameof(logicalValue), $"The decimal value has a scale of {scale} which cannot be encoded against a logical 'decimal' with a scale of {logicalScale}"); } var buffer = decimalValue.UnscaledValue.ToByteArray(); Array.Reverse(buffer); return(Schema.Type.Bytes == schema.BaseSchema.Tag ? (object)buffer : (object)new GenericFixed( (FixedSchema)schema.BaseSchema, GetDecimalFixedByteArray(buffer, ((FixedSchema)schema.BaseSchema).Size, decimalValue.Sign < 0 ? (byte)0xFF : (byte)0x00))); }
/// <summary> /// Retrieves a logical type implementation for a given logical schema. /// </summary> /// <param name="schema">The schema.</param> /// <param name="ignoreInvalidOrUnknown">A flag to indicate if an exception should be thrown for invalid /// or unknown logical types.</param> /// <returns>A <see cref="LogicalType" />.</returns> public LogicalType GetFromLogicalSchema(LogicalSchema schema, bool ignoreInvalidOrUnknown = false) { try { if (!_logicalTypes.TryGetValue(schema.LogicalTypeName, out LogicalType logicalType)) { throw new AvroTypeException("Logical type '" + schema.LogicalTypeName + "' is not supported."); } logicalType.ValidateSchema(schema); return(logicalType); } catch (AvroTypeException) { if (!ignoreInvalidOrUnknown) { throw; } } return(null); }
/// <summary> /// Serializes a logical value object by using the underlying logical type to convert the value /// to its base value. /// </summary> /// <param name="ls">The schema for serialization</param> /// <param name="value">The value to be serialized</param> /// <param name="encoder">The encoder for serialization</param> protected virtual void WriteLogical(LogicalSchema ls, object value, Encoder encoder) { Write(ls.BaseSchema, ls.LogicalType.ConvertToBaseValue(value, ls), encoder); }
/// <summary> /// Deserializes an object based on the writer's logical schema. Uses the underlying logical type to convert /// the value to the logical type. /// </summary> /// <param name="reuse">If appropriate, uses this object instead of creating a new one.</param> /// <param name="writerSchema">The UnionSchema that the writer used.</param> /// <param name="readerSchema">The schema the reader uses.</param> /// <param name="d">The decoder for serialization.</param> /// <returns>The deserialized object.</returns> protected virtual object ReadLogical(object reuse, LogicalSchema writerSchema, Schema readerSchema, Decoder d) { LogicalSchema ls = (LogicalSchema)readerSchema; return(writerSchema.LogicalType.ConvertToLogicalValue(Read(reuse, writerSchema.BaseSchema, ls.BaseSchema, d), ls)); }
/// <summary> /// Convers an integer representing the number of milliseconds after midnight to a logical TimeMillisecond. /// </summary> /// <param name="baseValue">The number of milliseconds after midnight.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { var noMs = (int)baseValue; return(UnixEpocDateTime.TimeOfDay.Add(TimeSpan.FromMilliseconds(noMs))); }
/// <inheritdoc /> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var date = (DateTimeOffset)logicalValue; return(date.ToUnixTimeMilliseconds()); }
/// <inheritdoc /> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { return(DateTimeOffset.FromUnixTimeMilliseconds((long)baseValue)); }
/// <summary> /// Serializes a logical value object by using the underlying logical type to convert the value /// to its base value. /// </summary> /// <param name="schema">The logical schema.</param> protected WriteItem ResolveLogical(LogicalSchema schema) { var baseWriter = ResolveWriter(schema.BaseSchema); return((d, e) => baseWriter(schema.LogicalType.ConvertToBaseValue(d, schema), e)); }
/// <inheritdoc /> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { return(logicalValue.ToString()); }
private ReadItem ResolveLogical(LogicalSchema writerSchema, LogicalSchema readerSchema) { var baseReader = ResolveReader(writerSchema.BaseSchema, readerSchema.BaseSchema); return((r, d) => readerSchema.LogicalType.ConvertToLogicalValue(baseReader(r, d), readerSchema)); }
/// <summary> /// Converts a base value to an instance of the logical type. /// </summary> /// <param name="baseValue">The base value to convert.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> /// <returns>An object representing the encoded value of the logical type.</returns> public abstract object ConvertToLogicalValue(object baseValue, LogicalSchema schema);
public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) => logicalValue;
/// <summary> /// Converts a logical TimestampMillisecond to a long representing the number of milliseconds since the Unix Epoch. /// </summary> /// <param name="logicalValue">The logical date to convert.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema) { var date = ((DateTime)logicalValue).ToUniversalTime(); return((long)((date - UnixEpocDateTime).TotalMilliseconds)); }
/// <summary> /// Generates POCOS /// </summary> public void Generate() { while (string.IsNullOrEmpty(InputJsonSchema)) { Console.WriteLine($"[Choose an Input JSON Schema File]"); Console.Write($"Input file: "); InputJsonSchema = Console.ReadLine(); } while (string.IsNullOrEmpty(TargetFolder)) { Console.WriteLine($"[Choose a Target Folder]"); Console.Write($"Target Folder: "); TargetFolder = Console.ReadLine(); } while (string.IsNullOrEmpty(Namespace)) { Console.WriteLine($"[Choose a Namespace]"); Console.Write($"Namespace: "); Namespace = Console.ReadLine(); } _generatorContext = new CodegenContext(); Console.WriteLine("Reading Schema..."); LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(InputJsonSchema)); //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>(); CodegenOutputFile writer = null; if (SingleFile) { writer = _generatorContext[singleFileName]; writer .WriteLine(@"using System;") .WriteLine(@"using System.Collections.Generic;") .WriteLine(@"using System.ComponentModel.DataAnnotations;") .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;") .WriteLine(@"using System.Linq;"); if (GenerateActiveRecord) { writer.WriteLine(@"using Dapper;"); } if (TrackPropertiesChange) { writer.WriteLine(@"using System.ComponentModel;"); } writer .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent(); } if (GenerateCrudExtensions) { _dbConnectionCrudExtensions = _generatorContext[CrudExtensionsFile]; _dbConnectionCrudExtensions.Write(@" using Dapper; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.CompilerServices; "); _dbConnectionCrudExtensions .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent() .WriteLine($"public static class {CrudExtensionsClass}").WriteLine("{").IncreaseIndent(); } if (GenerateActiveRecord) { using (var writerConnectionFactory = _generatorContext[ActiveRecordIDbConnectionFactoryFile]) { writerConnectionFactory.WriteLine($@" using System; using System.Data; using System.Data.SqlClient; namespace {Namespace} {{ public class IDbConnectionFactory {{ public static IDbConnection CreateConnection() {{ string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS; Initial Catalog=AdventureWorks; Integrated Security=True;""; return new SqlConnection(connectionString); }} }} }} "); } } foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (!ShouldProcessTable(table)) { continue; } GeneratePOCO(table); } if (GenerateCrudExtensions) { _dbConnectionCrudExtensions .DecreaseIndent().WriteLine("}") // end of class .DecreaseIndent().WriteLine("}"); // end of namespace } if (SingleFile) { writer.DecreaseIndent().WriteLine("}"); // end of namespace } // since no errors happened, let's save all files _generatorContext.SaveFiles(outputFolder: TargetFolder); Console.WriteLine("Success!"); }
/// <summary> /// Generates POCOS /// </summary> /// <param name="targetFolder">Absolute path of the target folder where files will be written</param> public void Generate(string targetFolder) { Console.WriteLine($"TargetFolder: {targetFolder}"); _generatorContext = new CodegenContext(); Console.WriteLine("Reading Schema..."); LogicalSchema schema = Newtonsoft.Json.JsonConvert.DeserializeObject <LogicalSchema>(File.ReadAllText(_inputJsonSchema)); //schema.Tables = schema.Tables.Select(t => Map<LogicalTable, Table>(t)).ToList<Table>(); CodegenOutputFile writer = null; if (SingleFile) { writer = _generatorContext[singleFileName]; writer .WriteLine(@"using System;") .WriteLine(@"using System.Collections.Generic;") .WriteLine(@"using System.ComponentModel.DataAnnotations;") .WriteLine(@"using System.ComponentModel.DataAnnotations.Schema;") .WriteLine(@"using System.Linq;"); if (GenerateActiveRecord) { writer.WriteLine(@"using Dapper;"); } writer .WriteLine() .WriteLine($"namespace {Namespace}").WriteLine("{").IncreaseIndent(); } if (GenerateActiveRecord) { using (var writerConnectionFactory = _generatorContext["..\\IDbConnectionFactory.cs"]) { writerConnectionFactory.WriteLine($@" using System; using System.Data; using System.Data.SqlClient; namespace {Namespace} {{ public class IDbConnectionFactory {{ public static IDbConnection CreateConnection() {{ string connectionString = @""Data Source=MYWORKSTATION\\SQLEXPRESS; Initial Catalog=AdventureWorks; Integrated Security=True;""; return new SqlConnection(connectionString); }} }} }} "); } } foreach (var table in schema.Tables.OrderBy(t => GetClassNameForTable(t))) { if (table.TableType == "VIEW") { continue; } GeneratePOCO(table); } if (SingleFile) { writer.DecreaseIndent().WriteLine("}"); // end of namespace } // since no errors happened, let's save all files _generatorContext.SaveFiles(outputFolder: targetFolder); Console.WriteLine("Success!"); }
/// <summary> /// Convers a long representing the number of milliseconds since the Unix Epoch to a logical TimestampMillisecond. /// </summary> /// <param name="baseValue">The number of milliseconds since the Unix Epoch.</param> /// <param name="schema">The schema that represents the target of the conversion.</param> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { var noMs = (long)baseValue; return(UnixEpocDateTime.AddMilliseconds(noMs)); }
/// <inheritdoc /> public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) { return(new Guid((string)baseValue)); }
public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) => baseValue.ToString();
/// <summary> /// Applies logical type validation for a given logical schema. /// </summary> /// <param name="schema">The schema to be validated.</param> public virtual void ValidateSchema(LogicalSchema schema) { }