Beispiel #1
0
 /// <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");
     }
 }
Beispiel #2
0
 /// <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");
     }
 }
Beispiel #3
0
 /// <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");
     }
 }
Beispiel #4
0
 /// <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");
     }
 }
Beispiel #5
0
        /// <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));
        }
Beispiel #6
0
        /// <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'");
            }
        }
Beispiel #7
0
        /// <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)));
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        /// <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));
        }
Beispiel #12
0
        /// <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)));
        }
Beispiel #13
0
        /// <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);
        }
Beispiel #14
0
 /// <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);
 }
Beispiel #15
0
        /// <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));
        }
Beispiel #16
0
        /// <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)));
        }
Beispiel #17
0
        /// <inheritdoc />
        public override object ConvertToBaseValue(object logicalValue, LogicalSchema schema)
        {
            var date = (DateTimeOffset)logicalValue;

            return(date.ToUnixTimeMilliseconds());
        }
Beispiel #18
0
 /// <inheritdoc />
 public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema)
 {
     return(DateTimeOffset.FromUnixTimeMilliseconds((long)baseValue));
 }
Beispiel #19
0
        /// <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));
        }
Beispiel #20
0
 /// <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));
        }
Beispiel #22
0
 /// <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;
Beispiel #24
0
        /// <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!");
    }
Beispiel #26
0
    /// <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!");
    }
Beispiel #27
0
        /// <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));
        }
Beispiel #28
0
 /// <inheritdoc />
 public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema)
 {
     return(new Guid((string)baseValue));
 }
 public override object ConvertToLogicalValue(object baseValue, LogicalSchema schema) => baseValue.ToString();
Beispiel #30
0
 /// <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)
 {
 }